12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- #pragma once
- #include "openmpt/all/BuildSettings.hpp"
- #include "../common/FileReader.h"
- #include <stdexcept>
- #include "mpt/io/base.hpp"
- OPENMPT_NAMESPACE_BEGIN
- class BitReader : private FileReader
- {
- protected:
- off_t m_bufPos = 0, m_bufSize = 0;
- uint32 bitBuf = 0;
- int m_bitNum = 0;
- std::byte buffer[mpt::IO::BUFFERSIZE_TINY]{};
- public:
- class eof : public std::range_error
- {
- public:
- eof() : std::range_error("Truncated bit buffer") { }
- };
- BitReader() : FileReader() { }
- BitReader(mpt::span<const std::byte> bytedata) : FileReader(bytedata) { }
- BitReader(const FileCursor &other) : FileReader(other) { }
- BitReader(FileCursor &&other) : FileReader(std::move(other)) { }
- off_t GetLength() const
- {
- return FileReader::GetLength();
- }
- off_t GetPosition() const
- {
- return FileReader::GetPosition() - m_bufSize + m_bufPos;
- }
- uint32 ReadBits(int numBits)
- {
- while(m_bitNum < numBits)
- {
-
- if(m_bufPos >= m_bufSize)
- {
- m_bufSize = ReadRaw(mpt::as_span(buffer)).size();
- m_bufPos = 0;
- if(!m_bufSize)
- {
- throw eof();
- }
- }
- bitBuf |= (static_cast<uint32>(buffer[m_bufPos++]) << m_bitNum);
- m_bitNum += 8;
- }
- uint32 v = bitBuf & ((1 << numBits) - 1);
- bitBuf >>= numBits;
- m_bitNum -= numBits;
- return v;
- }
- };
- OPENMPT_NAMESPACE_END
|