#ifndef NETWORK_PACKET_HH
#define NETWORK_PACKET_HH
#include "Config.hh"
#include "../Vector.hh"
#include "../Error.hh"
class NetworkPacketError : public Error {
public:
NetworkPacketError (const std::string &message) : Error(message) { }
};
// forward-declare for write_packet
class NetworkPacketBuffer;
/*
* Read-interface for network packets
*/
class NetworkPacketInput {
public:
/*
* Copies len bytes from the packet to ptr, first testing that they exist
*/
virtual void read (void *ptr, size_t len) = 0;
/*
* Convenience function to read() and return the value of the given type
*/
template <typename T> T read_val (void);
// thse handle network-endianlness
uint32_t read_uint32 (void);
uint16_t read_uint16 (void);
uint8_t read_uint8 (void);
int32_t read_int32 (void);
int16_t read_int16 (void);
int8_t read_int8 (void);
float read_float32 (void);
Vector read_vector (void);
};
/*
* Write-interface for network packets
*/
class NetworkPacketOutput {
public:
/*
* Copies len bytes from ptr to the packet, first testing that they fit
*/
virtual void write (const void *ptr, size_t len) = 0;
/*
* Convenience function to write() the value of the given type-value
*/
template <typename T> void write_val (const T &val);
// thse handle network-endianlness
void write_uint32 (uint32_t val);
void write_uint16 (uint16_t val);
void write_uint8 (uint8_t val);
void write_int32 (int32_t val);
void write_int16 (int16_t val);
void write_int8 (int8_t val);
void write_float32 (float val);
void write_vector (const Vector &vec);
/*
* This copies the contents of the given packet into this packet
*/
void write_packet (const NetworkPacketBuffer &pkt);
};
/*
* Implements the in-memory seekable buffer used by NetworkPackets.
*/
class NetworkPacketBuffer : public NetworkPacketInput, public NetworkPacketOutput {
protected:
// the pointer to the buffer
char *buf_ptr;
// the buffer size, the amount of data in the buffer, and the current read/write offset
size_t buf_size, data_size, offset;
/*
* Assert that the given number of bytes fits into the buffer. Throws NetworkPacketError if not.
*
* The default implementation just checks offset and buf_size
*/
virtual void check_write_size (size_t item_size);
/*
* Assert that the give number of bytes is available from the buffer. Throws NetworkPacketError if not
*
* The default implementation just checks offset and data_size
*/
virtual void check_read_size (size_t item_size);
public:
/*
* Construct the NetworkPacketBuffer using the given initial buf_ptr and buf_size
*/
NetworkPacketBuffer (char *buf_ptr, size_t buf_size, size_t data_size);
/*
* These memcpy() into/out of the buf_ptr, using ceck_read/write_size
*/
virtual void read (void *ptr, size_t len);
virtual void write (const void *ptr, size_t len);
/*
* Accessor functions, used by the actual socket code to read/write the buffer
*/
char* get_buf (void) { return buf_ptr; }
const char* get_buf (void) const { return buf_ptr; }
size_t get_data_size (void) const { return data_size; }
size_t get_buf_size (void) const { return buf_size; }
/*
* Used by the socket code after recv() to mark how many bytes of data the buffer has
*/
void set_data_size (size_t size) { offset = 0; data_size = size; }
};
/*
* The common case is a packet that fits in a single UDP packet, so this just uses a static buffer of a fixed size,
* NETWORK_PACKET_SIZE.
*/
class NetworkPacket : public NetworkPacketBuffer {
private:
char _buf[NETWORK_PACKET_SIZE];
public:
NetworkPacket (void);
};
/*
* This is intended for sending bigger packets via TCP; the buffer is allocated on the heap.
*
* XXX: let the buffer grow as well
*/
class BigNetworkPacket : public NetworkPacketBuffer {
public:
BigNetworkPacket (size_t size);
private:
// no copies
BigNetworkPacket (const BigNetworkPacket &pkt);
BigNetworkPacket& operator= (const BigNetworkPacket &pkt);
public:
virtual ~BigNetworkPacket (void);
};
#endif /* NETWORK_PACKET_HH */