X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FPacket.cc;h=bb8fcc7b88bb9a2413526c9a40ab8164b0b7e7e7;hp=4f3b7fd64f00def5b04ce2f9d7f74287f63e2b2c;hb=3fd6f206f0e64122b7cb289907a1a780b6ed2dc9;hpb=41f8dd670e963aad94527ce2be0486268993a477 diff --git a/src/Moof/Packet.cc b/src/Moof/Packet.cc index 4f3b7fd..bb8fcc7 100644 --- a/src/Moof/Packet.cc +++ b/src/Moof/Packet.cc @@ -15,66 +15,150 @@ #if HAVE_BYTESWAP_H #include #endif +#include +#if HAVE_ARPA_INET_H #include +#endif #include #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(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(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); @@ -119,48 +203,84 @@ Packet& Packet::operator<<(int64_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(&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(&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); @@ -205,40 +325,97 @@ Packet& Packet::operator>>(int64_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(&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(&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