added BitReader::readUnsignedExpGolombCodedBits() and
BitReader::readSignedExpGolombCodedBits()
This commit is contained in:
parent
2e6a8dc6a8
commit
a7941b92e2
|
@ -66,8 +66,8 @@ set(META_APP_AUTHOR "Martchus")
|
|||
set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
|
||||
set(META_APP_DESCRIPTION "Common C++ classes and routines used by my applications such as argument parser, IO and conversion utilities.")
|
||||
set(META_VERSION_MAJOR 3)
|
||||
set(META_VERSION_MINOR 1)
|
||||
set(META_VERSION_PATCH 1)
|
||||
set(META_VERSION_MINOR 2)
|
||||
set(META_VERSION_PATCH 0)
|
||||
set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH})
|
||||
|
||||
# stringification of meta data
|
||||
|
|
|
@ -3,7 +3,7 @@ projectname = c++utilities
|
|||
appname = "C++ Utilities"
|
||||
appauthor = Martchus
|
||||
QMAKE_TARGET_DESCRIPTION = "Common C++ classes and routines used by my applications such as argument parser, IO and conversion utilities."
|
||||
VERSION = 3.1.1
|
||||
VERSION = 3.2.0
|
||||
|
||||
# include ../../common.pri when building as part of a subdirs project; otherwise include general.pri
|
||||
!include(../../common.pri) {
|
||||
|
|
|
@ -160,7 +160,7 @@ inline bool BinaryReader::fail() const
|
|||
*/
|
||||
inline bool BinaryReader::eof() const
|
||||
{
|
||||
return m_stream ? m_stream->eof() : false;
|
||||
return m_stream && m_stream->eof();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -168,7 +168,7 @@ inline bool BinaryReader::eof() const
|
|||
*/
|
||||
inline bool BinaryReader::canRead() const
|
||||
{
|
||||
return m_stream ? !(m_stream->fail() || m_stream->eof()) : false;
|
||||
return m_stream && m_stream->good();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#include "../application/global.h"
|
||||
|
||||
#include <ios>
|
||||
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
|
||||
namespace IoUtilities {
|
||||
|
||||
|
@ -18,6 +18,8 @@ public:
|
|||
|
||||
template<typename intType> intType readBits(byte bitCount);
|
||||
byte readBit();
|
||||
template<typename intType> intType readUnsignedExpGolombCodedBits();
|
||||
template<typename intType> intType readSignedExpGolombCodedBits();
|
||||
template<typename intType> intType showBits(byte bitCount);
|
||||
void skipBits(std::size_t bitCount);
|
||||
void align();
|
||||
|
@ -88,6 +90,39 @@ inline byte BitReader::readBit()
|
|||
return readBits<byte>(1) == 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads "Exp-Golomb coded" bits (unsigned).
|
||||
* \tparam intType Specifies the type of the returned value.
|
||||
* \remarks Does not check whether intType is big enough to hold result.
|
||||
* \throws Throws ios_base::failure if the end of the buffer is exceeded.
|
||||
* The reader becomes invalid in that case.
|
||||
* \sa https://en.wikipedia.org/wiki/Exponential-Golomb_coding
|
||||
*/
|
||||
template<typename intType>
|
||||
intType BitReader::readUnsignedExpGolombCodedBits()
|
||||
{
|
||||
byte count = 0;
|
||||
while(!readBit()) {
|
||||
++count;
|
||||
}
|
||||
return count ? (((1 << count) | readBits<intType>(count)) - 1) : 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads "Exp-Golomb coded" bits (signed).
|
||||
* \tparam intType Specifies the type of the returned value which should be signed (obviously).
|
||||
* \remarks Does not check whether intType is big enough to hold result.
|
||||
* \throws Throws ios_base::failure if the end of the buffer is exceeded.
|
||||
* The reader becomes invalid in that case.
|
||||
* \sa https://en.wikipedia.org/wiki/Exponential-Golomb_coding
|
||||
*/
|
||||
template<typename intType>
|
||||
intType BitReader::readSignedExpGolombCodedBits()
|
||||
{
|
||||
auto value = readUnsignedExpGolombCodedBits<typename std::make_unsigned<intType>::type>();
|
||||
return (value % 2) ? static_cast<intType>((value + 1) / 2) : (-static_cast<intType>(value / 2));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads the specified number of bits from the buffer without advancing the current position.
|
||||
*/
|
||||
|
|
|
@ -181,8 +181,8 @@ void IoTests::testBinaryWriter()
|
|||
*/
|
||||
void IoTests::testBitReader()
|
||||
{
|
||||
byte testData[] = {0x81, 0x90, 0x3C, 0x44, 0x28, 0x00, 0x44};
|
||||
BitReader reader(reinterpret_cast<char *>(testData), sizeof(testData));
|
||||
const byte testData[] = {0x81, 0x90, 0x3C, 0x44, 0x28, 0x00, 0x44, 0x10, 0x20};
|
||||
BitReader reader(reinterpret_cast<const char *>(testData), sizeof(testData));
|
||||
CPPUNIT_ASSERT(reader.readBit() == 1);
|
||||
reader.skipBits(6);
|
||||
CPPUNIT_ASSERT(reader.showBits<byte>(2) == 3);
|
||||
|
@ -190,6 +190,10 @@ void IoTests::testBitReader()
|
|||
CPPUNIT_ASSERT(reader.readBits<uint32>(32) == (0x103C4428 << 1));
|
||||
reader.align();
|
||||
CPPUNIT_ASSERT(reader.readBits<byte>(8) == 0x44);
|
||||
CPPUNIT_ASSERT(reader.readUnsignedExpGolombCodedBits<byte>() == 7);
|
||||
CPPUNIT_ASSERT(reader.readSignedExpGolombCodedBits<sbyte>() == 4);
|
||||
CPPUNIT_ASSERT(reader.readBit() == 0);
|
||||
CPPUNIT_ASSERT(reader.readBit() == 0);
|
||||
CPPUNIT_ASSERT_THROW(reader.readBit(), std::ios_base::failure);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue