Author: mattip <matti.pi...@gmail.com>
Branch: cpyext-ext
Changeset: r83827:38e54c1f208b
Date: 2016-04-22 14:58 +0300
http://bitbucket.org/pypy/pypy/changeset/38e54c1f208b/

Log:    add PyBytesArrayObject, based on PyStringObject. Still not clear how
        to make it mutable

diff --git a/pypy/module/cpyext/__init__.py b/pypy/module/cpyext/__init__.py
--- a/pypy/module/cpyext/__init__.py
+++ b/pypy/module/cpyext/__init__.py
@@ -35,6 +35,7 @@
 import pypy.module.cpyext.typeobject
 import pypy.module.cpyext.object
 import pypy.module.cpyext.bytesobject
+import pypy.module.cpyext.bytearrayobject
 import pypy.module.cpyext.tupleobject
 import pypy.module.cpyext.setobject
 import pypy.module.cpyext.dictobject
diff --git a/pypy/module/cpyext/bytearrayobject.py 
b/pypy/module/cpyext/bytearrayobject.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/bytearrayobject.py
@@ -0,0 +1,120 @@
+from pypy.interpreter.error import OperationError, oefmt
+from rpython.rtyper.lltypesystem import rffi, lltype
+from pypy.module.cpyext.api import (
+    cpython_api, cpython_struct, bootstrap_function, build_type_checkers,
+    PyVarObjectFields, Py_ssize_t, CONST_STRING, CANNOT_FAIL)
+from pypy.module.cpyext.pyerrors import PyErr_BadArgument
+from pypy.module.cpyext.pyobject import (
+    PyObject, PyObjectP, Py_DecRef, make_ref, from_ref, track_reference,
+    make_typedescr, get_typedescr, Py_IncRef)
+# Type PyByteArrayObject represents a mutable array of bytes.
+# The Python API is that of a sequence;
+# the bytes are mapped to ints in [0, 256).
+# Bytes are not characters; they may be used to encode characters.
+# The only way to go between bytes and str/unicode is via encoding
+# and decoding.
+# For the convenience of C programmers, the bytes type is considered
+# to contain a char pointer, not an unsigned char pointer.
+
+# XXX Since the ob_bytes is mutable, we must reflect the buffer back
+# into the W_ByteArray object at each call to from_ref and each call to
+# exported functions
+
+PyByteArrayObjectStruct = lltype.ForwardReference()
+PyByteArrayObject = lltype.Ptr(PyByteArrayObjectStruct)
+PyByteArrayObjectFields = PyVarObjectFields + \
+    (("ob_exports", rffi.INT), ("ob_alloc", rffi.LONG), ("ob_bytes", 
rffi.CCHARP))
+cpython_struct("PyByteArrayObject", PyByteArrayObjectFields, 
PyByteArrayObjectStruct)
+
+@bootstrap_function
+def init_bytearrayobject(space):
+    "Type description of PyByteArrayObject"
+    make_typedescr(space.w_str.layout.typedef,
+                   basestruct=PyByteArrayObject.TO,
+                   attach=bytearray_attach,
+                   dealloc=bytearray_dealloc,
+                   realize=bytearray_realize)
+
+PyByteArray_Check, PyByteArray_CheckExact = build_type_checkers("ByteArray", 
"w_bytearray")
+
+def bytearray_attach(space, py_obj, w_obj):
+    """
+    Fills a newly allocated PyByteArrayObject with the given bytearray object
+    """
+    py_ba = rffi.cast(PyByteArrayObject, py_obj)
+    py_ba.c_ob_size = len(space.str_w(w_obj))
+    py_ba.c_ob_bytes = lltype.nullptr(rffi.CCHARP.TO)
+    py_ba.c_ob_exports = rffi.cast(rffi.INT, 0)
+
+def bytearray_realize(space, py_obj):
+    """
+    Creates the bytearray in the interpreter. 
+    """
+    py_ba = rffi.cast(PyByteArrayObject, py_obj)
+    if not py_ba.c_ob_bytes:
+        py_ba.c_buffer = lltype.malloc(rffi.CCHARP.TO, py_ba.c_ob_size + 1,
+                                    flavor='raw', zero=True)
+    s = rffi.charpsize2str(py_ba.c_ob_bytes, py_ba.c_ob_size)
+    w_obj = space.wrap(s)
+    py_ba.c_ob_exports = rffi.cast(rffi.INT, 0)
+    track_reference(space, py_obj, w_obj)
+    return w_obj
+
+@cpython_api([PyObject], lltype.Void, header=None)
+def bytearray_dealloc(space, py_obj):
+    """Frees allocated PyByteArrayObject resources.
+    """
+    py_ba = rffi.cast(PyByteArrayObject, py_obj)
+    if py_ba.c_ob_bytes:
+        lltype.free(py_ba.c_ob_bytes, flavor="raw")
+    from pypy.module.cpyext.object import PyObject_dealloc
+    PyObject_dealloc(space, py_obj)
+
+#_______________________________________________________________________
+
+@cpython_api([PyObject], PyObject)
+def PyByteArray_FromObject(space, o):
+    """Return a new bytearray object from any object, o, that implements the
+    buffer protocol.
+
+    XXX expand about the buffer protocol, at least somewhere"""
+    raise NotImplementedError
+
+@cpython_api([rffi.CCHARP, Py_ssize_t], PyObject)
+def PyByteArray_FromStringAndSize(space, string, len):
+    """Create a new bytearray object from string and its length, len.  On
+    failure, NULL is returned."""
+    raise NotImplementedError
+
+@cpython_api([PyObject, PyObject], PyObject)
+def PyByteArray_Concat(space, a, b):
+    """Concat bytearrays a and b and return a new bytearray with the result."""
+    raise NotImplementedError
+
+@cpython_api([PyObject], Py_ssize_t, error=-1)
+def PyByteArray_Size(space, bytearray):
+    """Return the size of bytearray after checking for a NULL pointer."""
+    raise NotImplementedError
+
+@cpython_api([PyObject], rffi.CCHARP)
+def PyByteArray_AsString(space, bytearray):
+    """Return the contents of bytearray as a char array after checking for a
+    NULL pointer."""
+    raise NotImplementedError
+
+@cpython_api([PyObject, Py_ssize_t], rffi.INT_real, error=-1)
+def PyByteArray_Resize(space, bytearray, len):
+    """Resize the internal buffer of bytearray to len."""
+    raise NotImplementedError
+
+@cpython_api([PyObject], rffi.CCHARP)
+def PyByteArray_AS_STRING(space, bytearray):
+    """Macro version of PyByteArray_AsString()."""
+    raise NotImplementedError
+
+@cpython_api([PyObject], Py_ssize_t, error=-1)
+def PyByteArray_GET_SIZE(space, bytearray):
+    """Macro version of PyByteArray_Size()."""
+    raise NotImplementedError
+
+
diff --git a/pypy/module/cpyext/include/Python.h 
b/pypy/module/cpyext/include/Python.h
--- a/pypy/module/cpyext/include/Python.h
+++ b/pypy/module/cpyext/include/Python.h
@@ -106,6 +106,7 @@
 #include "pythonrun.h"
 #include "pyerrors.h"
 #include "sysmodule.h"
