Skip to content

Commit 96d7652

Browse files
committed
working for integers
1 parent bae2a96 commit 96d7652

File tree

5 files changed

+50
-12
lines changed

5 files changed

+50
-12
lines changed

r/src/init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ extern SEXP nanoarrow_c_schema_set_dictionary(SEXP schema_mut_xptr, SEXP diction
9292
extern SEXP nanoarrow_c_preserved_count(void);
9393
extern SEXP nanoarrow_c_preserved_empty(void);
9494
extern SEXP nanoarrow_c_preserve_and_release_on_other_thread(SEXP obj);
95+
extern SEXP nanoarrow_c_convert_array2(SEXP array_xptr, SEXP ptype_sexp);
9596
extern SEXP nanoarrow_c_version(void);
9697
extern SEXP nanoarrow_c_version_runtime(void);
9798

@@ -166,6 +167,7 @@ static const R_CallMethodDef CallEntries[] = {
166167
{"nanoarrow_c_preserved_empty", (DL_FUNC)&nanoarrow_c_preserved_empty, 0},
167168
{"nanoarrow_c_preserve_and_release_on_other_thread",
168169
(DL_FUNC)&nanoarrow_c_preserve_and_release_on_other_thread, 1},
170+
{"nanoarrow_c_convert_array2", (DL_FUNC)&nanoarrow_c_convert_array2, 2},
169171
{"nanoarrow_c_version", (DL_FUNC)&nanoarrow_c_version, 0},
170172
{"nanoarrow_c_version_runtime", (DL_FUNC)&nanoarrow_c_version_runtime, 0},
171173
{NULL, NULL, 0}};

r/src/vctr_builder.cc

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@
2222
#include <memory>
2323
#include <vector>
2424

25+
#include "array.h"
2526
#include "materialize.h"
2627
#include "nanoarrow.h"
2728
#include "nanoarrow/r.h"
2829

2930
#include "vctr_builder.h"
3031
#include "vctr_builder_base.h"
32+
#include "vctr_builder_list_of.h"
3133
#include "vctr_builder_primitive.h"
3234
#include "vctr_builder_rcrd.h"
33-
#include "vctr_builder_list_of.h"
3435

3536
// These conversions are the default R-native type guesses for
3637
// an array that don't require extra information from the ptype (e.g.,
@@ -276,3 +277,31 @@ SEXP nanoarrow_c_infer_ptype(SEXP schema_xptr) {
276277
UNPROTECT(2);
277278
return ptype_sexp;
278279
}
280+
281+
SEXP nanoarrow_c_convert_array2(SEXP array_xptr, SEXP ptype_sexp) {
282+
ArrowArray* array = nanoarrow_array_from_xptr(array_xptr);
283+
SEXP schema_xptr = PROTECT(array_xptr_get_schema(array_xptr));
284+
SEXP builder_xptr = PROTECT(nanoarrow_vctr_builder_init(schema_xptr, ptype_sexp));
285+
auto builder = reinterpret_cast<VctrBuilder*>(R_ExternalPtrAddr(builder_xptr));
286+
287+
ArrowError error;
288+
ArrowErrorInit(&error);
289+
290+
int result = builder->Reserve(array->length, &error);
291+
if (result != NANOARROW_OK) {
292+
Rf_error("builder->Reserve() failed: %s", error.message);
293+
}
294+
295+
result = builder->PushNext(array, &error);
296+
if (result != NANOARROW_OK) {
297+
Rf_error("builder->PushNext() failed: %s", error.message);
298+
}
299+
300+
result = builder->Finish(&error);
301+
if (result != NANOARROW_OK) {
302+
Rf_error("builder->Finish() failed: %s", error.message);
303+
}
304+
305+
UNPROTECT(2);
306+
return builder->GetValue();
307+
}

r/src/vctr_builder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ SEXP nanoarrow_vctr_builder_init(SEXP schema_xptr, SEXP ptype_sexp);
5454

5555
SEXP nanoarrow_c_infer_ptype(SEXP schema_xptr);
5656

57+
SEXP nanoarrow_c_convert_array2(SEXP array_xptr, SEXP ptype_sexp);
58+
5759
#ifdef __cplusplus
5860
}
5961
#endif

