Skip to content

Commit

Permalink
construct
Browse files Browse the repository at this point in the history
  • Loading branch information
tomerfiliba committed Dec 19, 2012
1 parent 0f193fe commit f45d11c
Show file tree
Hide file tree
Showing 10 changed files with 507 additions and 38 deletions.
8 changes: 7 additions & 1 deletion construct3/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
from construct3.lib import this
from construct3.version import version, version_str as __version__
from construct3.lib import this
from construct3.packers import Packer, PackerError, Adapter, Struct, Member, Array, Raw
from construct3.macros import (u_int8, s_int8, ub_int16, sb_int16, ul_int16, sl_int16, ub_int32, sb_int32, ul_int32,
sl_int32, ub_int64, sb_int64, ul_int64, sl_int64, b_float32, b_float64, l_float32, l_float64, If, PascalString)




__author__ = "Tomer Filiba <[email protected]>"

10 changes: 5 additions & 5 deletions construct3/adapters.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import struct as _struct
from construct3.packers import Adapter, Noop, Struct, Field, Member, PackerError
from construct3.packers import Adapter, Noop, Struct, Raw, Member, PackerError
from construct3.lib import this


Expand Down Expand Up @@ -42,7 +42,7 @@ def decode(self, obj, ctx):
class Signature(Adapter):
__slots__ = ["value"]
def __init__(self, value):
Adapter.__init__(self, Field(len(value)))
Adapter.__init__(self, Raw(len(value)))
self.value = value
def decode(self, obj, ctx):
if obj != self.value:
Expand All @@ -56,7 +56,7 @@ class LengthValue(Adapter):
def __init__(self, lengthpkr):
Adapter.__init__(self, Struct(
Member("length", lengthpkr),
Member("data", Field(this.length)),
Member("data", Raw(this.length)),
)
)
def decode(self, obj, ctx):
Expand All @@ -74,12 +74,12 @@ def decode(self, obj, ctx):
def encode(self, obj, ctx):
return obj.encode(self.encoding)

class FormattedField(Adapter):
class Formatted(Adapter):
__slots__ = ["fmt"]
FORMAT = None
def __init__(self):
self.fmt = _struct.Struct(self.FORMAT)
Adapter.__init__(self, Field(self.fmt.size))
Adapter.__init__(self, Raw(self.fmt.size))
def encode(self, obj, ctx):
return self.fmt.pack(obj)
def decode(self, obj, ctx):
Expand Down
13 changes: 9 additions & 4 deletions construct3/experimental.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,18 @@ def _unpack(self, stream, ctx):
return obj, digestor

#class Modified(Packer):
# def __init__(self, underlying, ctx_factory):
# def __init__(self, underlying, ctx_modifier):
# self.underlying = underlying
# self.ctx_factory = ctx_factory
# self.ctx_modifier = ctx_modifier
# def _unpack(self, stream, ctx):
# ctx2 = ctx.copy()
# ctx2.update(self.ctx_factory())
# return
# self.ctx_modifier(ctx2)
# return self.underlying._unpack(stream, ctx2)
#
#def DigestedStruct(*members, **kwargs):
# digestor_factory = kwargs.pop("digestor_factory")
# return Modified(Struct(*members, **kwargs),
# lambda ctx: ctx.update(__digestor__ = digestor_factory()))

if __name__ == "__main__":
from construct3.macros import ub_int64
Expand Down
4 changes: 4 additions & 0 deletions construct3/lib/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from construct3.lib.thisexpr import this

def singleton(cls):
return cls()
165 changes: 165 additions & 0 deletions construct3/lib/thisexpr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import operator

if not hasattr(operator, "truediv"):
operator.truediv = operator.div


