I've been wanting to start a little side project which would be a small networking wrapper around enet. To get started I worked on creating this Packet class which would wrap all the data sent and received providing easy methods to add and retrieve the data. I did get the class working with char, c-strings, and std::strings but after trying to add support for integer types it hasn't worked so well. The class is based on code code from irrNetLite but I was trying to do it without the dependencies on the irrlicht types such as irr::array.
Here is the header file for the class:
LPacket.h
Here is the CPP file for the class:Code:// BEGIN Includes #include "LTypes.h" #include <string> #include <vector> // END Includes #ifndef LPACKET_H #define LPACKET_H class LPacket { public: LPacket(); LPacket(const char* buff, const unsigned int buffSize); // Methods to append data to the packet LPacket& operator << (c8 data); LPacket& operator << (u8 data); LPacket& operator << (u16 data); LPacket& operator << (u32 data); LPacket& operator << (s8 data); LPacket& operator << (s16 data); LPacket& operator << (s32 data); LPacket& operator << (f32 data); LPacket& operator << (f64 data); LPacket& operator << (c8* data); LPacket& operator << (std::string& data); LPacket& operator << (LPacket& data); // Methods to retrieve data from the packet void operator >> (c8& data); void operator >> (u8& data); void operator >> (u16& data); void operator >> (u32& data); void operator >> (s8& data); void operator >> (s16& data); void operator >> (s32& data); void operator >> (f32& data); void operator >> (f64& data); void operator >> (c8* data); void operator >> (std::string& data); /** * Retrieve that packet's data. * * @return char* */ c8* getData(); /** * Retrieve that packet's data. * * @return const char* */ const c8* getConstData(); /** * Reset the internal read position. */ void resetPos(); /** * Clear the packet contents. */ void clearData(); /** * Retrieve the size in bytes of the packet. * * @return unsigned int */ u32 getSize(); private: /** * Position in packet. * * @var unsigned */ u32 pos; /** * Packet contents. * * @var std::vector<char> */ std::vector<u8> buffer; }; #endif /* LPACKET_H */
Here is the header file for types:Code:// BEGIN Includes #include "LPacket.h" #include <memory.h> #include <stdio.h> #include <iostream> // END Includes #ifndef LPACKET_CPP #define LPACKET_CPP /** * Default constructor. */ LPacket::LPacket() { this->pos = 0; } /** * Contructor. * * @param const char* buff Intial buffer contents. * @param const unsigned int buffSize Inital buffer size. */ LPacket::LPacket(const char* buff, const unsigned int buffSize) { // @TODO: Implement this->pos = 0; } /** * Operator method to append data. */ LPacket& LPacket::operator << (c8 data) { // Append data std::copy(&data, &data + 1, std::back_inserter(this->buffer)); return *this; } /** * Operator method to append data. */ LPacket& LPacket::operator << (u8 data) { // Append data std::copy(&data, &data + 1, std::back_inserter(this->buffer)); return *this; } /** * Operator method to append data. */ LPacket& LPacket::operator << (u16 data) { // Append data std::copy(&data, &data + 2, std::back_inserter(this->buffer)); return *this; } /** * Operator method to append data. */ LPacket& LPacket::operator << (u32 data) { // Append data std::copy(&data, &data + 4, std::back_inserter(this->buffer)); return *this; } /** * Operator method to append data. */ LPacket& LPacket::operator << (s8 data) { // Append data std::copy(&data, &data + 1, std::back_inserter(this->buffer)); return *this; } /** * Operator method to append data. */ LPacket& LPacket::operator << (s16 data) { // Append data std::copy(&data, &data + 2, std::back_inserter(this->buffer)); return *this; } /** * Operator method to append data. */ LPacket& LPacket::operator << (s32 data) { // Append data std::copy(&data, &data + 4, std::back_inserter(this->buffer)); return *this; } /** * Operator method to append data. */ LPacket& LPacket::operator << (f32 data) { // Append data std::copy(&data, &data + 4, std::back_inserter(this->buffer)); return *this; } /** * Operator method to append data. */ LPacket& LPacket::operator << (f64 data) { // Append data std::copy(&data, &data + 8, std::back_inserter(this->buffer)); return *this; } /** * Operator method to append data. */ LPacket& LPacket::operator << (c8* data) { unsigned short dataSize = (unsigned short)strlen(data) + 1; // Append data size std::copy(&dataSize, &dataSize + 2, std::back_inserter(this->buffer)); // Append data std::copy(&data[0], &data[0] + dataSize, std::back_inserter(this->buffer)); return *this; } /** * Operator method to append data. */ LPacket& LPacket::operator << (std::string& data) { unsigned short dataSize = (unsigned short)data.size(); // Append data size std::copy(&dataSize, &dataSize + 2, std::back_inserter(this->buffer)); // Append data std::copy(&data[0], &data[0] + dataSize, std::back_inserter(this->buffer)); return *this; } /** * Operator method to append data. */ LPacket& LPacket::operator << (LPacket& data) { // Append packet std::copy(data.getData(), data.getData() + data.getSize(), std::back_inserter(this->buffer)); return *this; } /** * Operator method to retrieve data. */ void LPacket::operator >> (c8& data) { // Retrieve data std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + 1, &data); pos++; } /** * Operator method to retrieve data. */ void LPacket::operator >> (u8& data) { // Retrieve data std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + 1, &data); pos++; } /** * Operator method to retrieve data. */ void LPacket::operator >> (u16& data) { // Retrieve data std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + 2, &data); pos += 2; } /** * Operator method to retrieve data. */ void LPacket::operator >> (u32& data) { // Retrieve data std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + 4, &data); pos += 4; } /** * Operator method to retrieve data. */ void LPacket::operator >> (s8& data) { // Retrieve data std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + 1, &data); pos++; } /** * Operator method to retrieve data. */ void LPacket::operator >> (s16& data) { // Retrieve data std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + 2, &data); pos += 2; } /** * Operator method to retrieve data. */ void LPacket::operator >> (s32& data) { // Retrieve data std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + 4, &data); pos += 4; } /** * Operator method to retrieve data. */ void LPacket::operator >> (f32& data) { // Retrieve data std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + 4, &data); pos += 4; } /** * Operator method to retrieve data. */ void LPacket::operator >> (f64& data) { // Retrieve data std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + 8, &data); pos += 8; } /** * Operator method to retrieve data. */ void LPacket::operator >> (c8* data) { // Retrieve data size unsigned short size; std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + 2, &size); pos += 2; // Retrieve data std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + size, data); pos += size; data[size] = '\0'; } /** * Operator method to retrieve data. */ void LPacket::operator >> (std::string &data) { // Retrieve data size unsigned short size; std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + 2, &size); pos += 2; // Retrieve data std::copy(&this->buffer[0] + pos, &this->buffer[0] + pos + size, std::back_inserter(data)); pos += size; data.append("\0"); } /** * Retrieve that packet's data. * * @return char* */ c8* LPacket::getData() { return (c8*)&this->buffer[0]; } /** * Retrieve that packet's data. * * @return const char* */ const c8* LPacket::getConstData() { return (const c8*)&this->buffer[0]; } /** * Reset the internal read position. */ void LPacket::resetPos() { pos = 0; } /** * Clear the packet contents. */ void LPacket::clearData() { this->buffer.clear(); } /** * Retrieve the size in bytes of the packet. * * @return unsigned int */ u32 LPacket::getSize() { return this->buffer.size(); } #endif /* LPACKET_CPP */
LTypes.h
and finally here is the testing code:Code:// BEGIN Includes // END Includes #ifndef LTYPES_H #define LTYPES_H /** * 8 bit unsigned variable. */ typedef unsigned char u8; /** * 8 bit signed variable. */ typedef signed char s8; /** * 8 bit character variable. */ typedef char c8; /** * 16 bit signed variable. */ typedef unsigned short u16; /** * 16 bit signed variable. */ typedef signed short s16; /** * 32 bit unsigned variable. */ typedef unsigned int u32; /** * 32 bit signed variable. */ typedef signed int s32; /** * 32 bit signed variable. * * Unused and supposedly only supported by Microsoft compilers, thus commented out. */ //typedef __int64 s64; /** * 32 bit floating point variable. */ typedef float f32; /** * 64 bit floating point variable. */ typedef double f64; #endif /* LTYPES_H */
Expected output should be like so:Code:#include "LPacket.h" #include <stdio.h> #include <iostream> #include <string> #include <memory.h> int main(int argc, char **argv) { // Declare our packet object LPacket packet; // Prepare some data to add to the packet std::string s1 = "This is a string!"; std::string s2 = "This had better."; char cS[21] = "C-Style strings!"; c8 c = 'i'; u32 i1 = 1024; u16 i2 = 256; // Add the data to the packet packet << s1 << s2 << 'h'; packet << cS; packet << c; packet << i1; packet << i2; /// std::string rS1, rS2; char rC1; char rCS[21]; c8 rC2; u32 rI1; u16 rI2; // Get the data from the packet packet >> rS1; packet >> rS2; packet >> rC1; packet >> rCS; packet >> rC2; packet >> rI1; packet >> rI2; // Output the recieved data std::cout << "String - " << rS1 << std::endl; std::cout << "String - " << rS2 << std::endl; std::cout << "char - " << rC1 << std::endl; std::cout << "char* - " << rCS << std::endl; std::cout << "char - " << rC2 << std::endl; std::cout << "u32 - " << rI1 << std::endl; std::cout << "u16 - " << rI2 << std::endl; return 0; }
Instead I get:Code:String - This is a string! String - This had better. char - h char* - C-Style strings! char - i u32 - 1024 u16 - 256
An interesting thing I noticed when I tried to use GDB to debug (never really used it before though) was that initially the call to packet >> rC2; would work correctly and set rC2 to 'i', but after the call to packet >> rI1; or packet >> rI2; it would somehow change into some "garbage" value. I'm quite confused as to why that would happen.Code:String - This is a string! String - This had better. char - h char* - C-Style strings! char - u32 - 0 u16 - 0
I also compiled with: gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)
Thus, if anyone could assist me with this I would be utterly grateful,
thanks in advance.



LinkBack URL
About LinkBacks


