def AlignedStruct(*members): """ Algorithm taken from http://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding Example:: s = AlignedStruct( "a" / word8, # 0 # padding (1) # 1 "b" / word16, # 2-3 "c" / word16, # 4-5 # padding (2) # 6-7 "d" / word32, # 8-11 "e" / word8, # 12 "f" / BitStruct( # 13 "x" / nibble, "y" / nibble, ) # padding (2) # 14-15 # total size = 16 ) """ members2 = [] offset = 0 largest = 0 # align each member to its native size, e.g., int32 is aligned to 4-bytes for name, pkr in members: align = pkr.sizeof() largest = max(align, largest) padding = (align - offset % align) % align offset += align + padding if padding > 0: members2.append(Padding(padding)) members2.append((name, pkr)) # the struct must be aligned to its largest member if offset % largest != 0: members2.append(Padding(largest - offset % largest)) return Struct(*members2)
def _unpack(self, stream, ctx): digestor = ctx["__digestor__"] = self.digestor_factory() obj = Struct._unpack(self, stream, ctx) del ctx["__digestor__"] return obj, digestor
def __init__(self, *members, **kwargs): self.digestor_factory = kwargs.pop("digestor_factory") Struct.__init__(self, *members, **kwargs)
def BitStruct(*args, **kwargs): return Bitwise(Struct(*args, **kwargs))
def _generate_unpacker(pkr, streamvar, ctxvar): return _get_visitor(pkr).generate_unpacker(pkr, streamvar, ctxvar) def generate(pkr, name): with PythonModule(name) as mod: _get_visitor(pkr).setup(pkr) SEP() with DEF("%s_unpack" % (name, ), ["stream"]): ctx = {} res = _generate_unpacker(pkr, "stream", ctx) STMT("return {0}", res) return mod if __name__ == "__main__": from construct3.lib import this from construct3.numbers import byte from construct3.adapters import LengthPrefixed #testpkr = Sequence(byte, byte, Sequence(byte, byte, Raw(this[0] + this[1] + this._[0] + this._[1]))) testpkr = Struct("len" / byte, "gth" / byte, "data" / Raw(this.len + this.gth)) mod = generate(testpkr, "test") print testpkr mod.dump("testpacker.py") import testpacker from io import BytesIO data = BytesIO("\x03\x02helloXX") #data = BytesIO("\x01\x01\x01\x02helloXX") print testpacker.test_unpack(data)
def _unpack(self, stream, ctx, cfg): digestor = self.digestor_factory() with cfg.set(digestor = digestor): obj = Struct._unpack(self, stream, ctx, cfg) obj["__digest__"] = digestor.digest() return obj
def _unpack(self, stream, ctx, cfg): digestor = self.digestor_factory() with cfg.set(digestor=digestor): obj = Struct._unpack(self, stream, ctx, cfg) obj["__digest__"] = digestor.digest() return obj