+#include "bytearrayobject.h"
 #include "stringobject.h"
 #include "descrobject.h"
 #include "tupleobject.h"
diff --git a/pypy/module/cpyext/include/bytearrayobject.h 
b/pypy/module/cpyext/include/bytearrayobject.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/include/bytearrayobject.h
@@ -0,0 +1,33 @@
+/* ByteArray object interface */
+
+#ifndef Py_BYTEARRAYOBJECT_H
+#define Py_BYTEARRAYOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+
+/* Type PyByteArrayObject represents a mutable array of bytes.
+ * The Python API is that of a sequence;
+ * the bytes are mapped to ints in [0, 256).
+ * Bytes are not characters; they may be used to encode characters.
+ * The only way to go between bytes and str/unicode is via encoding
+ * and decoding.
+ * For the convenience of C programmers, the bytes type is considered
+ * to contain a char pointer, not an unsigned char pointer.
+ */
+
+/* Object layout */
+typedef struct {
+    PyObject_VAR_HEAD
+    /* XXX(nnorwitz): should ob_exports be Py_ssize_t? */
+    int ob_exports; /* how many buffer exports */
+    Py_ssize_t ob_alloc; /* How many bytes allocated */
+    char *ob_bytes;
+} PyByteArrayObject;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_BYTEARRAYOBJECT_H */
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -59,63 +59,6 @@
     raise NotImplementedError
 
 @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyByteArray_Check(space, o):
-    """Return true if the object o is a bytearray object or an instance of a
-    subtype of the bytearray type."""
-    raise NotImplementedError
-
-@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyByteArray_CheckExact(space, o):
-    """Return true if the object o is a bytearray object, but not an instance 
of a
-    subtype of the bytearray type."""
-    raise NotImplementedError
-
-@cpython_api([PyObject], PyObject)
-def PyByteArray_FromObject(space, o):
-    """Return a new bytearray object from any object, o, that implements the
-    buffer protocol.
-
-    XXX expand about the buffer protocol, at least somewhere"""
-    raise NotImplementedError
-
-@cpython_api([rffi.CCHARP, Py_ssize_t], PyObject)
-def PyByteArray_FromStringAndSize(space, string, len):
-    """Create a new bytearray object from string and its length, len.  On
-    failure, NULL is returned."""
-    raise NotImplementedError
-
-@cpython_api([PyObject, PyObject], PyObject)
-def PyByteArray_Concat(space, a, b):
-    """Concat bytearrays a and b and return a new bytearray with the result."""
-    raise NotImplementedError
-
-@cpython_api([PyObject], Py_ssize_t, error=-1)
-def PyByteArray_Size(space, bytearray):
-    """Return the size of bytearray after checking for a NULL pointer."""
-    raise NotImplementedError
-
-@cpython_api([PyObject], rffi.CCHARP)
-def PyByteArray_AsString(space, bytearray):
-    """Return the contents of bytearray as a char array after checking for a
-    NULL pointer."""
-    raise NotImplementedError
-
-@cpython_api([PyObject, Py_ssize_t], rffi.INT_real, error=-1)
-def PyByteArray_Resize(space, bytearray, len):
-    """Resize the internal buffer of bytearray to len."""
-    raise NotImplementedError
-
-@cpython_api([PyObject], rffi.CCHARP)
-def PyByteArray_AS_STRING(space, bytearray):
-    """Macro version of PyByteArray_AsString()."""
-    raise NotImplementedError
-
-@cpython_api([PyObject], Py_ssize_t, error=-1)
-def PyByteArray_GET_SIZE(space, bytearray):
-    """Macro version of PyByteArray_Size()."""
-    raise NotImplementedError
-
-@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
 def PyCell_Check(space, ob):
     """Return true if ob is a cell object; ob must not be NULL."""
     raise NotImplementedError
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to