opnames = {
operator.add : "+",
operator.sub : "-",
operator.mul : "*",
operator.div : "/",
operator.floordiv : "//",
operator.mod : "%",
operator.pow : "**",
operator.xor : "^",
operator.lshift : "<<",
operator.rshift : ">>",
operator.and_ : "&",
operator.or_ : "|",
operator.not_ : "~",
operator.neg : "-",
operator.pos : "+",
operator.contains : "in",
operator.gt : ">",
operator.ge : ">=",
operator.lt : "<",
operator.le : "<=",
operator.eq : "==",
operator.ne : "!=",
}


class ExprMixin(object):
__slots__ = ()
def __add__(self, other):
return BinExpr(operator.add, self, other)
def __sub__(self, other):
return BinExpr(operator.sub, self, other)
def __mul__(self, other):
return BinExpr(operator.mul, self, other)
def __floordiv__(self, other):
return BinExpr(operator.floordiv, self, other)
def __truediv__(self, other):
return BinExpr(operator.div, self, other)
__div__ = __floordiv__
def __mod__(self, other):
return BinExpr(operator.mod, self, other)
def __pow__(self, other):
return BinExpr(operator.pow, self, other)
def __xor__(self, other):
return BinExpr(operator.xor, self, other)
def __rshift__(self, other):
return BinExpr(operator.rshift, self, other)
def __lshift__(self, other):
return BinExpr(operator.rshift, self, other)
def __and__(self, other):
return BinExpr(operator.and_, self, other)
def __or__(self, other):
return BinExpr(operator.or_, self, other)

def __radd__(self, other):
return BinExpr(operator.add, other, self)
def __rsub__(self, other):
return BinExpr(operator.sub, other, self)
def __rmul__(self, other):
return BinExpr(operator.mul, other, self)
def __rfloordiv__(self, other):
return BinExpr(operator.floordiv, other, self)
def __rtruediv__(self, other):
return BinExpr(operator.div, other, self)
__rdiv__ = __rfloordiv__
def __rmod__(self, other):
return BinExpr(operator.mod, other, self)
def __rpow__(self, other):
return BinExpr(operator.pow, other, self)
def __rxor__(self, other):
return BinExpr(operator.xor, other, self)
def __rrshift__(self, other):
return BinExpr(operator.rshift, other, self)
def __rlshift__(self, other):
return BinExpr(operator.rshift, other, self)
def __rand__(self, other):
return BinExpr(operator.and_, other, self)
def __ror__(self, other):
return BinExpr(operator.or_, other, self)

def __neg__(self):
return UniExpr(operator.neg, self)
def __pos__(self):
return UniExpr(operator.pos, self)
def __invert__(self):
return UniExpr(operator.not_, self)
__inv__ = __invert__

def __contains__(self, other):
return BinExpr(operator.contains, self, other)
def __gt__(self, other):
return BinExpr(operator.gt, self, other)
def __ge__(self, other):
return BinExpr(operator.ge, self, other)
def __lt__(self, other):
return BinExpr(operator.lt, self, other)
def __le__(self, other):
return BinExpr(operator.le, self, other)
def __eq__(self, other):
return BinExpr(operator.eq, self, other)
def __ne__(self, other):
return BinExpr(operator.ne, self, other)


class UniExpr(ExprMixin):
__slots__ = ["op", "operand"]
def __init__(self, op, operand):
self.op = op
self.operand = operand
def __repr__(self):
return "%s%r" % (opnames[self.op], self.operand)
def __call__(self, context):
operand = self.operand(context) if callable(self.operand) else self.operand
return self.op(operand)


class BinExpr(ExprMixin):
__slots__ = ["op", "lhs", "rhs"]
def __init__(self, op, lhs, rhs):
self.op = op
self.lhs = lhs
self.rhs = rhs
def __repr__(self):
return "(%r %s %r)" % (self.lhs, opnames[self.op], self.rhs)
def __call__(self, context):
lhs = self.lhs(context) if callable(self.lhs) else self.lhs
rhs = self.rhs(context) if callable(self.rhs) else self.rhs
return self.op(lhs, rhs)


