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_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_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_MAJOR 3)
|
||||||
set(META_VERSION_MINOR 1)
|
set(META_VERSION_MINOR 2)
|
||||||
set(META_VERSION_PATCH 1)
|
set(META_VERSION_PATCH 0)
|
||||||
set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH})
|
set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH})
|
||||||
|
|
||||||
# stringification of meta data
|
# stringification of meta data
|
||||||
|
|
|
@ -3,7 +3,7 @@ projectname = c++utilities
|
||||||
appname = "C++ Utilities"
|
appname = "C++ Utilities"
|
||||||
appauthor = Martchus
|
appauthor = Martchus
|
||||||
QMAKE_TARGET_DESCRIPTION = "Common C++ classes and routines used by my applications such as argument parser, IO and conversion utilities."
|
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 when building as part of a subdirs project; otherwise include general.pri
|
||||||
!include(../../common.pri) {
|
!include(../../common.pri) {
|
||||||
|
|
|
@ -160,7 +160,7 @@ inline bool BinaryReader::fail() const
|
||||||
*/
|
*/
|
||||||
inline bool BinaryReader::eof() 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
|
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 "../application/global.h"
|
||||||
|
|
||||||
#include <ios>
|
#include <ios>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
namespace IoUtilities {
|
namespace IoUtilities {
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@ public:
|
||||||
|
|
||||||
template<typename intType> intType readBits(byte bitCount);
|
template<typename intType> intType readBits(byte bitCount);
|
||||||
byte readBit();
|
byte readBit();
|
||||||
|
template<typename intType> intType readUnsignedExpGolombCodedBits();
|
||||||
|
template<typename intType> intType readSignedExpGolombCodedBits();
|
||||||
template<typename intType> intType showBits(byte bitCount);
|
template<typename intType> intType showBits(byte bitCount);
|
||||||
void skipBits(std::size_t bitCount);
|
void skipBits(std::size_t bitCount);
|
||||||
void align();
|
void align();
|
||||||
|
@ -88,6 +90,39 @@ inline byte BitReader::readBit()
|
||||||
return readBits<byte>(1) == 1;
|
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.
|
* \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()
|
void IoTests::testBitReader()
|
||||||
{
|
{
|
||||||
byte testData[] = {0x81, 0x90, 0x3C, 0x44, 0x28, 0x00, 0x44};
|
const byte testData[] = {0x81, 0x90, 0x3C, 0x44, 0x28, 0x00, 0x44, 0x10, 0x20};
|
||||||
BitReader reader(reinterpret_cast<char *>(testData), sizeof(testData));
|
BitReader reader(reinterpret_cast<const char *>(testData), sizeof(testData));
|
||||||
CPPUNIT_ASSERT(reader.readBit() == 1);
|
CPPUNIT_ASSERT(reader.readBit() == 1);
|
||||||
reader.skipBits(6);
|
reader.skipBits(6);
|
||||||
CPPUNIT_ASSERT(reader.showBits<byte>(2) == 3);
|
CPPUNIT_ASSERT(reader.showBits<byte>(2) == 3);
|
||||||
|
@ -190,6 +190,10 @@ void IoTests::testBitReader()
|
||||||
CPPUNIT_ASSERT(reader.readBits<uint32>(32) == (0x103C4428 << 1));
|
CPPUNIT_ASSERT(reader.readBits<uint32>(32) == (0x103C4428 << 1));
|
||||||
reader.align();
|
reader.align();
|
||||||
CPPUNIT_ASSERT(reader.readBits<byte>(8) == 0x44);
|
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);
|
CPPUNIT_ASSERT_THROW(reader.readBit(), std::ios_base::failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue