in extensions/nanoarrow_ipc/src/nanoarrow/nanoarrow_ipc_decoder.c [1309:1412]
static int ArrowIpcDecoderSwapEndian(struct ArrowIpcBufferSource* src,
struct ArrowBufferView* out_view,
struct ArrowBuffer* dst, struct ArrowError* error) {
// Some buffer data types don't need any endian swapping
switch (src->data_type) {
case NANOARROW_TYPE_BOOL:
case NANOARROW_TYPE_INT8:
case NANOARROW_TYPE_UINT8:
case NANOARROW_TYPE_STRING:
case NANOARROW_TYPE_BINARY:
return NANOARROW_OK;
default:
break;
}
// Make sure dst is not a shared buffer that we can't modify
struct ArrowBuffer tmp;
ArrowBufferInit(&tmp);
if (dst->allocator.private_data != NULL) {
ArrowBufferMove(dst, &tmp);
ArrowBufferInit(dst);
}
if (dst->size_bytes == 0) {
NANOARROW_RETURN_NOT_OK(ArrowBufferReserve(dst, out_view->size_bytes));
dst->size_bytes = out_view->size_bytes;
}
switch (src->data_type) {
case NANOARROW_TYPE_DECIMAL128:
case NANOARROW_TYPE_DECIMAL256: {
const uint64_t* ptr_src = out_view->data.as_uint64;
uint64_t* ptr_dst = (uint64_t*)dst->data;
uint64_t words[4];
int n_words = src->element_size_bits / 64;
for (int64_t i = 0; i < (dst->size_bytes / n_words / 8); i++) {
for (int j = 0; j < n_words; j++) {
words[j] = bswap64(ptr_src[i * n_words + j]);
}
for (int j = 0; j < n_words; j++) {
ptr_dst[i * n_words + j] = words[n_words - j - 1];
}
}
break;
}
case NANOARROW_TYPE_INTERVAL_DAY_TIME: {
uint32_t* ptr = (uint32_t*)dst->data;
for (int64_t i = 0; i < (dst->size_bytes / 4); i++) {
ptr[i] = bswap32(out_view->data.as_uint32[i]);
}
break;
}
case NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO: {
const uint8_t* ptr_src = out_view->data.as_uint8;
uint8_t* ptr_dst = dst->data;
int item_size_bytes = 16;
struct ArrowIpcIntervalMonthDayNano item;
for (int64_t i = 0; i < (dst->size_bytes / item_size_bytes); i++) {
memcpy(&item, ptr_src + i * item_size_bytes, item_size_bytes);
item.months = bswap32(item.months);
item.days = bswap32(item.days);
item.ns = bswap64(item.ns);
memcpy(ptr_dst + i * item_size_bytes, &item, item_size_bytes);
}
break;
}
default:
switch (src->element_size_bits) {
case 16: {
uint16_t* ptr = (uint16_t*)dst->data;
for (int64_t i = 0; i < (dst->size_bytes / 2); i++) {
ptr[i] = bswap16(out_view->data.as_uint16[i]);
}
break;
}
case 32: {
uint32_t* ptr = (uint32_t*)dst->data;
for (int64_t i = 0; i < (dst->size_bytes / 4); i++) {
ptr[i] = bswap32(out_view->data.as_uint32[i]);
}
break;
}
case 64: {
uint64_t* ptr = (uint64_t*)dst->data;
for (int64_t i = 0; i < (dst->size_bytes / 8); i++) {
ptr[i] = bswap64(out_view->data.as_uint64[i]);
}
break;
}
default:
ArrowErrorSet(error, "Endian swapping for element bitwidth %d is not supported",
(int)src->element_size_bits);
return ENOTSUP;
}
break;
}
ArrowBufferReset(&tmp);
out_view->data.data = dst->data;
return NANOARROW_OK;
}