#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

from __future__ import absolute_import

import uuid

from cproton import PN_ARRAY, PN_BINARY, PN_BOOL, PN_BYTE, PN_CHAR, PN_DECIMAL128, PN_DECIMAL32, PN_DECIMAL64, \
    PN_DESCRIBED, PN_DOUBLE, PN_FLOAT, PN_INT, PN_LIST, PN_LONG, PN_MAP, PN_NULL, PN_OVERFLOW, PN_SHORT, PN_STRING, \
    PN_SYMBOL, PN_TIMESTAMP, PN_UBYTE, PN_UINT, PN_ULONG, PN_USHORT, PN_UUID, pn_data, pn_data_clear, pn_data_copy, \
    pn_data_decode, pn_data_dump, pn_data_encode, pn_data_encoded_size, pn_data_enter, pn_data_error, pn_data_exit, \
    pn_data_format, pn_data_free, pn_data_get_array, pn_data_get_array_type, pn_data_get_binary, pn_data_get_bool, \
    pn_data_get_byte, pn_data_get_char, pn_data_get_decimal128, pn_data_get_decimal32, pn_data_get_decimal64, \
    pn_data_get_double, pn_data_get_float, pn_data_get_int, pn_data_get_list, pn_data_get_long, pn_data_get_map, \
    pn_data_get_short, pn_data_get_string, pn_data_get_symbol, pn_data_get_timestamp, pn_data_get_ubyte, \
    pn_data_get_uint, pn_data_get_ulong, pn_data_get_ushort, pn_data_get_uuid, pn_data_is_array_described, \
    pn_data_is_described, pn_data_is_null, pn_data_lookup, pn_data_narrow, pn_data_next, pn_data_prev, \
    pn_data_put_array, pn_data_put_binary, pn_data_put_bool, pn_data_put_byte, pn_data_put_char, pn_data_put_decimal128, \
    pn_data_put_decimal32, pn_data_put_decimal64, pn_data_put_described, pn_data_put_double, pn_data_put_float, \
    pn_data_put_int, pn_data_put_list, pn_data_put_long, pn_data_put_map, pn_data_put_null, pn_data_put_short, \
    pn_data_put_string, pn_data_put_symbol, pn_data_put_timestamp, pn_data_put_ubyte, pn_data_put_uint, \
    pn_data_put_ulong, pn_data_put_ushort, pn_data_put_uuid, pn_data_rewind, pn_data_type, pn_data_widen, pn_error_text

from . import _compat
from ._common import Constant
from ._exceptions import DataException, EXCEPTIONS

#
# Hacks to provide Python2 <---> Python3 compatibility
#
# The results are
# |       |long|unicode|
# |Python2|long|unicode|
# |Python3| int|    str|
try:
    long()
except NameError:
    long = int
try:
    unicode()
except NameError:
    unicode = str


class UnmappedType:

    def __init__(self, msg):
        self.msg = msg

    def __repr__(self):
        return "UnmappedType(%s)" % self.msg


class ulong(long):
    """
    The ulong AMQP type.

    An unsigned 64 bit integer in the range :math:`0` to :math:`2^{64} - 1` inclusive.
    """

    def __init__(self, l):
        if (l < 0):
            raise AssertionError("initializing ulong with negative value")
        super(ulong, self).__new__(ulong, l)

    def __repr__(self):
        return "ulong(%s)" % long.__repr__(self)


class timestamp(long):
    """
    The timestamp AMQP type.

    An absolute point in time, represented by a signed 64 bit value measuring
    milliseconds since the epoch. This value is encoded using the Unix ``time_t``
    [IEEE1003] encoding of UTC, but with a precision of milliseconds. For
    example, ``1311704463521`` represents the moment ``2011-07-26T18:21:03.521Z``.
    """

    def __repr__(self):
        return "timestamp(%s)" % long.__repr__(self)


class symbol(unicode):
    """
    The symbol AMQP type.

    Symbolic values from a constrained domain, represented by a sequence of ASCII characters.
    """

    def __repr__(self):
        return "symbol(%s)" % unicode.__repr__(self)


class char(unicode):
    """
    The char AMQP type.

    A 32 bit UTF-32BE encoded Unicode character.
    """

    def __repr__(self):
        return "char(%s)" % unicode.__repr__(self)


class byte(int):
    """
    The byte AMQP type.

    An 8 bit signed integer in the range :math:`-(2^7)` to :math:`2^7 - 1` inclusive.
    """

    def __repr__(self):
        return "byte(%s)" % int.__repr__(self)


class short(int):
    """
    The short AMQP type.

    A 16 bit signed integer in the range :math:`-(2^{15})` to :math:`2^{15} - 1` inclusive.
    """

    def __repr__(self):
        return "short(%s)" % int.__repr__(self)


class int32(int):
    """
    The signed int AMQP type.

    A 32 bit signed integer in the range :math:`-(2^{31})` to :math:`2^{31} - 1` inclusive.
    """

    def __repr__(self):
        return "int32(%s)" % int.__repr__(self)


class ubyte(int):
    """
    The unsigned byte AMQP type.

    An 8 bit unsigned integer in the range :math:`0` to :math:`2^8 - 1` inclusive.
    """

    def __init__(self, i):
        if (i < 0):
            raise AssertionError("initializing ubyte with negative value")
        super(ubyte, self).__new__(ubyte, i)

    def __repr__(self):
        return "ubyte(%s)" % int.__repr__(self)


class ushort(int):
    """
    The unsigned short AMQP type.

    A 16 bit unsigned integer in the range :math:`0` to :math:`2^{16} - 1` inclusive.
    """

    def __init__(self, i):
        if (i < 0):
            raise AssertionError("initializing ushort with negative value")
        super(ushort, self).__new__(ushort, i)

    def __repr__(self):
        return "ushort(%s)" % int.__repr__(self)


class uint(long):
    """
    The unsigned int AMQP type.

    A 32 bit unsigned integer in the range :math:`0` to :math:`2^{32} - 1` inclusive.
    """

    def __init__(self, l):
        if (l < 0):
            raise AssertionError("initializing uint with negative value")
        super(uint, self).__new__(uint, l)

    def __repr__(self):
        return "uint(%s)" % long.__repr__(self)


