#include "ByteBuffer.h" #include #include #include using namespace std; ByteBuffer::ByteBuffer(const uint8_t *bytes, size_t capacity) : bytes(bytes), capacity(capacity), zero(&bytes[0]), end(&bytes[capacity]) { ptr = (uint8_t *) &bytes[0]; } ByteBuffer::ByteBuffer(const uint8_t *bytes, size_t capacity, size_t zero, size_t size) : bytes(bytes), capacity(capacity), zero(&bytes[0]), end(&bytes[size]) { assert(zero <= size); assert(size <= capacity); ptr = (uint8_t *) &bytes[0]; } ByteBuffer::ByteBuffer(const uint8_t *bytes, size_t capacity, const uint8_t *zero, const uint8_t *end) : bytes(bytes), capacity(capacity), zero(zero), end(end), ptr((uint8_t *) zero) { } ByteBuffer &ByteBuffer::add8(uint8_t value) { checkAndUpdateEnd(1); (*ptr++) = value; return *this; } ByteBuffer &ByteBuffer::add16le(uint16_t value) { checkAndUpdateEnd(2); (*ptr++) = (uint8_t) (value & 0xff); (*ptr++) = (uint8_t) ((value >> 8) & 0xff); return *this; } uint8_t ByteBuffer::get8(size_t index) { assertCanAccessRelative(index); return *ptr++; } uint8_t ByteBuffer::get8() { assertCanAccessRelative(0); return *ptr++; } uint16_t ByteBuffer::get16le() { assertCanAccessRelative(0); uint16_t value; value = *ptr++; value |= ((uint16_t) *ptr++) << 8; return value; } void ByteBuffer::copy(uint8_t *bytes, size_t length) { assertCanAccessRelative(length); memcpy(bytes, ptr, length); ptr += length; } ByteBuffer ByteBuffer::view() const { // DF << "cursor=" << getCursor() << ", size=" << getSize() << ", new size=" << end - ptr << ", ptr=" << (uint64_t) ptr << ", zero=" << (uint64_t) zero; return view(ptr, end); } ByteBuffer ByteBuffer::view(size_t length) const { return ByteBuffer(bytes, length, ptr, ptr + length); } ByteBuffer ByteBuffer::view(uint8_t *ptr, const uint8_t *end) const { return ByteBuffer(bytes, end - ptr, ptr, end); } void ByteBuffer::checkAndUpdateEnd(size_t newBytes) { uint8_t *newPtr = ptr + newBytes; if (newPtr >= end) { if (newPtr >= &zero[capacity]) { throw ByteBufferException(string("New size is too large! cursor=") + to_string(getCursor()) + ", size=" + to_string(getSize()) + ", capacity=" + to_string(capacity)); } end = newPtr; } } void ByteBuffer::assertCanAccessRelative(size_t diff) const { assertCanAccessIndex(ptr + diff); } void ByteBuffer::assertCanAccessIndex(uint8_t *p) const { if (p >= end || p < zero) { throw ByteBufferException(string("Out of bounds! size=") + to_string(getSize()) + ", index=" + to_string(p - zero)); } } std::string ByteBuffer::toString() const { stringstream s; for (uint8_t *i = (uint8_t *) zero; i < end; i++) { s << hex << setfill('0') << setw(2) << (int) *i << " "; } return string(s.str()); }