+++ /dev/null
-
-/*] Copyright (c) 2009-2010, Charles McGarvey [**************************
-**] All rights reserved.
-*
-* vi:ts=4 sw=4 tw=75
-*
-* Distributable under the terms and conditions of the 2-clause BSD license;
-* see the file COPYING for a complete text of the license.
-*
-**************************************************************************/
-
-/**
- * \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>
-
-
-#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:
-
- /**
- * 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);
- Packet& operator<<(int32_t value);
- Packet& operator<<(int64_t value);
- Packet& operator<<(uint8_t value);
- Packet& operator<<(uint16_t value);
- Packet& operator<<(uint32_t value);
- Packet& operator<<(uint64_t 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);
- Packet& operator>>(int32_t& value);
- Packet& operator>>(int64_t& value);
- Packet& operator>>(uint8_t& value);
- 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 + 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:
-
- char* mBuffer;
- size_t mSize;
-
- size_t mR;
- size_t mW;
- size_t mOriginalW;
-
- size_t mBoolR;
- size_t mBoolW;
- size_t mBoolNumR;
- size_t mBoolNumW;
-};
-
-
-inline Packet& operator<<(Packet& packet, const char* value)
-{
- uint16_t length = strlen(value);
- packet << length;
- if (packet.write(value, length) != length)
- {
- throw std::length_error("out of memory");
- }
- return packet;
-}
-
-template <class T>
-inline Packet& operator<<(Packet& packet, const std::basic_string<T>& value)
-{
- 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, std::basic_string<T>& value)
-{
- uint16_t length = 0;
- packet >> length;
-
- T str[length];
- size_t numBytes = length * sizeof(T);
- if (packet.read(str, numBytes) != numBytes)
- {
- throw std::out_of_range("end of packet");
- }
- value.assign(str, length);
- return packet;
-}
-
-
-template <class T>
-inline Packet& operator<<(Packet& packet, const std::vector<T>& value)
-{
- 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)
-{
- uint16_t size = 0;
- packet >> size;
-
- value.clear();
- for (uint16_t i = 0; i < size; ++i)
- {
- T item;
- packet >> item;
- value.push_back(item);
- }
- return packet;
-}
-
-
-} // namespace Mf
-
-#endif // _MOOF_PACKET_HH_
-