summaryrefslogtreecommitdiff
path: root/external/construct/lib
diff options
context:
space:
mode:
Diffstat (limited to 'external/construct/lib')
-rw-r--r--external/construct/lib/__init__.py5
-rw-r--r--external/construct/lib/__init__.pycbin0 -> 700 bytes
-rw-r--r--external/construct/lib/binary.py187
-rw-r--r--external/construct/lib/binary.pycbin0 -> 7551 bytes
-rw-r--r--external/construct/lib/bitstream.py81
-rw-r--r--external/construct/lib/bitstream.pycbin0 -> 4227 bytes
-rw-r--r--external/construct/lib/container.py224
-rw-r--r--external/construct/lib/container.pycbin0 -> 11401 bytes
-rw-r--r--external/construct/lib/expr.py166
-rw-r--r--external/construct/lib/expr.pycbin0 -> 12000 bytes
-rw-r--r--external/construct/lib/hex.py46
-rw-r--r--external/construct/lib/hex.pycbin0 -> 3081 bytes
-rw-r--r--external/construct/lib/py3compat.py70
-rw-r--r--external/construct/lib/py3compat.pycbin0 -> 3600 bytes
14 files changed, 779 insertions, 0 deletions
diff --git a/external/construct/lib/__init__.py b/external/construct/lib/__init__.py
new file mode 100644
index 0000000..2d533e8
--- /dev/null
+++ b/external/construct/lib/__init__.py
@@ -0,0 +1,5 @@
+from construct.lib.binary import int_to_bin, bin_to_int, swap_bytes, encode_bin, decode_bin
+from construct.lib.bitstream import BitStreamReader, BitStreamWriter
+from construct.lib.container import (Container, FlagsContainer, ListContainer,
+ LazyContainer)
+from construct.lib.hex import HexString, hexdump
diff --git a/external/construct/lib/__init__.pyc b/external/construct/lib/__init__.pyc
new file mode 100644
index 0000000..6eda7eb
--- /dev/null
+++ b/external/construct/lib/__init__.pyc
Binary files differ
diff --git a/external/construct/lib/binary.py b/external/construct/lib/binary.py
new file mode 100644
index 0000000..c5ef9b3
--- /dev/null
+++ b/external/construct/lib/binary.py
@@ -0,0 +1,187 @@
+import six
+from construct.lib.py3compat import int2byte
+
+
+if six.PY3:
+ def int_to_bin(number, width = 32):
+ r"""
+ Convert an integer into its binary representation in a bytes object.
+ Width is the amount of bits to generate. If width is larger than the actual
+ amount of bits required to represent number in binary, sign-extension is
+ used. If it's smaller, the representation is trimmed to width bits.
+ Each "bit" is either '\x00' or '\x01'. The MSBit is first.
+
+ Examples:
+
+ >>> int_to_bin(19, 5)
+ b'\x01\x00\x00\x01\x01'
+ >>> int_to_bin(19, 8)
+ b'\x00\x00\x00\x01\x00\x00\x01\x01'
+ """
+ number = int(number)
+ if number < 0:
+ number += 1 << width
+ i = width - 1
+ bits = bytearray(width)
+ while number and i >= 0:
+ bits[i] = number & 1
+ number >>= 1
+ i -= 1
+ return bytes(bits)
+
+ # heavily optimized for performance
+ def bin_to_int(bits, signed = False):
+ r"""
+ Logical opposite of int_to_bin. Both '0' and '\x00' are considered zero,
+ and both '1' and '\x01' are considered one. Set sign to True to interpret
+ the number as a 2-s complement signed integer.
+ """
+ bits = "".join("01"[b & 1] for b in bits)
+ if signed and bits[0] == "1":
+ bits = bits[1:]
+ bias = 1 << len(bits)
+ else:
+ bias = 0
+ return int(bits, 2) - bias
+
+ _char_to_bin = [0] * 256
+ _bin_to_char = {}
+ for i in range(256):
+ ch = int2byte(i)
+ bin = int_to_bin(i, 8)
+ # Populate with for both keys i and ch, to support Python 2 & 3
+ _char_to_bin[i] = bin
+ _bin_to_char[bin] = ord(ch)
+
+ def encode_bin(data):
+ """
+ Create a binary representation of the given b'' object. Assume 8-bit
+ ASCII. Example:
+
+ >>> encode_bin('ab')
+ b"\x00\x01\x01\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x00\x01\x00"
+ """
+ return six.b("").join(_char_to_bin[int(ch)] for ch in data)
+
+ def decode_bin(data):
+ if len(data) & 7:
+ raise ValueError("Data length must be a multiple of 8")
+ i = 0
+ j = 0
+ l = len(data) // 8
+ arr = bytearray(l)
+ while j < l:
+ arr[j] = _bin_to_char[data[i:i+8]]
+ i += 8
+ j += 1
+ return arr
+
+ def swap_bytes(bits, bytesize=8):
+ r"""
+ Bits is a b'' object containing a binary representation. Assuming each
+ bytesize bits constitute a bytes, perform a endianness byte swap. Example:
+
+ >>> swap_bytes(b'00011011', 2)
+ b'11100100'
+ """
+ i = 0
+ l = len(bits)
+ output = [six.b("")] * ((l // bytesize) + 1)
+ j = len(output) - 1
+ while i < l:
+ output[j] = bits[i : i + bytesize]
+ i += bytesize
+ j -= 1
+ return six.b("").join(output)
+
+else:
+
+ def int_to_bin(number, width = 32):
+ r"""
+ Convert an integer into its binary representation in a bytes object.
+ Width is the amount of bits to generate. If width is larger than the actual
+ amount of bits required to represent number in binary, sign-extension is
+ used. If it's smaller, the representation is trimmed to width bits.
+ Each "bit" is either '\x00' or '\x01'. The MSBit is first.
+
+ Examples:
+
+ >>> int_to_bin(19, 5)
+ '\x01\x00\x00\x01\x01'
+ >>> int_to_bin(19, 8)
+ '\x00\x00\x00\x01\x00\x00\x01\x01'
+ """
+ if number < 0:
+ number += 1 << width
+ i = width - 1
+ bits = ["\x00"] * width
+ while number and i >= 0:
+ bits[i] = "\x00\x01"[number & 1]
+ number >>= 1
+ i -= 1
+ return "".join(bits)
+
+ # heavily optimized for performance
+ def bin_to_int(bits, signed = False):
+ r"""
+ Logical opposite of int_to_bin. Both '0' and '\x00' are considered zero,
+ and both '1' and '\x01' are considered one. Set sign to True to interpret
+ the number as a 2-s complement signed integer.
+ """
+ bits = "".join("01"[ord(b) & 1] for b in bits)
+ if signed and bits[0] == "1":
+ bits = bits[1:]
+ bias = 1 << len(bits)
+ else:
+ bias = 0
+ return int(bits, 2) - bias
+
+ _char_to_bin = [0] * 256
+ _bin_to_char = {}
+ for i in range(256):
+ ch = int2byte(i)
+ bin = int_to_bin(i, 8)
+ # Populate with for both keys i and ch, to support Python 2 & 3
+ _char_to_bin[i] = bin
+ _bin_to_char[bin] = ch
+
+ def encode_bin(data):
+ """
+ Create a binary representation of the given b'' object. Assume 8-bit
+ ASCII. Example:
+
+ >>> encode_bin('ab')
+ b"\x00\x01\x01\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x00\x01\x00"
+ """
+ return "".join(_char_to_bin[ord(ch)] for ch in data)
+
+ def decode_bin(data):
+ if len(data) & 7:
+ raise ValueError("Data length must be a multiple of 8")
+ i = 0
+ j = 0
+ l = len(data) // 8
+ chars = [""] * l
+ while j < l:
+ chars[j] = _bin_to_char[data[i:i+8]]
+ i += 8
+ j += 1
+ return "".join(chars)
+
+ def swap_bytes(bits, bytesize=8):
+ r"""
+ Bits is a b'' object containing a binary representation. Assuming each
+ bytesize bits constitute a bytes, perform a endianness byte swap. Example:
+
+ >>> swap_bytes(b'00011011', 2)
+ b'11100100'
+ """
+ i = 0
+ l = len(bits)
+ output = [""] * ((l // bytesize) + 1)
+ j = len(output) - 1
+ while i < l:
+ output[j] = bits[i : i + bytesize]
+ i += bytesize
+ j -= 1
+ return "".join(output)
diff --git a/external/construct/lib/binary.pyc b/external/construct/lib/binary.pyc
new file mode 100644
index 0000000..1614005
--- /dev/null
+++ b/external/construct/lib/binary.pyc
Binary files differ
diff --git a/external/construct/lib/bitstream.py b/external/construct/lib/bitstream.py
new file mode 100644
index 0000000..3b51f66
--- /dev/null
+++ b/external/construct/lib/bitstream.py
@@ -0,0 +1,81 @@
+import six
+from construct.lib.binary import encode_bin, decode_bin
+
+try:
+ bytes
+except NameError:
+ bytes = str
+
+class BitStreamReader(object):
+ __slots__ = ["substream", "buffer", "total_size"]
+
+ def __init__(self, substream):
+ self.substream = substream
+ self.total_size = 0
+ self.buffer = six.b("")
+
+ def close(self):
+ if self.total_size % 8 != 0:
+ raise ValueError("total size of read data must be a multiple of 8",
+ self.total_size)
+
+ def tell(self):
+ return self.substream.tell()
+
+ def seek(self, pos, whence = 0):
+ self.buffer = six.b("")
+ self.total_size = 0
+ self.substream.seek(pos, whence)
+
+ def read(self, count):
+ if count < 0:
+ raise ValueError("count cannot be negative")
+
+ l = len(self.buffer)
+ if count == 0:
+ data = six.b("")
+ elif count <= l:
+ data = self.buffer[:count]
+ self.buffer = self.buffer[count:]
+ else:
+ data = self.buffer
+ count -= l
+ count_bytes = count // 8
+ if count & 7:
+ count_bytes += 1
+ buf = encode_bin(self.substream.read(count_bytes))
+ data += buf[:count]
+ self.buffer = buf[count:]
+ self.total_size += len(data)
+ return data
+
+class BitStreamWriter(object):
+ __slots__ = ["substream", "buffer", "pos"]
+
+ def __init__(self, substream):
+ self.substream = substream
+ self.buffer = []
+ self.pos = 0
+
+ def close(self):
+ self.flush()
+
+ def flush(self):
+ raw = decode_bin(six.b("").join(self.buffer))
+ self.substream.write(raw)
+ self.buffer = []
+ self.pos = 0
+
+ def tell(self):
+ return self.substream.tell() + self.pos // 8
+
+ def seek(self, pos, whence = 0):
+ self.flush()
+ self.substream.seek(pos, whence)
+
+ def write(self, data):
+ if not data:
+ return
+ if not isinstance(data, bytes):
+ raise TypeError("data must be a string, not %r" % (type(data),))
+ self.buffer.append(data)
diff --git a/external/construct/lib/bitstream.pyc b/external/construct/lib/bitstream.pyc
new file mode 100644
index 0000000..8ea4399
--- /dev/null
+++ b/external/construct/lib/bitstream.pyc
Binary files differ
diff --git a/external/construct/lib/container.py b/external/construct/lib/container.py
new file mode 100644
index 0000000..f04d037
--- /dev/null
+++ b/external/construct/lib/container.py
@@ -0,0 +1,224 @@
+"""
+Various containers.
+"""
+
+def recursion_lock(retval, lock_name = "__recursion_lock__"):
+ def decorator(func):
+ def wrapper(self, *args, **kw):
+ if getattr(self, lock_name, False):
+ return retval
+ setattr(self, lock_name, True)
+ try:
+ return func(self, *args, **kw)
+ finally:
+ setattr(self, lock_name, False)
+ wrapper.__name__ = func.__name__
+ return wrapper
+ return decorator
+
+class Container(dict):
+ """
+ A generic container of attributes.
+
+ Containers are the common way to express parsed data.
+ """
+ __slots__ = ["__keys_order__"]
+
+ def __init__(self, **kw):
+ object.__setattr__(self, "__keys_order__", [])
+ for k, v in kw.items():
+ self[k] = v
+ def __getattr__(self, name):
+ try:
+ return self[name]
+ except KeyError:
+ raise AttributeError(name)
+ def __setitem__(self, key, val):
+ if key not in self:
+ self.__keys_order__.append(key)
+ dict.__setitem__(self, key, val)
+ def __delitem__(self, key):
+ dict.__delitem__(self, key)
+ self.__keys_order__.remove(key)
+
+ __delattr__ = __delitem__
+ __setattr__ = __setitem__
+
+ def clear(self):
+ dict.clear(self)
+ del self.__keys_order__[:]
+ def pop(self, key, *default):
+ val = dict.pop(self, key, *default)
+ self.__keys_order__.remove(key)
+ return val
+ def popitem(self):
+ k, v = dict.popitem(self)
+ self.__keys_order__.remove(k)
+ return k, v
+
+ def update(self, seq, **kw):
+ if hasattr(seq, "keys"):
+ for k in seq.keys():
+ self[k] = seq[k]
+ else:
+ for k, v in seq:
+ self[k] = v
+ dict.update(self, kw)
+
+ def copy(self):
+ inst = self.__class__()
+ inst.update(self.iteritems())
+ return inst
+
+ __update__ = update
+ __copy__ = copy
+
+ def __iter__(self):
+ return iter(self.__keys_order__)
+ iterkeys = __iter__
+ def itervalues(self):
+ return (self[k] for k in self.__keys_order__)
+ def iteritems(self):
+ return ((k, self[k]) for k in self.__keys_order__)
+ def keys(self):
+ return self.__keys_order__
+ def values(self):
+ return list(self.itervalues())
+ def items(self):
+ return list(self.iteritems())
+
+ def __repr__(self):
+ return "%s(%s)" % (self.__class__.__name__, dict.__repr__(self))
+
+ @recursion_lock("<...>")
+ def __pretty_str__(self, nesting = 1, indentation = " "):
+ attrs = []
+ ind = indentation * nesting
+ for k, v in self.iteritems():
+ if not k.startswith("_"):
+ text = [ind, k, " = "]
+ if hasattr(v, "__pretty_str__"):
+ text.append(v.__pretty_str__(nesting + 1, indentation))
+ else:
+ text.append(repr(v))
+ attrs.append("".join(text))
+ if not attrs:
+ return "%s()" % (self.__class__.__name__,)
+ attrs.insert(0, self.__class__.__name__ + ":")
+ return "\n".join(attrs)
+
+ __str__ = __pretty_str__
+
+
+class FlagsContainer(Container):
+ """
+ A container providing pretty-printing for flags.
+
+ Only set flags are displayed.
+ """
+
+ @recursion_lock("<...>")
+ def __pretty_str__(self, nesting = 1, indentation = " "):
+ attrs = []
+ ind = indentation * nesting
+ for k in self.keys():
+ v = self[k]
+ if not k.startswith("_") and v:
+ attrs.append(ind + k)
+ if not attrs:
+ return "%s()" % (self.__class__.__name__,)
+ attrs.insert(0, self.__class__.__name__+ ":")
+ return "\n".join(attrs)
+
+
+class ListContainer(list):
+ """
+ A container for lists.
+ """
+ __slots__ = ["__recursion_lock__"]
+
+ def __str__(self):
+ return self.__pretty_str__()
+
+ @recursion_lock("[...]")
+ def __pretty_str__(self, nesting = 1, indentation = " "):
+ if not self:
+ return "[]"
+ ind = indentation * nesting
+ lines = ["["]
+ for elem in self:
+ lines.append("\n")
+ lines.append(ind)
+ if hasattr(elem, "__pretty_str__"):
+ lines.append(elem.__pretty_str__(nesting + 1, indentation))
+ else:
+ lines.append(repr(elem))
+ lines.append("\n")
+ lines.append(indentation * (nesting - 1))
+ lines.append("]")
+ return "".join(lines)
+
+
+class LazyContainer(object):
+
+ __slots__ = ["subcon", "stream", "pos", "context", "_value"]
+
+ def __init__(self, subcon, stream, pos, context):
+ self.subcon = subcon
+ self.stream = stream
+ self.pos = pos
+ self.context = context
+ self._value = NotImplemented
+
+ def __eq__(self, other):
+ try:
+ return self._value == other._value
+ except AttributeError:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __str__(self):
+ return self.__pretty_str__()
+
+ def __pretty_str__(self, nesting = 1, indentation = " "):
+ if self._value is NotImplemented:
+ text = "<unread>"
+ elif hasattr(self._value, "__pretty_str__"):
+ text = self._value.__pretty_str__(nesting, indentation)
+ else:
+ text = str(self._value)
+ return "%s: %s" % (self.__class__.__name__, text)
+
+ def read(self):
+ self.stream.seek(self.pos)
+ return self.subcon._parse(self.stream, self.context)
+
+ def dispose(self):
+ self.subcon = None
+ self.stream = None
+ self.context = None
+ self.pos = None
+
+ def _get_value(self):
+ if self._value is NotImplemented:
+ self._value = self.read()
+ return self._value
+
+ value = property(_get_value)
+
+ has_value = property(lambda self: self._value is not NotImplemented)
+
+
+
+if __name__ == "__main__":
+ c = Container(x=5)
+ c.y = 8
+ c.z = 9
+ c.w = 10
+ c.foo = 5
+
+ print (c)
+
+
diff --git a/external/construct/lib/container.pyc b/external/construct/lib/container.pyc
new file mode 100644
index 0000000..690afbb
--- /dev/null
+++ b/external/construct/lib/container.pyc
Binary files differ
diff --git a/external/construct/lib/expr.py b/external/construct/lib/expr.py
new file mode 100644
index 0000000..783c947
--- /dev/null
+++ b/external/construct/lib/expr.py
@@ -0,0 +1,166 @@
+import operator
+
+if not hasattr(operator, "div"):
+ operator.div = operator.truediv
+
+
+opnames = {
+ operator.add : "+",
+ operator.sub : "-",
+ operator.mul : "*",
+ operator.div : "/",
+ operator.floordiv : "//",
+ operator.mod : "+",
+ operator.pow : "**",
+ operator.xor : "^",
+ operator.lshift : "<<",
+ operator.rshift : ">>",
+ operator.and_ : "and",
+ operator.or_ : "or",
+ operator.not_ : "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}))
+
+
+
+
diff --git a/external/construct/lib/expr.pyc b/external/construct/lib/expr.pyc
new file mode 100644
index 0000000..14e1ca2
--- /dev/null
+++ b/external/construct/lib/expr.pyc
Binary files differ
diff --git a/external/construct/lib/hex.py b/external/construct/lib/hex.py
new file mode 100644
index 0000000..62fd3c7
--- /dev/null
+++ b/external/construct/lib/hex.py
@@ -0,0 +1,46 @@
+from construct.lib.py3compat import byte2int, int2byte, bytes2str
+
+
+# Map an integer in the inclusive range 0-255 to its string byte representation
+_printable = dict((i, ".") for i in range(256))
+_printable.update((i, bytes2str(int2byte(i))) for i in range(32, 128))
+
+
+def hexdump(data, linesize):
+ """
+ data is a bytes object. The returned result is a string.
+ """
+ prettylines = []
+ if len(data) < 65536:
+ fmt = "%%04X %%-%ds %%s"
+ else:
+ fmt = "%%08X %%-%ds %%s"
+ fmt = fmt % (3 * linesize - 1,)
+ for i in range(0, len(data), linesize):
+ line = data[i : i + linesize]
+ hextext = " ".join('%02x' % byte2int(b) for b in line)
+ rawtext = "".join(_printable[byte2int(b)] for b in line)
+ prettylines.append(fmt % (i, str(hextext), str(rawtext)))
+ return prettylines
+
+
+try:
+ basecls = bytes
+except NameError:
+ basecls = str
+
+class HexString(basecls):
+ """
+ Represents bytes that will be hex-dumped to a string when its string
+ representation is requested.
+ """
+ def __init__(self, data, linesize = 16):
+ self.linesize = linesize
+ def __new__(cls, data, *args, **kwargs):
+ return basecls.__new__(cls, data)
+ def __str__(self):
+ if not self:
+ return "''"
+ return "\n" + "\n".join(hexdump(self, self.linesize))
+
+
diff --git a/external/construct/lib/hex.pyc b/external/construct/lib/hex.pyc
new file mode 100644
index 0000000..bc766fa
--- /dev/null
+++ b/external/construct/lib/hex.pyc
Binary files differ
diff --git a/external/construct/lib/py3compat.py b/external/construct/lib/py3compat.py
new file mode 100644
index 0000000..4a52c29
--- /dev/null
+++ b/external/construct/lib/py3compat.py
@@ -0,0 +1,70 @@
+#-------------------------------------------------------------------------------
+# py3compat.py
+#
+# Some Python2&3 compatibility code
+#-------------------------------------------------------------------------------
+import sys
+PY3 = sys.version_info[0] == 3
+
+
+if PY3:
+ import io
+ StringIO = io.StringIO
+ BytesIO = io.BytesIO
+
+ def bchr(i):
+ """ When iterating over b'...' in Python 2 you get single b'_' chars
+ and in Python 3 you get integers. Call bchr to always turn this
+ to single b'_' chars.
+ """
+ return bytes((i,))
+
+ def u(s):
+ return s
+
+ def int2byte(i):
+ return bytes((i,))
+
+ def byte2int(b):
+ return b
+
+ def str2bytes(s):
+ return s.encode("latin-1")
+
+ def str2unicode(s):
+ return s
+
+ def bytes2str(b):
+ return b.decode('latin-1')
+
+ def decodebytes(b, encoding):
+ return bytes(b, encoding)
+
+ advance_iterator = next
+
+else:
+ import cStringIO
+ StringIO = BytesIO = cStringIO.StringIO
+
+ int2byte = chr
+ byte2int = ord
+ bchr = lambda i: i
+
+ def u(s):
+ return unicode(s, "unicode_escape")
+
+ def str2bytes(s):
+ return s
+
+ def str2unicode(s):
+ return unicode(s, "unicode_escape")
+
+ def bytes2str(b):
+ return b
+
+ def decodebytes(b, encoding):
+ return b.decode(encoding)
+
+ def advance_iterator(it):
+ return it.next()
+
diff --git a/external/construct/lib/py3compat.pyc b/external/construct/lib/py3compat.pyc
new file mode 100644
index 0000000..4f06b7b
--- /dev/null
+++ b/external/construct/lib/py3compat.pyc
Binary files differ