Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersBytes.c
1// Copyright 2026, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3/* This helpers is used to quickly create a bytes objects.
4
5*/
6
7// This file is included from another C file, help IDEs to still parse it on
8// its own.
9#ifdef __IDE_ONLY__
10#include "nuitka/prelude.h"
11#endif
12
13#if PYTHON_VERSION >= 0x300
14
15// Custom allocation to save bytes at the end.
16#define PyBytesObject_SIZE (offsetof(PyBytesObject, ob_sval) + 1)
17
18#if NUITKA_BYTES_HAS_FREELIST
19
20#if PYTHON_VERSION < 0x3b0
21static struct _Py_bytes_state *Nuitka_Py_get_bytes_state(void) {
22 PyInterpreterState *interp = _PyInterpreterState_GET();
23 return &interp->bytes;
24}
25#else
26#define BYTES_CHARACTERS _Py_SINGLETON(bytes_characters)
27#define BYTES_CHARACTER(ch) ((PyBytesObject *)&(BYTES_CHARACTERS[ch]));
28#define BYTES_EMPTY (&_Py_SINGLETON(bytes_empty))
29#endif
30
31PyObject *Nuitka_Bytes_FromStringAndSize(const char *data, Py_ssize_t size) {
32 assert(size >= 0);
33 PyBytesObject *op;
34
35 if (size == 1) {
36 // For Python3.10 we can use the internal cache.
37#if PYTHON_VERSION < 0x3b0
38 struct _Py_bytes_state *state = Nuitka_Py_get_bytes_state();
39
40 op = state->characters[*data & UCHAR_MAX];
41
42 if (op != NULL) {
43 Py_INCREF(op);
44 return (PyObject *)op;
45 }
46#else
47 op = BYTES_CHARACTER(*data & 255);
48 Py_INCREF(op);
49 return (PyObject *)op;
50#endif
51 }
52
53 if (size == 0) {
54#if PYTHON_VERSION < 0x3b0
55 struct _Py_bytes_state *state = Nuitka_Py_get_bytes_state();
56
57 assert(state->empty_string != NULL);
58 Py_INCREF(state->empty_string);
59
60 return state->empty_string;
61#else
62 Py_INCREF(BYTES_EMPTY);
63 return (PyObject *)BYTES_EMPTY;
64
65#endif
66 }
67
68 op = (PyBytesObject *)NuitkaObject_Malloc(PyBytesObject_SIZE + size);
69
70 Py_SET_TYPE(op, &PyBytes_Type);
71 Py_SET_SIZE(op, size);
72
73 Nuitka_Py_NewReference((PyObject *)op);
74
75 op->ob_shash = -1;
76 memcpy(op->ob_sval, data, size);
77 op->ob_sval[size] = '\0';
78
79#if PYTHON_VERSION < 0x3b0
80 // For Python3.10 we might have to populate the cache.
81 if (size == 1) {
82 struct _Py_bytes_state *state = Nuitka_Py_get_bytes_state();
83 Py_INCREF(op);
84 state->characters[*data & UCHAR_MAX] = op;
85 }
86#endif
87
88 return (PyObject *)op;
89}
90
91#endif
92
93void Nuitka_Bytes_AsStringAndSize(PyObject *obj, char **s, Py_ssize_t *len) {
94 CHECK_OBJECT(obj);
95 assert(s != NULL);
96 assert(len != NULL);
97 assert(PyBytes_Check(obj));
98
99 *s = PyBytes_AS_STRING(obj);
100 *len = PyBytes_GET_SIZE(obj);
101}
102
103char *Nuitka_Bytes_AsString(PyObject *obj) {
104 CHECK_OBJECT(obj);
105 assert(PyBytes_Check(obj));
106
107 return PyBytes_AS_STRING(obj);
108}
109
110#endif
111
112// Part of "Nuitka", an optimizing Python compiler that is compatible and
113// integrates with CPython, but also works on its own.
114//
115// Licensed under the GNU Affero General Public License, Version 3 (the "License");
116// you may not use this file except in compliance with the License.
117// You may obtain a copy of the License at
118//
119// http://www.gnu.org/licenses/agpl.txt
120//
121// Unless required by applicable law or agreed to in writing, software
122// distributed under the License is distributed on an "AS IS" BASIS,
123// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124// See the License for the specific language governing permissions and
125// limitations under the License.