in r/src/as_array.c [49:116]
static void as_array_int(SEXP x_sexp, struct ArrowArray* array, SEXP schema_xptr,
struct ArrowError* error) {
struct ArrowSchema* schema = schema_from_xptr(schema_xptr);
struct ArrowSchemaView schema_view;
int result = ArrowSchemaViewInit(&schema_view, schema, error);
if (result != NANOARROW_OK) {
Rf_error("ArrowSchemaViewInit(): %s", error->message);
}
// Only consider the default create for now
if (schema_view.type != NANOARROW_TYPE_INT32) {
call_as_nanoarrow_array(x_sexp, array, schema_xptr, "as_nanoarrow_array_from_c");
return;
}
// We don't consider altrep for now: we need an array of int32_t, and while we
// *could* avoid materializing, there's no point because the source altrep
// object almost certainly knows how to do this faster than we do.
int* x_data = INTEGER(x_sexp);
int64_t len = Rf_xlength(x_sexp);
result = ArrowArrayInitFromType(array, NANOARROW_TYPE_INT32);
if (result != NANOARROW_OK) {
Rf_error("ArrowArrayInitFromType() failed");
}
// Borrow the data buffer
buffer_borrowed(ArrowArrayBuffer(array, 1), x_data, len * sizeof(int32_t), x_sexp);
// Set the array fields
array->length = len;
array->offset = 0;
int64_t null_count = 0;
// Look for the first null (will be the last index if there are none)
int64_t first_null = -1;
for (int64_t i = 0; i < len; i++) {
if (x_data[i] == NA_INTEGER) {
first_null = i;
break;
}
}
// If there are nulls, pack the validity buffer
if (first_null != -1) {
struct ArrowBitmap bitmap;
ArrowBitmapInit(&bitmap);
result = ArrowBitmapReserve(&bitmap, len);
if (result != NANOARROW_OK) {
Rf_error("ArrowBitmapReserve() failed");
}
ArrowBitmapAppendUnsafe(&bitmap, 1, first_null);
for (int64_t i = first_null; i < len; i++) {
uint8_t is_valid = x_data[i] != NA_INTEGER;
null_count += !is_valid;
ArrowBitmapAppend(&bitmap, is_valid, 1);
}
ArrowArraySetValidityBitmap(array, &bitmap);
}
array->null_count = null_count;
result = ArrowArrayFinishBuildingDefault(array, error);
if (result != NANOARROW_OK) {
Rf_error("ArrowArrayFinishBuildingDefault(): %s", error->message);
}
}