29
29
static R_xlen_t nanoarrow_vec_size (SEXP vec_sexp , struct PTypeView * ptype_view ) {
30
30
if (ptype_view -> vector_type == VECTOR_TYPE_DATA_FRAME ) {
31
31
return nanoarrow_data_frame_size (vec_sexp );
32
+ } else if (Rf_isMatrix (vec_sexp )) {
33
+ return Rf_nrows (vec_sexp );
32
34
} else {
33
35
return Rf_xlength (vec_sexp );
34
36
}
@@ -149,12 +151,7 @@ static void set_converter_data_frame(SEXP converter_xptr, struct RConverter* con
149
151
}
150
152
151
153
static void set_converter_list_of (SEXP converter_xptr , struct RConverter * converter ,
152
- SEXP ptype ) {
153
- SEXP child_ptype = Rf_getAttrib (ptype , Rf_install ("ptype" ));
154
- if (child_ptype == R_NilValue ) {
155
- Rf_error ("Expected attribute 'ptype' for conversion to list_of" );
156
- }
157
-
154
+ SEXP ptype , SEXP child_ptype ) {
158
155
converter -> children = (struct RConverter * * )ArrowMalloc (1 * sizeof (struct RConverter * ));
159
156
if (converter -> children == NULL ) {
160
157
Rf_error ("Failed to allocate converter children array" );
@@ -230,15 +227,25 @@ SEXP nanoarrow_converter_from_ptype(SEXP ptype) {
230
227
SEXP converter_shelter = R_ExternalPtrProtected (converter_xptr );
231
228
struct RConverter * converter = (struct RConverter * )R_ExternalPtrAddr (converter_xptr );
232
229
233
- if (Rf_isObject (ptype )) {
230
+ if (Rf_isMatrix (ptype )) {
231
+ converter -> ptype_view .vector_type = VECTOR_TYPE_MATRIX ;
232
+ SEXP child_ptype = PROTECT (Rf_allocVector (TYPEOF (ptype ), 0 ));
233
+ set_converter_list_of (converter_xptr , converter , ptype , child_ptype );
234
+ UNPROTECT (1 );
235
+ } else if (Rf_isObject (ptype )) {
234
236
if (nanoarrow_ptype_is_data_frame (ptype )) {
235
237
converter -> ptype_view .vector_type = VECTOR_TYPE_DATA_FRAME ;
236
238
set_converter_data_frame (converter_xptr , converter , ptype );
237
239
} else if (Rf_inherits (ptype , "blob" )) {
238
240
converter -> ptype_view .vector_type = VECTOR_TYPE_BLOB ;
239
241
} else if (Rf_inherits (ptype , "vctrs_list_of" )) {
240
242
converter -> ptype_view .vector_type = VECTOR_TYPE_LIST_OF ;
241
- set_converter_list_of (converter_xptr , converter , ptype );
243
+ SEXP child_ptype = Rf_getAttrib (ptype , Rf_install ("ptype" ));
244
+ if (child_ptype == R_NilValue ) {
245
+ Rf_error ("Expected attribute 'ptype' for conversion to list_of" );
246
+ }
247
+
248
+ set_converter_list_of (converter_xptr , converter , ptype , child_ptype );
242
249
} else if (Rf_inherits (ptype , "vctrs_unspecified" )) {
243
250
converter -> ptype_view .vector_type = VECTOR_TYPE_UNSPECIFIED ;
244
251
} else if (Rf_inherits (ptype , "Date" )) {
@@ -300,7 +307,8 @@ int nanoarrow_converter_set_schema(SEXP converter_xptr, SEXP schema_xptr) {
300
307
ArrowArrayViewInitFromSchema (& converter -> array_view , schema , & converter -> error ));
301
308
302
309
if (converter -> ptype_view .vector_type == VECTOR_TYPE_LIST_OF ||
303
- converter -> ptype_view .vector_type == VECTOR_TYPE_DATA_FRAME ) {
310
+ converter -> ptype_view .vector_type == VECTOR_TYPE_DATA_FRAME ||
311
+ converter -> ptype_view .vector_type == VECTOR_TYPE_MATRIX ) {
304
312
set_converter_children_schema (converter_xptr , schema_xptr );
305
313
}
306
314
@@ -318,7 +326,8 @@ int nanoarrow_converter_set_array(SEXP converter_xptr, SEXP array_xptr) {
318
326
converter -> src .length = 0 ;
319
327
320
328
if (converter -> ptype_view .vector_type == VECTOR_TYPE_LIST_OF ||
321
- converter -> ptype_view .vector_type == VECTOR_TYPE_DATA_FRAME ) {
329
+ converter -> ptype_view .vector_type == VECTOR_TYPE_DATA_FRAME ||
330
+ converter -> ptype_view .vector_type == VECTOR_TYPE_MATRIX ) {
322
331
set_converter_children_array (converter_xptr , array_xptr );
323
332
}
324
333
@@ -343,17 +352,23 @@ void sync_after_converter_reallocate(SEXP converter_xptr, struct RConverter* con
343
352
converter -> children [i ], VECTOR_ELT (result_sexp , i ),
344
353
capacity );
345
354
}
355
+ } else if (converter -> ptype_view .vector_type == VECTOR_TYPE_MATRIX ) {
356
+ // Reserve for the child converter here, which ensures that a matrix column in
357
+ // a data.frame() will get allocated properly.
358
+ SEXP child_converters = VECTOR_ELT (converter_shelter , 3 );
359
+ SEXP item_converter_xptr = VECTOR_ELT (child_converters , 0 );
360
+ nanoarrow_converter_reserve (item_converter_xptr ,
361
+ capacity * Rf_ncols (converter -> ptype_view .ptype ));
346
362
}
347
363
}
348
364
349
- int nanoarrow_converter_reserve (SEXP converter_xptr , R_xlen_t additional_size ) {
365
+ void nanoarrow_converter_reserve (SEXP converter_xptr , R_xlen_t additional_size ) {
350
366
struct RConverter * converter = (struct RConverter * )R_ExternalPtrAddr (converter_xptr );
351
367
SEXP converter_shelter = R_ExternalPtrProtected (converter_xptr );
352
368
SEXP current_result = VECTOR_ELT (converter_shelter , 4 );
353
369
354
370
if (current_result != R_NilValue ) {
355
- ArrowErrorSet (& converter -> error , "Reallocation in converter is not implemented" );
356
- return ENOTSUP ;
371
+ Rf_error ("Reallocation in converter is not implemented" );
357
372
}
358
373
359
374
SEXP result_sexp ;
@@ -368,7 +383,6 @@ int nanoarrow_converter_reserve(SEXP converter_xptr, R_xlen_t additional_size) {
368
383
sync_after_converter_reallocate (converter_xptr , converter , result_sexp ,
369
384
additional_size );
370
385
UNPROTECT (1 );
371
- return NANOARROW_OK ;
372
386
}
373
387
374
388
R_xlen_t nanoarrow_converter_materialize_n (SEXP converter_xptr , R_xlen_t n ) {
@@ -401,7 +415,7 @@ R_xlen_t nanoarrow_converter_materialize_n(SEXP converter_xptr, R_xlen_t n) {
401
415
int nanoarrow_converter_materialize_all (SEXP converter_xptr ) {
402
416
struct RConverter * converter = (struct RConverter * )R_ExternalPtrAddr (converter_xptr );
403
417
R_xlen_t remaining = converter -> array_view .array -> length ;
404
- NANOARROW_RETURN_NOT_OK ( nanoarrow_converter_reserve (converter_xptr , remaining ) );
418
+ nanoarrow_converter_reserve (converter_xptr , remaining );
405
419
if (nanoarrow_converter_materialize_n (converter_xptr , remaining ) != remaining ) {
406
420
return ERANGE ;
407
421
} else {
@@ -415,6 +429,7 @@ int nanoarrow_converter_finalize(SEXP converter_xptr) {
415
429
SEXP current_result = VECTOR_ELT (converter_shelter , 4 );
416
430
417
431
NANOARROW_RETURN_NOT_OK (nanoarrow_materialize_finalize_result (converter_xptr ));
432
+ current_result = VECTOR_ELT (converter_shelter , 4 );
418
433
419
434
// Check result size. A future implementation could also shrink the length
420
435
// or reallocate a shorter vector.
0 commit comments