SEXP nanoarrow_c_schema_parse()

in r/src/schema.c [258:331]


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

  struct ArrowSchemaView schema_view;
  struct ArrowError error;
  int status = ArrowSchemaViewInit(&schema_view, schema, &error);
  if (status != NANOARROW_OK) {
    Rf_error("ArrowSchemaViewInit(): %s", ArrowErrorMessage(&error));
  }

  const char* names[] = {
      "type",       "storage_type",     "extension_name",    "extension_metadata",
      "fixed_size", "decimal_bitwidth", "decimal_precision", "decimal_scale",
      "time_unit",  "timezone",         "union_type_ids",    ""};

  SEXP result = PROTECT(Rf_mkNamed(VECSXP, names));
  SET_VECTOR_ELT(result, 0, Rf_mkString(ArrowTypeString((schema_view.type))));
  SET_VECTOR_ELT(result, 1, Rf_mkString(ArrowTypeString((schema_view.storage_type))));

  if (schema_view.extension_name.data != NULL) {
    SET_VECTOR_ELT(result, 2, mkStringView(&schema_view.extension_name));
  }

  if (schema_view.extension_metadata.data != NULL) {
    SEXP metadata_sexp =
        PROTECT(Rf_allocVector(RAWSXP, schema_view.extension_metadata.size_bytes));
    memcpy(RAW(metadata_sexp), schema_view.extension_metadata.data,
           schema_view.extension_metadata.size_bytes);
    SET_VECTOR_ELT(result, 3, metadata_sexp);
    UNPROTECT(1);
  }

  if (schema_view.type == NANOARROW_TYPE_FIXED_SIZE_LIST ||
      schema_view.type == NANOARROW_TYPE_FIXED_SIZE_BINARY) {
    SET_VECTOR_ELT(result, 4, Rf_ScalarInteger(schema_view.fixed_size));
  }

  if (schema_view.type == NANOARROW_TYPE_DECIMAL128 ||
      schema_view.type == NANOARROW_TYPE_DECIMAL256) {
    SET_VECTOR_ELT(result, 5, Rf_ScalarInteger(schema_view.decimal_bitwidth));
    SET_VECTOR_ELT(result, 6, Rf_ScalarInteger(schema_view.decimal_precision));
    SET_VECTOR_ELT(result, 7, Rf_ScalarInteger(schema_view.decimal_scale));
  }

  if (schema_view.type == NANOARROW_TYPE_TIME32 ||
      schema_view.type == NANOARROW_TYPE_TIME64 ||
      schema_view.type == NANOARROW_TYPE_TIMESTAMP ||
      schema_view.type == NANOARROW_TYPE_DURATION) {
    SET_VECTOR_ELT(result, 8, Rf_mkString(ArrowTimeUnitString((schema_view.time_unit))));
  }

  if (schema_view.type == NANOARROW_TYPE_TIMESTAMP) {
    SET_VECTOR_ELT(result, 9, Rf_mkString(schema_view.timezone));
  }

  if (schema_view.type == NANOARROW_TYPE_DENSE_UNION ||
      schema_view.type == NANOARROW_TYPE_SPARSE_UNION) {
    int8_t type_ids[128];
    int num_type_ids = _ArrowParseUnionTypeIds(schema_view.union_type_ids, type_ids);
    if (num_type_ids == -1) {
      Rf_error("Invalid type IDs in union type: '%s'", schema_view.union_type_ids);
    }

    SEXP union_type_ids = PROTECT(Rf_allocVector(INTSXP, num_type_ids));
    for (int i = 0; i < num_type_ids; i++) {
      INTEGER(union_type_ids)[i] = type_ids[i];
    }
    SET_VECTOR_ELT(result, 10, union_type_ids);
    UNPROTECT(1);
  }

  UNPROTECT(1);
  return result;
}