[pypy-svn] r73410 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test

trundle at codespeak.net trundle at codespeak.net
Mon Apr 5 15:30:44 CEST 2010


Author: trundle
Date: Mon Apr  5 15:30:42 2010
New Revision: 73410

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/api.py
   pypy/branch/cpython-extension/pypy/module/cpyext/include/unicodeobject.h
   pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py
Log:
Add PyUnicode_AS_DATA and PyUnicode_GET_DATA_SIZE.


Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/api.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py	Mon Apr  5 15:30:42 2010
@@ -274,6 +274,12 @@
     (("buffer", rffi.CCHARP), ("size", Py_ssize_t))
 cpython_struct("PyStringObject", PyStringObjectFields, PyStringObjectStruct)
 
+PyUnicodeObjectStruct = lltype.ForwardReference()
+PyUnicodeObject = lltype.Ptr(PyUnicodeObjectStruct)
+PyUnicodeObjectFields = (PyObjectFields +
+    (("buffer", rffi.VOIDP), ("size", Py_ssize_t)))
+cpython_struct("PyUnicodeObject", PyUnicodeObjectFields, PyUnicodeObjectStruct)
+
 VA_TP_LIST = {'int': lltype.Signed,
               'PyObject*': PyObject,
               'int*': rffi.INTP}

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/unicodeobject.h
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/include/unicodeobject.h	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/include/unicodeobject.h	Mon Apr  5 15:30:42 2010
@@ -1,9 +1,26 @@
+#ifndef Py_UNICODEOBJECT_H
+#define Py_UNICODEOBJECT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 typedef struct {
     PyObject_HEAD
+    void *buffer;
+    Py_ssize_t size;
 } PyUnicodeObject;
+
+
 //XXX
 typedef unsigned int Py_UCS4; 
 // pypy only supports only UCS4
 #define PY_UNICODE_TYPE Py_UCS4
 typedef PY_UNICODE_TYPE Py_UNICODE;
 
+  
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_UNICODEOBJECT_H */

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py	Mon Apr  5 15:30:42 2010
@@ -3,9 +3,10 @@
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import cpython_api, PyObject, PyStringObject, ADDR,\
-        Py_TPFLAGS_HEAPTYPE
+        Py_TPFLAGS_HEAPTYPE, PyUnicodeObject
 from pypy.module.cpyext.state import State
 from pypy.objspace.std.stringobject import W_StringObject
+from pypy.objspace.std.unicodeobject import W_UnicodeObject
 from pypy.rlib.objectmodel import we_are_translated
 
 #________________________________________________________
@@ -73,6 +74,14 @@
             py_obj = rffi.cast(PyObject, py_obj_str)
             py_obj.c_ob_refcnt = 1
             py_obj.c_ob_type = rffi.cast(PyTypeObjectPtr, pto)
