Skip to content

Instantly share code, notes, and snippets.

@Jookia
Created February 6, 2011 02:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jookia/813050 to your computer and use it in GitHub Desktop.
Save Jookia/813050 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <cassert>
#include "endian.hpp"
int main(void)
{
assert(flipEndian(long(0x123456789ABCDEF)) == long(0xEFCDAB8967452301));
assert(flipEndian(int(0x12345678)) == int(0x78563412));
assert(flipEndian(short(0x1234)) == short(0x3412));
assert(flipEndian(char(0x12)) == char(0x12));
assert(flipEndian(long(0x123456789000000)) == long(0x0000008967452301));
assert(flipEndian(int(0x12340000)) == int(0x00003412));
assert(flipEndian(short(0x1200)) == short(0x0012));
assert(flipEndian(char(0x10)) == char(0x10));
assert(flipEndian(long(0x000000123456789)) == long(0x0000008967452301));
assert(flipEndian(int(0x00001234)) == int(0x00003412));
assert(flipEndian(short(0x0012)) == short(0x0012));
assert(flipEndian(char(0x01)) == char(0x01));
if(isLittleEndianSystem())
{
assert(bigEndian(short(0x1234)) == short(0x3412));
assert(littleEndian(short(0x1234)) == short(0x1234));
}
else
{
assert(littleEndian(short(0x1234)) == short(0x3412));
assert(bigEndian(short(0x1234)) == short(0x1234));
}
return 0;
}
#ifndef ENDIAN_HPP
#define ENDIAN_HPP
// A union to extract individual bytes from a type.
template <typename T>
union byteSplitter
{
T number;
unsigned char byte[sizeof(T)];
};
// A simple endian flipper.
template <typename T>
T flipEndian(T data)
{
// split will be used to get the individual byte.
// fixed will be used to piece them back together in the opposite endian.
byteSplitter<T> split = {data};
byteSplitter<T> fixed = {0};
// Offset is used to signal where to start reading the bytes.
// (0x1234 == 0x00001234, 0x34210000 is not the proper result.)
int offset = -1;
const size_t bytes = (sizeof(T) - 1);
for(unsigned int i = 0; i <= bytes; ++i)
{
unsigned char byte = split.byte[bytes - i];
if(offset != -1)
{
fixed.byte[i - offset] = byte;
}
else if(byte != 0x00)
{
offset = i;
--i; // Found the offset, now go back so the byte won't be missed.
}
}
return fixed.number;
}
// Returns if a system uses little endian or not.
inline bool isLittleEndianSystem(void)
{
static int test = 0x01;
static unsigned char* testAddress = (unsigned char*)&test;
return (*testAddress == 0x01);
}
// Returns the little endian version of a number.
template <typename T>
inline T littleEndian(T data)
{
if(isLittleEndianSystem())
{
return data;
}
else
{
return flipEndian(data);
}
}
// Returns the big endian version of a number.
template <typename T>
inline T bigEndian(T data)
{
if(isLittleEndianSystem())
{
return flipEndian(data);
}
else
{
return data;
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment