Mercurial > minori
view include/core/byte_stream.h @ 367:8d45d892be88 default tip
*: instead of pugixml, use Qt XML features
this means we have one extra Qt dependency though...
author | Paper <paper@tflc.us> |
---|---|
date | Sun, 17 Nov 2024 22:55:47 -0500 |
parents | 99c961c91809 |
children |
line wrap: on
line source
#ifndef MINORI_CORE_BYTE_STREAM_H_ #define MINORI_CORE_BYTE_STREAM_H_ #include "core/endian.h" #include <string> #include <vector> #include <cstdint> #include <type_traits> struct ByteStream { public: enum class ByteOrder { Little, Big, }; ByteStream(std::uint8_t *bytes, std::size_t size); void ResetOffset(); void SetEndianness(ByteOrder endian); template<typename T> bool ReadBinary(T& ret) { if (offset_ + sizeof(T) >= size_) return false; ret = *reinterpret_cast<T*>(bytes_ + offset_); Advance(sizeof(T)); return true; } template<typename T> bool ReadInt(T& ret) { static_assert(std::is_integral<T>::value); if (!ReadBinary<T>(ret)) return false; switch (endian_) { case ByteOrder::Little: if constexpr (std::is_unsigned<T>::value) { ret = Endian::byteswap_little_to_host(ret); } else { ret = Endian::signed_byteswap_little_to_host(ret); } break; case ByteOrder::Big: if constexpr (std::is_unsigned<T>::value) { ret = Endian::byteswap_big_to_host(ret); } else { ret = Endian::signed_byteswap_big_to_host(ret); } break; default: /* can't know for sure. punt */ return false; } return true; } bool ReadString(std::string& str, std::size_t size); bool Advance(std::size_t amount); private: /* raw data */ std::uint8_t *bytes_ = nullptr; std::size_t offset_ = 0; std::size_t size_ = 0; ByteOrder endian_ = ByteOrder::Little; }; #endif /* MINORI_CORE_BYTE_STREAM_H_ */