X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FPacket.hh;h=db371f4e58bd22081c12daf721c0bddd73eccc48;hp=198212c352646984e3a3352a6705a73e0de9c600;hb=de6942ee1401fea16a171610de779ef0a8c57e38;hpb=41f8dd670e963aad94527ce2be0486268993a477 diff --git a/src/Moof/Packet.hh b/src/Moof/Packet.hh index 198212c..db371f4 100644 --- a/src/Moof/Packet.hh +++ b/src/Moof/Packet.hh @@ -9,26 +9,65 @@ * **************************************************************************/ +/** + * \file Packet.hh + * Classes for building and interpreting datagram packets. + */ + #ifndef _MOOF_PACKET_HH_ #define _MOOF_PACKET_HH_ #include +#include #include #include -#include + +#ifndef PAGE_SIZE +#define PAGE_SIZE 4096 +#endif namespace Mf { +/** + * Represents a packet of serialized variables ready for transfer over the + * network. This method is most suitable for representing datagram + * packets, but it may also be useful for seralizing data for persistent + * state storage. The semantics are similar to that of a FIFO queue or + * stream where packets are written and read by inserting and extracting + * variables to and from the packet, although the actual order of the + * variables in the buffer may be different. At any time, a pointer to a + * buffer and the size of the buffer can be retrieved. This class also + * handles endian differences by serializing variables in network byte + * order (big endian). + */ class Packet { public: - Packet(size_t size = 1024); + /** + * Construct a packet with an initial capacity. + * \param capacity Initial capacity of the packet. + */ + explicit Packet(size_t size = PAGE_SIZE); + + /** + * Construct a packet with some bytes from a buffer. The bytes will be + * copied into the packet, so you don't need to keep the original + * buffer. + * \param data The bytes. + * \param size The number of bytes. + */ Packet(const char* data, size_t size); + /** + * Insert a variable into the packet, serializing it. This usually + * increases the size of the packet by the size of the data type. + * \param value The value to insert. + * \return This. + */ Packet& operator<<(bool value); Packet& operator<<(int8_t value); Packet& operator<<(int16_t value); @@ -38,12 +77,24 @@ public: Packet& operator<<(uint16_t value); Packet& operator<<(uint32_t value); Packet& operator<<(uint64_t value); - //Packet& operator<<(float value); - //Packet& operator<<(double value); - //Packet& operator<<(long double value); - + Packet& operator<<(float value); + Packet& operator<<(double value); + + /** + * Write some bytes to the packet. + * \param bytes The bytes. + * \param size The number of bytes. + * return The number of bytes actually written. + */ size_t write(const void* bytes, size_t size); + + /** + * Extract a variable from the packet. This usually decreases the size + * of the packet by the size of the data type. + * \param value Reference to the variable to extract. + * \return This. + */ Packet& operator>>(bool& value); Packet& operator>>(int8_t& value); Packet& operator>>(int16_t& value); @@ -53,83 +104,136 @@ public: Packet& operator>>(uint16_t& value); Packet& operator>>(uint32_t& value); Packet& operator>>(uint64_t& value); - + Packet& operator>>(float& value); + Packet& operator>>(double& value); + + /** + * Read some bytes from the packet. + * \param bytes The buffer to hold the bytes read. + * \param size The size of the read buffer. + * \return The number of bytes actually read. + */ size_t read(void* bytes, size_t size); + /** + * Clear the contents of the packet, setting the size of the packet to + * zero. + */ + void clear(); + + + /** + * Reset the read/write markers to their initial positions, putting the + * packet in the state it was at right after construction. + */ + void reset(); + + + /** + * Get a pointer to an internal structure holding the serialized bytes + * of the packet. + * return The pointer. + */ const char* bytes() const { - return &mBuffer.get()[mR]; + return mBuffer + mR; } + /** + * Get the size of the buffer holding the serialized bytes of the + * packet. + * \return The number of bytes. + */ size_t size() const { return mW - mR; } + // The rest of this stuff is just to implement correct copy semantics. + + Packet(const Packet& copy); + Packet& operator=(const Packet& copy); + ~Packet(); + + private: - boost::shared_array mBuffer; - size_t mSize; + char* mBuffer; + size_t mSize; - size_t mR; - size_t mW; + size_t mR; + size_t mW; + size_t mOriginalW; - size_t mBoolR; - size_t mBoolW; - size_t mBoolNumR; - size_t mBoolNumW; + size_t mBoolR; + size_t mBoolW; + size_t mBoolNumR; + size_t mBoolNumW; }; inline Packet& operator<<(Packet& packet, const char* value) { - uint8_t length = strnlen(value, 255); + uint16_t length = strlen(value); packet << length; - packet.write(value, length); + if (packet.write(value, length) != length) + { + throw std::length_error("out of memory"); + } return packet; } -inline Packet& operator<<(Packet& packet, const std::string& value) +template +inline Packet& operator<<(Packet& packet, const std::basic_string& value) { - packet << (uint8_t)value.length(); - packet.write(value.c_str(), value.length()); + packet << static_cast(value.length()); + size_t numBytes = value.length() * sizeof(T); + if (packet.write(value.data(), numBytes) != numBytes) + { + throw std::length_error("out of memory"); + } return packet; } template -inline Packet& operator<<(Packet& packet, const std::vector& value) +inline Packet& operator>>(Packet& packet, std::basic_string& value) { - packet << (uint8_t)value.size(); - typename std::vector::const_iterator it; - for (it = value.begin(); it != value.end(); ++it) + uint16_t length = 0; + packet >> length; + + T str[length]; + size_t numBytes = length * sizeof(T); + if (packet.read(str, numBytes) != numBytes) { - packet << *it; + throw std::out_of_range("end of packet"); } + value.assign(str, length); return packet; } -inline Packet& operator>>(Packet& packet, std::string& value) +template +inline Packet& operator<<(Packet& packet, const std::vector& value) { - uint8_t length = 0; - packet >> length; - - char str[256]; - size_t charsRead = packet.read(str, length); - value.assign(str, charsRead); + packet << static_cast(value.size()); + typename std::vector::const_iterator it; + for (it = value.begin(); it != value.end(); ++it) + { + packet << *it; + } return packet; } template inline Packet& operator>>(Packet& packet, std::vector& value) { - uint8_t size = 0; + uint16_t size = 0; packet >> size; value.clear(); - for (uint8_t i = 0; i < size; ++i) + for (uint16_t i = 0; i < size; ++i) { T item; packet >> item; @@ -139,7 +243,6 @@ inline Packet& operator>>(Packet& packet, std::vector& value) } - } // namespace Mf #endif // _MOOF_PACKET_HH_