66#include "CPy.h"
77#include "librt_strings.h"
88
9- #define START_SIZE 512
10-
119#define CPY_BOOL_ERROR 2
1210#define CPY_NONE_ERROR 2
1311#define CPY_NONE 1
1614// BytesWriter
1715//
1816
17+ // Length of the default buffer embedded directly in a BytesWriter object
18+ #define WRITER_EMBEDDED_BUF_LEN 512
19+
1920typedef struct {
2021 PyObject_HEAD
2122 char * buf ; // Beginning of the buffer
2223 char * ptr ; // Current write location in the buffer
2324 char * end ; // End of the buffer
25+ char data [WRITER_EMBEDDED_BUF_LEN ]; // Default buffer
2426} BytesWriterObject ;
2527
2628#define _WRITE (data , type , v ) \
@@ -36,10 +38,15 @@ _grow_buffer(BytesWriterObject *data, Py_ssize_t n) {
3638 Py_ssize_t index = data -> ptr - data -> buf ;
3739 Py_ssize_t target = index + n ;
3840 Py_ssize_t size = data -> end - data -> buf ;
41+ Py_ssize_t old_size = size ;
3942 do {
4043 size *= 2 ;
4144 } while (target >= size );
42- data -> buf = PyMem_Realloc (data -> buf , size );
45+ if (old_size == WRITER_EMBEDDED_BUF_LEN ) {
46+ data -> buf = PyMem_Malloc (size );
47+ } else {
48+ data -> buf = PyMem_Realloc (data -> buf , size );
49+ }
4350 if (unlikely (data -> buf == NULL )) {
4451 PyErr_NoMemory ();
4552 return false;
@@ -58,6 +65,13 @@ ensure_bytes_writer_size(BytesWriterObject *data, Py_ssize_t n) {
5865 }
5966}
6067
68+ static inline void
69+ BytesWriter_init_internal (BytesWriterObject * self ) {
70+ self -> buf = self -> data ;
71+ self -> ptr = self -> data ;
72+ self -> end = self -> data + WRITER_EMBEDDED_BUF_LEN ;
73+ }
74+
6175static PyObject *
6276BytesWriter_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
6377{
@@ -68,38 +82,17 @@ BytesWriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
6882
6983 BytesWriterObject * self = (BytesWriterObject * )type -> tp_alloc (type , 0 );
7084 if (self != NULL ) {
71- self -> buf = NULL ;
72- self -> ptr = NULL ;
73- self -> end = NULL ;
85+ BytesWriter_init_internal (self );
7486 }
7587 return (PyObject * )self ;
7688}
7789
78- static int
79- BytesWriter_init_internal (BytesWriterObject * self ) {
80- Py_ssize_t size = START_SIZE ;
81- self -> buf = PyMem_Malloc (size + 1 );
82- if (self -> buf == NULL ) {
83- PyErr_NoMemory ();
84- return -1 ;
85- }
86- self -> ptr = self -> buf ;
87- self -> end = self -> buf + size ;
88- return 0 ;
89- }
90-
9190static PyObject *
9291BytesWriter_internal (void ) {
9392 BytesWriterObject * self = (BytesWriterObject * )BytesWriterType .tp_alloc (& BytesWriterType , 0 );
9493 if (self == NULL )
9594 return NULL ;
96- self -> buf = NULL ;
97- self -> ptr = NULL ;
98- self -> end = NULL ;
99- if (BytesWriter_init_internal (self ) == -1 ) {
100- Py_DECREF (self );
101- return NULL ;
102- }
95+ BytesWriter_init_internal (self );
10396 return (PyObject * )self ;
10497}
10598
@@ -116,14 +109,17 @@ BytesWriter_init(BytesWriterObject *self, PyObject *args, PyObject *kwds)
116109 return -1 ;
117110 }
118111
119- return BytesWriter_init_internal (self );
112+ BytesWriter_init_internal (self );
113+ return 0 ;
120114}
121115
122116static void
123117BytesWriter_dealloc (BytesWriterObject * self )
124118{
125- PyMem_Free (self -> buf );
126- self -> buf = NULL ;
119+ if (self -> buf != self -> data ) {
120+ PyMem_Free (self -> buf );
121+ self -> buf = NULL ;
122+ }
127123 Py_TYPE (self )-> tp_free ((PyObject * )self );
128124}
129125
0 commit comments