SEXP nanoarrow_c_array_proxy()

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