from ctypes import * from enum import IntEnum from itertools import product import numpy as np from numpy import random def copy(src, dst): """Copies the contents of src to dst""" pointer(dst)[0] = src knownCTypes = set([c_float, c_uint, c_int, c_bool]) def toString(struct): fields = [field + "=" + str(getattr(struct, field)) for (field, _) in struct._fields_] return "%s{%s}" % (struct.__class__.__name__, ", ".join(fields)) def toTuple(value, ctype=None): if ctype is None: ctype = type(value) if ctype in knownCTypes: return value if issubclass(ctype, Structure): return tuple(toTuple(getattr(value, f), t) for f, t in ctype._fields_) # an array type return tuple(toTuple(v, ctype._type_) for v in value) def toDict(value, ctype=None): if ctype is None: ctype = type(value) if ctype in knownCTypes: return value if issubclass(ctype, Structure): return {f: toDict(getattr(value, f), t) for f, t in ctype._fields_} # an array type return [toDict(v, ctype._type_) for v in value] def hashStruct(struct): return hash(toTuple(struct)) def eqStruct(struct1, struct2): return toTuple(struct1) == toTuple(struct2) def toCType(t): if issubclass(t, IntEnum): return c_uint return t # class decorator def pretty_struct(cls): cls._fields_ = [(name, toCType(t)) for name, t in cls._fields] cls.__repr__ = toString cls.__hash__ = hashStruct cls.__eq__ = eqStruct cls.allValues = classmethod(allValues) cls.randomValue = classmethod(randomValue) return cls def allValues(ctype): if issubclass(ctype, IntEnum): return list(ctype) if issubclass(ctype, Structure): names, types = zip(*ctype._fields) values = [allValues(t) for t in types] def make(vals): obj = ctype() for name, val in zip(names, vals): setattr(obj, name, val) return obj return [make(vals) for vals in product(*values)] # TODO: handle bounded ints via _fields # TODO: handle arrays raise TypeError("Unsupported type %s" % ctype) def randomValue(ctype): if issubclass(ctype, IntEnum): return random.choice(list(ctype)) if issubclass(ctype, Structure): obj = ctype() for name, type_ in ctype._fields: setattr(obj, name, randomValue(type_)) return obj # TODO: handle arrays raise TypeError("Unsupported type %s" % ctype)