def parse(self, obj, prefix='', depth=10): """ Returns a string formatted description of this Structure. The returned string should be python-compatible... """ # TODO: use a ref table to stop loops on parsed instance, # depth kinda sux. if depth <= 0: return 'None, # DEPTH LIMIT REACHED' if hasattr(obj, 'toString'): return obj.to_string(prefix, depth) if hasattr(obj, '_orig_address_'): s = "{ # <%s at 0x%x>" % ( obj.__class__.__name__, obj._orig_address_) else: s = "{ # <%s at 0x???>" % (obj.__class__.__name__) for field, typ in basicmodel.get_fields(obj): attr = getattr(obj, field) s += '\n%s"%s": %s' % (prefix, field, self._attrToString( attr, field, typ, prefix, depth)) s += '\n' + prefix + '}' return s
def check_varname_for_type(memory_handler, varname, struct_type): done = [] st = struct_type model = memory_handler.get_model() ctypes = memory_handler.get_target_platform().get_target_ctypes() for v in varname: if not hasattr(st, v): fields = ["%s: %s" % (n, t) for n, t in basicmodel.get_fields(st)] log.error('(%s.)%s does not exists in type %s\n\t%s', '.'.join(done), v, st, '\n\t'.join(fields)) return False st = st._get_field_type(v) if ctypes.is_pointer_type(st): # accept pointers st = model.get_subtype(st) done.append(v) return True
def parse(self, obj, prefix='', depth=10, addr_was=None): """ Returns a string formatted description of this Structure. The returned string should be python-compatible... """ # TODO: use a ref table to stop loops on parsed instance, # depth kinda sux. # if obj._orig_address_ in self._addr_cache: if addr_was: addr = addr_was elif hasattr(obj, '_orig_address_'): addr = obj._orig_address_ else: addr = self._ctypes.addressof(obj) if addr in self._addr_cache: if type(obj) in self._addr_cache[addr]: #depth = min(depth, 1) s = "{}, # 0x%x ...already shown..." % addr self._addr_cache[addr].append(type(obj)) return s else: self._addr_cache[addr] = [] self._addr_cache[addr].append(type(obj)) if depth <= 0: return 'None, # DEPTH LIMIT REACHED' if hasattr(obj, 'toString'): return obj.to_string(prefix, depth) if hasattr(obj, '_orig_address_'): s = "{ # <%s at 0x%x>" % ( obj.__class__.__name__, obj._orig_address_) else: s = "{ # <%s at 0x%x>" % (obj.__class__.__name__, addr) for field, typ in basicmodel.get_fields(obj): attr = getattr(obj, field) offset = getattr(type(obj), field).offset s += '\n%s"%s": %s' % (prefix, field, self._attrToString( attr, field, typ, prefix, addr + offset, depth)) s += '\n' + prefix + '}' self._addr_cache = {} return s
def parse(self, obj, prefix='', depth=10, addr_was=None): """ Returns a string formatted description of this Structure. The returned string should be python-compatible... """ # TODO: use a ref table to stop loops on parsed instance, # depth kinda sux. # if obj._orig_address_ in self._addr_cache: if addr_was: addr = addr_was elif hasattr(obj, '_orig_address_'): addr = obj._orig_address_ else: addr = self._ctypes.addressof(obj) if addr in self._addr_cache: if type(obj) in self._addr_cache[addr]: #depth = min(depth, 1) s = "{}, # 0x%x ...already shown..." % addr self._addr_cache[addr].append(type(obj)) return s else: self._addr_cache[addr] = [] self._addr_cache[addr].append(type(obj)) if depth <= 0: return 'None, # DEPTH LIMIT REACHED' if hasattr(obj, 'toString'): return obj.to_string(prefix, depth) if hasattr(obj, '_orig_address_'): s = "{ # <%s at 0x%x>" % (obj.__class__.__name__, obj._orig_address_) else: s = "{ # <%s at 0x%x>" % (obj.__class__.__name__, addr) for field, typ in basicmodel.get_fields(obj): attr = getattr(obj, field) offset = getattr(type(obj), field).offset s += '\n%s"%s": %s' % (prefix, field, self._attrToString(attr, field, typ, prefix, addr + offset, depth)) s += '\n' + prefix + '}' self._addr_cache = {} return s
def parse(self, obj, prefix='', depth=50): """ Returns a Plain Old python object as a perfect copy of this self._ctypes object. array would be lists, pointers, inner allocators, and circular reference should be handled nicely. """ # get self class. try: obj_module_name = obj.__class__.__module__ obj_class_name = obj.__class__.__name__ try: obj_module = self._model.get_pythoned_module(obj_module_name) except KeyError: # FIXME - ctypes modules should not be in sys.modules. what about reloading? self._model.build_python_class_clones( sys.modules[obj_module_name]) obj_module = self._model.get_pythoned_module(obj_module_name) my_class = getattr(obj_module, "%s_py" % obj_class_name) except AttributeError as e: log.warning('did you forget to register your python allocators ?') raise my_self = my_class() my_address = self._ctypes.addressof(obj) # keep ref of the POPO too. if self._memory_handler.hasRef(my_class, my_address): return self._memory_handler.getRef(my_class, my_address) # save our POPO in a partially resolved state, to keep from loops. self._memory_handler.keepRef(my_self, my_class, my_address) for field, typ in basicmodel.get_fields(obj): attr = getattr(obj, field) try: member = self._attrToPyObject(attr, field, typ) except NameError as e: raise NameError('%s %s\n%s' % (field, typ, e)) setattr(my_self, field, member) # save the original type (me) and the field setattr(my_self, '_ctype_', type(obj)) return my_self
def parse(self, obj, prefix='', depth=50): """ Returns a Plain Old python object as a perfect copy of this self._ctypes object. array would be lists, pointers, inner allocators, and circular reference should be handled nicely. """ # get self class. try: obj_module_name = obj.__class__.__module__ obj_class_name = obj.__class__.__name__ try: obj_module = self._model.get_pythoned_module(obj_module_name) except KeyError: # FIXME - ctypes modules should not be in sys.modules. what about reloading? self._model.build_python_class_clones(sys.modules[obj_module_name]) obj_module = self._model.get_pythoned_module(obj_module_name) my_class = getattr(obj_module, "%s_py" % obj_class_name) except AttributeError as e: log.warning('did you forget to register your python allocators ?') raise my_self = my_class() my_address = self._ctypes.addressof(obj) # keep ref of the POPO too. if self._memory_handler.hasRef(my_class, my_address): return self._memory_handler.getRef(my_class, my_address) # save our POPO in a partially resolved state, to keep from loops. self._memory_handler.keepRef(my_self, my_class, my_address) for field, typ in basicmodel.get_fields(obj): attr = getattr(obj, field) try: member = self._attrToPyObject(attr, field, typ) except NameError as e: raise NameError('%s %s\n%s' % (field, typ, e)) setattr(my_self, field, member) # save the original type (me) and the field setattr(my_self, '_ctype_', type(obj)) return my_self
def __iter__(self): """ iterate on a instance's type's _fields_ members following the original type field order """ for k, typ in basicmodel.get_fields(self._ctype_): v = getattr(self, k) yield (k, v, typ) pass