@@ -20,8 +20,8 @@ new_stringdtype_instance(PyObject *na_object, int coerce)
20
20
21
21
Py_XINCREF (na_object );
22
22
((StringDTypeObject * )new )-> na_object = na_object ;
23
- npy_static_string na_name = NPY_EMPTY_STRING ;
24
- npy_static_string default_string = NPY_EMPTY_STRING ;
23
+ npy_packed_static_string packed_na_name = * NPY_EMPTY_STRING ;
24
+ npy_packed_static_string packed_default_string = * NPY_EMPTY_STRING ;
25
25
int hasnull = na_object != NULL ;
26
26
int has_nan_na = 0 ;
27
27
int has_string_na = 0 ;
@@ -31,8 +31,8 @@ new_stringdtype_instance(PyObject *na_object, int coerce)
31
31
has_string_na = 1 ;
32
32
Py_ssize_t size = 0 ;
33
33
const char * buf = PyUnicode_AsUTF8AndSize (na_object , & size );
34
- default_string = NPY_EMPTY_STRING ;
35
- int res = npy_string_newsize ( buf , ( size_t ) size , & default_string );
34
+ int res = npy_string_newsize ( buf , ( size_t ) size ,
35
+ & packed_default_string );
36
36
if (res == -1 ) {
37
37
PyErr_NoMemory ();
38
38
Py_DECREF (new );
@@ -72,7 +72,8 @@ new_stringdtype_instance(PyObject *na_object, int coerce)
72
72
73
73
Py_ssize_t size = 0 ;
74
74
const char * utf8_ptr = PyUnicode_AsUTF8AndSize (na_pystr , & size );
75
- int res = npy_string_newsize (utf8_ptr , (size_t )size , & na_name );
75
+ // discard const to initialize buffer
76
+ int res = npy_string_newsize (utf8_ptr , (size_t )size , & packed_na_name );
76
77
if (res == -1 ) {
77
78
PyErr_NoMemory ();
78
79
Py_DECREF (new );
@@ -86,11 +87,23 @@ new_stringdtype_instance(PyObject *na_object, int coerce)
86
87
}
87
88
Py_DECREF (na_pystr );
88
89
}
89
- ((StringDTypeObject * )new )-> has_nan_na = has_nan_na ;
90
- ((StringDTypeObject * )new )-> has_string_na = has_string_na ;
91
- ((StringDTypeObject * )new )-> default_string = default_string ;
92
- ((StringDTypeObject * )new )-> na_name = na_name ;
93
- ((StringDTypeObject * )new )-> coerce = coerce ;
90
+
91
+ StringDTypeObject * snew = (StringDTypeObject * )new ;
92
+
93
+ snew -> has_nan_na = has_nan_na ;
94
+ snew -> has_string_na = has_string_na ;
95
+ snew -> packed_default_string = packed_default_string ;
96
+ snew -> packed_na_name = packed_na_name ;
97
+ snew -> coerce = coerce ;
98
+
99
+ npy_static_string default_string = {0 , NULL };
100
+ npy_load_string (& snew -> packed_default_string , & default_string );
101
+
102
+ npy_static_string na_name = {0 , NULL };
103
+ npy_load_string (& snew -> packed_na_name , & na_name );
104
+
105
+ snew -> na_name = na_name ;
106
+ snew -> default_string = default_string ;
94
107
95
108
PyArray_Descr * base = (PyArray_Descr * )new ;
96
109
base -> elsize = sizeof (npy_static_string );
@@ -194,10 +207,10 @@ string_discover_descriptor_from_pyobject(PyTypeObject *NPY_UNUSED(cls),
194
207
int
195
208
stringdtype_setitem (StringDTypeObject * descr , PyObject * obj , char * * dataptr )
196
209
{
197
- npy_static_string * sdata = (npy_static_string * )dataptr ;
210
+ npy_packed_static_string * sdata = (npy_packed_static_string * )dataptr ;
198
211
199
212
// free if dataptr holds preexisting string data,
200
- // npy_string_free does a NULL check
213
+ // npy_string_free does a NULL check and checks for small strings
201
214
npy_string_free (sdata );
202
215
203
216
// borrow reference
@@ -206,7 +219,7 @@ stringdtype_setitem(StringDTypeObject *descr, PyObject *obj, char **dataptr)
206
219
// setting NA *must* check pointer equality since NA types might not
207
220
// allow equality
208
221
if (na_object != NULL && obj == na_object ) {
209
- * sdata = NPY_NULL_STRING ;
222
+ * sdata = * NPY_NULL_STRING ;
210
223
}
211
224
else {
212
225
PyObject * val_obj = get_value (obj , descr -> coerce );
@@ -244,10 +257,11 @@ static PyObject *
244
257
stringdtype_getitem (StringDTypeObject * descr , char * * dataptr )
245
258
{
246
259
PyObject * val_obj = NULL ;
247
- npy_static_string * sdata = (npy_static_string * )dataptr ;
260
+ npy_packed_static_string * psdata = (npy_packed_static_string * )dataptr ;
261
+ npy_static_string sdata = {0 , NULL };
248
262
int hasnull = descr -> na_object != NULL ;
249
263
250
- if (npy_string_isnull ( sdata )) {
264
+ if (npy_load_string ( psdata , & sdata )) {
251
265
if (hasnull ) {
252
266
PyObject * na_object = descr -> na_object ;
253
267
Py_INCREF (na_object );
@@ -258,9 +272,7 @@ stringdtype_getitem(StringDTypeObject *descr, char **dataptr)
258
272
}
259
273
}
260
274
else {
261
- const char * data = npy_string_buf (sdata );
262
- size_t size = npy_string_size (sdata );
263
- val_obj = PyUnicode_FromStringAndSize (data , size );
275
+ val_obj = PyUnicode_FromStringAndSize (sdata .buf , sdata .size );
264
276
if (val_obj == NULL ) {
265
277
return NULL ;
266
278
}
@@ -285,7 +297,7 @@ stringdtype_getitem(StringDTypeObject *descr, char **dataptr)
285
297
npy_bool
286
298
nonzero (void * data , void * NPY_UNUSED (arr ))
287
299
{
288
- return npy_string_size ((npy_static_string * )data ) != 0 ;
300
+ return npy_string_size ((npy_packed_static_string * )data ) != 0 ;
289
301
}
290
302
291
303
// Implementation of PyArray_CompareFunc.
@@ -309,11 +321,13 @@ _compare(void *a, void *b, StringDTypeObject *descr)
309
321
return 0 ;
310
322
}
311
323
}
312
- const npy_static_string * default_string = & descr -> default_string ;
313
- const npy_static_string * ss_a = (npy_static_string * )a ;
314
- const npy_static_string * ss_b = (npy_static_string * )b ;
315
- int a_is_null = npy_string_isnull (ss_a );
316
- int b_is_null = npy_string_isnull (ss_b );
324
+ npy_static_string * default_string = & descr -> default_string ;
325
+ const npy_packed_static_string * ps_a = (npy_packed_static_string * )a ;
326
+ npy_static_string s_a = {0 , NULL };
327
+ int a_is_null = npy_load_string (ps_a , & s_a );
328
+ const npy_packed_static_string * ps_b = (npy_packed_static_string * )b ;
329
+ npy_static_string s_b = {0 , NULL };
330
+ int b_is_null = npy_load_string (ps_b , & s_b );
317
331
if (NPY_UNLIKELY (a_is_null || b_is_null )) {
318
332
if (hasnull && !has_string_na ) {
319
333
if (has_nan_na ) {
@@ -334,22 +348,22 @@ _compare(void *a, void *b, StringDTypeObject *descr)
334
348
}
335
349
else {
336
350
if (a_is_null ) {
337
- ss_a = default_string ;
351
+ s_a = * default_string ;
338
352
}
339
353
if (b_is_null ) {
340
- ss_b = default_string ;
354
+ s_b = * default_string ;
341
355
}
342
356
}
343
357
}
344
- return npy_string_cmp (ss_a , ss_b );
358
+ return npy_string_cmp (& s_a , & s_b );
345
359
}
346
360
347
361
// PyArray_ArgFunc
348
362
// The max element is the one with the highest unicode code point.
349
363
int
350
364
argmax (void * data , npy_intp n , npy_intp * max_ind , void * arr )
351
365
{
352
- npy_static_string * dptr = (npy_static_string * )data ;
366
+ npy_packed_static_string * dptr = (npy_packed_static_string * )data ;
353
367
* max_ind = 0 ;
354
368
for (int i = 1 ; i < n ; i ++ ) {
355
369
if (compare (& dptr [i ], & dptr [* max_ind ], arr ) > 0 ) {
@@ -364,7 +378,7 @@ argmax(void *data, npy_intp n, npy_intp *max_ind, void *arr)
364
378
int
365
379
argmin (void * data , npy_intp n , npy_intp * min_ind , void * arr )
366
380
{
367
- npy_static_string * dptr = (npy_static_string * )data ;
381
+ npy_packed_static_string * dptr = (npy_packed_static_string * )data ;
368
382
* min_ind = 0 ;
369
383
for (int i = 1 ; i < n ; i ++ ) {
370
384
if (compare (& dptr [i ], & dptr [* min_ind ], arr ) < 0 ) {
@@ -389,8 +403,8 @@ stringdtype_clear_loop(void *NPY_UNUSED(traverse_context),
389
403
{
390
404
while (size -- ) {
391
405
if (data != NULL ) {
392
- npy_string_free ((npy_static_string * )data );
393
- memset (data , 0 , sizeof (npy_static_string ));
406
+ npy_string_free ((npy_packed_static_string * )data );
407
+ memset (data , 0 , sizeof (npy_packed_static_string ));
394
408
}
395
409
data += stride ;
396
410
}
@@ -419,7 +433,7 @@ stringdtype_fill_zero_loop(void *NPY_UNUSED(traverse_context),
419
433
NpyAuxData * NPY_UNUSED (auxdata ))
420
434
{
421
435
while (size -- ) {
422
- * (npy_static_string * )(data ) = NPY_EMPTY_STRING ;
436
+ * (npy_packed_static_string * )(data ) = * NPY_EMPTY_STRING ;
423
437
data += stride ;
424
438
}
425
439
return 0 ;
@@ -568,8 +582,6 @@ static void
568
582
stringdtype_dealloc (StringDTypeObject * self )
569
583
{
570
584
Py_XDECREF (self -> na_object );
571
- npy_string_free (& self -> default_string );
572
- npy_string_free (& self -> na_name );
573
585
PyArrayDescr_Type .tp_dealloc ((PyObject * )self );
574
586
}
575
587
0 commit comments