| 289 | } |
| 290 | |
| 291 | Status Ingest_some_nulls(SEXP data, const std::shared_ptr<arrow::Array>& array, |
| 292 | R_xlen_t start, R_xlen_t n, size_t chunk_index) const { |
| 293 | auto p_offset = array->data()->GetValues<int32_t>(1); |
| 294 | if (!p_offset) { |
| 295 | return Status::Invalid("Invalid offset buffer"); |
| 296 | } |
| 297 | auto p_strings = array->data()->GetValues<char>(2, *p_offset); |
| 298 | if (!p_strings) { |
| 299 | // There is an offset buffer, but the data buffer is null |
| 300 | // There is at least one value in the array and not all the values are null |
| 301 | // That means all values are either empty strings or nulls so there is nothing to do |
| 302 | |
| 303 | if (array->null_count()) { |
| 304 | arrow::internal::BitmapReader null_reader(array->null_bitmap_data(), |
| 305 | array->offset(), n); |
| 306 | for (int i = 0; i < n; i++, null_reader.Next()) { |
| 307 | if (null_reader.IsNotSet()) { |
| 308 | SET_STRING_ELT(data, start + i, NA_STRING); |
| 309 | } |
| 310 | } |
| 311 | } |
| 312 | return Status::OK(); |
| 313 | } |
| 314 | |
| 315 | StringArrayType* string_array = static_cast<StringArrayType*>(array.get()); |
| 316 | |
| 317 | const bool all_valid = array->null_count() == 0; |
| 318 | const bool strip_out_nuls = GetBoolOption("arrow.skip_nul", false); |
| 319 | |
| 320 | bool nul_was_stripped = false; |
| 321 | |
| 322 | if (all_valid) { |
| 323 | // no need to watch for missing strings |
| 324 | cpp11::unwind_protect([&] { |
| 325 | if (strip_out_nuls) { |
| 326 | for (int i = 0; i < n; i++) { |
| 327 | SET_STRING_ELT(data, start + i, |
| 328 | r_string_from_view_strip_nul(string_array->GetView(i), |
| 329 | &nul_was_stripped)); |
| 330 | } |
| 331 | return; |
| 332 | } |
| 333 | |
| 334 | for (int i = 0; i < n; i++) { |
| 335 | SET_STRING_ELT(data, start + i, r_string_from_view(string_array->GetView(i))); |
| 336 | } |
| 337 | }); |
| 338 | } else { |
| 339 | cpp11::unwind_protect([&] { |
| 340 | arrow::internal::BitmapReader validity_reader(array->null_bitmap_data(), |
| 341 | array->offset(), n); |
| 342 | |
| 343 | if (strip_out_nuls) { |
| 344 | for (int i = 0; i < n; i++, validity_reader.Next()) { |
| 345 | if (validity_reader.IsSet()) { |
| 346 | SET_STRING_ELT(data, start + i, |
| 347 | r_string_from_view_strip_nul(string_array->GetView(i), |
| 348 | &nul_was_stripped)); |