def get_packable(self, packer, padding, obj, offs = 0, buf = None, idmap = None, implicit_offs = 0):
if idmap is None:
idmap = {}
baseoffs = offs
if buf is None:
buf = self._pack_buffer
has_bitmap, none_bitmap, present_bitmap = self._get_bitmaps(obj)
fixed_present = present_bitmap & self._fixed_bitmap
size = packer.size
offs += size + padding
if offs > len(buf):
raise struct.error('buffer too small')
packable = [
has_bitmap,
none_bitmap,
]
packable_append = packable.append
idmap_get = idmap.get
slot_types = self.slot_types
alignment = self.alignment
for i,slot in enumerate(self.slot_keys):
mask = cython.cast(cython.ulonglong, 1) << i
if present_bitmap & mask:
val = getattr(obj, slot)
if fixed_present & mask:
packable_append(val)
else:
val_id = id(val)
val_offs = idmap_get(val_id)
if val_offs is None:
idmap[val_id] = ival_offs = offs + implicit_offs
offs = slot_types[slot].pack_into(val, buf, offs, idmap, implicit_offs)
padding = (offs + alignment - 1) / alignment * alignment - offs
offs += padding
else:
ival_offs = val_offs
packable_append(ival_offs - baseoffs - implicit_offs)
padding = (offs + alignment - 1) / alignment * alignment - offs
offs = offs + padding
if offs > len(buf):
raise struct.error('buffer too small')
return packable, offs
评论列表
文章目录