class float32(float):
    """
    The float AMQP type.

    A 32 bit floating point number (IEEE 754-2008 binary32).
    """

    def __repr__(self):
        return "float32(%s)" % float.__repr__(self)


class decimal32(int):
    """
    The decimal32 AMQP type.

    A 32 bit decimal floating point  number (IEEE 754-2008 decimal32).
    """

    def __repr__(self):
        return "decimal32(%s)" % int.__repr__(self)


class decimal64(long):
    """
    The decimal64 AMQP type.

    A 64 bit decimal floating point number (IEEE 754-2008 decimal64).
    """

    def __repr__(self):
        return "decimal64(%s)" % long.__repr__(self)


class decimal128(bytes):
    """
    The decimal128 AMQP type.

    A 128-bit decimal floating-point number (IEEE 754-2008 decimal128).
    """

    def __repr__(self):
        return "decimal128(%s)" % bytes.__repr__(self)


class Described(object):
    """
    A described AMQP type.

    :ivar descriptor: A symbol describing the value.
    :vartype descriptor: :class:`symbol`
    :ivar value: The described value
    :vartype value: Any AMQP value
    """

    def __init__(self, descriptor, value):
        self.descriptor = descriptor
        self.value = value

    def __repr__(self):
        return "Described(%r, %r)" % (self.descriptor, self.value)

    def __eq__(self, o):
        if isinstance(o, Described):
            return self.descriptor == o.descriptor and self.value == o.value
        else:
            return False


UNDESCRIBED = Constant("UNDESCRIBED")


class Array(object):
    """
    An AMQP array, a sequence of AMQP values of a single type.

    This class provides a convenient way to handle AMQP arrays when used with
    convenience methods :func:`Data.get_py_array` and :func:`Data.put_py_array`.

    :ivar descriptor: Optional descriptor if the array is to be described, otherwise ``None``
    :ivar type: Array element type, as an integer. The :class:`Data` class has constants defined
        for all the valid AMQP types. For example, for an array of double values, use
        :const:`Data.DOUBLE`, which has integer value 14.
    :ivar elements: A Python list of elements of the appropriate type.
    """

    def __init__(self, descriptor, type, *elements):
        self.descriptor = descriptor
        self.type = type
        self.elements = elements

    def __iter__(self):
        return iter(self.elements)

    def __repr__(self):
        if self.elements:
            els = ", %s" % (", ".join(map(repr, self.elements)))
        else:
            els = ""
        return "Array(%r, %r%s)" % (self.descriptor, self.type, els)

    def __eq__(self, o):
        if isinstance(o, Array):
            return self.descriptor == o.descriptor and \
                self.type == o.type and self.elements == o.elements
        else:
            return False


def _check_type(s, allow_ulong=False, raise_on_error=True):
    if isinstance(s, symbol):
        return s
    if allow_ulong and isinstance(s, ulong):
        return s
    if isinstance(s, str):
        # Must be py2 or py3 str
        return symbol(s)
    if isinstance(s, unicode):
        # This must be python2 unicode as we already detected py3 str above
        return symbol(s.encode('utf-8'))
    if raise_on_error:
        raise TypeError('Non-symbol type %s: %s' % (type(s), s))
    return s


def _check_is_symbol(s, raise_on_error=True):
    return _check_type(s, allow_ulong=False, raise_on_error=raise_on_error)


def _check_is_symbol_or_ulong(s, raise_on_error=True):
    return _check_type(s, allow_ulong=True, raise_on_error=raise_on_error)


class RestrictedKeyDict(dict):
    """Parent class for :class:`PropertyDict` and :class:`AnnotationDict`"""

    def __init__(self, validation_fn, e=None, raise_on_error=True, **kwargs):
        super(RestrictedKeyDict, self).__init__()
        self.validation_fn = validation_fn
        self.raise_on_error = raise_on_error
        self.update(e, **kwargs)

    def __setitem__(self, key, value):
        """Checks if the key is a :class:`symbol` type before setting the value"""
        try:
            return super(RestrictedKeyDict, self).__setitem__(self.validation_fn(key, self.raise_on_error), value)
        except TypeError:
            pass
        # __setitem__() must raise a KeyError, not TypeError
        raise KeyError('invalid non-symbol key: %s: %s' % (type(key), key))

    def update(self, e=None, **kwargs):
        """
        Equivalent to dict.update(), but it was needed to call :meth:`__setitem__()`
        instead of ``dict.__setitem__()``.
        """
        if e:
            try:
                for k in e:
                    self.__setitem__(k, e[k])
            except TypeError:
                self.__setitem__(k[0], k[1])  # use tuple consumed from from zip
                for (k, v) in e:
                    self.__setitem__(k, v)
        for k in kwargs:
            self.__setitem__(k, kwargs[k])


class PropertyDict(RestrictedKeyDict):
    """
    A dictionary that only takes :class:`symbol` types as a key.
    However, if a string key is provided, it will be silently converted
    into a symbol key.

        >>> from proton import symbol, ulong, PropertyDict
        >>> a = PropertyDict(one=1, two=2)
        >>> b = PropertyDict({'one':1, symbol('two'):2})
        >>> c = PropertyDict(zip(['one', symbol('two')], [1, 2]))
        >>> d = PropertyDict([(symbol('one'), 1), ('two', 2)])
        >>> e = PropertyDict(a)
        >>> a == b == c == d == e
        True

    By default, non-string and non-symbol keys cause a ``KeyError`` to be raised:

        >>> PropertyDict({'one':1, 2:'two'})
          ...
        KeyError: "invalid non-symbol key: <type 'int'>: 2"

    but by setting ``raise_on_error=False``, non-string and non-symbol keys will be ignored:

        >>> PropertyDict({'one':1, 2:'two'}, raise_on_error=False)
        PropertyDict({2: 'two', symbol(u'one'): 1})

    :param e: Initialization for ``dict``
    :type e: ``dict`` or ``list`` of ``tuple`` or ``zip`` object
    :param raise_on_error: If ``True``, will raise an ``KeyError`` if a non-string or non-symbol
        is encountered as a key in the initialization, or in a subsequent operation which
        adds such an key. If ``False``, non-strings and non-symbols will be added as keys
        to the dictionary without an error.
    :type raise_on_error: ``bool``
    :param kwargs: Keyword args for initializing a ``dict`` of the form key1=val1, key2=val2, ...
    """

    def __init__(self, e=None, raise_on_error=True, **kwargs):
        super(PropertyDict, self).__init__(_check_is_symbol, e, raise_on_error, **kwargs)

    def __repr__(self):
        """ Representation of PropertyDict """
        return 'PropertyDict(%s)' % super(PropertyDict, self).__repr__()


