in r/src/schema.c [416:492]
SEXP nanoarrow_c_schema_set_metadata(SEXP schema_mut_xptr, SEXP metadata_sexp) {
struct ArrowSchema* schema = schema_from_xptr(schema_mut_xptr);
int result;
if (Rf_xlength(metadata_sexp) == 0) {
result = ArrowSchemaSetMetadata(schema, NULL);
if (result != NANOARROW_OK) {
Rf_error("Failed to set schema$metadata");
}
return R_NilValue;
}
// We need this to ensure buffer gets cleaned up amongst the potential longjmp
// possibilities below.
SEXP buffer_xptr = PROTECT(buffer_owning_xptr());
struct ArrowBuffer* buffer = (struct ArrowBuffer*)R_ExternalPtrAddr(buffer_xptr);
result = ArrowMetadataBuilderInit(buffer, NULL);
if (result != NANOARROW_OK) {
Rf_error("ArrowMetadataBuilderInit() failed");
}
SEXP metadata_names = PROTECT(Rf_getAttrib(metadata_sexp, R_NamesSymbol));
if (metadata_names == R_NilValue) {
Rf_error("schema$metadata must be named");
}
struct ArrowStringView key;
struct ArrowStringView value;
for (R_xlen_t i = 0; i < Rf_xlength(metadata_sexp); i++) {
SEXP name_sexp = STRING_ELT(metadata_names, i);
if (name_sexp == NA_STRING) {
Rf_error("schema$metadata[[%ld]] must be named", (long)i + 1);
}
const void* vmax = vmaxget();
key = ArrowCharView(Rf_translateCharUTF8(name_sexp));
if (key.size_bytes == 0) {
Rf_error("schema$metadata[[%ld]] must be named", (long)i + 1);
}
SEXP value_sexp = VECTOR_ELT(metadata_sexp, i);
if (TYPEOF(value_sexp) == STRSXP && Rf_xlength(value_sexp) == 1) {
SEXP value_chr = STRING_ELT(value_sexp, 0);
if (value_chr == NA_STRING) {
Rf_error("schema$metadata[[%ld]] must not be NA_character_", (long)i + 1);
}
value = ArrowCharView(Rf_translateCharUTF8(value_chr));
} else if (TYPEOF(value_sexp) == RAWSXP) {
value.data = (const char*)RAW(value_sexp);
value.size_bytes = Rf_xlength(value_sexp);
} else {
Rf_error("schema$metadata[[%ld]] must be character(1) or raw()", (long)i + 1);
}
result = ArrowMetadataBuilderAppend(buffer, key, value);
if (result != NANOARROW_OK) {
Rf_error("ArrowMetadataBuilderAppend() failed");
}
vmaxset(vmax);
}
UNPROTECT(1);
result = ArrowSchemaSetMetadata(schema, (const char*)buffer->data);
ArrowBufferReset(buffer);
if (result != NANOARROW_OK) {
Rf_error("ArrowSchemaSetMetadata() failed");
}
UNPROTECT(1);
return R_NilValue;
}