in r/src/convert_array.c [177:232]
SEXP nanoarrow_c_convert_array(SEXP array_xptr, SEXP ptype_sexp) {
// See if we can skip any ptype resolution at all
if (ptype_sexp == R_NilValue) {
enum VectorType vector_type = nanoarrow_infer_vector_type_array(array_xptr);
switch (vector_type) {
case VECTOR_TYPE_LGL:
case VECTOR_TYPE_INT:
case VECTOR_TYPE_DBL:
return convert_array_default(array_xptr, vector_type, R_NilValue);
case VECTOR_TYPE_CHR:
return convert_array_chr(array_xptr);
case VECTOR_TYPE_DATA_FRAME:
return convert_array_data_frame(array_xptr, R_NilValue);
default:
break;
}
// Otherwise, resolve the ptype and use it (this will also error
// for ptypes that can't be resolved)
ptype_sexp = PROTECT(nanoarrow_c_infer_ptype(array_xptr_get_schema(array_xptr)));
SEXP result = nanoarrow_c_convert_array(array_xptr, ptype_sexp);
UNPROTECT(1);
return result;
}
// Handle some S3 objects internally to avoid S3 dispatch
// (e.g., when looping over a data frame with a lot of columns)
if (Rf_isObject(ptype_sexp)) {
if (nanoarrow_ptype_is_data_frame(ptype_sexp)) {
return convert_array_data_frame(array_xptr, ptype_sexp);
} else if (Rf_inherits(ptype_sexp, "vctrs_unspecified") ||
Rf_inherits(ptype_sexp, "blob") ||
Rf_inherits(ptype_sexp, "vctrs_list_of") ||
Rf_inherits(ptype_sexp, "Date") || Rf_inherits(ptype_sexp, "hms") ||
Rf_inherits(ptype_sexp, "POSIXct") ||
Rf_inherits(ptype_sexp, "difftime")) {
return convert_array_default(array_xptr, VECTOR_TYPE_OTHER, ptype_sexp);
} else {
return call_convert_array(array_xptr, ptype_sexp);
}
}
// If we're here, these are non-S3 objects
switch (TYPEOF(ptype_sexp)) {
case LGLSXP:
return convert_array_default(array_xptr, VECTOR_TYPE_LGL, ptype_sexp);
case INTSXP:
return convert_array_default(array_xptr, VECTOR_TYPE_INT, ptype_sexp);
case REALSXP:
return convert_array_default(array_xptr, VECTOR_TYPE_DBL, ptype_sexp);
case STRSXP:
return convert_array_chr(array_xptr);
default:
return call_convert_array(array_xptr, ptype_sexp);
}
}