The routines do I/O one byte at a time. This isn't slow as one might think as the underlying system buffering takes care of much of the work. Every single I/O operation is tested for success/failure.
Note: The streams must be opened in std::ios::binary mode to work on some systems (e.g., Windows).
To assist other C++ programmers, here's the source:
Code: Select all
#include <iostream>
// Integer types (natural)
typedef signed int si;
typedef unsigned int ui;
// Integer types (specific lengths required)
typedef signed char si8;
typedef unsigned char ui8;
typedef signed short int si16;
typedef unsigned short int ui16;
typedef signed int si32;
typedef unsigned int ui32;
typedef signed long long int si64;
typedef unsigned long long int ui64;
#define ByteBitsLen 8
bool GetNetUi16(ui16& value, std::istream& istr)
{
bool valid = true;
ui index = 0;
char ch;
value = 0;
while (valid && (index < sizeof(ui16)))
{
istr.read(&ch, 1);
if (istr.fail()) valid = false; else {value = (value << ByteBitsLen) | (ui8) ch; index++;};
};
if (!valid) value = 0;
return valid;
}
bool GetNetUi32(ui32& value, std::istream& istr)
{
bool valid = true;
ui index = 0;
char ch;
value = 0;
while (valid && (index < sizeof(ui32)))
{
istr.read(&ch, 1);
if (istr.fail()) valid = false; else {value = (value << ByteBitsLen) | (ui8) ch; index++;};
};
if (!valid) value = 0;
return valid;
}
bool GetNetUi64(ui64& value, std::istream& istr)
{
bool valid = true;
ui index = 0;
char ch;
value = 0;
while (valid && (index < sizeof(ui64)))
{
istr.read(&ch, 1);
if (istr.fail()) valid = false; else {value = (value << ByteBitsLen) | (ui8) ch; index++;};
};
if (!valid) value = 0;
return valid;
}
bool PutNetUi16(const ui16 value, std::ostream& ostr)
{
bool valid = true;
ui index = 0;
char ch;
while (valid && (index < sizeof(ui16)))
{
ch = (value >> (ByteBitsLen * (sizeof(ui16) - 1 - index))) & 0x00ff;
ostr.write(&ch, 1); if (ostr.fail()) valid = false; else index++;
};
return valid;
}
bool PutNetUi32(const ui32 value, std::ostream& ostr)
{
bool valid = true;
ui index = 0;
char ch;
while (valid && (index < sizeof(ui32)))
{
ch = (value >> (ByteBitsLen * (sizeof(ui32) - 1 - index))) & 0x00ff;
ostr.write(&ch, 1); if (ostr.fail()) valid = false; else index++;
};
return valid;
}
bool PutNetUi64(const ui64 value, std::ostream& ostr)
{
bool valid = true;
ui index = 0;
char ch;
while (valid && (index < sizeof(ui64)))
{
ch = (value >> (ByteBitsLen * (sizeof(ui64) - 1 - index))) & 0x00ff;
ostr.write(&ch, 1); if (ostr.fail()) valid = false; else index++;
};
return valid;
}