class AnnotationDict(RestrictedKeyDict):
    """
    A dictionary that only takes :class:`symbol` or :class:`ulong` types
    as a key. However, if a string key is provided, it will be silently
    converted into a symbol key.

        >>> from proton import symbol, ulong, AnnotationDict
        >>> a = AnnotationDict(one=1, two=2)
        >>> a[ulong(3)] = 'three'
        >>> b = AnnotationDict({'one':1, symbol('two'):2, ulong(3):'three'})
        >>> c = AnnotationDict(zip([symbol('one'), 'two', ulong(3)], [1, 2, 'three']))
        >>> d = AnnotationDict([('one', 1), (symbol('two'), 2), (ulong(3), 'three')])
        >>> e = AnnotationDict(a)
        >>> a == b == c == d == e
        True

    By default, non-string, non-symbol and non-ulong keys cause a ``KeyError`` to be raised:

        >>> AnnotationDict({'one': 1, 2: 'two'})
          ...
        KeyError: "invalid non-symbol key: <type 'int'>: 2"

    but by setting ``raise_on_error=False``, non-string, non-symbol and non-ulong keys will be ignored:

        >>> AnnotationDict({'one': 1, 2: 'two'}, raise_on_error=False)
        AnnotationDict({2: 'two', symbol(u'one'): 1})

    :param e: Initialization for ``dict``
    :type e: ``dict`` or ``list`` of ``tuple`` or ``zip`` object
    :param raise_on_error: If ``True``, will raise an ``KeyError`` if a non-string, non-symbol or
        non-ulong is encountered as a key in the initialization, or in a subsequent
        operation which adds such an key. If ``False``, non-strings, non-ulongs and non-symbols
        will be added as keys to the dictionary without an error.
    :type raise_on_error: ``bool``
    :param kwargs: Keyword args for initializing a ``dict`` of the form key1=val1, key2=val2, ...
    """

    def __init__(self, e=None, raise_on_error=True, **kwargs):
        super(AnnotationDict, self).__init__(_check_is_symbol_or_ulong, e, raise_on_error, **kwargs)

    def __repr__(self):
        """ Representation of AnnotationDict """
        return 'AnnotationDict(%s)' % super(AnnotationDict, self).__repr__()


class SymbolList(list):
    """
    A list that can only hold :class:`symbol` elements. However, if any string elements
    are present, they will be converted to symbols.

        >>> a = SymbolList(['one', symbol('two'), 'three'])
        >>> b = SymbolList([symbol('one'), 'two', symbol('three')])
        >>> c = SymbolList(a)
        >>> a == b == c
        True

    By default, using any key other than a symbol or string will result in a ``TypeError``:

        >>> SymbolList(['one', symbol('two'), 3])
          ...
        TypeError: Non-symbol type <class 'int'>: 3

    but by setting ``raise_on_error=False``, non-symbol and non-string keys will be ignored:

        >>> SymbolList(['one', symbol('two'), 3], raise_on_error=False)
        SymbolList([symbol(u'one'), symbol(u'two'), 3])

    :param t: Initialization for list
    :type t: ``list``
    :param raise_on_error: If ``True``, will raise an ``TypeError`` if a non-string or non-symbol is
        encountered in the initialization list, or in a subsequent operation which adds such
        an element. If ``False``, non-strings and non-symbols will be added to the list without
        an error.
    :type raise_on_error: ``bool``
    """

    def __init__(self, t=None, raise_on_error=True):
        super(SymbolList, self).__init__()
        self.raise_on_error = raise_on_error
        if t:
            self.extend(t)

    def _check_list(self, t):
        """ Check all items in list are :class:`symbol`s (or are converted to symbols). """
        l = []
        if t:
            for v in t:
                l.append(_check_is_symbol(v, self.raise_on_error))
        return l

    def append(self, v):
        """ Add a single value v to the end of the list """
        return super(SymbolList, self).append(_check_is_symbol(v, self.raise_on_error))

    def extend(self, t):
        """ Add all elements of an iterable t to the end of the list """
        return super(SymbolList, self).extend(self._check_list(t))

    def insert(self, i, v):
        """ Insert a value v at index i """
        return super(SymbolList, self).insert(i, _check_is_symbol(v, self.raise_on_error))

    def __add__(self, t):
        """ Handles list1 + list2 """
        return SymbolList(super(SymbolList, self).__add__(self._check_list(t)), raise_on_error=self.raise_on_error)

    def __iadd__(self, t):
        """ Handles list1 += list2 """
        return super(SymbolList, self).__iadd__(self._check_list(t))

    def __setitem__(self, i, t):
        """ Handles list[i] = v """
        return super(SymbolList, self).__setitem__(i, _check_is_symbol(t, self.raise_on_error))

    def __repr__(self):
        """ Representation of SymbolList """
        return 'SymbolList(%s)' % super(SymbolList, self).__repr__()


