// For simplicity, this code assumes that CHAR_BITS is 8
// It is possible to further generalize this code for
// platforms having different CHAR_BITS values.
//
// In any case, the network format must have 8-bit chars,
// 16-bit shorts and 32-bit ints
typedef std::vector<char> Buffer;
class NetBuffer
{
Buffer theBuffer;
size_t theReadCounter;
size_t theWriteCounter;
void reset()
{
theReadCounter = 0;
theWriteCounter = 0;
}
public:
explicit NetBuffer(size_t aSize=0)
: theBuffer(aSize) { reset(); }
NetBuffer(const Buffer &aBuffer) : theBuffer(aBuffer) { reset(); }
NetBuffer(const char *aBuffer, size_t aSize)
: theBuffer(aSize) { reset(); put(aBuffer, aSize); reset(); }
bool get(char *aBuffer, size_t aSize);
void put(const char *aBuffer, size_t aSize);
const Buffer & buffer() const { return theBuffer; }
Buffer & buffer() { return theBuffer; }
size_t size() const { return theBuffer.size(); }
void resize(size_t aSize) { theBuffer.resize(aSize); }
size_t bytesRead() const { return theReadCounter; }
size_t bytesWritten() const { return theWriteCounter; }
};
void NetBuffer::put(const char * aBuffer, size_t aSize)
{
if( theWriteCounter + aSize <= size() )
{
memcpy(&(theBuffer[theWriteCounter]), aBuffer, aSize);
}
theWriteCounter += aSize;
}
bool NetBuffer::get(char * aBuffer, size_t aSize)
{
bool ret = true;
if( theReadCounter + aSize <= size() )
{
memcpy( aBuffer, &(theBuffer[theReadCounter]), aSize);
}
else
{
ret = false;
}
theReadCounter += aSize;
return ret;
}
bool operator==(const NetBuffer & a, const NetBuffer &b)
{
if(a.size() != b.size()) return false;
return memcmp(&(a.buffer()[0]), &(b.buffer()[0]), a.size() )==0;
}
NetBuffer & operator << (NetBuffer &n, int8_t aChar)
{
n.put(reinterpret_cast<char *>(&aChar), 1);
return n;
}
NetBuffer & operator >> (NetBuffer &n, int8_t & aChar)
{
if(!n.get(reinterpret_cast<char *>(&aChar), 1))
aChar = 0;
return n;
}
NetBuffer & operator << (NetBuffer &n, int16_t aShort)
{
int16_t netValue = htons(aShort);
n.put(reinterpret_cast<char *>(&netValue), 2);
return n;
}
NetBuffer & operator >> (NetBuffer &n, int16_t & aShort)
{
aShort = n.get( reinterpret_cast<char *>(&aShort),2)
? ntohs(aShort) : 0;
return n;
}
NetBuffer & operator << (NetBuffer &n, int32_t anInt)
{
int32_t netValue = htonl(anInt);
n.put(reinterpret_cast<char *>(&netValue), 4);
return n;
}
NetBuffer & operator >> (NetBuffer &n, int32_t & anInt)
{
anInt = n.get( reinterpret_cast<char *>(&anInt),4)
? ntohs(anInt) : 0;
return n;
}
NetBuffer & operator << (NetBuffer &n, const Buffer &aBuffer)
{
n.put( &(aBuffer[0]) , aNetBuffer.size() );
return n;
}
NetBuffer & operator >> (NetBuffer &n, NetBuffer &aBuffer)
{
n.get( &(aBuffer[0]) , aNetBuffer.size() );
return n;
}
End of Listing