in r/src/array.h [113:170]
static inline void array_export(SEXP array_xptr, struct ArrowArray* array_copy) {
// If array_xptr has SEXP dependencies (most commonly this would occur if it's
// a borrowed child of a struct array), this will ensure a version that can be
// released independently of its parent.
SEXP independent_array_xptr = PROTECT(array_xptr_ensure_independent(array_xptr));
struct ArrowArray* array = array_from_xptr(independent_array_xptr);
int result = ArrowArrayInitFromType(array_copy, NANOARROW_TYPE_UNINITIALIZED);
if (result != NANOARROW_OK) {
Rf_error("ArrowArrayInitFromType() failed");
}
array_copy->length = array->length;
array_copy->null_count = array->null_count;
array_copy->offset = array->offset;
// Get buffer references, each of which preserve a reference to independent_array_xptr
array_copy->n_buffers = array->n_buffers;
for (int64_t i = 0; i < array->n_buffers; i++) {
SEXP borrowed_buffer =
PROTECT(buffer_borrowed_xptr(array->buffers[i], 0, independent_array_xptr));
result = ArrowArraySetBuffer(array_copy, i,
(struct ArrowBuffer*)R_ExternalPtrAddr(borrowed_buffer));
if (result != NANOARROW_OK) {
array_copy->release(array_copy);
Rf_error("ArrowArraySetBuffer() failed");
}
UNPROTECT(1);
}
// Swap out any children for independently releasable chilren and export them
// into array_copy->children
result = ArrowArrayAllocateChildren(array_copy, array->n_children);
if (result != NANOARROW_OK) {
array_copy->release(array_copy);
Rf_error("ArrowArrayAllocateChildren() failed");
}
for (int64_t i = 0; i < array->n_children; i++) {
SEXP independent_child = PROTECT(array_ensure_independent(array->children[i]));
array_export(independent_child, array_copy->children[i]);
UNPROTECT(1);
}
if (array->dictionary != NULL) {
result = ArrowArrayAllocateDictionary(array_copy);
if (result != NANOARROW_OK) {
array_copy->release(array_copy);
Rf_error("ArrowArrayAllocateDictionary() failed");
}
SEXP independent_dictionary = PROTECT(array_ensure_independent(array->dictionary));
array_export(independent_dictionary, array_copy->dictionary);
UNPROTECT(1);
}
UNPROTECT(1);
}