Created
March 29, 2012 08:01
-
-
Save dtalley/2234745 to your computer and use it in GitHub Desktop.
Small C++ utility for reading binary data from a byte array
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 "ByteReader.h" | |
using namespace Orionark::Utility; | |
ByteReader::ByteReader(char *data) | |
: data(data), | |
pointer(0) | |
{ | |
if( O32_HOST_ORDER == O32_LITTLE_ENDIAN ) | |
{ | |
endian = LITTLE_ENDIAN; | |
} | |
else if( O32_HOST_ORDER == O32_BIG_ENDIAN ) | |
{ | |
endian = BIG_ENDIAN; | |
} | |
else | |
{ | |
endian = POP_ENDIAN; | |
} | |
} | |
ByteReader::~ByteReader() | |
{ | |
} | |
void ByteReader::SetEndian(ByteEndianness end) | |
{ | |
endian = end; | |
} | |
long unsigned int ByteReader::Tell() | |
{ | |
return pointer; | |
} | |
void ByteReader::Seek(long unsigned int target) | |
{ | |
pointer = target; | |
} | |
char ByteReader::ReadByte() | |
{ | |
return ReadAny<char>(); | |
} | |
float ByteReader::ReadSingle() | |
{ | |
return ReadAny<float>(); | |
} | |
double ByteReader::ReadDouble() | |
{ | |
return ReadAny<double>(); | |
} | |
short ByteReader::ReadInt16() | |
{ | |
return ReadAny<short>(); | |
} | |
unsigned short ByteReader::ReadUInt16() | |
{ | |
return ReadAny<unsigned short>(); | |
} | |
int ByteReader::ReadInt32() | |
{ | |
return ReadAny<int>(); | |
} | |
unsigned int ByteReader::ReadUInt32() | |
{ | |
return ReadAny<unsigned int>(); | |
} | |
long long int ByteReader::ReadInt64() | |
{ | |
return ReadAny<long int>(); | |
} | |
long long unsigned int ByteReader::ReadUInt64() | |
{ | |
return ReadAny<long long unsigned int>(); | |
} | |
std::string ByteReader::ReadString(unsigned int length) | |
{ | |
std::string ret((char*)(data+pointer), length); | |
pointer += length; | |
return ret; | |
} | |
template<class T> T ByteReader::ReadAny() | |
{ | |
T ret; | |
char *dst = (char *)&ret; | |
char *src = (char *)&(data[pointer]); | |
StoreBytes(src,dst,sizeof(T)); | |
pointer += sizeof(T); | |
return ret; | |
} | |
void ByteReader::StoreBytes( | |
char *src, | |
char *dst, | |
size_t size | |
) | |
{ | |
for( size_t i = 0; i < size; i++ ) | |
{ | |
if( O32_HOST_ORDER == O32_LITTLE_ENDIAN ) | |
{ | |
if( endian == LITTLE_ENDIAN ) | |
dst[i] = src[i]; | |
else if( endian == BIG_ENDIAN ) | |
dst[i] = src[(size-i-1)]; | |
else if( endian == POP_ENDIAN ) | |
dst[i] = src[(i%2==0?(size-i-2):(size-i))]; | |
} | |
else if( O32_HOST_ORDER == O32_BIG_ENDIAN ) | |
{ | |
if( endian == BIG_ENDIAN ) | |
dst[i] = src[i]; | |
else if( endian == LITTLE_ENDIAN ) | |
dst[i] = src[(size-i-1)]; | |
else if( endian == POP_ENDIAN ) | |
dst[i] = src[(i%2==0?(i+1):(i-1))]; | |
} | |
else | |
{ | |
if( endian == POP_ENDIAN ) | |
dst[i] = src[i]; | |
else if( endian == LITTLE_ENDIAN ) | |
dst[i] = src[(i%2==0?(size-i-2):(size-i))]; | |
else if( endian == BIG_ENDIAN ) | |
dst[i] = src[(i%2==0?(i+1):(i-1))]; | |
} | |
} | |
} |
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 __ORIONARK_BYTE_READER__ | |
#define __ORIONARK_BYTE_READER__ | |
#include <limits.h> | |
#include <stdint.h> | |
#include <string> | |
#if CHAR_BIT != 8 | |
#error "unsupported char size" | |
#endif | |
enum | |
{ | |
O32_LITTLE_ENDIAN = 0x03020100ul, | |
O32_BIG_ENDIAN = 0x00010203ul, | |
O32_POP_ENDIAN = 001000302ul | |
}; | |
static const union | |
{ | |
unsigned char bytes[4]; | |
uint32_t value; | |
} | |
o32_host_order = { { 0, 1, 2, 3 } }; | |
#define O32_HOST_ORDER (o32_host_order.value) | |
namespace Orionark | |
{ | |
namespace Utility | |
{ | |
enum ByteEndianness | |
{ | |
LITTLE_ENDIAN, | |
BIG_ENDIAN, | |
POP_ENDIAN | |
}; | |
class ByteReader | |
{ | |
public: | |
ByteReader(char*); | |
~ByteReader(); | |
void SetEndian(ByteEndianness); | |
long long unsigned int ReadUInt64(); | |
long long int ReadInt64(); | |
unsigned int ReadUInt32(); | |
int ReadInt32(); | |
unsigned short ReadUInt16(); | |
short ReadInt16(); | |
double ReadDouble(); | |
float ReadSingle(); | |
char ReadByte(); | |
std::string ReadString(unsigned int); | |
void StoreBytes(char *, char *, size_t); | |
long unsigned int Tell(); | |
void Seek(long unsigned int); | |
private: | |
const char *data; | |
ByteEndianness endian; | |
template<class T> T ReadAny(); | |
long unsigned int pointer; | |
}; | |
} | |
} | |
#endif //__ORIONARK_BYTE_READER__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment