Skip to content

Commit a4f8e14

Browse files
committed
Add test for '_PyBytes_Resize'.
1 parent cfb4d18 commit a4f8e14

File tree

1 file changed

+82
-2
lines changed
  • graalpython/com.oracle.graal.python.test/src/tests/cpyext

1 file changed

+82
-2
lines changed

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_bytes.py

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -37,7 +37,7 @@
3737
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3838
# SOFTWARE.
3939

40-
from . import CPyExtTestCase, CPyExtFunction, CPyExtFunctionOutVars, unhandled_error_compare, GRAALPYTHON
40+
from . import CPyExtTestCase, CPyExtFunction, CPyExtFunctionOutVars, unhandled_error_compare
4141
__dir__ = __file__.rpartition("/")[0]
4242

4343

@@ -257,3 +257,83 @@ def compile_module(self, name):
257257
callfunction="mutate_bytes",
258258
cmpfunc=unhandled_error_compare
259259
)
260+
261+
test_PyBytes_Resize = CPyExtFunction(
262+
lambda args: args[0][:args[1]],
263+
lambda: (
264+
(b"hello_beatiful_world", 5),
265+
),
266+
code="""
267+
PyObject* wrap_PyBytes_Resize(PyObject* bytesObj, Py_ssize_t new_size) {
268+
/* we need to create a fresh bytes object */
269+
PyObject* res = PyBytes_FromString(PyBytes_AsString(bytesObj));
270+
_PyBytes_Resize(&res, new_size);
271+
return res;
272+
}
273+
""",
274+
resultspec="O",
275+
argspec="On",
276+
arguments=["PyObject* bytesObj", "Py_ssize_t new_size"],
277+
callfunction="wrap_PyBytes_Resize",
278+
cmpfunc=unhandled_error_compare
279+
)
280+
281+
test_PyBytes_Resize_NativeStorage = CPyExtFunction(
282+
lambda args: args[1],
283+
lambda: (
284+
(b"hello_beatiful_world", b"hello_world"),
285+
),
286+
code="""
287+
#include <stdio.h>
288+
289+
/* Copies content from 'smaller' to 'larger_content' and returns a pointer to the last char. */
290+
static char* do_pointer_arithmetics(char* larger_content, PyObject* smaller) {
291+
char* smaller_content = PyBytes_AS_STRING(smaller);
292+
Py_ssize_t smaller_len = PyBytes_Size(smaller);
293+
294+
// 'smaller_len + 1' also contains the null byte
295+
memcpy(larger_content, smaller_content, smaller_len + 1);
296+
return larger_content + smaller_len;
297+
}
298+
299+
PyObject* resize_bytes(PyObject* larger, PyObject* smaller) {
300+
char* data;
301+
char* dummy;
302+
char* end_ptr;
303+
Py_ssize_t len;
304+
Py_ssize_t new_len;
305+
PyObject* larger_copy;
306+
307+
Py_INCREF(larger);
308+
Py_INCREF(smaller);
309+
310+
/* we need to create a fresh bytes object */
311+
larger_copy = PyBytes_FromString(PyBytes_AsString(larger));
312+
Py_DECREF(larger);
313+
314+
len = PyBytes_Size(larger_copy) + 1;
315+
316+
dummy = (char*) calloc(len, sizeof(char));
317+
data = PyBytes_AS_STRING(larger_copy);
318+
319+
/* this will force the bytes object's content to native */
320+
snprintf(data, len, "%s", dummy);
321+
free(dummy);
322+
323+
/* copy smaller data and return the pointer to the last char */
324+
end_ptr = do_pointer_arithmetics(data, smaller);
325+
Py_DECREF(smaller);
326+
327+
/* compute new size */
328+
new_len = (Py_ssize_t) (end_ptr - PyBytes_AS_STRING(larger_copy));
329+
_PyBytes_Resize(&larger_copy, new_len);
330+
memcpy(PyBytes_AS_STRING(larger_copy), data, new_len * sizeof(char));
331+
return larger_copy;
332+
}
333+
""",
334+
resultspec="O",
335+
argspec="OO",
336+
arguments=["PyObject* larger", "PyObject* smaller"],
337+
callfunction="resize_bytes",
338+
cmpfunc=unhandled_error_compare
339+
)

0 commit comments

Comments
 (0)