[pypy-svn] r76827 - in pypy/branch/reflex-support/pypy/module/cppyy: . test

wlav at codespeak.net wlav at codespeak.net
Thu Sep 2 02:20:21 CEST 2010


Author: wlav
Date: Thu Sep  2 02:20:18 2010
New Revision: 76827

Modified:
   pypy/branch/reflex-support/pypy/module/cppyy/converter.py
   pypy/branch/reflex-support/pypy/module/cppyy/executor.py
   pypy/branch/reflex-support/pypy/module/cppyy/helper.py
   pypy/branch/reflex-support/pypy/module/cppyy/test/datatypes.h
   pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py
   pypy/branch/reflex-support/pypy/module/cppyy/test/test_helper.py
Log:
Initial implementation for passing short int arrays.


Modified: pypy/branch/reflex-support/pypy/module/cppyy/converter.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/converter.py	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/converter.py	Thu Sep  2 02:20:18 2010
@@ -3,6 +3,8 @@
 from pypy.rlib.rarithmetic import r_singlefloat
 from pypy.objspace.std.intobject import W_IntObject
 
+from pypy.module._rawffi.interp_rawffi import unpack_simple_shape
+
 from pypy.module.cppyy import helper, capi
 
 _converters = {}
@@ -166,6 +168,41 @@
         return rffi.cast(rffi.VOIDP, x)
 
 
+class ShortPtrConverter(TypeConverter):
+    _immutable_ = True
+    def __init__(self, detail=None):
+        if detail is None:
+            import sys
+            detail = sys.maxint
+        self.size = detail
+    
+    def convert_argument(self, space, w_obj):
+        assert "not yet implemented"
+
+    def from_memory(self, space, w_obj, offset):
+        # read access, so no copy needed
+        fieldptr = self._get_fieldptr(space, w_obj, offset)
+        shortptr = rffi.cast(rffi.SHORTP, fieldptr)
+        w_array = unpack_simple_shape(space, space.wrap('h'))
+        return w_array.fromaddress(space, shortptr, self.size)
+
+    def to_memory(self, space, w_obj, w_value, offset):
+        # copy only the pointer value
+        obj = space.interpclass_w(space.findattr(w_obj, space.wrap("_cppinstance")))
+        byteptr = rffi.cast(rffi.LONGP, obj.rawobject[offset])
+        # TODO: now what ... ?? AFAICS, w_value is a pure python list, not an array?
+#        byteptr[0] = space.unwrap(space.id(w_value.getslotvalue(2)))
+
+
+class ShortArrayConverter(ShortPtrConverter):
+    def to_memory(self, space, w_obj, w_value, offset):
+        # copy the full array (uses byte copy for now)
+        fieldptr = self._get_fieldptr(space, w_obj, offset)
+        value = w_value.getslotvalue(2)
+        for i in range(min(self.size*2, value.getlength())):
+            fieldptr[i] = value.getitem(i)
+
+
 class InstancePtrConverter(TypeConverter):
     _immutable_ = True
     def __init__(self, space, cpptype):
@@ -199,13 +236,23 @@
     #   5) generalized cases (covers basically all user classes)
     #   6) void converter, which fails on use
 
+    #   1) full, exact match
     try:
-        return _converters[name]
+        return _converters[name]()
     except KeyError:
         pass
 
-    compound = helper.compound(name)
-    cpptype = interp_cppyy.type_byname(space, helper.clean_type(name))
+    #   2) match of decorated, unqualified type
+    compound, detail = helper.compound(name)
+    clean_name = helper.clean_type(name)
+    try:
+        if detail:
+            return _converters[clean_name+compound](detail)
+        return _converters[clean_name+compound]()
+    except KeyError:
+        pass
+        
+    cpptype = interp_cppyy.type_byname(space, clean_name)
     if compound == "*":
         return InstancePtrConverter(space, cpptype)
 
@@ -214,15 +261,17 @@
     return VoidConverter(space, name)
 
 
-_converters["bool"]                = BoolConverter()
-_converters["char"]                = CharConverter()
-_converters["unsigned char"]       = CharConverter()
-_converters["short int"]           = ShortConverter()
-_converters["unsigned short int"]  = ShortConverter()
-_converters["int"]                 = LongConverter()
-_converters["unsigned int"]        = LongConverter()
-_converters["long int"]            = LongConverter()
-_converters["unsigned long int"]   = LongConverter()
-_converters["float"]               = FloatConverter()
-_converters["double"]              = DoubleConverter()
-_converters["const char*"]         = CStringConverter()
+_converters["bool"]                = BoolConverter
+_converters["char"]                = CharConverter
+_converters["unsigned char"]       = CharConverter
+_converters["short int"]           = ShortConverter
+_converters["short int*"]          = ShortPtrConverter
+_converters["short int[]"]         = ShortArrayConverter
+_converters["unsigned short int"]  = ShortConverter
+_converters["int"]                 = LongConverter
+_converters["unsigned int"]        = LongConverter
+_converters["long int"]            = LongConverter
+_converters["unsigned long int"]   = LongConverter
+_converters["float"]               = FloatConverter
+_converters["double"]              = DoubleConverter
+_converters["const char*"]         = CStringConverter

