]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Packet.hh
constructors should be explicit
[chaz/yoink] / src / Moof / Packet.hh
index 198212c352646984e3a3352a6705a73e0de9c600..db371f4e58bd22081c12daf721c0bddd73eccc48 100644 (file)
@@ -9,26 +9,65 @@
 *
 **************************************************************************/
 
+/**
+ * \file Packet.hh
+ * Classes for building and interpreting datagram packets.
+ */
+
 #ifndef _MOOF_PACKET_HH_
 #define _MOOF_PACKET_HH_
 
 #include <cstring>
+#include <stdexcept>
 #include <string>
 #include <vector>
 
-#include <boost/shared_array.hpp>
+
+#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<char>       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 <class T>
+inline Packet& operator<<(Packet& packet, const std::basic_string<T>& value)
 {
-       packet << (uint8_t)value.length();
-       packet.write(value.c_str(), value.length());
+       packet << static_cast<uint16_t>(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 <class T>
-inline Packet& operator<<(Packet& packet, const std::vector<T>& value)
+inline Packet& operator>>(Packet& packet, std::basic_string<T>& value)
 {
-       packet << (uint8_t)value.size();
-       typename std::vector<T>::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 <class T>
+inline Packet& operator<<(Packet& packet, const std::vector<T>& value)
 {
-       uint8_t length = 0;
-       packet >> length;
-
-       char str[256];
-       size_t charsRead = packet.read(str, length);
-       value.assign(str, charsRead);
+       packet << static_cast<uint16_t>(value.size());
+       typename std::vector<T>::const_iterator it;
+       for (it = value.begin(); it != value.end(); ++it)
+       {
+               packet << *it;
+       }
        return packet;
 }
 
 template <class T>
 inline Packet& operator>>(Packet& packet, std::vector<T>& 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<T>& value)
 }
 
 
-
 } // namespace Mf
 
 #endif // _MOOF_PACKET_HH_
This page took 0.025605 seconds and 4 git commands to generate.