diff --git a/src/Functions/reinterpretAs.cpp b/src/Functions/reinterpretAs.cpp index 1481f73fbbf..36c944d16fd 100644 --- a/src/Functions/reinterpretAs.cpp +++ b/src/Functions/reinterpretAs.cpp @@ -180,14 +180,19 @@ public: size_t offset = 0; for (size_t i = 0; i < size; ++i) { + size_t copy_size = std::min(static_cast(sizeof(ToFieldType)), offsets_from[i] - offset - 1); if constexpr (std::endian::native == std::endian::little) memcpy(&vec_res[i], &data_from[offset], - std::min(static_cast(sizeof(ToFieldType)), offsets_from[i] - offset - 1)); + copy_size); else - reverseMemcpy(&vec_res[i], + { + size_t offset_to = sizeof(ToFieldType) > copy_size ? sizeof(ToFieldType) - copy_size : 0; + reverseMemcpy( + reinterpret_cast(&vec_res[i]) + offset_to, &data_from[offset], - std::min(static_cast(sizeof(ToFieldType)), offsets_from[i] - offset - 1)); + copy_size); + } offset = offsets_from[i]; } @@ -208,6 +213,7 @@ public: size_t offset = 0; size_t copy_size = std::min(step, sizeof(ToFieldType)); + size_t index = data_from.size() - copy_size; if (sizeof(ToFieldType) <= step) vec_res.resize(size); @@ -216,7 +222,13 @@ public: for (size_t i = 0; i < size; ++i) { - memcpy(&vec_res[i], &data_from[offset], copy_size); + if constexpr (std::endian::native == std::endian::little) + memcpy(&vec_res[i], &data_from[offset], copy_size); + else + { + size_t offset_to = sizeof(ToFieldType) > copy_size ? sizeof(ToFieldType) - copy_size : 0; + memcpy(reinterpret_cast(&vec_res[i]) + offset_to, &data_from[index - offset], copy_size); + } offset += step; } @@ -244,10 +256,18 @@ public: static constexpr size_t copy_size = std::min(sizeof(From), sizeof(To)); for (size_t i = 0; i < size; ++i) - memcpy(static_cast(&to[i]), static_cast(&from[i]), copy_size); + { + if constexpr (std::endian::native == std::endian::little) + memcpy(static_cast(&to[i]), static_cast(&from[i]), copy_size); + else + { + size_t offset_to = sizeof(To) > sizeof(From) ? sizeof(To) - sizeof(From) : 0; + memcpy(reinterpret_cast(&to[i]) + offset_to, static_cast(&from[i]), copy_size); + } + + } result = std::move(column_to); - return true; } } @@ -322,11 +342,21 @@ private: StringRef data = src.getDataAt(i); /// Cut trailing zero bytes. +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ while (data.size && data.data[data.size - 1] == 0) --data.size; - +#else + size_t index = 0; + while (index < data.size && data.data[index] == 0) + index++; + data.size -= index; +#endif data_to.resize(offset + data.size + 1); +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ memcpy(&data_to[offset], data.data, data.size); +#else + reverseMemcpy(&data_to[offset], data.data + index, data.size); +#endif offset += data.size; data_to[offset] = 0; ++offset; @@ -346,24 +376,6 @@ private: else return ColumnType::create(column_size); } - - template - static void reinterpretImpl(const FromContainer & from, ToContainer & to) - { - using From = typename FromContainer::value_type; - using To = typename ToContainer::value_type; - - size_t size = from.size(); - static constexpr size_t copy_size = std::min(sizeof(From), sizeof(To)); - - if (sizeof(To) <= sizeof(From)) - to.resize(size); - else - to.resize_fill(size); - - for (size_t i = 0; i < size; ++i) - memcpy(static_cast(&to[i]), static_cast(&from[i]), copy_size); - } }; template