1
0
Fork 0

optional endianness support

This commit is contained in:
Kevin Matz 2023-04-03 15:39:42 -04:00
parent 76a7078cef
commit 3bea3097d0
2 changed files with 54 additions and 15 deletions

View File

@ -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);

View File

@ -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_;
};