| 699 | |
| 700 | template <typename T> |
| 701 | Status NumPyConverter::VisitString(T* builder) { |
| 702 | auto data = reinterpret_cast<const uint8_t*>(PyArray_DATA(arr_)); |
| 703 | |
| 704 | char numpy_byteorder = dtype_->byteorder; |
| 705 | |
| 706 | // For Python C API, -1 is little-endian, 1 is big-endian |
| 707 | #if ARROW_LITTLE_ENDIAN |
| 708 | // Yield little-endian from both '|' (native) and '<' |
| 709 | int byteorder = numpy_byteorder == '>' ? 1 : -1; |
| 710 | #else |
| 711 | // Yield big-endian from both '|' (native) and '>' |
| 712 | int byteorder = numpy_byteorder == '<' ? -1 : 1; |
| 713 | #endif |
| 714 | |
| 715 | PyAcquireGIL gil_lock; |
| 716 | |
| 717 | const bool is_binary_type = dtype_->type_num == NPY_STRING; |
| 718 | const bool is_unicode_type = dtype_->type_num == NPY_UNICODE; |
| 719 | |
| 720 | if (!is_binary_type && !is_unicode_type) { |
| 721 | const bool is_float_type = dtype_->kind == 'f'; |
| 722 | if (from_pandas_ && is_float_type) { |
| 723 | // in case of from_pandas=True, accept an all-NaN float array as input |
| 724 | RETURN_NOT_OK(NumPyNullsConverter::Convert(pool_, arr_, from_pandas_, &null_bitmap_, |
| 725 | &null_count_)); |
| 726 | if (null_count_ == length_) { |
| 727 | auto arr = std::make_shared<NullArray>(length_); |
| 728 | compute::ExecContext context(pool_); |
| 729 | ARROW_ASSIGN_OR_RAISE( |
| 730 | std::shared_ptr<Array> out, |
| 731 | compute::Cast(*arr, arrow::utf8(), cast_options_, &context)); |
| 732 | out_arrays_.emplace_back(out); |
| 733 | return Status::OK(); |
| 734 | } |
| 735 | } |
| 736 | std::string dtype_string; |
| 737 | RETURN_NOT_OK(internal::PyObject_StdStringStr(reinterpret_cast<PyObject*>(dtype_), |
| 738 | &dtype_string)); |
| 739 | return Status::TypeError("Expected a string or bytes dtype, got ", dtype_string); |
| 740 | } |
| 741 | |
| 742 | auto AppendNonNullValue = [&](const uint8_t* data) { |
| 743 | if (is_binary_type) { |
| 744 | if (ARROW_PREDICT_TRUE(util::ValidateUTF8(data, itemsize_))) { |
| 745 | return builder->Append(data, static_cast<int32_t>(itemsize_)); |
| 746 | } else { |
| 747 | return Status::Invalid("Encountered non-UTF8 binary value: ", |
| 748 | HexEncode(data, itemsize_)); |
| 749 | } |
| 750 | } else { |
| 751 | // is_unicode_type case |
| 752 | return AppendUTF32(reinterpret_cast<const char*>(data), itemsize_, byteorder, |
| 753 | builder); |
| 754 | } |
| 755 | }; |
| 756 | |
| 757 | if (mask_ != nullptr) { |
| 758 | Ndarray1DIndexer<uint8_t> mask_values(mask_); |
nothing calls this directly
no test coverage detected