r/src/vctr_builder_base.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ struct VctrBuilder {
7777
// called when the caller cannot safely relinquish ownership of an array (e.g.,
7878
// convert_array()). Calling this method may longjmp.
7979
virtual ArrowErrorCode PushNext(const ArrowArray* array, ArrowError* error) {
80-
return ENOTSUP;
80+
NANOARROW_RETURN_NOT_OK(ArrowArrayViewSetArray(&array_view_, array, error));
81+
return NANOARROW_OK;
8182
}
8283

8384
// Push an array into this builder. The implementation may (but is not required) to take
@@ -99,9 +100,11 @@ struct VctrBuilder {
99100

100101
// Release the final value of the builder. Calling this method may longjmp.
101102
virtual SEXP GetValue() {
103+
SEXP value = PROTECT(value_);
102104
nanoarrow_release_sexp(value_);
103105
value_ = R_NilValue;
104-
return value_;
106+
UNPROTECT(1);
107+
return value;
105108
}
106109

107110
// Get (or allocate if required) the SEXP ptype for this output

r/src/vctr_builder_primitive.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ class UnspecifiedBuilder : public VctrBuilder {
4444

4545
ArrowErrorCode Reserve(R_xlen_t n, ArrowError* error) override {
4646
NANOARROW_RETURN_NOT_OK(VctrBuilder::Reserve(n, error));
47-
value_ = PROTECT(Rf_allocVector(LGLSXP, n));
48-
SetValue(value_);
47+
SEXP value = PROTECT(Rf_allocVector(LGLSXP, n));
48+
SetValue(value);
4949
UNPROTECT(1);
5050
return NANOARROW_OK;
5151
}
@@ -88,19 +88,21 @@ class IntBuilder : public VctrBuilder {
8888

8989
ArrowErrorCode Reserve(R_xlen_t n, ArrowError* error) override {
9090
NANOARROW_RETURN_NOT_OK(VctrBuilder::Reserve(n, error));
91-
value_ = PROTECT(Rf_allocVector(INTSXP, n));
92-
SetValue(value_);
91+
SEXP value = PROTECT(Rf_allocVector(INTSXP, n));
92+
SetValue(value);
9393
UNPROTECT(1);
9494
return NANOARROW_OK;
9595
}
9696

9797
ArrowErrorCode PushNext(const ArrowArray* array, ArrowError* error) override {
98+
NANOARROW_RETURN_NOT_OK(VctrBuilder::PushNext(array, error));
99+
98100
int* result = INTEGER(value_);
99101
int64_t n_bad_values = 0;
100102

101103
// True for all the types supported here
102104
const uint8_t* is_valid = array_view_.buffer_views[0].data.as_uint8;
103-
int64_t raw_src_offset = array_view_.array->offset;
105+
int64_t raw_src_offset = array_view_.offset;
104106
R_xlen_t length = array->length;
105107

106108
// Fill the buffer
@@ -116,7 +118,7 @@ class IntBuilder : public VctrBuilder {
116118
length * sizeof(int32_t));
117119

118120
// Set any nulls to NA_INTEGER
119-
if (is_valid != NULL && array_view_.array->null_count != 0) {
121+
if (is_valid != NULL && array_view_.null_count != 0) {
120122
for (R_xlen_t i = 0; i < length; i++) {
121123
if (!ArrowBitGet(is_valid, raw_src_offset + i)) {
122124
result[value_size_ + i] = NA_INTEGER;
@@ -129,7 +131,7 @@ class IntBuilder : public VctrBuilder {
129131
raw_src_offset, length, result + value_size_);
130132

131133
// Set any nulls to NA_LOGICAL
132-
if (is_valid != NULL && array_view_.array->null_count != 0) {
134+
if (is_valid != NULL && array_view_.null_count != 0) {
133135
for (R_xlen_t i = 0; i < length; i++) {
134136
if (!ArrowBitGet(is_valid, raw_src_offset + i)) {
135137
result[value_size_ + i] = NA_LOGICAL;
@@ -147,7 +149,7 @@ class IntBuilder : public VctrBuilder {
147149
}
148150

149151
// Set any nulls to NA_INTEGER
150-
if (is_valid != NULL && array_view_.array->null_count != 0) {
152+
if (is_valid != NULL && array_view_.null_count != 0) {
151153
for (R_xlen_t i = 0; i < length; i++) {
152154
if (!ArrowBitGet(is_valid, raw_src_offset + i)) {
153155
result[value_size_ + i] = NA_INTEGER;
@@ -162,7 +164,7 @@ class IntBuilder : public VctrBuilder {
162164
case NANOARROW_TYPE_DOUBLE:
163165
// Loop + bounds check. Because we don't know what memory might be
164166
// in a null slot, we have to check nulls if there are any.
165-
if (is_valid != NULL && array_view_.array->null_count != 0) {
167+
if (is_valid != NULL && array_view_.null_count != 0) {
166168
for (R_xlen_t i = 0; i < length; i++) {
167169
if (ArrowBitGet(is_valid, raw_src_offset + i)) {
168170
int64_t value = ArrowArrayViewGetIntUnsafe(&array_view_, i);

0 commit comments

Comments
 (0)