Skip to content

Instantly share code, notes, and snippets.

@wrenoud
Created March 3, 2016 17:04
Show Gist options
  • Save wrenoud/44aa3a9ec68d14ebec9d to your computer and use it in GitHub Desktop.
Save wrenoud/44aa3a9ec68d14ebec9d to your computer and use it in GitHub Desktop.
ExecTest.py
# coding: utf-8
import struct
def with_metaclass(meta, *bases):
"""Create a base class with a metaclass. For 2/3 compatibility."""
class metaclass(meta):
__call__ = type.__call__
__init__ = type.__init__
def __new__(cls, name, this_bases, d):
if this_bases is None:
return type.__new__(cls, name, (), d)
return meta(name, bases, d)
return metaclass("NewBase", None, {})
class BinaryFieldBase():
_format = 'i'
class BinaryObjectMeta(type):
def __new__(metaclass, class_name, class_bases, class_attr):
if class_name != 'BinaryObjectBase':
class_attr['_structs'] = []
func_string = 'def unpack_from(self, data, offset = 0):\n'
partial_struct = class_attr['_byte_order']
partial_list = ''
partial_idx = 0
for i,key in enumerate(class_attr['_field_order']):
field = class_attr[key]
if issubclass(field.__class__, BinaryFieldBase):
partial_struct += field._format
partial_list += 'self.{}, '.format(key)
elif issubclass(field.__class__, BinaryObjectBase) and field._flat:
pass
elif issubclass(field.__class__, BinaryObjectBase) and not field._flat:
if len(partial_struct) > 1:
sId = len(class_attr['_structs'])
class_attr['_structs'].append(struct.Struct(partial_struct))
func_string += '\n\tsz = self._structs[{0}].size\n'.format(sId)
func_string += '\t' + partial_list[:-2] + ' = self._structs[{0}].unpack_from(data, offset)\n'.format(sId)
func_string += '\toffset += sz\n'
partial_struct = class_attr['_byte_order']
partial_list = ''
partial_idx = i
func_string += '\n\tself.{}.unpack_from(data, offset)\n'.format(key)
func_string += '\toffset += self.{}.size\n'.format(key)
else:
print field
print field.__class__
print field.__dict__
if len(partial_struct) > 1:
sId = len(class_attr['_structs'])
class_attr['_structs'].append(struct.Struct(partial_struct))
func_string += '\n\tsz = self._structs[{0}].size\n'.format(sId)
func_string += '\t' + partial_list[:-2] + ' = self._structs[{0}].unpack_from(data, offset)\n'.format(sId)
func_string += '\toffset += sz\n'
print func_string
return type.__new__(metaclass, class_name, class_bases, class_attr)
class BinaryObjectBase(with_metaclass(BinaryObjectMeta, object)):
_byte_order = '='
_field_order = None
_structs = None
class subItem(BinaryObjectBase):
_flat = False
_byte_order = '='
_field_order = ['c','d','e']
c = BinaryFieldBase()
d = BinaryFieldBase()
e = BinaryFieldBase()
class subItemFlat(BinaryObjectBase):
_flat = True
_byte_order = '='
_field_order = ['c','d','e']
c = BinaryFieldBase()
d = BinaryFieldBase()
e = BinaryFieldBase()
class test(BinaryObjectBase):
_byte_order = '='
_field_order = ['a','b','sub','f','g','h']
a = BinaryFieldBase()
b = BinaryFieldBase()
sub = subItem()
f = BinaryFieldBase()
g = BinaryFieldBase()
h = subItemFlat()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment