You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
5.2 KiB
C++
211 lines
5.2 KiB
C++
/***************************************************************************
|
|
* Copyright (C) 2009 by gempa GmbH *
|
|
* *
|
|
* All Rights Reserved. *
|
|
* *
|
|
* NOTICE: All information contained herein is, and remains *
|
|
* the property of gempa GmbH and its suppliers, if any. The intellectual *
|
|
* and technical concepts contained herein are proprietary to gempa GmbH *
|
|
* and its suppliers. *
|
|
* Dissemination of this information or reproduction of this material *
|
|
* is strictly forbidden unless prior written permission is obtained *
|
|
* from gempa GmbH. *
|
|
***************************************************************************/
|
|
|
|
|
|
#ifndef GEMPA_CAPS_ENDIANESS_H
|
|
#define GEMPA_CAPS_ENDIANESS_H
|
|
|
|
#include <iostream>
|
|
#include <stdint.h>
|
|
#include <streambuf>
|
|
|
|
|
|
namespace Gempa {
|
|
namespace CAPS {
|
|
namespace Endianess {
|
|
|
|
template <typename T1, typename T2> inline const T1* lvalue(const T2 &value) {
|
|
return reinterpret_cast<const T1*>(&value);
|
|
}
|
|
|
|
template <typename T, int swap, int size>
|
|
struct Swapper {
|
|
static T Take(const T &v) {
|
|
return v;
|
|
}
|
|
|
|
static void Take(T *ar, int len) {}
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
struct Swapper<T,1,2> {
|
|
static T Take(const T &v) {
|
|
return *lvalue<T, uint16_t>((*reinterpret_cast<const uint16_t*>(&v) >> 0x08) |
|
|
(*reinterpret_cast<const uint16_t*>(&v) << 0x08));
|
|
}
|
|
|
|
static void Take(T *ar, int len) {
|
|
for ( int i = 0; i < len; ++i )
|
|
ar[i] = Take(ar[i]);
|
|
}
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
struct Swapper<T,1,4> {
|
|
static T Take(const T &v) {
|
|
return *lvalue<T, uint32_t>(((*reinterpret_cast<const uint32_t*>(&v) << 24) & 0xFF000000) |
|
|
((*reinterpret_cast<const uint32_t*>(&v) << 8) & 0x00FF0000) |
|
|
((*reinterpret_cast<const uint32_t*>(&v) >> 8) & 0x0000FF00) |
|
|
((*reinterpret_cast<const uint32_t*>(&v) >> 24) & 0x000000FF));
|
|
}
|
|
|
|
static void Take(T *ar, int len) {
|
|
for ( int i = 0; i < len; ++i )
|
|
ar[i] = Take(ar[i]);
|
|
}
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
struct Swapper<T,1,8> {
|
|
static T Take(const T &v) {
|
|
return *lvalue<T, uint64_t>(((*reinterpret_cast<const uint64_t*>(&v) << 56) & 0xFF00000000000000LL) |
|
|
((*reinterpret_cast<const uint64_t*>(&v) << 40) & 0x00FF000000000000LL) |
|
|
((*reinterpret_cast<const uint64_t*>(&v) << 24) & 0x0000FF0000000000LL) |
|
|
((*reinterpret_cast<const uint64_t*>(&v) << 8) & 0x000000FF00000000LL) |
|
|
((*reinterpret_cast<const uint64_t*>(&v) >> 8) & 0x00000000FF000000LL) |
|
|
((*reinterpret_cast<const uint64_t*>(&v) >> 24) & 0x0000000000FF0000LL) |
|
|
((*reinterpret_cast<const uint64_t*>(&v) >> 40) & 0x000000000000FF00LL) |
|
|
((*reinterpret_cast<const uint64_t*>(&v) >> 56) & 0x00000000000000FFLL));
|
|
}
|
|
|
|
static void Take(T *ar, int len) {
|
|
for ( int i = 0; i < len; ++i )
|
|
ar[i] = Take(ar[i]);
|
|
}
|
|
};
|
|
|
|
|
|
template <int size>
|
|
struct TypeMap {
|
|
typedef void ValueType;
|
|
};
|
|
|
|
|
|
template <>
|
|
struct TypeMap<1> {
|
|
typedef uint8_t ValueType;
|
|
};
|
|
|
|
|
|
template <>
|
|
struct TypeMap<2> {
|
|
typedef uint16_t ValueType;
|
|
};
|
|
|
|
|
|
template <>
|
|
struct TypeMap<4> {
|
|
typedef uint32_t ValueType;
|
|
};
|
|
|
|
|
|
template <>
|
|
struct TypeMap<8> {
|
|
typedef uint64_t ValueType;
|
|
};
|
|
|
|
|
|
template <int swap, int size>
|
|
struct ByteSwapper {
|
|
static void Take(void *ar, int len) {}
|
|
};
|
|
|
|
|
|
template <int size>
|
|
struct ByteSwapper<1,size> {
|
|
static void Take(void *ar, int len) {
|
|
typedef typename TypeMap<size>::ValueType T;
|
|
Swapper<T,1,size>::Take(reinterpret_cast<T*>(ar), len);
|
|
}
|
|
};
|
|
|
|
|
|
struct Current {
|
|
enum {
|
|
LittleEndian = ((0x1234 >> 8) == 0x12?1:0),
|
|
BigEndian = 1-LittleEndian
|
|
};
|
|
};
|
|
|
|
|
|
struct Converter {
|
|
template <typename T>
|
|
static T ToLittleEndian(const T &v) {
|
|
return Swapper<T,Current::BigEndian,sizeof(T)>::Take(v);
|
|
}
|
|
|
|
template <typename T>
|
|
static void ToLittleEndian(T *data, int len) {
|
|
Swapper<T,Current::BigEndian,sizeof(T)>::Take(data, len);
|
|
}
|
|
|
|
template <typename T>
|
|
static T FromLittleEndian(const T &v) {
|
|
return Swapper<T,Current::BigEndian,sizeof(T)>::Take(v);
|
|
}
|
|
|
|
template <typename T>
|
|
static T ToBigEndian(const T &v) {
|
|
return Swapper<T,Current::LittleEndian,sizeof(T)>::Take(v);
|
|
}
|
|
|
|
template <typename T>
|
|
static T FromBigEndian(const T &v) {
|
|
return Swapper<T,Current::LittleEndian,sizeof(T)>::Take(v);
|
|
}
|
|
};
|
|
|
|
struct Reader {
|
|
Reader(std::streambuf &input) : stream(input), good(true) {}
|
|
|
|
void operator()(void *data, int size) {
|
|
good = stream.sgetn((char*)data, size) == size;
|
|
}
|
|
|
|
template <typename T>
|
|
void operator()(T &v) {
|
|
good = stream.sgetn((char*)&v, sizeof(T)) == sizeof(T);
|
|
v = Converter::FromLittleEndian(v);
|
|
}
|
|
|
|
std::streambuf &stream;
|
|
bool good;
|
|
};
|
|
|
|
struct Writer {
|
|
Writer(std::streambuf &output) : stream(output), good(true) {}
|
|
|
|
bool operator()(const void *data, int size) {
|
|
return (good = stream.sputn((char*)data, size) == size);
|
|
}
|
|
|
|
template <typename T>
|
|
bool operator()(T &v) {
|
|
T tmp = Converter::ToLittleEndian(v);
|
|
return (good = stream.sputn((char*)&tmp, sizeof(T)) == sizeof(T));
|
|
}
|
|
|
|
std::streambuf &stream;
|
|
bool good;
|
|
};
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|