#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) (((uint64_t)(x) << 56) | \
- (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \
- (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \
- (((uint64_t)(x) << 8) & 0xff00000000ULL) | \
- (((uint64_t)(x) >> 8) & 0xff000000ULL) | \
- (((uint64_t)(x) >> 24) & 0xff0000ULL) | \
- (((uint64_t)(x) >> 40) & 0xff00ULL) | \
- ((uint64_t)(x) >> 56))
+#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
-static uint64_t htonll(uint64_t x)
+
+#if !HAVE_ARPA_INET_H
+static uint16_t htons(uint16_t x)
{
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
- return bswap_64(x);
+ return bswap_16(x);
+#else
+ return x;
#endif
}
+static uint16_t ntohs(uint16_t x)
+{
+ return htons(x);
+}
-static uint64_t ntohll(uint64_t 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 size) :
+ mBuffer((char*)malloc(size)),
+ mSize(size),
mR(0),
mW(0),
+ mOriginalW(0),
mBoolR(0),
mBoolW(0),
mBoolNumR(0),
- mBoolNumW(0)
-{
- mBuffer = boost::shared_array<char>(new char[size]);
- mSize = size;
-}
+ 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)
{
- mBuffer = boost::shared_array<char>(new char[size]);
- mSize = size;
- mW = size;
- memcpy(mBuffer.get(), data, mSize);
+ if (mBuffer) memcpy(mBuffer, data, size);
+ else throw std::length_error("out of memory");
+}
+
+
+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);
+ else throw std::length_error("out of memory");
+}
+
+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);
+ else throw std::length_error("out of memory");
+ return *this;
+}
+
+
+Packet::~Packet()
+{
+ free(mBuffer);
}
mBoolW = mW;
unsigned char byte = 0;
- if (write(&byte, 1) == 0) return *this;
+ if (write(&byte, 1) == 0) throw std::length_error("out of memory");
}
if (value) mBuffer[mBoolW] |= (1 << bit);
Packet& Packet::operator<<(uint8_t value)
{
- write(&value, sizeof(value));
+ if (write(&value, sizeof(value)) != sizeof(value))
+ {
+ throw std::length_error("out of memory");
+ }
return *this;
}
Packet& Packet::operator<<(uint16_t value)
{
value = htons(value);
- write(&value, sizeof(value));
+ if (write(&value, sizeof(value)) != sizeof(value))
+ {
+ throw std::length_error("out of memory");
+ }
return *this;
}
Packet& Packet::operator<<(uint32_t value)
{
value = htonl(value);
- write(&value, sizeof(value));
+ if (write(&value, sizeof(value)) != sizeof(value))
+ {
+ throw std::length_error("out of memory");
+ }
return *this;
}
Packet& Packet::operator<<(uint64_t value)
{
value = htonll(value);
- write(&value, sizeof(value));
+ if (write(&value, sizeof(value)) != sizeof(value))
+ {
+ throw std::length_error("out of memory");
+ }
return *this;
}
-//Packet& Packet::operator<<(float value)
-//{
-//}
-
-//Packet& Packet::operator<<(double value)
-//{
-//}
-
-//Packet& Packet::operator<<(long double value)
-//{
-//}
+Packet& Packet::operator<<(float value)
+{
+ // XXX: assumes the ieee-754
+ uint32_t* integer = reinterpret_cast<uint32_t*>(&value);
+ *integer = htonl(*integer);
+ if (write(integer, sizeof(value)) != sizeof(value))
+ {
+ throw std::length_error("out of memory");
+ }
+ return *this;
+}
+Packet& Packet::operator<<(double value)
+{
+ // XXX: assumes the ieee-754
+ uint64_t* integer = reinterpret_cast<uint64_t*>(&value);
+ *integer = htonll(*integer);
+ if (write(integer, sizeof(value)) != sizeof(value))
+ {
+ throw std::length_error("out of memory");
+ }
+ return *this;
+}
size_t Packet::write(const void* bytes, size_t size)
{
size_t nBytes = std::min(size, mSize - mW);
- memcpy(&mBuffer[mW], bytes, nBytes);
+ 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;
}
mBoolR = mR;
unsigned char byte = 0;
- if (read(&byte, 1) == 0) return *this;
+ if (read(&byte, 1) == 0) throw std::out_of_range("end of packet");
}
value = 1 & (mBuffer[mBoolR] >> bit);
Packet& Packet::operator>>(uint8_t& value)
{
- read(&value, sizeof(value));
+ if (read(&value, sizeof(value)) != sizeof(value))
+ {
+ throw std::out_of_range("end of packet");
+ }
return *this;
}
Packet& Packet::operator>>(uint16_t& value)
{
- read(&value, sizeof(value));
+ if (read(&value, sizeof(value)) != sizeof(value))
+ {
+ throw std::out_of_range("end of packet");
+ }
value = ntohs(value);
return *this;
}
Packet& Packet::operator>>(uint32_t& value)
{
- read(&value, sizeof(value));
+ if (read(&value, sizeof(value)) != sizeof(value))
+ {
+ throw std::out_of_range("end of packet");
+ }
value = ntohl(value);
return *this;
}
Packet& Packet::operator>>(uint64_t& value)
{
- read(&value, sizeof(value));
+ if (read(&value, sizeof(value)) != sizeof(value))
+ {
+ throw std::out_of_range("end of packet");
+ }
value = ntohll(value);
return *this;
}
+Packet& Packet::operator>>(float& value)
+{
+ // XXX: assumes the ieee-754
+ uint32_t* integer = reinterpret_cast<uint32_t*>(&value);
+ if (read(integer, sizeof(value)) != sizeof(value))
+ {
+ throw std::out_of_range("end of packet");
+ }
+ *integer = htonl(*integer);
+ return *this;
+}
+
+Packet& Packet::operator>>(double& value)
+{
+ // XXX: assumes the ieee-754
+ uint64_t* integer = reinterpret_cast<uint64_t*>(&value);
+ if (read(integer, sizeof(value)) != sizeof(value))
+ {
+ throw std::out_of_range("end of packet");
+ }
+ *integer = htonll(*integer);
+ return *this;
+}
size_t Packet::read(void* bytes, size_t size)
{
size_t nBytes = std::min(size, mW - mR);
- memcpy(bytes, &mBuffer[mR], nBytes);
+ memcpy(bytes, mBuffer + mR, nBytes);
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