#include "byte_utils.hpp" #include #include #include void ByteBuilder::put(ubyte b) { buffer.push_back(b); } void ByteBuilder::putCStr(const char* str) { size_t size = strlen(str)+1; buffer.reserve(buffer.size() + size); for (size_t i = 0; i < size; i++) { buffer.push_back(str[i]); } } void ByteBuilder::put(const std::string& s) { size_t len = s.length(); putInt32(len); put(reinterpret_cast(s.data()), len); } void ByteBuilder::put(const ubyte* arr, size_t size) { buffer.reserve(buffer.size() + size); for (size_t i = 0; i < size; i++) { buffer.push_back(arr[i]); } } void ByteBuilder::putInt16(int16_t val) { buffer.push_back(static_cast(val >> 0 & 255)); buffer.push_back(static_cast(val >> 8 & 255)); } void ByteBuilder::putInt32(int32_t val) { buffer.reserve(buffer.size() + 4); buffer.push_back(static_cast(val >> 0 & 255)); buffer.push_back(static_cast (val >> 8 & 255)); buffer.push_back(static_cast (val >> 16 & 255)); buffer.push_back(static_cast (val >> 24 & 255)); } void ByteBuilder::putInt64(int64_t val) { buffer.reserve(buffer.size() + 8); buffer.push_back(static_cast (val >> 0 & 255)); buffer.push_back(static_cast (val >> 8 & 255)); buffer.push_back(static_cast (val >> 16 & 255)); buffer.push_back(static_cast (val >> 24 & 255)); buffer.push_back(static_cast (val >> 32 & 255)); buffer.push_back(static_cast (val >> 40 & 255)); buffer.push_back(static_cast (val >> 48 & 255)); buffer.push_back(static_cast (val >> 56 & 255)); } void ByteBuilder::putFloat32(float val) { int32_t i32_val; std::memcpy(&i32_val, &val, sizeof(int32_t)); putInt32(i32_val); } void ByteBuilder::putFloat64(double val) { int64_t i64_val; std::memcpy(&i64_val, &val, sizeof(int64_t)); putInt64(i64_val); } void ByteBuilder::set(size_t position, ubyte val) { buffer[position] = val; } void ByteBuilder::setInt16(size_t position, int16_t val) { buffer[position++] = val >> 0 & 255; buffer[position] = val >> 8 & 255; } void ByteBuilder::setInt32(size_t position, int32_t val) { buffer[position++] = val >> 0 & 255; buffer[position++] = val >> 8 & 255; buffer[position++] = val >> 16 & 255; buffer[position] = val >> 24 & 255; } void ByteBuilder::setInt64(size_t position, int64_t val) { buffer[position++] = val >> 0 & 255; buffer[position++] = val >> 8 & 255; buffer[position++] = val >> 16 & 255; buffer[position++] = val >> 24 & 255; buffer[position++] = val >> 32 & 255; buffer[position++] = val >> 40 & 255; buffer[position++] = val >> 48 & 255; buffer[position] = val >> 56 & 255; } std::vector ByteBuilder::build() { return buffer; } ByteReader::ByteReader(const ubyte* data, size_t size) : data(data), size(size), pos(0) { } ByteReader::ByteReader(const ubyte* data) : data(data), size(4), pos(0) { size = getInt32(); } void ByteReader::checkMagic(const char* data, size_t size) { if (pos + size >= this->size) { throw std::runtime_error("invalid magic number"); } for (size_t i = 0; i < size; i++) { if (this->data[pos + i] != (ubyte)data[i]){ throw std::runtime_error("invalid magic number"); } } pos += size; } ubyte ByteReader::get() { if (pos == size) { throw std::runtime_error("buffer underflow"); } return data[pos++]; } ubyte ByteReader::peek() { if (pos == size) { throw std::runtime_error("buffer underflow"); } return data[pos]; } int16_t ByteReader::getInt16() { if (pos+2 > size) { throw std::runtime_error("buffer underflow"); } pos += 2; return (static_cast(data[pos - 1]) << 8) | (static_cast(data[pos - 2])); } int32_t ByteReader::getInt32() { if (pos+4 > size) { throw std::runtime_error("buffer underflow"); } pos += 4; return (static_cast(data[pos - 1]) << 24) | (static_cast(data[pos - 2]) << 16) | (static_cast(data[pos - 3]) << 8) | (static_cast(data[pos - 4])); } int64_t ByteReader::getInt64() { if (pos+8 > size) { throw std::runtime_error("buffer underflow"); } pos += 8; return (static_cast(data[pos - 1]) << 56) | (static_cast(data[pos - 2]) << 48) | (static_cast(data[pos - 3]) << 40) | (static_cast(data[pos - 4]) << 32) | (static_cast(data[pos - 5]) << 24) | (static_cast(data[pos - 6]) << 16) | (static_cast(data[pos - 7]) << 8) | (static_cast(data[pos - 8])); } float ByteReader::getFloat32() { int32_t i32_val = getInt32(); float val; std::memcpy(&val, &i32_val, sizeof(float)); return val; } double ByteReader::getFloat64() { int64_t i64_val = getInt64(); double val; std::memcpy(&val, &i64_val, sizeof(double)); return val; } const char* ByteReader::getCString() { const char* cstr = reinterpret_cast(data+pos); pos += strlen(cstr) + 1; return cstr; } std::string ByteReader::getString() { uint32_t length = (uint32_t)getInt32(); if (pos+length > size) { throw std::runtime_error("buffer underflow"); } pos += length; return std::string(reinterpret_cast(data+pos-length), length); } bool ByteReader::hasNext() const { return pos < size; } const ubyte* ByteReader::pointer() const { return data + pos; } void ByteReader::skip(size_t n) { pos += n; }