@@ -953,7 +953,8 @@ int64_t ColumnWriterImpl::RleEncodeLevels(const void* src_buffer,
953953 DCHECK_EQ (encoded, num_buffered_values_);
954954
955955 if (include_length_prefix) {
956- reinterpret_cast <int32_t *>(dest_buffer->mutable_data ())[0 ] = level_encoder_.len ();
956+ ::arrow::util::SafeStore (dest_buffer->mutable_data (),
957+ ::arrow::bit_util::ToLittleEndian(level_encoder_.len()));
957958 }
958959
959960 return level_encoder_.len() + prefix_size;
@@ -2578,13 +2579,31 @@ struct SerializeFunctor<
25782579 if constexpr (std::is_same_v<ArrowType, ::arrow::Decimal64Type>) {
25792580 *p++ = ::arrow::bit_util::ToBigEndian (u64_in[0 ]);
25802581 } else if constexpr (std::is_same_v<ArrowType, ::arrow::Decimal128Type>) {
2582+ #if ARROW_LITTLE_ENDIAN
2583+ // On little-endian: u64_in[0] = low, u64_in[1] = high
2584+ // Write high first for big-endian output
25812585 *p++ = ::arrow::bit_util::ToBigEndian (u64_in[1 ]);
25822586 *p++ = ::arrow::bit_util::ToBigEndian (u64_in[0 ]);
2587+ #else
2588+ // On big-endian: u64_in[0] = high, u64_in[1] = low
2589+ // Write high first for big-endian output
2590+ *p++ = ::arrow::bit_util::ToBigEndian (u64_in[0 ]);
2591+ *p++ = ::arrow::bit_util::ToBigEndian (u64_in[1 ]);
2592+ #endif
25832593 } else if constexpr (std::is_same_v<ArrowType, ::arrow::Decimal256Type>) {
2594+ #if ARROW_LITTLE_ENDIAN
2595+ // On little-endian: write words in reverse order (high to low)
25842596 *p++ = ::arrow::bit_util::ToBigEndian (u64_in[3 ]);
25852597 *p++ = ::arrow::bit_util::ToBigEndian (u64_in[2 ]);
25862598 *p++ = ::arrow::bit_util::ToBigEndian (u64_in[1 ]);
25872599 *p++ = ::arrow::bit_util::ToBigEndian (u64_in[0 ]);
2600+ #else
2601+ // On big-endian: write words in natural order (high to low)
2602+ *p++ = ::arrow::bit_util::ToBigEndian (u64_in[0 ]);
2603+ *p++ = ::arrow::bit_util::ToBigEndian (u64_in[1 ]);
2604+ *p++ = ::arrow::bit_util::ToBigEndian (u64_in[2 ]);
2605+ *p++ = ::arrow::bit_util::ToBigEndian (u64_in[3 ]);
2606+ #endif
25882607 }
25892608 scratch = reinterpret_cast <uint8_t *>(p);
25902609 }
@@ -2600,6 +2619,7 @@ struct SerializeFunctor<
26002619
26012620// Requires a custom serializer because Float16s in Parquet are stored as a 2-byte
26022621// (little-endian) FLBA, whereas in Arrow they're a native `uint16_t`.
2622+ #if ARROW_LITTLE_ENDIAN
26032623template <>
26042624struct SerializeFunctor <::parquet::FLBAType, ::arrow::HalfFloatType> {
26052625 Status Serialize (const ::arrow::HalfFloatArray& array, ArrowWriteContext*, FLBA* out) {
@@ -2621,6 +2641,38 @@ struct SerializeFunctor<::parquet::FLBAType, ::arrow::HalfFloatType> {
26212641 return FLBA{reinterpret_cast <const uint8_t *>(value_ptr)};
26222642 }
26232643};
2644+ #else
2645+ template <>
2646+ struct SerializeFunctor <::parquet::FLBAType, ::arrow::HalfFloatType> {
2647+ Status Serialize (const ::arrow::HalfFloatArray& array, ArrowWriteContext*, FLBA* out) {
2648+ const uint16_t * values = array.raw_values ();
2649+ const int64_t length = array.length ();
2650+
2651+ // Allocate buffer for little-endian converted values
2652+ converted_values_.resize (length);
2653+
2654+ if (array.null_count () == 0 ) {
2655+ for (int64_t i = 0 ; i < length; ++i) {
2656+ converted_values_[i] = ::arrow::bit_util::ToLittleEndian (values[i]);
2657+ out[i] = FLBA{reinterpret_cast <const uint8_t *>(&converted_values_[i])};
2658+ }
2659+ } else {
2660+ for (int64_t i = 0 ; i < length; ++i) {
2661+ if (array.IsValid (i)) {
2662+ converted_values_[i] = ::arrow::bit_util::ToLittleEndian (values[i]);
2663+ out[i] = FLBA{reinterpret_cast <const uint8_t *>(&converted_values_[i])};
2664+ } else {
2665+ out[i] = FLBA{};
2666+ }
2667+ }
2668+ }
2669+ return Status::OK ();
2670+ }
2671+
2672+ private:
2673+ std::vector<uint16_t > converted_values_;
2674+ };
2675+ #endif
26242676
26252677template <>
26262678Status TypedColumnWriterImpl<FLBAType>::WriteArrowDense(
0 commit comments