]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Packet.cc
more explicit constructors
[chaz/yoink] / src / Moof / Packet.cc
index 4f3b7fd64f00def5b04ce2f9d7f74287f63e2b2c..437438effd73803b814123f3bfbea4ab32c45be4 100644 (file)
 #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);
 }
 
 
@@ -86,7 +170,7 @@ Packet& Packet::operator<<(bool value)
                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);
@@ -98,69 +182,105 @@ Packet& Packet::operator<<(bool value)
 
 Packet& Packet::operator<<(int8_t value)
 {
-       return *this << (uint8_t)value;
+       return *this << reinterpret_cast<uint8_t&>(value);
 }
 
 Packet& Packet::operator<<(int16_t value)
 {
-       return *this << (uint16_t)value;
+       return *this << reinterpret_cast<uint16_t&>(value);
 }
 
 Packet& Packet::operator<<(int32_t value)
 {
-       return *this << (uint32_t)value;
+       return *this << reinterpret_cast<uint32_t&>(value);
 }
 
 Packet& Packet::operator<<(int64_t value)
 {
-       return *this << (uint64_t)value;
+       return *this << reinterpret_cast<uint64_t&>(value);
 }
 
 
 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;
 }
@@ -174,7 +294,7 @@ Packet& Packet::operator>>(bool& value)
                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);
@@ -185,60 +305,117 @@ Packet& Packet::operator>>(bool& value)
 
 Packet& Packet::operator>>(int8_t& value)
 {
-       return *this >> (uint8_t&)value;
+       return *this >> reinterpret_cast<uint8_t&>(value);
 }
 
 Packet& Packet::operator>>(int16_t& value)
 {
-       return *this >> (uint16_t&)value;
+       return *this >> reinterpret_cast<uint16_t&>(value);
 }
 
 Packet& Packet::operator>>(int32_t& value)
 {
-       return *this >> (uint32_t&)value;
+       return *this >> reinterpret_cast<uint32_t&>(value);
 }
 
 Packet& Packet::operator>>(int64_t& value)
 {
-       return *this >> (uint64_t&)value;
+       return *this >> reinterpret_cast<uint64_t&>(value);
 }
 
 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
 
This page took 0.027222 seconds and 4 git commands to generate.