Modified: pypy/branch/reflex-support/pypy/module/cppyy/executor.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/executor.py	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/executor.py	Thu Sep  2 02:20:18 2010
@@ -75,7 +75,7 @@
     except KeyError:
         pass
 
-    compound = helper.compound(name)
+    compound, detail = helper.compound(name)
     cpptype = interp_cppyy.type_byname(space, helper.clean_type(name))
     if compound == "*":           
         return InstancePtrExecutor(space, cpptype)

Modified: pypy/branch/reflex-support/pypy/module/cppyy/helper.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/helper.py	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/helper.py	Thu Sep  2 02:20:18 2010
@@ -4,8 +4,11 @@
     name = "".join(rstring.split(name, "const")) # poor man's replace
     i = _find_qualifier_index(name)
     if name[-1] == "]":                          # array type
-        return "*"
-    return "".join(name[i:].split(" "))
+        for i in range(len(name) - 1, -1, -1):
+            c = name[i]
+            if c == "[":
+                return "[]", int(name[i+1:-1])
+    return "".join(name[i:].split(" ")), None
 
 def _find_qualifier_index(name):
     i = len(name)

Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/datatypes.h
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/datatypes.h	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/datatypes.h	Thu Sep  2 02:20:18 2010
@@ -14,6 +14,9 @@
     cppyy_test_data();
     ~cppyy_test_data();
 
+// helper
+    void destroy_arrays();
+
 // getters
     bool           get_bool();
     char           get_char();
@@ -107,9 +110,6 @@
     static double         s_double;
 
 private:
-    void destroy_arrays();
-
-private:
     bool m_owns_arrays;
 };
 

Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py	Thu Sep  2 02:20:18 2010
@@ -16,11 +16,10 @@
         raise OSError("'make' failed (see stderr)")
 
 class AppTestDATATYPES:
-    N = 5               # should be imported from the dictionary
-
     def setup_class(cls):
         cls.space = space
         env = os.environ
+        cls.w_N = space.wrap(5)    # should be imported from the dictionary
         cls.w_shared_lib = space.wrap(shared_lib)
         cls.w_datatypes = cls.space.appexec([], """():
             import cppyy
@@ -93,23 +92,22 @@
         c.m_double = 0.456;    assert round(c.get_double() - 0.456, 8) == 0
         c.set_double( 0.567 ); assert round(c.m_double     - 0.567, 8) == 0
 
-        """
         # arrays; there will be pointer copies, so destroy the current ones
         c.destroy_arrays()
 
         # integer arrays
-        a = range(N)
-        atypes = [ 'h', 'H', 'i', 'I', 'l', 'L' ]
-        for j in range(len(names)):
-            b = array(atypes[j], a)
+        import array
+        a = range(self.N)
+        atypes = [ 'h' ] #, 'H', 'i', 'I', 'l', 'L' ]
+        for j in range(len(atypes)):#names)):
+            b = array.array(atypes[j], a)
             exec 'c.m_%s_array = b' % names[j]   # buffer copies
-            for i in range(N):
+            for i in range(self.N):
                 assert eval('c.m_%s_array[i]' % names[j]) == b[i]
 
-            exec 'c.m_%s_array2 = b' % names[j]  # pointer copies
-            b[i] = 28
-            for i in range(N):
-                assert eval('c.m_%s_array2[i]' % names[j]) == b[i]
-        """
+#            exec 'c.m_%s_array2 = b' % names[j]  # pointer copies
+#            b[i] = 28
+#            for i in range(self.N):
+#                assert eval('c.m_%s_array2[i]' % names[j]) == b[i]
 
         c.destruct()

Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/test_helper.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/test_helper.py	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/test_helper.py	Thu Sep  2 02:20:18 2010
@@ -1,11 +1,13 @@
 from pypy.module.cppyy import helper
 
 def test_compound():
-    assert helper.compound("int*") == "*"
-    assert helper.compound("int* const *&") == "**&"
-    assert helper.compound("std::vector<int>*") == "*"
+    assert helper.compound("int*") == ("*", None)
+    assert helper.compound("int* const *&") == ("**&", None)
+    assert helper.compound("std::vector<int>*") == ("*", None)
+    assert helper.compound("unsigned long int[5]") == ("[]", 5)
 
 
 def test_clean_type():
     assert helper.clean_type(" int***") == "int"
     assert helper.clean_type("std::vector<int>&") == "std::vector<int>"
+    assert helper.clean_type("unsigned short int[3]") == "unsigned short int"



More information about the Pypy-commit mailing list