:mod:`macholib.ptypes` --- Packable types
=========================================

.. module:: macholib.ptypes
   :synopsis: Serializable types

The module :mod:`macholib.ptypes` defines types that can be serialized into
byte arrays, both for basic types and structured types (C ``struct`` values).

Utility functions
-----------------

.. function:: sizeof(value)

   Returns the size in bytes of an object when packed, raises :exc:`ValueError`
   for inappropriate values.

.. function:: pypackable(name, pytype, format)

   Returns a packable type that is a subclass of the Python type
   *pytype*. The value is converted to and from the packed format using
   the struct *format*.



Packable types
--------------


.. class:: BasePackable

   All packable types are a subclass of :class:`BasePackable`, which defines
   the basic interface but is itself an abstract base class.

   .. data:: _endian_

      The byteorder of a packed value. This will be ``"<"` for
      little endian values and ``">"`` for big-endian ones.

      .. note:: the endianness option is a public value to be
         able to support both big- and little-endian file formats.

         The name suggests that this attribute is private, this
         is partically for historical reasons and partially to
         avoid conflicts with field names in C structs.

   .. method:: from_mmap(mmap, ptr, \**kw)

      This class method constructs the value from a subview of a
      :class:`mmap.mmap` object. It uses bytes starting at offset *ptr* and
      reads just enough bytes to read the entire object.

   .. method:: from_fileobj(fp, \**kw)

      This class method constructs the value by reading just enough bytes
      from a file-like object.

      .. note:: The file must be opened in binary mode, that is read calls
         should return byte-strings and not unicode-strings.

   .. method:: from_str(value, \**kw)

      This class method construct the value by using the struct module
      to parse the given bytes.

      .. note:: contrary to what the name suggests the argument to this
         method is a byte-string, not a unicode-string.

   .. method:: from_tuple(fp, \**kw)

      This class method constructs the object from a tuple with all fields.


   .. method:: to_str()

      Returns a byte representation of the value.

      .. note:: there is no default implementation for this method

   .. method:: to_fileobj(fp)

      Write a byte representation of the value to the given file-like
      object. The file should be opened in binary mode.

   .. method:: to_mmap(mmap, ptr)

      Write the byte representation of the value to a :class:`mmap.mmap`
      object, starting at offset *ptr*.


.. class:: Structure(...)

   .. data:: _fields_

      This class attribute is a list that contains the fields of the
      structure in the right order. Every item of this list is a tuple
      with 2 arguments: the first element is the name of the field, and
      the second the packable type for the field.

      Every subclass of :class:`Structure` must define *_fields_* to be
      usefull, and the value of *_fields_* should not be changed after
      class construction.


Basic packables
---------------

Other than the core functionality this module defines a number of
:func:`pypackable` types that correspond to useful basic C types.

.. class:: p_char([value])

   A byte string of length 1

.. class:: p_int8

   An 8-bit signed integer

.. class:: p_uint8

   An 8-bit unsigned integer

.. class:: p_int16

   An 16-bit signed integer

.. class:: p_uint16

   An 16-bit unsigned integer

.. class:: p_int32

   An 32-bit signed integer

.. class:: p_uint32

   An 32-bit unsigned integer

.. class:: p_int64

   An 64-bit signed integer

.. class:: p_uint64

   An 64-bit unsigned integer

.. class:: p_float

   An floating point value of type ``float``

.. class:: p_double

   An floating point value of type ``double``

.. note:: the module exports a number of other types with
   names starting with ``p_``, such as ``p_int``. Those types
   are deprecated and should not be used.
