added BitReader::readUnsignedExpGolombCodedBits() and

BitReader::readSignedExpGolombCodedBits()
This commit is contained in:
Martchus 2016-02-15 22:53:39 +01:00
parent 2e6a8dc6a8
commit a7941b92e2
5 changed files with 47 additions and 8 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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();
}
/*!

View File

@ -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.
*/

View File

@ -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);
}