*
**************************************************************************/
+#ifndef _MOOF_PACKET_HH_
+#define _MOOF_PACKET_HH_
+
/**
- * \file Packet.hh
+ * \file packet.hh
* Classes for building and interpreting datagram packets.
*/
-#ifndef _MOOF_PACKET_HH_
-#define _MOOF_PACKET_HH_
-
#include <cstring>
#include <stdexcept>
#include <string>
#endif
-namespace Mf {
+namespace moof {
/**
* handles endian differences by serializing variables in network byte
* order (big endian).
*/
-class Packet
+class packet
{
public:
* Construct a packet with an initial capacity.
* \param capacity Initial capacity of the packet.
*/
- explicit Packet(size_t size = PAGE_SIZE);
+ explicit packet(size_t size = PAGE_SIZE);
/**
* Construct a packet with some bytes from a buffer. The bytes will be
* \param data The bytes.
* \param size The number of bytes.
*/
- Packet(const char* data, size_t size);
+ packet(const char* data, size_t size);
/**
* Insert a variable into the packet, serializing it. This usually
* \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);
+ 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 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);
+ 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.
/**
- * Reset the read/write markers to their initial positions, putting the
- * packet in the state it was at right after construction.
+ * Save the current state internally, allowing it to be reverted to
+ * later using revert().
*/
- void reset();
+ void save();
+
+ /**
+ * Revert the packet to a previously saved state, or to that state
+ * immediately after construction if none other state has been
+ * explicitly saved using save().
+ */
+ void revert();
/**
*/
const char* bytes() const
{
- return mBuffer + mR;
+ return buffer_ + state_.read_mark;
}
/**
*/
size_t size() const
{
- return mW - mR;
+ return state_.write_mark - state_.read_mark;
}
// The rest of this stuff is just to implement correct copy semantics.
- Packet(const Packet& copy);
- Packet& operator=(const Packet& copy);
- ~Packet();
+ packet(const packet& copy);
+ packet& operator = (const packet& copy);
+ ~packet();
private:
- char* mBuffer;
- size_t mSize;
+ char* buffer_;
+ size_t size_;
- size_t mR;
- size_t mW;
- size_t mOriginalW;
-
- size_t mBoolR;
- size_t mBoolW;
- size_t mBoolNumR;
- size_t mBoolNumW;
+ struct state
+ {
+ size_t read_mark;
+ size_t read_bool_mark;
+ size_t read_bool_num;
+ size_t write_mark;
+ size_t write_bool_mark;
+ size_t write_bool_num;
+
+ state(size_t size = 0) :
+ read_mark(0),
+ read_bool_mark(0),
+ read_bool_num(0),
+ write_mark(size),
+ write_bool_mark(0),
+ write_bool_num(0) {}
+ };
+
+ state state_;
+ state saved_;
};
-inline Packet& operator<<(Packet& packet, const char* value)
+template <class T>
+inline packet& operator << (packet& packet, const T& value)
+{
+ value.pack(packet);
+ return packet;
+}
+
+template <class T>
+inline packet& operator >> (packet& packet, T& value)
+{
+ value.unpack(packet);
+ return packet;
+}
+
+
+inline packet& operator << (packet& packet, const char* value)
{
uint16_t length = strlen(value);
packet << length;
}
template <class T>
-inline Packet& operator<<(Packet& packet, const std::basic_string<T>& value)
+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)
+ size_t num_bytes = value.length() * sizeof(T);
+ if (packet.write(value.data(), num_bytes) != num_bytes)
{
throw std::length_error("out of memory");
}
}
template <class T>
-inline Packet& operator>>(Packet& packet, std::basic_string<T>& value)
+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)
+ size_t num_bytes = length * sizeof(T);
+ if (packet.read(str, num_bytes) != num_bytes)
{
throw std::out_of_range("end of packet");
}
template <class T>
-inline Packet& operator<<(Packet& packet, const std::vector<T>& value)
+inline packet& operator << (packet& packet, const std::vector<T>& value)
{
packet << static_cast<uint16_t>(value.size());
typename std::vector<T>::const_iterator it;
}
template <class T>
-inline Packet& operator>>(Packet& packet, std::vector<T>& value)
+inline packet& operator >> (packet& packet, std::vector<T>& value)
{
uint16_t size = 0;
packet >> size;
}
-} // namespace Mf
+} // namespace moof
#endif // _MOOF_PACKET_HH_