SEXP nanoarrow_c_schema_to_list()

in r/src/schema.c [189:244]


SEXP nanoarrow_c_schema_to_list(SEXP schema_xptr) {
  struct ArrowSchema* schema = schema_from_xptr(schema_xptr);

  const char* names[] = {"format",   "name",       "metadata", "flags",
                         "children", "dictionary", ""};
  SEXP result = PROTECT(Rf_mkNamed(VECSXP, names));

  SEXP format_sexp = PROTECT(Rf_allocVector(STRSXP, 1));
  SET_STRING_ELT(format_sexp, 0, Rf_mkCharCE(schema->format, CE_UTF8));
  SET_VECTOR_ELT(result, 0, format_sexp);
  UNPROTECT(1);

  if (schema->name != NULL) {
    SEXP name_sexp = PROTECT(Rf_allocVector(STRSXP, 1));
    SET_STRING_ELT(name_sexp, 0, Rf_mkCharCE(schema->name, CE_UTF8));
    SET_VECTOR_ELT(result, 1, name_sexp);
    UNPROTECT(1);
  } else {
    SET_VECTOR_ELT(result, 1, R_NilValue);
  }

  SET_VECTOR_ELT(result, 2, schema_metadata_to_list(schema->metadata));
  SET_VECTOR_ELT(result, 3, Rf_ScalarInteger(schema->flags));

  if (schema->n_children > 0) {
    SEXP children_sexp = PROTECT(Rf_allocVector(VECSXP, schema->n_children));
    SEXP children_names_sexp = PROTECT(Rf_allocVector(STRSXP, schema->n_children));
    for (R_xlen_t i = 0; i < schema->n_children; i++) {
      SEXP child_xptr = PROTECT(borrow_schema_xptr(schema->children[i], schema_xptr));
      SET_VECTOR_ELT(children_sexp, i, child_xptr);
      if (schema->children[i]->name != NULL) {
        SET_STRING_ELT(children_names_sexp, i,
                       Rf_mkCharCE(schema->children[i]->name, CE_UTF8));
      } else {
        SET_STRING_ELT(children_names_sexp, i, Rf_mkCharCE("", CE_UTF8));
      }
      UNPROTECT(1);
    }
    Rf_setAttrib(children_sexp, R_NamesSymbol, children_names_sexp);
    SET_VECTOR_ELT(result, 4, children_sexp);
    UNPROTECT(2);
  } else {
    SET_VECTOR_ELT(result, 4, Rf_allocVector(VECSXP, schema->n_children));
  }

  if (schema->dictionary != NULL) {
    SEXP dictionary_xptr = PROTECT(borrow_schema_xptr(schema->dictionary, schema_xptr));
    SET_VECTOR_ELT(result, 5, dictionary_xptr);
    UNPROTECT(1);
  } else {
    SET_VECTOR_ELT(result, 5, R_NilValue);
  }

  UNPROTECT(1);
  return result;
}