+        elif isinstance(w_obj, W_UnicodeObject):
+            py_obj_unicode = lltype.malloc(PyUnicodeObject.TO, flavor='raw', zero=True)
+            py_obj_unicode.c_size = len(space.unicode_w(w_obj))
+            py_obj_unicode.c_buffer = lltype.nullptr(rffi.VOIDP.TO)
+            pto = make_ref(space, space.w_unicode)
+            py_obj = rffi.cast(PyObject, py_obj_unicode)
+            py_obj.c_ob_refcnt = 1
+            py_obj.c_ob_type = rffi.cast(PyTypeObjectPtr, pto)
         else:
             py_obj = lltype.malloc(PyObject.TO, flavor="raw", zero=True)
             py_obj.c_ob_refcnt = 1

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py	Mon Apr  5 15:30:42 2010
@@ -5653,27 +5653,12 @@
     """
     raise NotImplementedError
 
- at cpython_api([PyObject], Py_ssize_t)
-def PyUnicode_GET_DATA_SIZE(space, o):
-    """Return the size of the object's internal buffer in bytes.  o has to be a
-    PyUnicodeObject (not checked).
-    
-    This function returned an int type. This might require changes
-    in your code for properly supporting 64-bit systems."""
-    raise NotImplementedError
-
 @cpython_api([PyObject], {Py_UNICODE*})
 def PyUnicode_AS_UNICODE(space, o):
     """Return a pointer to the internal Py_UNICODE buffer of the object.  o
     has to be a PyUnicodeObject (not checked)."""
     raise NotImplementedError
 
- at cpython_api([PyObject], rffi.CCHARP)
-def PyUnicode_AS_DATA(space, o):
-    """Return a pointer to the internal buffer of the object. o has to be a
-    PyUnicodeObject (not checked)."""
-    raise NotImplementedError
-
 @cpython_api([], rffi.INT_real)
 def PyUnicode_ClearFreeList(space, ):
     """Clear the free list. Return the total number of freed items.

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py	Mon Apr  5 15:30:42 2010
@@ -1,10 +1,18 @@
 # encoding: iso-8859-15
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.unicodeobject import Py_UNICODE
+from pypy.rpython.lltypesystem import rffi
 
 class TestUnicode(BaseApiTest):
     def test_unicodeobject(self, space, api):
         assert space.unwrap(api.PyUnicode_GET_SIZE(space.wrap(u'späm'))) == 4
 
+    def test_AS_DATA(self, space, api):
+        word = space.wrap(u'spam')
+        array = rffi.cast(rffi.CWCHARP, api.PyUnicode_AS_DATA(word))
+        for (i, char) in enumerate(space.unwrap(word)):
+            assert array[i] == char
+
     def test_IS(self, space, api):
         for char in [0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x1c, 0x1d, 0x1e, 0x1f,
                      0x20, 0x85, 0xa0, 0x1680, 0x2000, 0x2001, 0x2002,

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py	Mon Apr  5 15:30:42 2010
@@ -1,8 +1,8 @@
-from pypy.rpython.lltypesystem import rffi
+from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.unicodedata import unicodedb_4_1_0 as unicodedb
-from pypy.module.cpyext.api import (CANNOT_FAIL, Py_ssize_t,
+from pypy.module.cpyext.api import (CANNOT_FAIL, Py_ssize_t, PyUnicodeObject,
                                     build_type_checkers, cpython_api)
-from pypy.module.cpyext.pyobject import PyObject
+from pypy.module.cpyext.pyobject import PyObject, from_ref
 from pypy.objspace.std import unicodeobject
 
 PyUnicode_Check, PyUnicode_CheckExact = build_type_checkers("Unicode", "w_unicode")
@@ -55,6 +55,24 @@
     """Return the character ch converted to lower case."""
     return unicodedb.tolower(w_ch)
 
+ at cpython_api([PyObject], rffi.CCHARP, error=CANNOT_FAIL)
+def PyUnicode_AS_DATA(space, ref):
+    """Return a pointer to the internal buffer of the object. o has to be a
+    PyUnicodeObject (not checked)."""
+    ref_unicode = rffi.cast(PyUnicodeObject, ref)
+    if not ref_unicode.c_buffer:
+        # Copy unicode buffer
+        w_unicode = from_ref(space, ref)
+        u = space.unicode_w(w_unicode)
+        ref_unicode.c_buffer = rffi.cast(rffi.VOIDP, rffi.unicode2wcharp(u))
+    return rffi.cast(rffi.CCHARP, ref_unicode.c_buffer)
+
+ at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+def PyUnicode_GET_DATA_SIZE(space, obj):
+    """Return the size of the object's internal buffer in bytes.  o has to be a
+    PyUnicodeObject (not checked)."""
+    return rffi.sizeof(lltype.UniChar) * (PyUnicode_GET_SIZE(space, obj) + 1)
+
 @cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
 def PyUnicode_GET_SIZE(space, w_obj):
     """Return the size of the object.  o has to be a PyUnicodeObject (not



More information about the Pypy-commit mailing list