def set_members(self, buf): """Read the size and count indicator from the buffer.""" self.member_size = compat.from_bytes(buf.read(self.width), "big") self.member_count = compat.from_bytes(buf.read(self.width), "big") start = buf.tell() - self.width if self.is_array(): self.member_ctr = decode_constructor(buf.read) # Set the start of the members to the current buffer position # minus the width of the type length, because the total length # includes. end = start + self.member_size while buf.tell() < end: node = type(self).frombuf(buf, parent=self, ctr=self.member_ctr, depth=self.depth) self.children.append(node) assert buf.tell() == end, "{0}!={1}".format(buf.tell(), end)
def frombuf(cls, buf, parent=None, ctr=None, depth=-1): start = buf.tell() if ctr is None: ctr = decode_constructor(buf.read) instance = cls(start, ctr, offset=buf.tell() - start, parent=parent, depth=depth) if is_collection(ctr.format_code): instance.set_members(buf) elif is_variable(ctr.format_code): instance.set_length(buf) else: instance.length = instance.width buf.seek(instance.width, os.SEEK_CUR) # If parent is None, this is the top-level node so reset # the buffer. # if parent is None: # buf.seek(0) instance.end = buf.tell() return instance