+++ /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.
-*
-**************************************************************************/
-
-#include "../config.h"
-
-#include <algorithm>
-#if HAVE_BYTESWAP_H
-#include <byteswap.h>
-#endif
-#include <cstdlib>
-
-#if HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#include <SDL/SDL.h>
-
-#include "Packet.hh"
-
-
-#ifndef bswap_16
-#define bswap_16(x) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
-#endif
-
-#ifndef bswap_32
-#define bswap_32(x) ((((x) & 0xff000000) >> 24) | \
- (((x) & 0x00ff0000) >> 8) | \
- (((x) & 0x0000ff00) << 8) | \
- (((x) & 0x000000ff) << 24))
-#endif
-
-#ifndef bswap_64
-#define bswap_64(x) (((x) << 56) | \
- (((x) << 40) & 0xff000000000000ULL) | \
- (((x) << 24) & 0xff0000000000ULL) | \
- (((x) << 8) & 0xff00000000ULL) | \
- (((x) >> 8) & 0xff000000ULL) | \
- (((x) >> 24) & 0xff0000ULL) | \
- (((x) >> 40) & 0xff00ULL) | \
- ((x) >> 56))
-#endif
-
-
-#if !HAVE_ARPA_INET_H
-static uint16_t htons(uint16_t x)
-{
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN
- return bswap_16(x);
-#else
- return x;
-#endif
-}
-static uint16_t ntohs(uint16_t x)
-{
- return htons(x);
-}
-
-static uint32_t htonl(uint32_t x)
-{
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN
- return bswap_32(x);
-#else
- return x;
-#endif
-}
-static uint32_t ntohl(uint32_t x)
-{
- return htonl(x);
-}
-#endif
-
-
-static uint64_t htonll(uint64_t x)
-{
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN
- return bswap_64(x);
-#else
- return x;
-#endif
-}
-static uint64_t ntohll(uint64_t x)
-{
- return htonll(x);
-}
-
-
-namespace Mf {
-
-
-Packet::Packet(size_t capacity) :
- mBuffer((char*)malloc(capacity)),
- mSize(capacity),
- mR(0),
- mW(0),
- mOriginalW(0),
- mBoolR(0),
- mBoolW(0),
- mBoolNumR(0),
- mBoolNumW(0) {}
-
-Packet::Packet(const char* data, size_t size) :
- mBuffer((char*)malloc(size)),
- mSize(size),
- mR(0),
- mW(size),
- mOriginalW(size),
- mBoolR(0),
- mBoolW(0),
- mBoolNumR(0),
- mBoolNumW(0)
-{
- if (mBuffer) memcpy(mBuffer, data, size);
-}
-
-
-Packet::Packet(const Packet& copy) :
- mBuffer((char*)malloc(copy.mSize)),
- mSize(copy.mSize),
- mR(copy.mR),
- mW(copy.mW),
- mOriginalW(copy.mOriginalW),
- mBoolR(copy.mBoolR),
- mBoolW(copy.mBoolW),
- mBoolNumR(copy.mBoolNumR),
- mBoolNumW(copy.mBoolNumW)
-{
- if (mBuffer) memcpy(mBuffer, copy.mBuffer, mSize);
-}
-
-Packet& Packet::operator=(const Packet& copy)
-{
- free(mBuffer);
-
- mBuffer = (char*)malloc(copy.mSize);
- mSize = copy.mSize;
- mR = copy.mR;
- mW = copy.mW;
- mOriginalW = copy.mOriginalW;
- mBoolR = copy.mBoolR;
- mBoolW = copy.mBoolW;
- mBoolNumR = copy.mBoolNumR;
- mBoolNumW = copy.mBoolNumW;
- if (mBuffer) memcpy(mBuffer, copy.mBuffer, mSize);
- return *this;
-}
-
-
-Packet::~Packet()
-{
- free(mBuffer);
-}
-
-
-bool Packet::put(bool value)
-{
- int bit = mBoolNumW % 8;
- if (bit == 0)
- {
- mBoolW = mW;
-
- unsigned char byte = 0;
- if (write(&byte, 1) == 0) return false;
- }
-
- if (value) mBuffer[mBoolW] |= (1 << bit);
- ++mBoolNumW;
- return true;
-}
-
-
-bool Packet::put(int8_t value)
-{
- return put(uint8_t(value));
-}
-
-bool Packet::put(int16_t value)
-{
- return put(uint16_t(value));
-}
-
-bool Packet::put(int32_t value)
-{
- return put(uint32_t(value));
-}
-
-bool Packet::put(int64_t value)
-{
- return put(uint64_t(value));
-}
-
-
-bool Packet::put(uint8_t value)
-{
- return write(&value, sizeof(value)) == sizeof(value);
-}
-
-bool Packet::put(uint16_t value)
-{
- value = htons(value);
- return write(&value, sizeof(value)) == sizeof(value);
-}
-
-bool Packet::put(uint32_t value)
-{
- value = htonl(value);
- return write(&value, sizeof(value)) == sizeof(value);
-}
-
-bool Packet::put(uint64_t value)
-{
- value = htonll(value);
- return write(&value, sizeof(value)) == sizeof(value);
-}
-
-bool Packet::put(float value)
-{
- // XXX: assumes the ieee-754
- uint32_t* integer = reinterpret_cast<uint32_t*>(&value);
- *integer = htonl(*integer);
- return write(integer, sizeof(value)) == sizeof(value);
-}
-
-bool Packet::put(double value)
-{
- // XXX: assumes the ieee-754
- uint64_t* integer = reinterpret_cast<uint64_t*>(&value);
- *integer = htonll(*integer);
- return write(integer, sizeof(value)) == sizeof(value);
-}
-
-
-size_t Packet::write(const void* bytes, size_t size)
-{
- size_t nBytes = std::min(size, mSize - mW);
- if (!mBuffer || nBytes < size)
- {
- int nPages = 1 + size / PAGE_SIZE;
- int newSize = mSize + nPages * PAGE_SIZE;
- char* newBuffer = (char*)realloc(mBuffer, newSize);
- if (newBuffer)
- {
- mBuffer = newBuffer;
- mSize = newSize;
- nBytes = size;
- }
- if (!mBuffer) return 0;
- }
- memcpy(mBuffer + mW, bytes, nBytes);
- mW += nBytes;
- return nBytes;
-}
-
-
-bool Packet::get(bool& value, int flags)
-{
- int bit = mBoolNumR % 8;
- if (bit == 0)
- {
- mBoolR = mR;
-
- unsigned char byte = 0;
- if (read(&byte, 1, flags) == 0) return false;
- }
-
- value = 1 & (mBuffer[mBoolR] >> bit);
- if (!(flags & PEEK)) ++mBoolNumR;
- return true;
-}
-
-bool Packet::get(int8_t& value, int flags)
-{
- return get((uint8_t&)value, flags);
-}
-
-bool Packet::get(int16_t& value, int flags)
-{
- return get((uint16_t&)value, flags);
-}
-
-bool Packet::get(int32_t& value, int flags)
-{
- return get((uint32_t&)value, flags);
-}
-
-bool Packet::get(int64_t& value, int flags)
-{
- return get((uint64_t&)value, flags);
-}
-
-bool Packet::get(uint8_t& value, int flags)
-{
- size_t numBytes = read(&value, sizeof(value), flags);
- return numBytes == sizeof(value);
-}
-
-bool Packet::get(uint16_t& value, int flags)
-{
- size_t numBytes = read(&value, sizeof(value), flags);
- value = ntohs(value);
- return numBytes == sizeof(value);
-}
-
-bool Packet::get(uint32_t& value, int flags)
-{
- size_t numBytes = read(&value, sizeof(value), flags);
- value = ntohl(value);
- return numBytes == sizeof(value);
-}
-
-bool Packet::get(uint64_t& value, int flags)
-{
- size_t numBytes = read(&value, sizeof(value), flags);
- value = ntohll(value);
- return numBytes == sizeof(value);
-}
-
-bool Packet::get(float& value, int flags)
-{
- // XXX: assumes the ieee-754
- uint32_t* integer = reinterpret_cast<uint32_t*>(&value);
- size_t numBytes = read(integer, sizeof(value));
- *integer = htonl(*integer);
- return numBytes == sizeof(value);
-}
-
-bool Packet::get(double& value, int flags)
-{
- // XXX: assumes the ieee-754
- uint64_t* integer = reinterpret_cast<uint64_t*>(&value);
- size_t numBytes = read(integer, sizeof(value));
- *integer = htonll(*integer);
- return numBytes == sizeof(value);
-}
-
-
-size_t Packet::read(void* bytes, size_t size, int flags)
-{
- size_t nBytes = std::min(size, mW - mR);
- memcpy(bytes, mBuffer + mR, nBytes);
- if (!(flags & PEEK)) mR += nBytes;
- return nBytes;
-}
-
-
-void Packet::clear()
-{
- mR = 0;
- mW = 0;
- mBoolR = 0;
- mBoolW = 0;
- mBoolNumR = 0;
- mBoolNumW = 0;
-}
-
-
-void Packet::reset()
-{
- mR = 0;
- mW = mOriginalW;
- mBoolR = 0;
- mBoolW = 0;
- mBoolNumR = 0;
- mBoolNumW = 0;
-}
-
-
-} // namespace Mf
-
+++ /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 <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:
-
- /**
- * Packet flags.
- */
- enum Flags
- {
- PEEK = 0x01 /// Do not actually remove anything.
- };
-
-
- /**
- * Construct a packet with an initial capacity.
- * \param capacity Initial capacity of the packet.
- */
- Packet(size_t capacity = 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.
- */
- bool put(bool value);
- bool put(int8_t value);
- bool put(int16_t value);
- bool put(int32_t value);
- bool put(int64_t value);
- bool put(uint8_t value);
- bool put(uint16_t value);
- bool put(uint32_t value);
- bool put(uint64_t value);
- bool put(float value);
- bool put(double value);
-
- bool put(const char* value)
- {
- uint16_t length = strlen(value);
- if (put(length))
- {
- size_t numBytes = write(value, length);
- return numBytes == length;
- }
- return false;
- }
-
- template <class T>
- bool put(const std::basic_string<T>& value)
- {
- if (put(uint16_t(value.length())))
- {
- size_t byteLength = value.length() * sizeof(T);
- size_t numBytes = write(value.data(), byteLength);
- return numBytes == byteLength;
- }
- return false;
- }
-
- template <class T>
- bool put(const std::vector<T>& value)
- {
- if (put(uint16_t(value.size())))
- {
- typename std::vector<T>::const_iterator it;
- for (it = value.begin(); it != value.end(); ++it)
- {
- if (!put(*it)) return false;
- }
- return true;
- }
- return false;
- }
-
-
- /**
- * 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.
- */
- bool get(bool& value, int flags = 0);
- bool get(int8_t& value, int flags = 0);
- bool get(int16_t& value, int flags = 0);
- bool get(int32_t& value, int flags = 0);
- bool get(int64_t& value, int flags = 0);
- bool get(uint8_t& value, int flags = 0);
- bool get(uint16_t& value, int flags = 0);
- bool get(uint32_t& value, int flags = 0);
- bool get(uint64_t& value, int flags = 0);
- bool get(float& value, int flags = 0);
- bool get(double& value, int flags = 0);
-
- template <class T>
- bool get(std::basic_string<T>& value, int flags = 0)
- {
- uint16_t length = 0;
- if (get(length, flags))
- {
- size_t byteLength = length * sizeof(T);
- T str[length];
- size_t numBytes = read(str, byteLength, flags);
- value.assign(str, numBytes);
- return numBytes == byteLength;
- }
- return false;
- }
-
- template <class T>
- bool get(std::vector<T>& value, int flags = 0)
- {
- uint16_t size = 0;
- if (get(size, flags))
- {
- value.clear();
- for (uint16_t i = 0; i < size; ++i)
- {
- T item;
- if (get(item, flags)) value.push_back(item);
- else return false;
- }
- return true;
- }
- return false;
- }
-
- /**
- * 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, int flags = 0);
-
-
- /**
- * 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;
-};
-
-
-} // namespace Mf
-
-#endif // _MOOF_PACKET_HH_
-