in r/src/array.c [401:470]
SEXP nanoarrow_c_array_proxy(SEXP array_xptr, SEXP array_view_xptr, SEXP recursive_sexp) {
struct ArrowArray* array = array_from_xptr(array_xptr);
int recursive = LOGICAL(recursive_sexp)[0];
struct ArrowArrayView* array_view = NULL;
if (array_view_xptr != R_NilValue) {
array_view = (struct ArrowArrayView*)R_ExternalPtrAddr(array_view_xptr);
}
const char* names[] = {"length", "null_count", "offset", "buffers",
"children", "dictionary", ""};
SEXP array_proxy = PROTECT(Rf_mkNamed(VECSXP, names));
SET_VECTOR_ELT(array_proxy, 0, length_from_int64(array->length));
SET_VECTOR_ELT(array_proxy, 1, length_from_int64(array->null_count));
SET_VECTOR_ELT(array_proxy, 2, length_from_int64(array->offset));
if (array->n_buffers > 0) {
SEXP buffers = PROTECT(Rf_allocVector(VECSXP, array->n_buffers));
for (int64_t i = 0; i < array->n_buffers; i++) {
if (array_view != NULL) {
SET_VECTOR_ELT(buffers, i, borrow_buffer(array_view, i, array_xptr));
} else {
SET_VECTOR_ELT(buffers, i, borrow_unknown_buffer(array, i, array_xptr));
}
}
SET_VECTOR_ELT(array_proxy, 3, buffers);
UNPROTECT(1);
}
if (array->n_children > 0) {
SEXP children = PROTECT(Rf_allocVector(VECSXP, array->n_children));
for (int64_t i = 0; i < array->n_children; i++) {
SEXP child = PROTECT(borrow_array_xptr(array->children[i], array_xptr));
if (recursive) {
SEXP array_view_child =
PROTECT(borrow_array_view_child(array_view, i, array_view_xptr));
SET_VECTOR_ELT(children, i,
nanoarrow_c_array_proxy(child, array_view_child, recursive_sexp));
UNPROTECT(1);
} else {
SET_VECTOR_ELT(children, i, child);
}
UNPROTECT(1);
}
SET_VECTOR_ELT(array_proxy, 4, children);
UNPROTECT(1);
}
if (array->dictionary != NULL) {
SEXP dictionary_xptr = PROTECT(borrow_array_xptr(array->dictionary, array_xptr));
if (recursive) {
SEXP dictionary_view_xptr =
PROTECT(borrow_array_view_dictionary(array_view, array_view_xptr));
SEXP dictionary_proxy = PROTECT(
nanoarrow_c_array_proxy(dictionary_xptr, dictionary_view_xptr, recursive_sexp));
SET_VECTOR_ELT(array_proxy, 5, dictionary_proxy);
UNPROTECT(2);
} else {
SET_VECTOR_ELT(array_proxy, 5, dictionary_xptr);
}
UNPROTECT(1);
}
UNPROTECT(1);
return array_proxy;
}