11#define PY_SSIZE_T_CLEAN
22#include <Python.h>
3+ #include "CPy.h"
34
45#define START_SIZE 512
56
67#define STR_LEN_TYPE unsigned int
7- #define MAX_STR_SIZE (1 << sizeof(STR_LEN_TYPE) * 8)
8-
9- #define FLOAT_ERR -113.0
8+ #define MAX_STR_SIZE (1L << sizeof(STR_LEN_TYPE) * 8)
109
1110typedef struct {
1211 PyObject_HEAD
@@ -122,7 +121,7 @@ static PyMethodDef Buffer_methods[] = {
122121};
123122
124123static PyTypeObject BufferType = {
125- .ob_base = PyVarObject_HEAD_INIT (NULL , 0 )
124+ .ob_base = PyVarObject_HEAD_INIT (& PyType_Type , 0 )
126125 .tp_name = "Buffer" ,
127126 .tp_doc = PyDoc_STR ("Mypy cache buffer objects" ),
128127 .tp_basicsize = sizeof (BufferObject ),
@@ -137,7 +136,9 @@ static PyTypeObject BufferType = {
137136static inline
138137char _check_buffer (PyObject * data ) {
139138 if (Py_TYPE (data ) != & BufferType ) {
140- PyErr_SetString (PyExc_TypeError , "data must be a Buffer object" );
139+ PyErr_Format (
140+ PyExc_TypeError , "data must be a Buffer object, got %s" , Py_TYPE (data )-> tp_name
141+ );
141142 return 2 ;
142143 }
143144 return 1 ;
@@ -168,7 +169,7 @@ char _check_read(BufferObject *data, Py_ssize_t need) {
168169 return 1 ;
169170}
170171
171- char read_bool_internal (PyObject * data ) {
172+ static char read_bool_internal (PyObject * data ) {
172173 if (_check_buffer (data ) == 2 )
173174 return 2 ;
174175
@@ -180,7 +181,7 @@ char read_bool_internal(PyObject *data) {
180181 return res ;
181182}
182183
183- PyObject * read_bool (PyObject * self , PyObject * args , PyObject * kwds ) {
184+ static PyObject * read_bool (PyObject * self , PyObject * args , PyObject * kwds ) {
184185 static char * kwlist [] = {"data" , NULL };
185186 PyObject * data = NULL ;
186187 if (!PyArg_ParseTupleAndKeywords (args , kwds , "O" , kwlist , & data ))
@@ -193,7 +194,7 @@ PyObject *read_bool(PyObject *self, PyObject *args, PyObject *kwds) {
193194 return retval ;
194195}
195196
196- char write_bool_internal (PyObject * data , char value ) {
197+ static char write_bool_internal (PyObject * data , char value ) {
197198 if (_check_buffer (data ) == 2 )
198199 return 2 ;
199200
@@ -206,7 +207,7 @@ char write_bool_internal(PyObject *data, char value) {
206207 return 1 ;
207208}
208209
209- PyObject * write_bool (PyObject * self , PyObject * args , PyObject * kwds ) {
210+ static PyObject * write_bool (PyObject * self , PyObject * args , PyObject * kwds ) {
210211 static char * kwlist [] = {"data" , "value" , NULL };
211212 PyObject * data = NULL ;
212213 PyObject * value = NULL ;
@@ -223,17 +224,16 @@ PyObject *write_bool(PyObject *self, PyObject *args, PyObject *kwds) {
223224 return Py_None ;
224225}
225226
226- PyObject * read_str_internal (PyObject * data ) {
227+ static PyObject * read_str_internal (PyObject * data ) {
227228 if (_check_buffer (data ) == 2 )
228229 return NULL ;
229230
230- STR_LEN_TYPE size ;
231- if (_check_read ((BufferObject * )data , sizeof (size )) == 2 )
231+ if (_check_read ((BufferObject * )data , sizeof (STR_LEN_TYPE )) == 2 )
232232 return NULL ;
233233 char * buf = ((BufferObject * )data )-> buf ;
234234 // Read string length.
235- size = * (STR_LEN_TYPE * )(buf + ((BufferObject * )data )-> pos );
236- ((BufferObject * )data )-> pos += sizeof (size );
235+ STR_LEN_TYPE size = * (STR_LEN_TYPE * )(buf + ((BufferObject * )data )-> pos );
236+ ((BufferObject * )data )-> pos += sizeof (STR_LEN_TYPE );
237237 if (_check_read ((BufferObject * )data , size ) == 2 )
238238 return NULL ;
239239 // Read string content.
@@ -246,15 +246,15 @@ PyObject *read_str_internal(PyObject *data) {
246246 return res ;
247247}
248248
249- PyObject * read_str (PyObject * self , PyObject * args , PyObject * kwds ) {
249+ static PyObject * read_str (PyObject * self , PyObject * args , PyObject * kwds ) {
250250 static char * kwlist [] = {"data" , NULL };
251251 PyObject * data = NULL ;
252252 if (!PyArg_ParseTupleAndKeywords (args , kwds , "O" , kwlist , & data ))
253253 return NULL ;
254254 return read_str_internal (data );
255255}
256256
257- char write_str_internal (PyObject * data , PyObject * value ) {
257+ static char write_str_internal (PyObject * data , PyObject * value ) {
258258 if (_check_buffer (data ) == 2 )
259259 return 2 ;
260260
@@ -285,7 +285,7 @@ char write_str_internal(PyObject *data, PyObject *value) {
285285 return 1 ;
286286}
287287
288- PyObject * write_str (PyObject * self , PyObject * args , PyObject * kwds ) {
288+ static PyObject * write_str (PyObject * self , PyObject * args , PyObject * kwds ) {
289289 static char * kwlist [] = {"data" , "value" , NULL };
290290 PyObject * data = NULL ;
291291 PyObject * value = NULL ;
@@ -302,31 +302,31 @@ PyObject *write_str(PyObject *self, PyObject *args, PyObject *kwds) {
302302 return Py_None ;
303303}
304304
305- double read_float_internal (PyObject * data ) {
305+ static double read_float_internal (PyObject * data ) {
306306 if (_check_buffer (data ) == 2 )
307- return FLOAT_ERR ;
307+ return CPY_FLOAT_ERROR ;
308308
309309 if (_check_read ((BufferObject * )data , sizeof (double )) == 2 )
310- return FLOAT_ERR ;
310+ return CPY_FLOAT_ERROR ;
311311 char * buf = ((BufferObject * )data )-> buf ;
312312 double res = * (double * )(buf + ((BufferObject * )data )-> pos );
313313 ((BufferObject * )data )-> pos += sizeof (double );
314314 return res ;
315315}
316316
317- PyObject * read_float (PyObject * self , PyObject * args , PyObject * kwds ) {
317+ static PyObject * read_float (PyObject * self , PyObject * args , PyObject * kwds ) {
318318 static char * kwlist [] = {"data" , NULL };
319319 PyObject * data = NULL ;
320320 if (!PyArg_ParseTupleAndKeywords (args , kwds , "O" , kwlist , & data ))
321321 return NULL ;
322322 double retval = read_float_internal (data );
323- if (retval == FLOAT_ERR && PyErr_Occurred ()) {
323+ if (retval == CPY_FLOAT_ERROR && PyErr_Occurred ()) {
324324 return NULL ;
325325 }
326326 return PyFloat_FromDouble (retval );
327327}
328328
329- char write_float_internal (PyObject * data , double value ) {
329+ static char write_float_internal (PyObject * data , double value ) {
330330 if (_check_buffer (data ) == 2 )
331331 return 2 ;
332332
@@ -339,7 +339,7 @@ char write_float_internal(PyObject *data, double value) {
339339 return 1 ;
340340}
341341
342- PyObject * write_float (PyObject * self , PyObject * args , PyObject * kwds ) {
342+ static PyObject * write_float (PyObject * self , PyObject * args , PyObject * kwds ) {
343343 static char * kwlist [] = {"data" , "value" , NULL };
344344 PyObject * data = NULL ;
345345 PyObject * value = NULL ;
@@ -356,13 +356,92 @@ PyObject *write_float(PyObject *self, PyObject *args, PyObject *kwds) {
356356 return Py_None ;
357357}
358358
359+ static CPyTagged read_int_internal (PyObject * data ) {
360+ if (_check_buffer (data ) == 2 )
361+ return CPY_INT_TAG ;
362+
363+ if (_check_read ((BufferObject * )data , sizeof (CPyTagged )) == 2 )
364+ return CPY_INT_TAG ;
365+ char * buf = ((BufferObject * )data )-> buf ;
366+
367+ CPyTagged ret = * (CPyTagged * )(buf + ((BufferObject * )data )-> pos );
368+ ((BufferObject * )data )-> pos += sizeof (CPyTagged );
369+ if ((ret & CPY_INT_TAG ) == 0 )
370+ return ret ;
371+ PyObject * str_ret = read_str_internal (data );
372+ if (str_ret == NULL )
373+ return CPY_INT_TAG ;
374+ PyObject * ret_long = PyLong_FromUnicodeObject (str_ret , 10 );
375+ Py_DECREF (str_ret );
376+ return ((CPyTagged )ret_long ) | CPY_INT_TAG ;
377+ }
378+
379+ static PyObject * read_int (PyObject * self , PyObject * args , PyObject * kwds ) {
380+ static char * kwlist [] = {"data" , NULL };
381+ PyObject * data = NULL ;
382+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "O" , kwlist , & data ))
383+ return NULL ;
384+ CPyTagged retval = read_int_internal (data );
385+ if (retval == CPY_INT_TAG ) {
386+ return NULL ;
387+ }
388+ return CPyTagged_StealAsObject (retval );
389+ }
390+
391+ char write_int_internal (PyObject * data , CPyTagged value ) {
392+ if (_check_buffer (data ) == 2 )
393+ return 2 ;
394+
395+ if (_check_size ((BufferObject * )data , sizeof (CPyTagged )) == 2 )
396+ return 2 ;
397+ char * buf = ((BufferObject * )data )-> buf ;
398+ if ((value & CPY_INT_TAG ) == 0 ) {
399+ * (CPyTagged * )(buf + ((BufferObject * )data )-> pos ) = value ;
400+ } else {
401+ * (CPyTagged * )(buf + ((BufferObject * )data )-> pos ) = CPY_INT_TAG ;
402+ }
403+ ((BufferObject * )data )-> pos += sizeof (CPyTagged );
404+ ((BufferObject * )data )-> end += sizeof (CPyTagged );
405+ if ((value & CPY_INT_TAG ) != 0 ) {
406+ PyObject * str_value = PyObject_Str (CPyTagged_LongAsObject (value ));
407+ if (str_value == NULL )
408+ return 2 ;
409+ char res = write_str_internal (data , str_value );
410+ Py_DECREF (str_value );
411+ if (res == 2 )
412+ return 2 ;
413+ }
414+ return 1 ;
415+ }
416+
417+ static PyObject * write_int (PyObject * self , PyObject * args , PyObject * kwds ) {
418+ static char * kwlist [] = {"data" , "value" , NULL };
419+ PyObject * data = NULL ;
420+ PyObject * value = NULL ;
421+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "OO" , kwlist , & data , & value ))
422+ return NULL ;
423+ if (!PyLong_Check (value )) {
424+ PyErr_SetString (PyExc_TypeError , "value must be an int" );
425+ return NULL ;
426+ }
427+ CPyTagged tagged_value = CPyTagged_BorrowFromObject (value );
428+ if (write_int_internal (data , tagged_value ) == 2 ) {
429+ return NULL ;
430+ }
431+ Py_INCREF (Py_None );
432+ return Py_None ;
433+ }
434+
359435static PyMethodDef native_buffer_module_methods [] = {
436+ // TODO: switch public wrappers to METH_FASTCALL.
360437 {"write_bool" , (PyCFunction )write_bool , METH_VARARGS | METH_KEYWORDS , PyDoc_STR ("write a bool" )},
361438 {"read_bool" , (PyCFunction )read_bool , METH_VARARGS | METH_KEYWORDS , PyDoc_STR ("read a bool" )},
362439 {"write_str" , (PyCFunction )write_str , METH_VARARGS | METH_KEYWORDS , PyDoc_STR ("write a string" )},
363440 {"read_str" , (PyCFunction )read_str , METH_VARARGS | METH_KEYWORDS , PyDoc_STR ("read a string" )},
364441 {"write_float" , (PyCFunction )write_float , METH_VARARGS | METH_KEYWORDS , PyDoc_STR ("write a float" )},
365442 {"read_float" , (PyCFunction )read_float , METH_VARARGS | METH_KEYWORDS , PyDoc_STR ("read a float" )},
443+ {"write_int" , (PyCFunction )write_int , METH_VARARGS | METH_KEYWORDS , PyDoc_STR ("write an int" )},
444+ {"read_int" , (PyCFunction )read_int , METH_VARARGS | METH_KEYWORDS , PyDoc_STR ("read an int" )},
366445 {NULL , NULL , 0 , NULL }
367446};
368447
0 commit comments