class Path(ExprMixin):
__slots__ = ["__name", "__parent"]
def __init__(self, name, parent = None):
self.__name = name
self.__parent = parent
def __repr__(self):
if self.__parent is None:
return self.__name
return "%r.%s" % (self.__parent, self.__name)
def __call__(self, context):
if self.__parent is None:
return context
context2 = self.__parent(context)
return context2[self.__name]
def __getattr__(self, name):
return Path(name, self)


# let the magic begin!
this = Path("this")


if __name__ == "__main__":
x = ~((this.foo * 2 + 3 << 2) % 11)
print (x)
print (x({"foo" : 7}))



40 changes: 20 additions & 20 deletions construct3/macros.py
Original file line number Diff line number Diff line change
@@ -1,95 +1,95 @@
from construct3.packers import Switch, contextify, Field
from construct3.adapters import LengthValue, StringAdapter, FormattedField, OneOf
from construct3.packers import Switch, contextify
from construct3.adapters import LengthValue, StringAdapter, Formatted, OneOf
from construct3.lib import singleton


@singleton
class u_int8(FormattedField):
class u_int8(Formatted):
"""Unsigned 8-bit integer"""
FORMAT = "B"

@singleton
class s_int8(FormattedField):
class s_int8(Formatted):
"""Signed 8-bit integer"""
FORMAT = "b"

@singleton
class ub_int16(FormattedField):
class ub_int16(Formatted):
"""Unsigned big-endian 16-bit integer"""
FORMAT = "!H"

@singleton
class sb_int16(FormattedField):
class sb_int16(Formatted):
"""Signed big-endian 16-bit integer"""
FORMAT = "!h"

@singleton
class ul_int16(FormattedField):
class ul_int16(Formatted):
"""Unsigned little-endian 16-bit integer"""
FORMAT = "<H"

@singleton
class sl_int16(FormattedField):
class sl_int16(Formatted):
"""Signed little-endian 16-bit integer"""
FORMAT = "<h"

@singleton
class ub_int32(FormattedField):
class ub_int32(Formatted):
"""Unsigned big-endian 32-bit integer"""
FORMAT = "!L"

@singleton
class sb_int32(FormattedField):
class sb_int32(Formatted):
"""Signed big-endian 32-bit integer"""
FORMAT = "!l"

@singleton
class ul_int32(FormattedField):
class ul_int32(Formatted):
"""Unsigned little-endian 32-bit integer"""
FORMAT = "<L"

@singleton
class sl_int32(FormattedField):
class sl_int32(Formatted):
"""Signed little-endian 32-bit integer"""
FORMAT = "<l"

@singleton
class ub_int64(FormattedField):
class ub_int64(Formatted):
"""Unsigned big-endian 64-bit integer"""
FORMAT = "!Q"

@singleton
class sb_int64(FormattedField):
class sb_int64(Formatted):
"""Signed big-endian 64-bit integer"""
FORMAT = "!q"

@singleton
class ul_int64(FormattedField):
class ul_int64(Formatted):
"""Unsigned little-endian 64-bit integer"""
FORMAT = "<Q"

@singleton
class sl_int64(FormattedField):
class sl_int64(Formatted):
"""Signed little-endian 64-bit integer"""
FORMAT = "<q"

@singleton
class b_float32(FormattedField):
class b_float32(Formatted):
"""Big-endian 32-bit floating point number"""
FORMAT = "!f"

@singleton
class b_float64(FormattedField):
class b_float64(Formatted):
"""Big-endian 64-bit floating point number"""
FORMAT = "!d"

@singleton
class l_float32(FormattedField):
class l_float32(Formatted):
"""Little-endian 32-bit floating point number"""
FORMAT = "<f"

@singleton
class l_float64(FormattedField):
class l_float64(Formatted):
"""Little-endian 64-bit floating point number"""
FORMAT = "<d"

Expand Down
Loading

0 comments on commit f45d11c

Please sign in to comment.