Ejemplo n.º 1
0
def dumps(obj):
    """
    Dump a struct into a message, returned as a string of bytes.

    The message is encoded using the recommended capnp format for serializing
    messages over a stream. It always uses a single segment.
    """
    if obj._is_compact():
        # fast path. On CPython, the real speedup comes from the fact that we
        # do not create a temporary SegmentBuilder. The memcpy vs copy_pointer
        # difference seems negligible, for small objects at least.
        start = obj._data_offset
        end = obj._get_end()
        end = (end + (8 - 1)) & -8  # Round up to 8-byte boundary
        p = ptr.new_struct(0, obj._data_size, obj._ptrs_size)
        return obj._seg.dump_message(p, start, end)
    else:
        builder = SegmentBuilder()
        builder.allocate(
            16)  # reserve space for segment header+the root pointer
        builder.copy_from_struct(8, Struct, obj)
        segment_count = 1
        segment_size = (builder.get_length() -
                        8) / 8  # subtract the segment header
        # and convert to words
        builder.write_uint32(0, segment_count - 1)
        builder.write_uint32(4, segment_size)
        return builder.as_string()
Ejemplo n.º 2
0
 def test_null_pointers(self):
     NULL = b'\x00\x00\x00\x00\x00\x00\x00\x00' # NULL pointer
     buf = SegmentBuilder()
     pos = buf.allocate(24)
     buf.copy_from_struct(0, Struct, None)
     buf.alloc_text(8, None)
     buf.copy_from_list(16, PrimitiveItemType(Types.int64), None)
     s = buf.as_string()
     assert s == NULL*3
Ejemplo n.º 3
0
 def compact(self):
     """
     Return a compact version of the struct. In case the struct was inside a
     bigger message, it "extracts" it into a new message which contains
     only the needed pieces.
     """
     builder = SegmentBuilder()
     pos = builder.allocate(8)
     builder.copy_from_struct(pos, Struct, self)
     buf = builder.as_string()
     t = type(self)
     res = t.__new__(t)
     res._init_from_buffer(buf, 8, self._data_size, self._ptrs_size)
     return res
Ejemplo n.º 4
0
def dumps(obj, fastpath=True):
    """
    Dump a struct into a message, returned as a string of bytes.

    The message is encoded using the recommended capnp format for serializing
    messages over a stream. It always uses a single segment.

    By default, it tries to follow a fast path: it checks if the object is
    "compact" (as defined by capnpy/visit.py) and, is so, uses a fast memcpy
    to dump the whole message.

    If the fast path can be taken, it is approximately 5x faster on CPython
    and 10x faster on PyPy. However, if the object is **not** compact, the
    fast path check makes it ~2x slower. If you are sure that the object is
    not compact, you can disable the check by passing ``fastpath=False``.
    """
    if fastpath:
        # try the fast path: if the object is compact, we can dump the
        # object with a fast memcpy
        end = obj._get_end()
    else:
        end = -1
    #
    if end != -1:
        # fast path. On CPython, the real speedup comes from the fact that we
        # do not create a temporary SegmentBuilder. The memcpy vs copy_pointer
        # difference seems negligible, for small objects at least.
        start = obj._data_offset
        p = ptr.new_struct(0, obj._data_size, obj._ptrs_size)
        return obj._seg.dump_message(p, start, end)
    else:
        builder = SegmentBuilder()
        builder.allocate(
            16)  # reserve space for segment header+the root pointer
        builder.copy_from_struct(8, Struct, obj)
        segment_count = 1
        segment_size = (builder.get_length() -
                        8) / 8  # subtract the segment header
        # and convert to words
        builder.write_uint32(0, segment_count - 1)
        builder.write_uint32(4, segment_size)
        return builder.as_string()