@@ -215,6 +215,12 @@ is_not_a_vstring(const npy_packed_static_string *s)
215
215
return is_short_string (s ) || npy_string_isnull (s );
216
216
}
217
217
218
+ int
219
+ is_a_vstring (const npy_packed_static_string * s )
220
+ {
221
+ return !is_not_a_vstring (s );
222
+ }
223
+
218
224
int
219
225
npy_string_load (npy_string_allocator * allocator ,
220
226
const npy_packed_static_string * packed_string ,
@@ -281,7 +287,7 @@ heap_or_arena_allocate(npy_string_allocator *allocator,
281
287
return buf ;
282
288
}
283
289
else {
284
- // no room, resort to a heap allocation this leaves the
290
+ // No room, resort to a heap allocation. This leaves the
285
291
// NPY_STRING_ARENA_FREED flag set to possibly re-use the arena
286
292
// allocation in the future if there is room for it
287
293
* flags |= NPY_STRING_ON_HEAP ;
@@ -454,14 +460,36 @@ npy_string_dup(const npy_packed_static_string *in,
454
460
memcpy (out , in , sizeof (npy_packed_static_string ));
455
461
return 0 ;
456
462
}
457
-
458
463
_npy_static_string_u * in_u = (_npy_static_string_u * )in ;
464
+ size_t size = VSTRING_SIZE (in_u );
465
+ if (size == 0 ) {
466
+ _npy_static_string_u * out_u = (_npy_static_string_u * )out ;
467
+ unsigned char flags = out_u -> direct_buffer .flags_and_size &
468
+ ~NPY_SHORT_STRING_SIZE_MASK ;
469
+ * out = * NPY_EMPTY_STRING ;
470
+ out_u -> direct_buffer .flags_and_size |= flags ;
471
+ return 0 ;
472
+ }
473
+ char * in_buf = NULL ;
459
474
npy_string_arena * arena = & in_allocator -> arena ;
460
- if (arena == NULL ) {
475
+ if (arena -> buffer == NULL ) {
461
476
return -1 ;
462
477
}
463
- return npy_string_newsize (vstring_buffer (arena , in_u ), VSTRING_SIZE (in_u ),
464
- out , out_allocator );
478
+ int used_malloc = 0 ;
479
+ if (in_allocator == out_allocator && is_a_vstring (in )) {
480
+ in_buf = in_allocator -> malloc (size );
481
+ memcpy (in_buf , vstring_buffer (arena , in_u ), size );
482
+ used_malloc = 1 ;
483
+ }
484
+ else {
485
+ in_buf = vstring_buffer (arena , in_u );
486
+ }
487
+ int ret =
488
+ npy_string_newsize (in_buf , VSTRING_SIZE (in_u ), out , out_allocator );
489
+ if (used_malloc ) {
490
+ in_allocator -> free (in_buf );
491
+ }
492
+ return ret ;
465
493
}
466
494
467
495
int
0 commit comments