optional endianness support
This commit is contained in:
parent
76a7078cef
commit
3bea3097d0
|
@ -28,10 +28,12 @@
|
|||
* @brief bufferstream::bufferstream
|
||||
* @param p
|
||||
* @param l
|
||||
* @param o
|
||||
*/
|
||||
bufferstream::bufferstream(uint8_t * p, std::streamsize l)
|
||||
bufferstream::bufferstream(uint8_t * p, std::streamsize l, byteorder o)
|
||||
: std::basic_streambuf<uint8_t>()
|
||||
, std::basic_iostream<uint8_t>(this)
|
||||
, order_(o)
|
||||
{
|
||||
setg(p, p, p + l);
|
||||
setp(p, p + l);
|
||||
|
|
|
@ -38,7 +38,13 @@ class bufferstream
|
|||
, public std::basic_iostream<uint8_t>
|
||||
{
|
||||
public:
|
||||
bufferstream(uint8_t * p, std::streamsize l);
|
||||
/// @brief The byteorder enum
|
||||
enum byteorder {
|
||||
LittleEndian, //!< Little Endian
|
||||
BigEndian, //!< Big Endian, Network Order
|
||||
};
|
||||
|
||||
bufferstream(uint8_t * p, std::streamsize l, byteorder o = BigEndian);
|
||||
|
||||
// input sequence
|
||||
uint32_t available();
|
||||
|
@ -85,17 +91,33 @@ public:
|
|||
template<typename T>
|
||||
T readType()
|
||||
{
|
||||
if (in_avail() < sizeof(T))
|
||||
setstate(std::ios_base::failbit);
|
||||
if (!good())
|
||||
return 0;
|
||||
T ret = 0;
|
||||
auto data = reinterpret_cast<uint8_t*>(&ret);
|
||||
for (int i = sizeof(T); --i >= 0; )
|
||||
data[i] = get();
|
||||
if (!in_avail())
|
||||
setstate(std::ios_base::eofbit);
|
||||
T ret = 0;
|
||||
int width = sizeof(T);
|
||||
if (in_avail() < width)
|
||||
setstate(std::ios_base::failbit);
|
||||
if (!good())
|
||||
return ret;
|
||||
if (width == 1)
|
||||
{
|
||||
ret = static_cast<T>(get());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto bytes = reinterpret_cast<uint8_t*>(&ret);
|
||||
switch (order_) {
|
||||
case LittleEndian:
|
||||
for (int i = 0; i < width; i++)
|
||||
bytes[i] = get();
|
||||
break;
|
||||
case BigEndian:
|
||||
for (int i = width; --i >= 0;)
|
||||
bytes[i] = get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!in_avail())
|
||||
setstate(std::ios_base::eofbit);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief writeType
|
||||
|
@ -104,10 +126,25 @@ public:
|
|||
template<typename T>
|
||||
void writeType (const T& val)
|
||||
{
|
||||
auto data = reinterpret_cast<const uint8_t*>(&val);
|
||||
for (int i = sizeof(T); --i >= 0; )
|
||||
put(data[i]);
|
||||
if (sizeof(T) == 1) {
|
||||
put(static_cast<uint8_t>(val));
|
||||
return;
|
||||
}
|
||||
auto bytes = reinterpret_cast<const uint8_t*>(&val);
|
||||
switch (order_) {
|
||||
case LittleEndian:
|
||||
for (int i = 0; i < sizeof(T); i++)
|
||||
put(bytes[i]);
|
||||
break;
|
||||
case BigEndian:
|
||||
for (int i = sizeof(T); --i >= 0;)
|
||||
put(bytes[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
byteorder order_;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue