File: bytearrayobject.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (89 lines) | stat: -rw-r--r-- 3,899 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib.objectmodel import specialize, we_are_translated
from pypy.interpreter.error import oefmt
from pypy.objspace.std.bytearrayobject import new_bytearray
from pypy.module.cpyext.api import (
    cpython_api, cpython_struct, build_type_checkers,
    PyVarObjectFields, Py_ssize_t, CONST_STRING)
from pypy.module.cpyext.pyerrors import PyErr_BadArgument
from pypy.module.cpyext.pyobject import (
    PyObject, make_ref, make_typedescr, get_typedescr)
# 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.

# Expose data as a rw cchar* only through PyByteArray_AsString
# Under this strategy the pointer could loose its synchronization with
# the underlying space.w_bytearray if PyByteArray_Resize is called, so
# hopefully the use of the pointer is short-lived

PyByteArrayObjectStruct = lltype.ForwardReference()
PyByteArrayObject = lltype.Ptr(PyByteArrayObjectStruct)
PyByteArrayObjectFields = PyVarObjectFields
cpython_struct("PyByteArrayObject", PyByteArrayObjectFields, PyByteArrayObjectStruct)

PyByteArray_Check, PyByteArray_CheckExact = build_type_checkers("ByteArray", "w_bytearray")

#_______________________________________________________________________

@cpython_api([PyObject], PyObject, result_is_ll=True)
def PyByteArray_FromObject(space, w_obj):
    """Return a new bytearray object from any object, o, that implements the
    buffer protocol.

    XXX expand about the buffer protocol, at least somewhere"""
    w_buffer = space.call_function(space.w_bytearray, w_obj)
    return make_ref(space, w_buffer)

@cpython_api([CONST_STRING, Py_ssize_t], PyObject, result_is_ll=True)
def PyByteArray_FromStringAndSize(space, char_p, length):
    """Create a new bytearray object from string and its length, len.  On
    failure, NULL is returned."""
    if char_p:
        w_s = space.newbytes(rffi.charpsize2str(char_p, length))
    else:
        w_s = space.newint(length)
    w_buffer = space.call_function(space.w_bytearray, w_s)
    return make_ref(space, w_buffer)

@cpython_api([PyObject, PyObject], PyObject)
def PyByteArray_Concat(space, w_left, w_right):
    """Concat bytearrays a and b and return a new bytearray with the result."""
    return space.add(w_left, w_right)

@cpython_api([PyObject], Py_ssize_t, error=-1)
def PyByteArray_Size(space, w_obj):
    """Return the size of bytearray after checking for a NULL pointer."""
    if not w_obj:
        return 0
    return space.len_w(w_obj)

@cpython_api([PyObject], rffi.CCHARP, error=0)
def PyByteArray_AsString(space, w_obj):
    """Return the contents of bytearray as a char array after checking for a
    NULL pointer."""
    if space.isinstance_w(w_obj, space.w_bytearray):
        return w_obj.nonmovable_carray(space)
    else:
        raise oefmt(space.w_TypeError,
                    "expected bytearray object, %T found", w_obj)

@cpython_api([PyObject, Py_ssize_t], rffi.INT_real, error=-1)
def PyByteArray_Resize(space, w_obj, newlen):
    """Resize the internal buffer of bytearray to len."""
    if space.isinstance_w(w_obj, space.w_bytearray):
        oldlen = space.len_w(w_obj)
        if newlen > oldlen:
            space.call_method(w_obj, 'extend', space.newbytes('\x00' * (newlen - oldlen)))
        elif oldlen > newlen:
            assert newlen >= 0
            space.delslice(w_obj, space.newint(newlen), space.newint(oldlen))
        return 0
    else:
        raise oefmt(space.w_TypeError,
                    "expected bytearray object, %T found", w_obj)