Created
February 6, 2011 02:35
-
-
Save Jookia/813050 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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