Add support for segment (de)serialization.

This commit is contained in:
Constantine Vetoshev
2016-06-23 14:15:31 -07:00
parent 032713f8b9
commit 09705b6d1f
3 changed files with 68 additions and 0 deletions

View File

@@ -53,6 +53,7 @@ cdef class _DynamicStructBuilder:
cdef _check_write(self)
cpdef to_bytes(_DynamicStructBuilder self) except +reraise_kj_exception
cpdef to_segments(_DynamicStructBuilder self) except +reraise_kj_exception
cpdef _to_bytes_packed_helper(_DynamicStructBuilder self, word_count) except +reraise_kj_exception
cpdef to_bytes_packed(_DynamicStructBuilder self) except +reraise_kj_exception

View File

@@ -1192,6 +1192,12 @@ cdef class _DynamicStructBuilder:
self._is_written = True
return ret
cpdef to_segments(_DynamicStructBuilder self) except +reraise_kj_exception:
self._check_write()
cdef _MessageBuilder builder = self._parent
segments = builder.get_segments_for_output()
return segments
cpdef _to_bytes_packed_helper(_DynamicStructBuilder self, word_count) except +reraise_kj_exception:
cdef _MessageBuilder builder = self._parent
array = helpers.messageToPackedBytes(deref(builder.thisptr), word_count)
@@ -2989,6 +2995,9 @@ class _StructModule(object):
else:
message = _FlatArrayMessageReader(buf, traversal_limit_in_words, nesting_limit)
return message.get_root(self.schema)
def from_segments(self, segments):
message = _SegmentArrayMessageReader(segments)
return message.get_root(self.schema)
def from_bytes_packed(self, buf, traversal_limit_in_words = None, nesting_limit = None):
"""Returns a Reader for the packed object in buf.
@@ -3285,6 +3294,18 @@ cdef class _MessageBuilder:
self.thisptr.setRootDynamicStruct((<_DynamicStructReader>value).thisptr)
return self.get_root(value.schema)
cpdef get_segments_for_output(self) except +reraise_kj_exception:
segments = self.thisptr.getSegmentsForOutput()
res = []
cdef const char* ptr
cdef bytes segment_bytes
for i in range(0, segments.size()):
segment = segments[i]
ptr = <const char *> segment.begin()
segment_bytes = ptr[:8*segment.size()]
res.append(segment_bytes)
return res
cpdef new_orphan(self, schema) except +reraise_kj_exception:
"""A method for instantiating Cap'n Proto orphans
@@ -3738,6 +3759,36 @@ cdef class _FlatArrayMessageReader(_MessageReader):
del self.thisptr
@cython.internal
cdef class _SegmentArrayMessageReader(_MessageReader):
cdef object _objects_to_pin
def __init__(self, segments):
# takes a Python array of bytes and constructs a ConstWordArrayArrayPtr
num_segments = len(segments)
cdef char* ptr
cdef schema_cpp.ConstWordArrayPtr seg_ptr
cdef schema_cpp.ConstWordArrayPtr* seg_ptrs = <schema_cpp.ConstWordArrayPtr*>malloc(num_segments * sizeof(schema_cpp.ConstWordArrayPtr))
self._objects_to_pin = []
for i in range(0, num_segments):
segment = bytes(segments[i])
ptr = segment
if (<uintptr_t>ptr) % 8 != 0:
aligned = _AlignedBuffer(segment)
ptr = aligned.buf
self._objects_to_pin.append(aligned)
else:
self._objects_to_pin.append(segment)
seg_ptr = schema_cpp.ConstWordArrayPtr(<schema_cpp.word*>ptr, len(segment)//8)
seg_ptrs[i] = seg_ptr
self.thisptr = new schema_cpp.SegmentArrayMessageReader(
schema_cpp.ConstWordArrayArrayPtr(seg_ptrs, num_segments))
def __dealloc__(self):
del self.thisptr
@cython.internal
cdef class _FlatMessageBuilder(_MessageBuilder):
cdef object _object_to_pin