Skip to content

Instantly share code, notes, and snippets.

@tmr232
Last active August 29, 2015 14:14
Show Gist options
  • Save tmr232/84b78fbf261605b0e024 to your computer and use it in GitHub Desktop.
Save tmr232/84b78fbf261605b0e024 to your computer and use it in GitHub Desktop.
New Construct Syntax
import operator
import construct
class ConstructGetter(object):
def __init__(self):
self._index = 0
def __getattr__(self, name):
cons = getattr(construct, name)
proxy = ConstructProxy(cons, self._index)
self._index += 1
return proxy
class ConstructProxy(object):
def __init__(self, cons, index):
self._cons = cons
self._index = index
self._args = []
self._kwargs = {}
def __call__(self, *args, **kwargs):
self._args = args
self._kwargs = kwargs
return self
def is_name_significant(self, name):
return (name[0] != "_") or (not name[1:].isdigit())
def get(self, name):
if self.is_name_significant(name):
return self._cons(name, *self._args, **self._kwargs)
return self._cons(*self._args, **self._kwargs)
def __cmp__(self, other):
return cmp(self._index, other._index)
cs = ConstructGetter()
def subcons(**members):
members = members.items()
members = sorted(members, key=operator.itemgetter(1))
members = [value.get(name) for name, value in members]
return members
def struct(name, **members):
return construct.Struct(name, *subcons(**members))
if __name__ == '__main__':
s = struct("MyStruct",
length=cs.UBInt8,
data=cs.Bytes(lambda ctx: ctx["length"]),
_1=cs.Padding(lambda ctx: 255 - ctx["length"])
)
print s.parse("\x0DHello, World!" + "\0" * 242)
string = "Hello, World!"
print repr(s.build(construct.Container(data=string, length=len(string))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment