blob: 7818ca2191b9660edf63a8216bcac68238dbf31e [file] [log] [blame]
#include "byte_order.h"
#include <string.h>
#if defined(_MSC_VER)
#include <stdlib.h>
#endif
static inline void swapBytes16(void *ptr)
{
uint16_t output;
memcpy(&output, ptr, sizeof(uint16_t));
#if defined(_MSC_VER) && !defined(_DEBUG)
output = _byteswap_ushort(output);
#elif defined(__llvm__) || defined(__GNUC__) && !defined(__ICC)
output = __builtin_bswap16(output);
#else
uint16_t Hi = output >> 8;
uint16_t Lo = output << 8;
output = Hi | Lo;
#endif
memcpy(ptr, &output, sizeof(uint16_t));
}
static inline void swapBytes32(void *ptr)
{
uint32_t output;
memcpy(&output, ptr, sizeof(uint32_t));
#if defined(_MSC_VER) && !defined(_DEBUG)
output = _byteswap_ulong(output);
#elif defined(__llvm__) || defined(__GNUC__) && !defined(__ICC)
output = __builtin_bswap32(output);
#else
uint32_t Byte0 = output & 0x000000FF;
uint32_t Byte1 = output & 0x0000FF00;
uint32_t Byte2 = output & 0x00FF0000;
uint32_t Byte3 = output & 0xFF000000;
output = (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
#endif
memcpy(ptr, &output, sizeof(uint32_t));
}
static inline void swapBytes64(void *ptr)
{
uint64_t output;
memcpy(&output, ptr, sizeof(uint64_t));
#if defined(_MSC_VER) && !defined(_DEBUG)
output = _byteswap_uint64(output);
#elif defined(__llvm__) || defined(__GNUC__) && !defined(__ICC)
output = __builtin_bswap64(output);
#else
uint64_t Hi = SwapByteOrder_32(uint32_t(value));
uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
return (Hi << 32) | Lo;
#endif
memcpy(ptr, &output, sizeof(uint64_t));
}
static inline uint16_t decodeUInt16LE(const uint8_t *data) {
uint16_t output;
memcpy(&output, data, sizeof(uint16_t));
return output;
}
static inline uint16_t decodeUInt16BE(const uint8_t *data) {
uint16_t output = decodeUInt16LE(data);
swapBytes16(&output);
return output;
}
static inline uint32_t decodeUInt32LE(const uint8_t *data) {
uint32_t output;
memcpy(&output, data, sizeof(uint32_t));
return output;
}
static inline uint32_t decodeUInt32BE(const uint8_t *data) {
uint32_t output = decodeUInt32LE(data);
swapBytes32(&output);
return output;
}
static inline uint64_t decodeUInt64LE(const uint8_t *data) {
uint64_t output;
memcpy(&output, data, sizeof(uint64_t));
return output;
}
static inline uint64_t decodeUInt64BE(const uint8_t *data) {
uint64_t output = decodeUInt64LE(data);
swapBytes64(&output);
return output;
}
THPByteOrder THP_nativeByteOrder()
{
uint32_t x = 1;
return *(uint8_t*)&x ? THP_LITTLE_ENDIAN : THP_BIG_ENDIAN;
}
void THP_decodeInt16Buffer(int16_t* dst, const uint8_t* src, THPByteOrder order, size_t len)
{
for (size_t i = 0; i < len; i++) {
dst[i] = (int16_t) (order == THP_BIG_ENDIAN ? decodeUInt16BE(src) : decodeUInt16LE(src));
src += sizeof(int16_t);
}
}
void THP_decodeInt32Buffer(int32_t* dst, const uint8_t* src, THPByteOrder order, size_t len)
{
for (size_t i = 0; i < len; i++) {
dst[i] = (int32_t) (order == THP_BIG_ENDIAN ? decodeUInt32BE(src) : decodeUInt32LE(src));
src += sizeof(int32_t);
}
}
void THP_decodeInt64Buffer(int64_t* dst, const uint8_t* src, THPByteOrder order, size_t len)
{
for (size_t i = 0; i < len; i++) {
dst[i] = (int64_t) (order == THP_BIG_ENDIAN ? decodeUInt64BE(src) : decodeUInt64LE(src));
src += sizeof(int64_t);
}
}
void THP_decodeHalfBuffer(THHalf* dst, const uint8_t* src, THPByteOrder order, size_t len)
{
for (size_t i = 0; i < len; i++) {
union { uint16_t x; THHalf f; };
x = (order == THP_BIG_ENDIAN ? decodeUInt16BE(src) : decodeUInt16LE(src));
dst[i] = f;
src += sizeof(uint16_t);
}
}
void THP_decodeFloatBuffer(float* dst, const uint8_t* src, THPByteOrder order, size_t len)
{
for (size_t i = 0; i < len; i++) {
union { uint32_t x; float f; };
x = (order == THP_BIG_ENDIAN ? decodeUInt32BE(src) : decodeUInt32LE(src));
dst[i] = f;
src += sizeof(float);
}
}
void THP_decodeDoubleBuffer(double* dst, const uint8_t* src, THPByteOrder order, size_t len)
{
for (size_t i = 0; i < len; i++) {
union { uint64_t x; double d; };
x = (order == THP_BIG_ENDIAN ? decodeUInt64BE(src) : decodeUInt64LE(src));
dst[i] = d;
src += sizeof(double);
}
}
void THP_encodeInt16Buffer(uint8_t* dst, const int16_t* src, THPByteOrder order, size_t len)
{
memcpy(dst, src, sizeof(int16_t) * len);
if (order != THP_nativeByteOrder()) {
for (size_t i = 0; i < len; i++) {
swapBytes16(dst);
dst += sizeof(int16_t);
}
}
}
void THP_encodeInt32Buffer(uint8_t* dst, const int32_t* src, THPByteOrder order, size_t len)
{
memcpy(dst, src, sizeof(int32_t) * len);
if (order != THP_nativeByteOrder()) {
for (size_t i = 0; i < len; i++) {
swapBytes32(dst);
dst += sizeof(int32_t);
}
}
}
void THP_encodeInt64Buffer(uint8_t* dst, const int64_t* src, THPByteOrder order, size_t len)
{
memcpy(dst, src, sizeof(int64_t) * len);
if (order != THP_nativeByteOrder()) {
for (size_t i = 0; i < len; i++) {
swapBytes64(dst);
dst += sizeof(int64_t);
}
}
}
void THP_encodeFloatBuffer(uint8_t* dst, const float* src, THPByteOrder order, size_t len)
{
memcpy(dst, src, sizeof(float) * len);
if (order != THP_nativeByteOrder()) {
for (size_t i = 0; i < len; i++) {
swapBytes32(dst);
dst += sizeof(float);
}
}
}
void THP_encodeDoubleBuffer(uint8_t* dst, const double* src, THPByteOrder order, size_t len)
{
memcpy(dst, src, sizeof(double) * len);
if (order != THP_nativeByteOrder()) {
for (size_t i = 0; i < len; i++) {
swapBytes64(dst);
dst += sizeof(double);
}
}
}