From: <wme...@us...> - 2009-09-04 02:39:03
|
Revision: 6748 http://jython.svn.sourceforge.net/jython/?rev=6748&view=rev Author: wmeissner Date: 2009-09-04 02:38:53 +0000 (Fri, 04 Sep 2009) Log Message: ----------- When a Structure subclass is instantiated with an argument list, fill out the structure contents with the values Modified Paths: -------------- branches/ctypes-jffi/Lib/ctypes/__init__.py branches/ctypes-jffi/src/org/python/modules/jffi/StructLayout.java branches/ctypes-jffi/src/org/python/modules/jffi/Structure.java Modified: branches/ctypes-jffi/Lib/ctypes/__init__.py =================================================================== --- branches/ctypes-jffi/Lib/ctypes/__init__.py 2009-09-04 01:31:51 UTC (rev 6747) +++ branches/ctypes-jffi/Lib/ctypes/__init__.py 2009-09-04 02:38:53 UTC (rev 6748) @@ -75,31 +75,26 @@ def build(self): return jffi.StructLayout(fields = self.fields, union = self.union) -class _StructMetaClass(type): - def __new__(cls, name, bases, dict): - try: - layout = dict['_jffi_type'] = _StructLayoutBuilder().add_fields(dict['_fields_']).build() +class _AggregateMetaClass(type): + def __new_aggregate__(cls, name, bases, dict, union = False): + if dict.has_key('_fields_'): + layout = dict['_jffi_type'] = _StructLayoutBuilder(union).add_fields(dict['_fields_']).build() # make all fields accessible via .foo for f in dict['_fields_']: dict[f[0]] = layout[f[0]] - except: - pass return type.__new__(cls, name, bases, dict) + __new_aggregate__ = staticmethod(__new_aggregate__) + +class _StructMetaClass(_AggregateMetaClass): + def __new__(cls, name, bases, dict): + return _AggregateMetaClass.__new_aggregate__(cls, name, bases, dict, union = False) + class _UnionMetaClass(type): def __new__(cls, name, bases, dict): - try: - layout = dict['_jffi_type'] = _StructLayoutBuilder().add_fields(dict['_fields_'], union = True).build() - # make all fields accessible via .foo - for f in dict['_fields_']: - dict[f[0]] = layout[f[0]] - except: - pass + return _AggregateMetaClass.__new_aggregate__(cls, name, bases, dict, union = True) - - return type.__new__(cls, name, bases, dict) - class Structure(jffi.Structure): __metaclass__ = _StructMetaClass @@ -107,12 +102,10 @@ __metaclass__ = _UnionMetaClass def sizeof(type): - if isinstance(type, jffi.CData): + if hasattr(type, '_jffi_type'): return type._jffi_type.size - elif hasattr(type, '_type_'): - return _TypeMap[type.__getattribute__('_type_')] else: - raise TypeError("invalid ctype") + raise TypeError("this type has no size") def alignment(type): return type._jffi_type.alignment Modified: branches/ctypes-jffi/src/org/python/modules/jffi/StructLayout.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/StructLayout.java 2009-09-04 01:31:51 UTC (rev 6747) +++ branches/ctypes-jffi/src/org/python/modules/jffi/StructLayout.java 2009-09-04 02:38:53 UTC (rev 6748) @@ -1,7 +1,10 @@ package org.python.modules.jffi; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.python.core.ArgParser; import org.python.core.Py; @@ -22,15 +25,18 @@ TYPE.fastGetDict().__setitem__("ScalarField", ScalarField.TYPE); } - private final Map<PyObject, Field> fieldMap; + private final Map<Object, Field> fieldMap; + private final List<Field> fields; StructLayout(Field[] fields, com.kenai.jffi.Type struct, MemoryOp op) { super(NativeType.STRUCT, struct, op); - Map<PyObject, Field> m = new HashMap<PyObject, Field>(fields.length); + Map<Object, Field> m = new HashMap<Object, Field>(fields.length); for (Field f : fields) { m.put(f.name, f); + m.put(f.name.toString(), f); } this.fieldMap = m; + this.fields = Collections.unmodifiableList(Arrays.asList(fields)); } @ExposedType(name = "jffi.StructLayout.Field", base = PyObject.class) @@ -152,6 +158,14 @@ return fieldMap.get(name); } + Field getField(String name) { + return fieldMap.get(name); + } + + List<Field> getFieldList() { + return fields; + } + @Override public PyObject __getitem__(PyObject key) { StructLayout.Field f = getField(key); Modified: branches/ctypes-jffi/src/org/python/modules/jffi/Structure.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/Structure.java 2009-09-04 01:31:51 UTC (rev 6747) +++ branches/ctypes-jffi/src/org/python/modules/jffi/Structure.java 2009-09-04 02:38:53 UTC (rev 6748) @@ -1,6 +1,9 @@ package org.python.modules.jffi; +import java.lang.reflect.Field; +import java.util.List; +import org.python.core.ArgParser; import org.python.core.Py; import org.python.core.PyNewWrapper; import org.python.core.PyObject; @@ -30,12 +33,30 @@ public static PyObject Structure_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { - PyObject layout = subtype.__getattr__("_jffi_type"); - if (!(layout instanceof StructLayout)) { + PyObject jffi_type = subtype.__getattr__("_jffi_type"); + if (!(jffi_type instanceof StructLayout)) { throw Py.TypeError("invalid _jffi_type for " + subtype.fastGetName() + "; should be instance of jffi.StructLayout"); } - return new Structure(subtype, (StructLayout) layout); + StructLayout layout = (StructLayout) jffi_type; + Structure s = new Structure(subtype, layout); + if (args.length > 0) { + int n = args.length - keywords.length; + List<StructLayout.Field> fields = layout.getFieldList(); + Memory m = s.getMemory(); + // First, do non-keyword args in order + for (int i = 0; i < n; ++i) { + StructLayout.Field f = fields.get(i); + f.op.put(m, f.offset, args[i]); + } + + // Now handle the keyworded args by looking up the field + for (int i = n; i < args.length; ++i) { + StructLayout.Field f = layout.getField(keywords[i - n]); + f.op.put(m, f.offset, args[i]); + } + } + return s; } protected final void initReferenceMemory(Memory m) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |