#ifndef BYTE_STREAM_WRAPPER_H #define BYTE_STREAM_WRAPPER_H #include #include #include #include #include #include #include namespace FLOAT { static const uint32_t positive_infinity = 0x007FFFFE; static const uint32_t negative_infinity = 0x00800002; static const uint32_t NaN = 0x007FFFFF; static const uint32_t NRes = 0x00800000; static const uint32_t FLAOT_reserved_value = 0x00800001; // (2^23 - 3) * 10^127 static const double max = 8.388604999999999e+133; static const double min = -max; static const double mantissa_max = 0x007FFFFD; static const double exponent_max = 127; static const double exponent_min = -128; // 10^-128 static const double epsilon = 1e-128; // 10^upper(23 * log(2) / log(10)) static const double precision = 10000000; } class ByteBufferException : public std::runtime_error { public: ByteBufferException(std::string const &what) : std::runtime_error(what) { } }; class ByteBuffer { public: static ByteBuffer alloc(std::size_t capacity); ByteBuffer(const std::shared_ptr bytes, size_t capacity); ByteBuffer(const std::shared_ptr bytes, size_t capacity, size_t size); ByteBuffer(const std::shared_ptr bytes, size_t capacity, size_t size, size_t zero); inline size_t getSize() const { return end - zero; } inline size_t getCapacity() const { return capacity; } inline size_t getCursor() const { return ptr - zero; } inline size_t getBytesLeft() const { return end - ptr; } inline ByteBuffer &setCursor(size_t newCursor) { ptr = (uint8_t *) &zero[newCursor]; return *this; } inline void skip(size_t length) { ptr += length; } ByteBuffer &write8(uint8_t value); ByteBuffer &write16le(uint16_t value); ByteBuffer &write32le(uint32_t value); /** * Appends the entire buffer. Make a view if you want to write a part of it. */ ByteBuffer &write(const ByteBuffer &value); ByteBuffer &write(const uint8_t *bytes, size_t len); ByteBuffer &writeFLOAT(double d); uint8_t get8(size_t index) const; uint8_t read8(); uint16_t read16le(); uint32_t read32le(); /** * IEEE-11073 32-bit FLOAT */ double readFLOAT(); void copy(uint8_t *bytes, size_t length) const; /** * Creates a view from cursor to size. */ ByteBuffer view() const; // TODO: should return const ByteBuffer view(size_t length) const; std::string toString() const; private: ByteBuffer(const std::shared_ptr bytes, size_t capacity, const uint8_t *zero, const uint8_t *end); ByteBuffer view(uint8_t *ptr, const uint8_t *end) const; void checkAndUpdateEnd(size_t count); void assertCanAccessRelative(size_t diff) const; void assertCanAccessIndex(uint8_t *p) const; const std::shared_ptr bytes; const size_t capacity; const uint8_t *zero; const uint8_t *end; uint8_t *ptr; }; #endif