Add some bit utils and initial l77 encoder.
This commit is contained in:
parent
ff962a6b16
commit
318b481ccc
12 changed files with 508 additions and 117 deletions
163
src/core/ByteUtils.cpp
Normal file
163
src/core/ByteUtils.cpp
Normal file
|
@ -0,0 +1,163 @@
|
|||
#include "ByteUtils.h"
|
||||
|
||||
|
||||
bool ByteUtils::MostSignificantBitIsOne(char c)
|
||||
{
|
||||
return c & (1 << 7);
|
||||
}
|
||||
|
||||
ByteUtils::Word ByteUtils::GetWordFirstBit(const Word word)
|
||||
{
|
||||
return word & ByteUtils::WORD_FIRST_BIT;
|
||||
};
|
||||
|
||||
ByteUtils::Word ByteUtils::GetWordLastByte(const Word word)
|
||||
{
|
||||
return word & ByteUtils::WORD_LAST_BYTE;
|
||||
}
|
||||
|
||||
unsigned char ByteUtils::getHigherNBits(unsigned char input, unsigned num)
|
||||
{
|
||||
return input >> 8 - num;
|
||||
}
|
||||
|
||||
unsigned char ByteUtils::getLowerNBits(unsigned char input, unsigned num)
|
||||
{
|
||||
switch (num)
|
||||
{
|
||||
case 1:
|
||||
return input & 0x01;
|
||||
case 2:
|
||||
return input & 0x03;
|
||||
case 3:
|
||||
return input & 0x07;
|
||||
case 4:
|
||||
return input & 0x0F;
|
||||
case 5:
|
||||
return input & 0x1F;
|
||||
case 6:
|
||||
return input & 0x3F;
|
||||
case 7:
|
||||
return input & 0x7F;
|
||||
case 8:
|
||||
return input;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char ByteUtils::getTwoBitsAtN(unsigned char input, unsigned n)
|
||||
{
|
||||
return (input & (0x03 << n)) >> n;
|
||||
}
|
||||
|
||||
unsigned char ByteUtils::getMBitsAtN(unsigned char input, unsigned m, unsigned n)
|
||||
{
|
||||
switch (m)
|
||||
{
|
||||
case 1:
|
||||
return (input & (0x01 << n)) >> n;
|
||||
case 2:
|
||||
return (input & (0x03 << n)) >> n;
|
||||
case 3:
|
||||
return (input & (0x07 << n)) >> n;
|
||||
case 4:
|
||||
return (input & (0x0F << n)) >> n;
|
||||
case 5:
|
||||
return (input & (0x1F << n)) >> n;
|
||||
case 6:
|
||||
return (input & (0x3F << n)) >> n;
|
||||
case 7:
|
||||
return (input & (0x7F << n)) >> n;
|
||||
case 8:
|
||||
return input;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char ByteUtils::getBitN(unsigned char input, unsigned n)
|
||||
{
|
||||
return input & (1 << n);
|
||||
}
|
||||
|
||||
unsigned char ByteUtils::getFromString(const std::string& string)
|
||||
{
|
||||
unsigned char ret{0};
|
||||
|
||||
if (string.length() < 8)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
for(unsigned idx=0; idx<8; idx++)
|
||||
{
|
||||
if (string[idx] == '1')
|
||||
{
|
||||
ret |= (0x01 << (7 - idx));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string ByteUtils::toString(unsigned char c)
|
||||
{
|
||||
std::string ret;
|
||||
for(unsigned idx=0; idx<8; idx++)
|
||||
{
|
||||
ret += getBitN(c, 7 - idx) ? '1' : '0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ByteUtils::ReverseBuffer(char* buffer, char* reverse, unsigned size, unsigned targetSize)
|
||||
{
|
||||
for(unsigned idx=0; idx<targetSize; idx++)
|
||||
{
|
||||
if (idx < size)
|
||||
{
|
||||
reverse[idx] = buffer[size - 1 -idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
reverse[idx] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ByteUtils::Word ByteUtils::ToWord(char* buffer, bool reverse)
|
||||
{
|
||||
return ToType<Word>(buffer, reverse);
|
||||
}
|
||||
|
||||
ByteUtils::DWord ByteUtils::ToDWord(char* buffer, bool reverse)
|
||||
{
|
||||
return ToType<DWord>(buffer, reverse);
|
||||
}
|
||||
|
||||
ByteUtils::QWord ByteUtils::ToQWord(char* buffer, bool reverse)
|
||||
{
|
||||
return ToType<QWord>(buffer, reverse);
|
||||
}
|
||||
|
||||
bool ByteUtils::Compare(char* buffer, const char* tag, unsigned size)
|
||||
{
|
||||
for(unsigned idx=0; idx<size; idx++)
|
||||
{
|
||||
if(tag[idx] != buffer[idx])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ByteUtils::CompareDWords(char* buffer, const char* tag)
|
||||
{
|
||||
return Compare(buffer, tag, sizeof(DWord));
|
||||
}
|
||||
|
||||
bool ByteUtils::CompareWords(char* buffer, const char* tag)
|
||||
{
|
||||
return Compare(buffer, tag, sizeof(Word));
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <cstring>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
class ByteUtils
|
||||
{
|
||||
|
@ -10,75 +11,27 @@ public:
|
|||
using DWord = int32_t;
|
||||
using QWord = int64_t;
|
||||
|
||||
static bool MostSignificantBitIsOne(char c)
|
||||
{
|
||||
return c & (1 << 7);
|
||||
}
|
||||
static bool MostSignificantBitIsOne(char c);
|
||||
|
||||
static Word GetWordFirstBit(const Word word)
|
||||
{
|
||||
return word & ByteUtils::WORD_FIRST_BIT;
|
||||
};
|
||||
static Word GetWordFirstBit(const Word word);
|
||||
|
||||
static Word GetWordLastByte(const Word word)
|
||||
{
|
||||
return word & ByteUtils::WORD_LAST_BYTE;
|
||||
}
|
||||
static Word GetWordLastByte(const Word word);
|
||||
|
||||
static unsigned char getHigherNBits(unsigned char input, unsigned num)
|
||||
{
|
||||
return input >> 8 - num;
|
||||
}
|
||||
static unsigned char getHigherNBits(unsigned char input, unsigned num);
|
||||
|
||||
static unsigned char getLowerNBits(unsigned char input, unsigned num)
|
||||
{
|
||||
switch (num)
|
||||
{
|
||||
case 1:
|
||||
return input & 0x01;
|
||||
case 2:
|
||||
return input & 0x03;
|
||||
case 3:
|
||||
return input & 0x07;
|
||||
case 4:
|
||||
return input & 0x0F;
|
||||
case 5:
|
||||
return input & 0x1F;
|
||||
case 6:
|
||||
return input & 0x3F;
|
||||
case 7:
|
||||
return input & 0x7F;
|
||||
case 8:
|
||||
return input;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static unsigned char getLowerNBits(unsigned char input, unsigned num);
|
||||
|
||||
static unsigned char getTwoBitsAtN(unsigned char input, unsigned n)
|
||||
{
|
||||
return (input & (0x03 << n)) >> n;
|
||||
}
|
||||
static unsigned char getTwoBitsAtN(unsigned char input, unsigned n);
|
||||
|
||||
static unsigned char getBitN(unsigned char input, unsigned n)
|
||||
{
|
||||
return input & (1 << n);
|
||||
}
|
||||
static unsigned char getMBitsAtN(unsigned char input, unsigned m, unsigned n);
|
||||
|
||||
static void ReverseBuffer(char* buffer, char* reverse, unsigned size, unsigned targetSize)
|
||||
{
|
||||
for(unsigned idx=0; idx<targetSize; idx++)
|
||||
{
|
||||
if (idx < size)
|
||||
{
|
||||
reverse[idx] = buffer[size - 1 -idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
reverse[idx] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
static unsigned char getBitN(unsigned char input, unsigned n);
|
||||
|
||||
static unsigned char getFromString(const std::string& string);
|
||||
|
||||
static std::string toString(unsigned char c);
|
||||
|
||||
static void ReverseBuffer(char* buffer, char* reverse, unsigned size, unsigned targetSize);
|
||||
|
||||
template<typename T>
|
||||
static T ToType(char* buffer, bool reverse = true)
|
||||
|
@ -97,42 +50,17 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
static Word ToWord(char* buffer, bool reverse = true)
|
||||
{
|
||||
return ToType<Word>(buffer, reverse);
|
||||
}
|
||||
static Word ToWord(char* buffer, bool reverse = true);
|
||||
|
||||
static DWord ToDWord(char* buffer, bool reverse = true)
|
||||
{
|
||||
return ToType<DWord>(buffer, reverse);
|
||||
}
|
||||
static DWord ToDWord(char* buffer, bool reverse = true);
|
||||
|
||||
static QWord ToQWord(char* buffer, bool reverse = true)
|
||||
{
|
||||
return ToType<QWord>(buffer, reverse);
|
||||
}
|
||||
static QWord ToQWord(char* buffer, bool reverse = true);
|
||||
|
||||
static bool Compare(char* buffer, const char* tag, unsigned size)
|
||||
{
|
||||
for(unsigned idx=0; idx<size; idx++)
|
||||
{
|
||||
if(tag[idx] != buffer[idx])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static bool Compare(char* buffer, const char* tag, unsigned size);
|
||||
|
||||
static bool CompareDWords(char* buffer, const char* tag)
|
||||
{
|
||||
return Compare(buffer, tag, sizeof(DWord));
|
||||
}
|
||||
static bool CompareDWords(char* buffer, const char* tag);
|
||||
|
||||
static bool CompareWords(char* buffer, const char* tag)
|
||||
{
|
||||
return Compare(buffer, tag, sizeof(Word));
|
||||
}
|
||||
static bool CompareWords(char* buffer, const char* tag);
|
||||
|
||||
static const int BYTE_FIRST_BIT = 0x40; // 1000 0000
|
||||
static const Word WORD_FIRST_BIT = 0x8000; // 1000 0000 - 0000 0000
|
||||
|
|
|
@ -14,6 +14,7 @@ list(APPEND core_HEADERS
|
|||
)
|
||||
|
||||
list(APPEND core_LIB_INCLUDES
|
||||
ByteUtils.cpp
|
||||
Event.cpp
|
||||
Dictionary.cpp
|
||||
Color.cpp
|
||||
|
@ -28,6 +29,7 @@ list(APPEND core_LIB_INCLUDES
|
|||
RandomUtils.cpp
|
||||
StringUtils.cpp
|
||||
streams/BinaryStream.cpp
|
||||
streams/BitStream.cpp
|
||||
http/HttpResponse.cpp
|
||||
http/HttpHeader.cpp
|
||||
http/HttpRequest.cpp
|
||||
|
|
56
src/core/streams/BitStream.cpp
Normal file
56
src/core/streams/BitStream.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include "BitStream.h"
|
||||
|
||||
#include "ByteUtils.h"
|
||||
|
||||
bool BitStream::loadNextByte()
|
||||
{
|
||||
if (mByteOffset + 1 == mBuffer.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mByteOffset++;
|
||||
mCurrentByte = mBuffer[mByteOffset];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool BitStream::getNextNBits(unsigned n, unsigned char& buffer)
|
||||
{
|
||||
int overshoot = n + mBitOffset - 7;
|
||||
|
||||
if (overshoot > 0)
|
||||
{
|
||||
unsigned char last_byte = mCurrentByte;
|
||||
if (!loadNextByte())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto num_lower = 7 - mBitOffset;
|
||||
char lower_bits = ByteUtils::getHigherNBits(last_byte, num_lower);
|
||||
char higher_bits = ByteUtils::getLowerNBits(mCurrentByte, overshoot);
|
||||
|
||||
buffer = (higher_bits << (8 - num_lower)) | (lower_bits >> mBitOffset);
|
||||
|
||||
mBitOffset = overshoot;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = ByteUtils::getMBitsAtN(mCurrentByte, n, mBitOffset);
|
||||
mBitOffset += n;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void BitStream::setByte(unsigned idx, unsigned char data)
|
||||
{
|
||||
mBuffer[idx] = data;
|
||||
}
|
||||
|
||||
void BitStream::setBufferSize(std::size_t size)
|
||||
{
|
||||
mBuffer = std::vector<unsigned char>(size);
|
||||
}
|
27
src/core/streams/BitStream.h
Normal file
27
src/core/streams/BitStream.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
class BitStream
|
||||
{
|
||||
public:
|
||||
bool getNextNBits(unsigned n, unsigned char& buffer);
|
||||
|
||||
bool loadNextByte();
|
||||
|
||||
void setByte(unsigned idx, unsigned char data);
|
||||
|
||||
void setBufferSize(std::size_t size);
|
||||
|
||||
unsigned char getCurrentByte() const
|
||||
{
|
||||
return mCurrentByte;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned mByteOffset{0};
|
||||
unsigned mBitOffset{0};
|
||||
|
||||
char mCurrentByte{0};
|
||||
std::vector<unsigned char> mBuffer;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue