Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersBytes.c
1// Copyright 2025, 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
93#endif
94// Part of "Nuitka", an optimizing Python compiler that is compatible and
95// integrates with CPython, but also works on its own.
96//
97// Licensed under the Apache License, Version 2.0 (the "License");
98// you may not use this file except in compliance with the License.
99// You may obtain a copy of the License at
100//
101// http://www.apache.org/licenses/LICENSE-2.0
102//
103// Unless required by applicable law or agreed to in writing, software
104// distributed under the License is distributed on an "AS IS" BASIS,
105// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
106// See the License for the specific language governing permissions and
107// limitations under the License.