@@ -38,43 +38,9 @@ Numeric decoder derived from TCL library
38
38
39
39
// Licence at LICENSES/ULTRAJSON_LICENSE
40
40
41
- #define PY_ARRAY_UNIQUE_SYMBOL UJSON_NUMPY
42
- #define NO_IMPORT_ARRAY
43
- #define PY_SSIZE_T_CLEAN
44
41
#include "pandas/vendored/ujson/lib/ultrajson.h"
42
+ #define PY_SSIZE_T_CLEAN
45
43
#include <Python.h>
46
- #include <numpy/arrayobject.h>
47
-
48
- typedef struct __PyObjectDecoder {
49
- JSONObjectDecoder dec ;
50
-
51
- void * npyarr ; // Numpy context buffer
52
- void * npyarr_addr ; // Ref to npyarr ptr to track DECREF calls
53
- } PyObjectDecoder ;
54
-
55
- typedef struct __NpyArrContext {
56
- PyObject * ret ;
57
- PyObject * labels [2 ];
58
- PyArray_Dims shape ;
59
-
60
- PyObjectDecoder * dec ;
61
- } NpyArrContext ;
62
-
63
- // free the numpy context buffer
64
- void Npy_releaseContext (NpyArrContext * npyarr ) {
65
- if (npyarr ) {
66
- if (npyarr -> shape .ptr ) {
67
- PyObject_Free (npyarr -> shape .ptr );
68
- }
69
- if (npyarr -> dec ) {
70
- npyarr -> dec -> npyarr = NULL ;
71
- }
72
- Py_XDECREF (npyarr -> labels [0 ]);
73
- Py_XDECREF (npyarr -> labels [1 ]);
74
- Py_XDECREF (npyarr -> ret );
75
- PyObject_Free (npyarr );
76
- }
77
- }
78
44
79
45
static int Object_objectAddKey (void * prv , JSOBJ obj , JSOBJ name , JSOBJ value ) {
80
46
int ret = PyDict_SetItem (obj , name , value );
@@ -132,95 +98,62 @@ static JSOBJ Object_newDouble(void *prv, double value) {
132
98
}
133
99
134
100
static void Object_releaseObject (void * prv , JSOBJ obj , void * _decoder ) {
135
- PyObjectDecoder * decoder = (PyObjectDecoder * )_decoder ;
136
- if (obj != decoder -> npyarr_addr ) {
137
- Py_XDECREF (((PyObject * )obj ));
138
- }
101
+ Py_XDECREF (((PyObject * )obj ));
139
102
}
140
103
141
- static char * g_kwlist [] = {"obj" , "precise_float" , "labelled" , "dtype" , NULL };
142
-
143
104
PyObject * JSONToObj (PyObject * self , PyObject * args , PyObject * kwargs ) {
144
- PyObject * ret ;
145
- PyObject * sarg ;
146
- PyObject * arg ;
147
- PyObject * opreciseFloat = NULL ;
148
- JSONObjectDecoder * decoder ;
149
- PyObjectDecoder pyDecoder ;
150
- PyArray_Descr * dtype = NULL ;
151
- int labelled = 0 ;
152
-
153
- JSONObjectDecoder dec = {
154
- Object_newString , Object_objectAddKey , Object_arrayAddItem ,
155
- Object_newTrue , Object_newFalse , Object_newNull ,
156
- Object_newPosInf , Object_newNegInf , Object_newObject ,
157
- Object_endObject , Object_newArray , Object_endArray ,
158
- Object_newInteger , Object_newLong , Object_newUnsignedLong ,
159
- Object_newDouble , Object_releaseObject , PyObject_Malloc ,
160
- PyObject_Free , PyObject_Realloc };
161
-
162
- dec .preciseFloat = 0 ;
163
- dec .prv = NULL ;
164
-
165
- pyDecoder .dec = dec ;
166
- pyDecoder .npyarr = NULL ;
167
- pyDecoder .npyarr_addr = NULL ;
168
-
169
- decoder = (JSONObjectDecoder * )& pyDecoder ;
170
-
171
- if (!PyArg_ParseTupleAndKeywords (args , kwargs , "O|OiiO&" , g_kwlist , & arg ,
172
- & opreciseFloat , & labelled ,
173
- PyArray_DescrConverter2 , & dtype )) {
174
- Npy_releaseContext (pyDecoder .npyarr );
105
+ JSONObjectDecoder dec = {.newString = Object_newString ,
106
+ .objectAddKey = Object_objectAddKey ,
107
+ .arrayAddItem = Object_arrayAddItem ,
108
+ .newTrue = Object_newTrue ,
109
+ .newFalse = Object_newFalse ,
110
+ .newNull = Object_newNull ,
111
+ .newPosInf = Object_newPosInf ,
112
+ .newNegInf = Object_newNegInf ,
113
+ .newObject = Object_newObject ,
114
+ .endObject = Object_endObject ,
115
+ .newArray = Object_newArray ,
116
+ .endArray = Object_endArray ,
117
+ .newInt = Object_newInteger ,
118
+ .newLong = Object_newLong ,
119
+ .newUnsignedLong = Object_newUnsignedLong ,
120
+ .newDouble = Object_newDouble ,
121
+ .releaseObject = Object_releaseObject ,
122
+ .malloc = PyObject_Malloc ,
123
+ .free = PyObject_Free ,
124
+ .realloc = PyObject_Realloc ,
125
+ .errorStr = NULL ,
126
+ .errorOffset = NULL ,
127
+ .preciseFloat = 0 ,
128
+ .prv = NULL };
129
+
130
+ char * kwlist [] = {"obj" , "precise_float" , NULL };
131
+ char * buf ;
132
+ Py_ssize_t len ;
133
+ if (!PyArg_ParseTupleAndKeywords (args , kwargs , "s#|b" , kwlist , & buf , & len ,
134
+ & dec .preciseFloat )) {
175
135
return NULL ;
176
136
}
177
137
178
- if (opreciseFloat && PyObject_IsTrue (opreciseFloat )) {
179
- decoder -> preciseFloat = 1 ;
180
- }
181
-
182
- if (PyBytes_Check (arg )) {
183
- sarg = arg ;
184
- } else if (PyUnicode_Check (arg )) {
185
- sarg = PyUnicode_AsUTF8String (arg );
186
- if (sarg == NULL ) {
187
- // Exception raised above us by codec according to docs
188
- return NULL ;
189
- }
190
- } else {
191
- PyErr_Format (PyExc_TypeError , "Expected 'str' or 'bytes'" );
192
- return NULL ;
193
- }
194
-
195
- decoder -> errorStr = NULL ;
196
- decoder -> errorOffset = NULL ;
197
-
198
- ret = JSON_DecodeObject (decoder , PyBytes_AS_STRING (sarg ),
199
- PyBytes_GET_SIZE (sarg ));
200
-
201
- if (sarg != arg ) {
202
- Py_DECREF (sarg );
203
- }
138
+ PyObject * ret = JSON_DecodeObject (& dec , buf , len );
204
139
205
140
if (PyErr_Occurred ()) {
206
141
if (ret ) {
207
142
Py_DECREF ((PyObject * )ret );
208
143
}
209
- Npy_releaseContext (pyDecoder .npyarr );
210
144
return NULL ;
211
145
}
212
146
213
- if (decoder -> errorStr ) {
147
+ if (dec . errorStr ) {
214
148
/*
215
149
FIXME: It's possible to give a much nicer error message here with actual
216
150
failing element in input etc*/
217
151
218
- PyErr_Format (PyExc_ValueError , "%s" , decoder -> errorStr );
152
+ PyErr_Format (PyExc_ValueError , "%s" , dec . errorStr );
219
153
220
154
if (ret ) {
221
155
Py_DECREF ((PyObject * )ret );
222
156
}
223
- Npy_releaseContext (pyDecoder .npyarr );
224
157
225
158
return NULL ;
226
159
}
0 commit comments