in python/pyfury/_serializer.py [0:0]
def write(self, buffer, o):
obj = o
length = len(obj)
buffer.write_varuint32(length)
if length == 0:
return
fury = self.fury
class_resolver = fury.class_resolver
ref_resolver = fury.ref_resolver
key_serializer = self.key_serializer
value_serializer = self.value_serializer
items_iter = iter(obj.items())
key, value = next(items_iter)
has_next = True
serialize_ref = fury.serialize_ref if self.fury.is_py else fury.xserialize_ref
while has_next:
while True:
if key is not None:
if value is not None:
break
if key_serializer is not None:
if key_serializer.need_to_write_ref:
buffer.write_int8(NULL_VALUE_KEY_DECL_TYPE_TRACKING_REF)
if not ref_resolver.write_ref_or_null(buffer, key):
self._write_obj(key_serializer, buffer, key)
else:
buffer.write_int8(NULL_VALUE_KEY_DECL_TYPE)
self._write_obj(key_serializer, buffer, key)
else:
buffer.write_int8(VALUE_HAS_NULL | TRACKING_KEY_REF)
serialize_ref(buffer, key)
else:
if value is not None:
if value_serializer is not None:
if value_serializer.need_to_write_ref:
buffer.write_int8(NULL_KEY_VALUE_DECL_TYPE_TRACKING_REF)
if not ref_resolver.write_ref_or_null(buffer, key):
value_serializer.write(buffer, key)
if not ref_resolver.write_ref_or_null(buffer, value):
value_serializer.write(buffer, value)
else:
buffer.write_int8(NULL_KEY_VALUE_DECL_TYPE)
value_serializer.write(buffer, value)
else:
buffer.write_int8(KEY_HAS_NULL | TRACKING_VALUE_REF)
serialize_ref(buffer, value)
else:
buffer.write_int8(KV_NULL)
try:
key, value = next(items_iter)
except StopIteration:
has_next = False
break
if not has_next:
break
key_cls = type(key)
value_cls = type(value)
buffer.write_int16(-1)
chunk_size_offset = buffer.writer_index - 1
chunk_header = 0
if key_serializer is not None:
chunk_header |= KEY_DECL_TYPE
else:
key_classinfo = self.class_resolver.get_classinfo(key_cls)
class_resolver.write_typeinfo(buffer, key_classinfo)
key_serializer = key_classinfo.serializer
if value_serializer is not None:
chunk_header |= VALUE_DECL_TYPE
else:
value_classinfo = self.class_resolver.get_classinfo(value_cls)
class_resolver.write_typeinfo(buffer, value_classinfo)
value_serializer = value_classinfo.serializer
key_write_ref = (
key_serializer.need_to_write_ref if key_serializer else False
)
value_write_ref = (
value_serializer.need_to_write_ref if value_serializer else False
)
if key_write_ref:
chunk_header |= TRACKING_KEY_REF
if value_write_ref:
chunk_header |= TRACKING_VALUE_REF
buffer.put_uint8(chunk_size_offset - 1, chunk_header)
chunk_size = 0
while chunk_size < MAX_CHUNK_SIZE:
if (
key is None
or value is None
or type(key) is not key_cls
or type(value) is not value_cls
):
break
if not key_write_ref or not ref_resolver.write_ref_or_null(buffer, key):
self._write_obj(key_serializer, buffer, key)
if not value_write_ref or not ref_resolver.write_ref_or_null(
buffer, value
):
value_serializer.write(buffer, value)
chunk_size += 1
try:
key, value = next(items_iter)
except StopIteration:
has_next = False
break
key_serializer = self.key_serializer
value_serializer = self.value_serializer
buffer.put_uint8(chunk_size_offset, chunk_size)