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