class Data:
    """
    The :class:`Data` class provides an interface for decoding, extracting,
    creating, and encoding arbitrary AMQP data. A :class:`Data` object
    contains a tree of AMQP values. Leaf nodes in this tree correspond
    to scalars in the AMQP type system such as :const:`ints <INT>` or
    :const:`strings <STRING>`. Non-leaf nodes in this tree correspond to
    compound values in the AMQP type system such as :const:`lists <LIST>`,
    :const:`maps <MAP>`, :const:`arrays <ARRAY>`, or :const:`described values <DESCRIBED>`.
    The root node of the tree is the :class:`Data` object itself and can have
    an arbitrary number of children.

    A :class:`Data` object maintains the notion of the current sibling node
    and a current parent node. Siblings are ordered within their parent.
    Values are accessed and/or added by using the :meth:`next`, :meth:`prev`,
    :meth:`enter`, and :meth:`exit` methods to navigate to the desired location in
    the tree and using the supplied variety of ``put_*`` / ``get_*`` methods to
    access or add a value of the desired type.

    The ``put_*`` methods will always add a value *after* the current node
    in the tree. If the current node has a next sibling the ``put_*`` method
    will overwrite the value on this node. If there is no current node
    or the current node has no next sibling then one will be added. The
    ``put_*`` methods always set the added/modified node to the current
    node. The ``get_*`` methods read the value of the current node and do
    not change which node is current.

    The following types of scalar values are supported:

        * :const:`NULL`
        * :const:`BOOL`
        * :const:`UBYTE`
        * :const:`USHORT`
        * :const:`SHORT`
        * :const:`UINT`
        * :const:`INT`
        * :const:`ULONG`
        * :const:`LONG`
        * :const:`FLOAT`
        * :const:`DOUBLE`
        * :const:`BINARY`
        * :const:`STRING`
        * :const:`SYMBOL`

    The following types of compound values are supported:

        * :const:`DESCRIBED`
        * :const:`ARRAY`
        * :const:`LIST`
        * :const:`MAP`
    """

    NULL = PN_NULL  #: A null value.
    BOOL = PN_BOOL  #: A boolean value.
    UBYTE = PN_UBYTE  #: An unsigned byte value.
    BYTE = PN_BYTE  #: A signed byte value.
    USHORT = PN_USHORT  #: An unsigned short value.
    SHORT = PN_SHORT  #: A short value.
    UINT = PN_UINT  #: An unsigned int value.
    INT = PN_INT  #: A signed int value.
    CHAR = PN_CHAR  #: A character value.
    ULONG = PN_ULONG  #: An unsigned long value.
    LONG = PN_LONG  #: A signed long value.
    TIMESTAMP = PN_TIMESTAMP  #: A timestamp value.
    FLOAT = PN_FLOAT  #: A float value.
    DOUBLE = PN_DOUBLE  #: A double value.
    DECIMAL32 = PN_DECIMAL32  #: A DECIMAL32 value.
    DECIMAL64 = PN_DECIMAL64  #: A DECIMAL64 value.
    DECIMAL128 = PN_DECIMAL128  #: A DECIMAL128 value.
    UUID = PN_UUID  #: A UUID value.
    BINARY = PN_BINARY  #: A binary string.
    STRING = PN_STRING  #: A unicode string.
    SYMBOL = PN_SYMBOL  #: A symbolic string.
    DESCRIBED = PN_DESCRIBED  #: A described value.
    ARRAY = PN_ARRAY  #: An array value.
    LIST = PN_LIST  #: A list value.
    MAP = PN_MAP  #: A map value.

    type_names = {
        NULL: "null",
        BOOL: "bool",
        BYTE: "byte",
        UBYTE: "ubyte",
        SHORT: "short",
        USHORT: "ushort",
        INT: "int",
        UINT: "uint",
        CHAR: "char",
        LONG: "long",
        ULONG: "ulong",
        TIMESTAMP: "timestamp",
        FLOAT: "float",
        DOUBLE: "double",
        DECIMAL32: "decimal32",
        DECIMAL64: "decimal64",
        DECIMAL128: "decimal128",
        UUID: "uuid",
        BINARY: "binary",
        STRING: "string",
        SYMBOL: "symbol",
        DESCRIBED: "described",
        ARRAY: "array",
        LIST: "list",
        MAP: "map"
    }
    """
    A map which uses the enumerated type as a key to get a text name for the type.
    """

    @classmethod
    def type_name(amqptype):
        """
        Return a string name for an AMQP type.

        :param type: Numeric Proton AMQP type (`enum pn_type_t`)
        :type type: integer
        :rtype: String describing the AMQP type with numeric value `amqptype`
        """
        return Data.type_names[amqptype]

    def __init__(self, capacity=16):
        if isinstance(capacity, (int, long)):
            self._data = pn_data(capacity)
            self._free = True
        else:
            self._data = capacity
            self._free = False

    def __del__(self):
        if self._free and hasattr(self, "_data"):
            pn_data_free(self._data)
            del self._data

    def _check(self, err):
        if err < 0:
            exc = EXCEPTIONS.get(err, DataException)
            raise exc("[%s]: %s" % (err, pn_error_text(pn_data_error(self._data))))
        else:
            return err

    def clear(self):
        """
        Clears the data object.
        """
        pn_data_clear(self._data)

    def rewind(self):
        """
        Clears current node and sets the parent to the root node.  Clearing the
        current node sets it _before_ the first node, calling next() will advance to
        the first node.
        """
        assert self._data is not None
        pn_data_rewind(self._data)

    def next(self):
        """
        Advances the current node to its next sibling and returns its
        type. If there is no next sibling the current node remains
        unchanged and ``None`` is returned.

        :return: Node type or ``None``
        :rtype: ``int`` or ``None``
        """
        found = pn_data_next(self._data)
        if found:
            return self.type()
        else:
            return None

    def prev(self):
        """
        Advances the current node to its previous sibling and returns its
        type. If there is no previous sibling the current node remains
        unchanged and ``None`` is returned.

        :return: Node type or ``None``
        :rtype: ``int`` or ``None``
        """
        found = pn_data_prev(self._data)
        if found:
            return self.type()
        else:
            return None

    def enter(self):
        """
        Sets the parent node to the current node and clears the current node.
        Clearing the current node sets it *before* the first child,
        call :meth:`next` to advance to the first child.

        :return: ``True`` iff the pointers to the current/parent nodes are changed,
            ``False`` otherwise.
        :rtype: ``bool``
        """
        return pn_data_enter(self._data)

    def exit(self):
        """
        Sets the current node to the parent node and the parent node to
        its own parent.

        :return: ``True`` iff the pointers to the current/parent nodes are changed,
            ``False`` otherwise.
        :rtype: ``bool``
        """
        return pn_data_exit(self._data)

    def lookup(self, name):
        return pn_data_lookup(self._data, name)

    def narrow(self):
        """
        Modify this :class:`Data` object to behave as if the current node is the
        root node of the tree. This impacts the behavior of :meth:`rewind`,
        :meth:`next`, :meth:`prev`, and anything else that depends on the
        navigational state of the :class:`Data` object. Use :meth:`widen`
        to reverse the effect of this operation.
        """
        pn_data_narrow(self._data)

    def widen(self):
        """ Reverse the effect of :meth:`narrow`. """
        pn_data_widen(self._data)

    def type(self):
        """
        Returns the type of the current node. Returns `None` if there is no
        current node.

        :return: The current node type enumeration.
        :rtype: ``int`` or ``None``
        """
        dtype = pn_data_type(self._data)
        if dtype == -1:
            return None
        else:
            return dtype

    def encoded_size(self):
        """
        Returns the size in bytes needed to encode the data in AMQP format.

        :return: The size of the encoded data or an error code if data is invalid.
        :rtype: ``int``
        """
        return pn_data_encoded_size(self._data)

    def encode(self):
        """
        Returns a representation of the data encoded in AMQP format.

        :return: The size of the encoded data
        :rtype: ``int``
        :raise: :exc:`DataException` if there is a Proton error.
        """
        size = 1024
        while True:
            cd, enc = pn_data_encode(self._data, size)
            if cd == PN_OVERFLOW:
                size *= 2
            elif cd >= 0:
                return enc
            else:
                self._check(cd)

    def decode(self, encoded):
        """
        Decodes the first value from supplied AMQP data and returns the
        number of bytes consumed.

        :type encoded: binary
        :param encoded: AMQP encoded binary data
        :raise: :exc:`DataException` if there is a Proton error.
        """
        return self._check(pn_data_decode(self._data, encoded))

    def put_list(self):
        """
        Puts a list value. Elements may be filled by entering the list
        node and putting element values.

            >>> data = Data()
            >>> data.put_list()
            >>> data.enter()
            >>> data.put_int(1)
            >>> data.put_int(2)
            >>> data.put_int(3)
            >>> data.exit()

        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_list(self._data))

    def put_map(self):
        """
        Puts a map value. Elements may be filled by entering the map node
        and putting alternating key value pairs.

            >>> data = Data()
            >>> data.put_map()
            >>> data.enter()
            >>> data.put_string("key")
            >>> data.put_string("value")
            >>> data.exit()

        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_map(self._data))

    def put_array(self, described, element_type):
        """
        Puts an array value. Elements may be filled by entering the array
        node and putting the element values. The values must all be of the
        specified array element type. If an array is described then the
        first child value of the array is the descriptor and may be of any
        type.

            >>> data = Data()
            >>>
            >>> data.put_array(False, Data.INT)
            >>> data.enter()
            >>> data.put_int(1)
            >>> data.put_int(2)
            >>> data.put_int(3)
            >>> data.exit()
            >>>
            >>> data.put_array(True, Data.DOUBLE)
            >>> data.enter()
            >>> data.put_symbol("array-descriptor")
            >>> data.put_double(1.1)
            >>> data.put_double(1.2)
            >>> data.put_double(1.3)
            >>> data.exit()

        :type described: bool
        :param described: specifies whether the array is described
        :type element_type: int
        :param element_type: the type of the array elements
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_array(self._data, described, element_type))

    def put_described(self):
        """
        Puts a described value. A described node has two children, the
        descriptor and the value. These are specified by entering the node
        and putting the desired values.

            >>> data = Data()
            >>> data.put_described()
            >>> data.enter()
            >>> data.put_symbol("value-descriptor")
            >>> data.put_string("the value")
            >>> data.exit()

        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_described(self._data))

    def put_null(self):
        """
        Puts a null value.

        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_null(self._data))

    def put_bool(self, b):
        """
        Puts a boolean value.

        :param b: a boolean value
        :type b: ``bool`` or ``int``
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_bool(self._data, b))

    def put_ubyte(self, ub):
        """
        Puts an unsigned byte value.

        :param ub: an integral value in the range :math:`0` to :math:`2^8 - 1` inclusive
        :type ub: ``int``, :class:`ubyte`
        :raise: * ``AssertionError`` if parameter is out of the range :math:`0` to :math:`2^8 - 1` inclusive.
                * :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_ubyte(self._data, ub))

    def put_byte(self, b):
        """
        Puts a signed byte value.

        :param b: an integral value in the range :math:`-(2^7)` to :math:`2^7 - 1` inclusive.
        :type b: ``int``, :class:`byte`
        :raise: * ``AssertionError`` if parameter is out of the range :math:`-(2^7)` to :math:`2^7 - 1` inclusive.
                * :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_byte(self._data, b))

    def put_ushort(self, us):
        """
        Puts an unsigned short value.

        :param us: an integral value in the range :math:`0` to :math:`2^{16} - 1` inclusive.
        :type us: ``int``, :class:`ushort`
        :raise: * ``AssertionError`` if parameter is out of the range :math:`0` to :math:`2^{16} - 1` inclusive.
                * :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_ushort(self._data, us))

    def put_short(self, s):
        """
        Puts a signed short value.

        :param s: an integral value in the range :math:`-(2^{15})` to :math:`2^{15} - 1` inclusive.
        :type s: ``int``, :class:`short`
        :raise: * ``AssertionError`` if parameter is out of the range :math:`-(2^{15})` to :math:`2^{15} - 1` inclusive.
                * :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_short(self._data, s))

    def put_uint(self, ui):
        """
        Puts an unsigned int value.

        :param ui: an integral value in the range :math:`0` to :math:`2^{32} - 1` inclusive.
        :type ui: ``int``, :class:`uint`
        :raise: * ``AssertionError`` if parameter is out of the range :math:`0` to :math:`2^{32} - 1` inclusive.
                * :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_uint(self._data, ui))

    def put_int(self, i):
        """
        Puts a signed int value.

        :param i: an integral value in the range :math:`-(2^{31})` to :math:`2^{31} - 1` inclusive.
        :type i: ``int``, :class:`int32`
        :raise: * ``AssertionError`` if parameter is out of the range :math:`-(2^{31})` to :math:`2^{31} - 1` inclusive.
                * :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_int(self._data, i))

    def put_char(self, c):
        """
        Puts a char value.

        :param c: a single character
        :type c: ``str``, :class:`char`
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_char(self._data, ord(c)))

    def put_ulong(self, ul):
        """
        Puts an unsigned long value.

        :param ul: an integral value in the range :math:`0` to :math:`2^{64} - 1` inclusive.
        :type ul: ``int``, ``long``, :class:`ulong`
        :raise: * ``AssertionError`` if parameter is out of the range :math:`0` to :math:`2^{64} - 1` inclusive.
                * :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_ulong(self._data, ul))

    def put_long(self, l):
        """
        Puts a signed long value.

        :param l: an integral value in the range :math:`-(2^{63})` to :math:`2^{63} - 1` inclusive.
        :type ul: ``int``, ``long``
        :raise: * ``AssertionError`` if parameter is out of the range :math:`-(2^{63})` to :math:`2^{63} - 1` inclusive.
                * :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_long(self._data, l))

    def put_timestamp(self, t):
        """
        Puts a timestamp value.

        :param t: a positive integral value
        :type t: ``int``, :class:`timestamp`
        :raise: * ``AssertionError`` if parameter is negative.
                * :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_timestamp(self._data, t))

    def put_float(self, f):
        """
        Puts a float value.

        :param f: a floating point value
        :type f: ``float``, :class:`float32`
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_float(self._data, f))

    def put_double(self, d):
        """
        Puts a double value.

        :param d: a floating point value.
        :type d: ``double``
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_double(self._data, d))

    def put_decimal32(self, d):
        """
        Puts a decimal32 value.

        :param d: a decimal32 number encoded in an 32-bit integral value.
        :type d: ``int``, :class:`decimal32`
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_decimal32(self._data, d))

    def put_decimal64(self, d):
        """
        Puts a decimal64 value.

        :param d: a decimal64 number encoded in an 32-bit integral value.
        :type d: ``int``, ``long``, :class:`decimal64`
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_decimal64(self._data, d))

    def put_decimal128(self, d):
        """
        Puts a decimal128 value.

        :param d: a decimal128 value encoded in a 16-byte binary value.
        :type d: ``bytes``, :class:`decimal128`
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_decimal128(self._data, d))

    def put_uuid(self, u):
        """
        Puts a UUID value.

        :param u: a uuid value.
        :type u: ``uuid.UUID``
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_uuid(self._data, u.bytes))

    def put_binary(self, b):
        """
        Puts a binary value.

        :param b: a binary value
        :type b: ``bytes``
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_binary(self._data, b))

    def put_memoryview(self, mv):
        """
        Put a Python memoryview object as an AMQP binary value.

        :param mv: A Python memoryview object
        :type mv: ``memoryview``
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self.put_binary(mv.tobytes())

    def put_buffer(self, buff):
        """
        Put a Python buffer object as an AMQP binary value.

        :param buff: A Python buffer object (**CHECK THIS**)
        :type buff: Any object supporting the Python buffer interface.
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self.put_binary(bytes(buff))

    def put_string(self, s):
        """
        Puts a unicode value.

        :param s: a unicode string
        :type s: ``str`` (Python 3.x) or ``unicode`` (Python 2.x)
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_string(self._data, s.encode("utf8")))

    def put_symbol(self, s):
        """
        Puts a symbolic value.

        :param s: the symbol name
        :type s: string, :class:`symbol`
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_put_symbol(self._data, s.encode('ascii')))

    def get_list(self):
        """
        If the current node is a list, return the number of elements,
        otherwise return 0. List elements can be accessed by entering
        the list.

            >>> count = data.get_list()
            >>> data.enter()
            >>> for i in range(count):
            ...   type = data.next()
            ...   if type == Data.STRING:
            ...     print data.get_string()
            ...   elif type == ...:
            ...     ...
            >>> data.exit()

        :return: the number of child elements of a list node
        :rtype: ``int``
        """
        return pn_data_get_list(self._data)

    def get_map(self):
        """
        If the current node is a map, return the number of child elements,
        otherwise return 0. Key value pairs can be accessed by entering
        the map.

            >>> count = data.get_map()
            >>> data.enter()
            >>> for i in range(count/2):
            ...   type = data.next()
            ...   if type == Data.STRING:
            ...     print data.get_string()
            ...   elif type == ...:
            ...     ...
            >>> data.exit()

        :return: the number of child elements of a map node
        :rtype: ``int``
        """
        return pn_data_get_map(self._data)

    def get_array(self):
        """
        If the current node is an array, return a tuple of the element
        count, a boolean indicating whether the array is described, and
        the type of each element, otherwise return ``None``. Array
        data can be accessed by entering the array.

            >>> # read an array of strings with a symbolic descriptor
            >>> count, described, type = data.get_array()
            >>> data.enter()
            >>> data.next()
            >>> print "Descriptor:", data.get_symbol()
            >>> for i in range(count):
            ...    data.next()
            ...    print "Element:", data.get_string()
            >>> data.exit()

        :return: A tuple containing the number of array elements, the descriptor
            (or ``None`` if no descriptor) and the enumerated array element type.
        :rtype: ``tuple`` (``int``, ``str`` or ``None``, ``int``)
        """
        count = pn_data_get_array(self._data)
        described = pn_data_is_array_described(self._data)
        type = pn_data_get_array_type(self._data)
        if type == -1:
            type = None
        return count, described, type

    def is_described(self):
        """
        Checks if the current node is a described value. The descriptor
        and value may be accessed by entering the described value.

            >>> # read a symbolically described string
            >>> assert data.is_described() # will error if the current node is not described
            >>> data.enter()
            >>> data.next()
            >>> print data.get_symbol()
            >>> data.next()
            >>> print data.get_string()
            >>> data.exit()

        :return: ``True`` if the current node is a described type, ``False`` otherwise.
        :rtype: ``bool``
        """
        return pn_data_is_described(self._data)

    def is_null(self):
        """
        Checks if the current node is the AMQP null type.

        :return: ``True`` if the current node is the AMQP null type, ``False`` otherwise.
        :rtype: ``bool``
        """
        return pn_data_is_null(self._data)

    def get_bool(self):
        """
        Get the current node value as a ``bool``.

        :return: If the current node is a boolean type, returns its value,
            ``False`` otherwise.
        :rtype: ``bool``
        """
        return pn_data_get_bool(self._data)

    def get_ubyte(self):
        """
        Get the current node value as a :class:`ubyte`.

        :return: If the current node is an unsigned byte, its value, 0 otherwise.
        :rtype: :class:`ubyte`
        """
        return ubyte(pn_data_get_ubyte(self._data))

    def get_byte(self):
        """
        Get the current node value as a :class:`byte`.

        :return: If the current node is a signed byte, its value, 0 otherwise.
        :rtype: :class:`byte`
        """
        return byte(pn_data_get_byte(self._data))

    def get_ushort(self):
        """
        Get the current node value as a :class:`ushort`.

        :return: If the current node is an unsigned short, its value, 0 otherwise.
        :rtype: :class:`ushort`
        """
        return ushort(pn_data_get_ushort(self._data))

    def get_short(self):
        """
        Get the current node value as a :class:`short`.

        :return: If the current node is a signed short, its value, 0 otherwise.
        :rtype: :class:`short`
        """
        return short(pn_data_get_short(self._data))

    def get_uint(self):
        """
        Get the current node value as a :class:`uint`.

        :return: If the current node is an unsigned int, its value, 0 otherwise.
        :rtype: :class:`uint`
        """
        return uint(pn_data_get_uint(self._data))

    def get_int(self):
        """
        Get the current node value as a :class:`int32`.

        :return: If the current node is a signed int, its value, 0 otherwise.
        :rtype: :class:`int32`
        """
        return int32(pn_data_get_int(self._data))

    def get_char(self):
        """
        Get the current node value as a :class:`char`.

        :return: If the current node is a char, its value, 0 otherwise.
        :rtype: :class:`char`
        """
        return char(_compat.unichr(pn_data_get_char(self._data)))

    def get_ulong(self):
        """
        Get the current node value as a :class:`long`.

        :return: If the current node is an unsigned long, its value, 0 otherwise.
        :rtype: :class:`ulong`
        """
        return ulong(pn_data_get_ulong(self._data))

    def get_long(self):
        """
        Get the current node value as a :class:`ulong`.

        :return: If the current node is an signed long, its value, 0 otherwise.
        :rtype: :class:`long`
        """
        return long(pn_data_get_long(self._data))

    def get_timestamp(self):
        """
        Get the current node value as a :class:`timestamp`.

        :return: If the current node is a timestamp, its value, 0 otherwise.
        :rtype: :class:`timestamp`
        """
        return timestamp(pn_data_get_timestamp(self._data))

    def get_float(self):
        """
        Get the current node value as a :class:`float32`.

        :return: If the current node is a float, its value, 0 otherwise.
        :rtype: :class:`float32`
        """
        return float32(pn_data_get_float(self._data))

    def get_double(self):
        """
        Get the current node value as a ``double``.

        :return: If the current node is a double, its value, 0 otherwise.
        :rtype: ``double``
        """
        return pn_data_get_double(self._data)

    # XXX: need to convert
    def get_decimal32(self):
        """
        Get the current node value as a :class:`decimal32`.

        :return: If the current node is a decimal32, its value, 0 otherwise.
        :rtype: :class:`decimal32`
        """
        return decimal32(pn_data_get_decimal32(self._data))

    # XXX: need to convert
    def get_decimal64(self):
        """
        Get the current node value as a :class:`decimal64`.

        :return: If the current node is a decimal64, its value, 0 otherwise.
        :rtype: :class:`decimal64`
        """
        return decimal64(pn_data_get_decimal64(self._data))

    # XXX: need to convert
    def get_decimal128(self):
        """
        Get the current node value as a :class:`decimal128`.

        :return: If the current node is a decimal128, its value, 0 otherwise.
        :rtype: :class:`decimal128`
        """
        return decimal128(pn_data_get_decimal128(self._data))

    def get_uuid(self):
        """
        Get the current node value as a ``uuid.UUID``.

        :return: If the current node is a UUID, its value, ``None`` otherwise.
        :rtype: ``uuid.UUID`` or ``None``
        """
        if pn_data_type(self._data) == Data.UUID:
            return uuid.UUID(bytes=pn_data_get_uuid(self._data))
        else:
            return None

    def get_binary(self):
        """
        Get the current node value as ``bytes``.

        :return: If the current node is binary, its value, ``""`` otherwise.
        :rtype: ``bytes``
        """
        return pn_data_get_binary(self._data)

    def get_string(self):
        """
        Get the current node value as ``str``.

        :return: If the current node is a string, its value, ``""`` otherwise.
        :rtype: ``str``
        """
        return pn_data_get_string(self._data).decode("utf8")

    def get_symbol(self):
        """
        Get the current node value as :class:`symbol`.

        :return: If the current node is a symbol, its value, ``""`` otherwise.
        :rtype: :class:`symbol`
        """
        return symbol(pn_data_get_symbol(self._data).decode('ascii'))

    def copy(self, src):
        """
        Copy the contents of another pn_data_t object. Any values in the
        data object will be lost.

        :param src: The source object from which to copy
        :type src: :class:`Data`
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self._check(pn_data_copy(self._data, src._data))

    def format(self):
        """
        Formats the contents of this :class:`Data` object in a human readable way.

        :return: A Formatted string containing contents of this :class:`Data` object.
        :rtype: ``str``
        :raise: :exc:`DataException` if there is a Proton error.
        """
        sz = 16
        while True:
            err, result = pn_data_format(self._data, sz)
            if err == PN_OVERFLOW:
                sz *= 2
                continue
            else:
                self._check(err)
                return result

    def dump(self):
        """
        Dumps a debug representation of the internal state of this :class:`Data`
        object that includes its navigational state to ``cout`` (``stdout``) for
        debugging purposes.
        """
        pn_data_dump(self._data)

    def put_dict(self, d):
        """
        A convenience method for encoding the contents of a Python ``dict``
        as an AMQP map.

        :param d: The dictionary to be encoded
        :type d: ``dict``
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self.put_map()
        self.enter()
        try:
            for k, v in d.items():
                self.put_object(k)
                self.put_object(v)
        finally:
            self.exit()

    def get_dict(self):
        """
        A convenience method for decoding an AMQP map as a Python ``dict``.

        :returns: The decoded dictionary.
        :rtype: ``dict``
        """
        if self.enter():
            try:
                result = {}
                while self.next():
                    k = self.get_object()
                    if self.next():
                        v = self.get_object()
                    else:
                        v = None
                    result[k] = v
            finally:
                self.exit()
            return result

    def put_sequence(self, s):
        """
        A convenience method for encoding a Python ``list`` as an
        AMQP list.

        :param s: The sequence to be encoded
        :type s: ``list``
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self.put_list()
        self.enter()
        try:
            for o in s:
                self.put_object(o)
        finally:
            self.exit()

    def get_sequence(self):
        """
        A convenience method for decoding an AMQP list as a Python ``list``.

        :returns: The decoded list.
        :rtype: ``list``
        """
        if self.enter():
            try:
                result = []
                while self.next():
                    result.append(self.get_object())
            finally:
                self.exit()
            return result

    def get_py_described(self):
        """
        A convenience method for decoding an AMQP described value.

        :returns: The decoded AMQP descriptor.
        :rtype: :class:`Described`
        """
        if self.enter():
            try:
                self.next()
                descriptor = self.get_object()
                self.next()
                value = self.get_object()
            finally:
                self.exit()
            return Described(descriptor, value)

    def put_py_described(self, d):
        """
        A convenience method for encoding a :class:`Described` object
        as an AMQP described value. This method encapsulates all the steps
        described in :func:`put_described` into a single method.

        :param d: The descriptor to be encoded
        :type d: :class:`Described`
        :raise: :exc:`DataException` if there is a Proton error.
        """
        self.put_described()
        self.enter()
        try:
            self.put_object(d.descriptor)
            self.put_object(d.value)
        finally:
            self.exit()

    def get_py_array(self):
        """
        A convenience method for decoding an AMQP array into an
        :class:`Array` object. This method encapsulates all the
        steps described in :func:`get_array` into a single function.

        If the current node is an array, return an Array object
        representing the array and its contents. Otherwise return ``None``.

        :returns: The decoded AMQP array.
        :rtype: :class:`Array`
        """

        count, described, type = self.get_array()
        if type is None:
            return None
        if self.enter():
            try:
                if described:
                    self.next()
                    descriptor = self.get_object()
                else:
                    descriptor = UNDESCRIBED
                elements = []
                while self.next():
                    elements.append(self.get_object())
            finally:
                self.exit()
            return Array(descriptor, type, *elements)

    def put_py_array(self, a):
        """
        A convenience method for encoding an :class:`Array` object as
        an AMQP array. This method encapsulates the steps described in
        :func:`put_array` into a single function.

        :param a: The array object to be encoded
        :type a: :class:`Array`
        :raise: :exc:`DataException` if there is a Proton error.
        """
        described = a.descriptor != UNDESCRIBED
        self.put_array(described, a.type)
        self.enter()
        try:
            if described:
                self.put_object(a.descriptor)
            for e in a.elements:
                self.put_object(e)
        finally:
            self.exit()

    put_mappings = {
        None.__class__: lambda s, _: s.put_null(),
        bool: put_bool,
        ubyte: put_ubyte,
        ushort: put_ushort,
        uint: put_uint,
        ulong: put_ulong,
        byte: put_byte,
        short: put_short,
        int32: put_int,
        long: put_long,
        float32: put_float,
        float: put_double,
        decimal32: put_decimal32,
        decimal64: put_decimal64,
        decimal128: put_decimal128,
        char: put_char,
        timestamp: put_timestamp,
        uuid.UUID: put_uuid,
        bytes: put_binary,
        unicode: put_string,
        symbol: put_symbol,
        list: put_sequence,
        tuple: put_sequence,
        dict: put_dict,
        Described: put_py_described,
        Array: put_py_array,
        AnnotationDict: put_dict,
        PropertyDict: put_dict,
        SymbolList: put_sequence
    }
    # for Python 3.x, long is merely an alias for int, but for Python 2.x
    # we need to add an explicit int since it is a different type
    if int not in put_mappings:
        put_mappings[int] = put_int
    # Python >=3.0 has 'memoryview', <=2.5 has 'buffer', >=2.6 has both.
    try:
        put_mappings[memoryview] = put_memoryview
    except NameError:
        pass
    try:
        put_mappings[buffer] = put_buffer
    except NameError:
        pass
    get_mappings = {
        NULL: lambda s: None,
        BOOL: get_bool,
        BYTE: get_byte,
        UBYTE: get_ubyte,
        SHORT: get_short,
        USHORT: get_ushort,
        INT: get_int,
        UINT: get_uint,
        CHAR: get_char,
        LONG: get_long,
        ULONG: get_ulong,
        TIMESTAMP: get_timestamp,
        FLOAT: get_float,
        DOUBLE: get_double,
        DECIMAL32: get_decimal32,
        DECIMAL64: get_decimal64,
        DECIMAL128: get_decimal128,
        UUID: get_uuid,
        BINARY: get_binary,
        STRING: get_string,
        SYMBOL: get_symbol,
        DESCRIBED: get_py_described,
        ARRAY: get_py_array,
        LIST: get_sequence,
        MAP: get_dict
    }

    def put_object(self, obj):
        putter = self.put_mappings[obj.__class__]
        putter(self, obj)

    def get_object(self):
        type = self.type()
        if type is None:
            return None
        getter = self.get_mappings.get(type)
        if getter:
            return getter(self)
        else:
            return UnmappedType(str(type))


def dat2obj(dimpl):
    if dimpl:
        d = Data(dimpl)
        d.rewind()
        d.next()
        obj = d.get_object()
        d.rewind()
        return obj


def obj2dat(obj, dimpl):
    if obj is not None:
        d = Data(dimpl)
        d.put_object(obj)
