static inline void array_export()

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);
}