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
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 CPP file for the class:

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 */
Here is the header file for types:

LTypes.h

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 */
and finally here is the testing code:

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;

}
Expected output should be like so:
Code:
String - This is a string!
String - This had better.
char   - h
char*  - C-Style strings!
char   - i
u32    - 1024
u16    - 256
Instead I get:
Code:
String - This is a string!
String - This had better.
char   - h
char*  - C-Style strings!
char   - 
u32    - 0
u16    - 0
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.

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.