18    inline bool operator()(CryptoPP::HuffmanDecoder::code_t lhs, 
const CryptoPP::HuffmanDecoder::CodeInfo &rhs)
 
   19        {
return lhs < rhs.code;}
 
   21    inline bool operator()(
const CryptoPP::HuffmanDecoder::CodeInfo &lhs, 
const CryptoPP::HuffmanDecoder::CodeInfo &rhs)
 
   22        {
return lhs.code < rhs.code;}
 
 
   25inline bool LowFirstBitReader::FillBuffer(
unsigned int length)
 
   27    while (m_bitsBuffered < length)
 
   32        m_buffer |= (
unsigned long)b << m_bitsBuffered;
 
   39inline unsigned long LowFirstBitReader::PeekBits(
unsigned int length)
 
   41    bool result = FillBuffer(length);
 
   43    return m_buffer & (((
unsigned long)1 << length) - 1);
 
   46inline void LowFirstBitReader::SkipBits(
unsigned int length)
 
   50    m_bitsBuffered -= length;
 
   53inline unsigned long LowFirstBitReader::GetBits(
unsigned int length)
 
   55    unsigned long result = PeekBits(length);
 
   60inline HuffmanDecoder::code_t HuffmanDecoder::NormalizeCode(HuffmanDecoder::code_t code, 
unsigned int codeBits)
 
   62    return code << (MAX_CODE_BITS - codeBits);
 
   65void HuffmanDecoder::Initialize(
const unsigned int *codeBits, 
unsigned int nCodes)
 
   83        throw Err(
"null code");
 
   85    m_maxCodeBits = *std::max_element(codeBits, codeBits+nCodes);
 
   87    if (m_maxCodeBits > MAX_CODE_BITS)
 
   88        throw Err(
"code length exceeds maximum");
 
   90    if (m_maxCodeBits == 0)
 
   91        throw Err(
"null code");
 
   95    std::fill(blCount.begin(), blCount.end(), 0);
 
   97    for (i=0; i<nCodes; i++)
 
   98        blCount[codeBits[i]]++;
 
  104    for (i=2; i<=m_maxCodeBits; i++)
 
  107        if (code > code + blCount[i-1])
 
  108            throw Err(
"codes oversubscribed");
 
  109        code += blCount[i-1];
 
  110        if (code > (code << 1))
 
  111            throw Err(
"codes oversubscribed");
 
  117    const word64 shiftedMaxCode = ((
word64)1 << m_maxCodeBits);
 
  118    if (code > shiftedMaxCode - blCount[m_maxCodeBits])
 
  119        throw Err(
"codes oversubscribed");
 
  120    else if (m_maxCodeBits != 1 && code < shiftedMaxCode - blCount[m_maxCodeBits])
 
  121        throw Err(
"codes incomplete");
 
  124    m_codeToValue.resize(nCodes - blCount[0]);
 
  126    for (i=0; i<nCodes; i++)
 
  128        unsigned int len = codeBits[i];
 
  132            code = NormalizeCode(nextCode[len]++, len);
 
  133            m_codeToValue[j].code = code;
 
  134            m_codeToValue[j].len = len;
 
  135            m_codeToValue[j].value = i;
 
  139    std::sort(m_codeToValue.begin(), m_codeToValue.end());
 
  142    m_cacheBits = 
STDMIN(9U, m_maxCodeBits);
 
  143    m_cacheMask = (1 << m_cacheBits) - 1;
 
  144    m_normalizedCacheMask = NormalizeCode(m_cacheMask, m_cacheBits);
 
  149    if (m_cache.size() != shiftedCache)
 
  150        m_cache.resize((
size_t)shiftedCache);
 
  152    for (i=0; i<m_cache.size(); i++)
 
  156void HuffmanDecoder::FillCacheEntry(LookupEntry &entry, code_t normalizedCode)
 const 
  158    normalizedCode &= m_normalizedCacheMask;
 
  159    const CodeInfo &codeInfo = *(std::upper_bound(m_codeToValue.begin(), m_codeToValue.end(), normalizedCode, 
CodeLessThan())-1);
 
  160    if (codeInfo.len <= m_cacheBits)
 
  163        entry.value = codeInfo.value;
 
  164        entry.len = codeInfo.len;
 
  168        entry.begin = &codeInfo;
 
  169        const CodeInfo *last = & *(std::upper_bound(m_codeToValue.begin(), m_codeToValue.end(), normalizedCode + ~m_normalizedCacheMask, 
CodeLessThan())-1);
 
  170        if (codeInfo.len == last->len)
 
  173            entry.len = codeInfo.len;
 
  183inline unsigned int HuffmanDecoder::Decode(code_t code,  value_t &value)
 const 
  186    LookupEntry &entry = m_cache[code & m_cacheMask];
 
  188    code_t normalizedCode = 0;
 
  193        FillCacheEntry(entry, normalizedCode);
 
  202        const CodeInfo &codeInfo = (entry.type == 2)
 
  203            ? entry.begin[(normalizedCode << m_cacheBits) >> (MAX_CODE_BITS - (entry.len - m_cacheBits))]
 
  204            : *(std::upper_bound(entry.begin, entry.end, normalizedCode, 
CodeLessThan())-1);
 
  205        value = codeInfo.value;
 
  212    bool result = reader.FillBuffer(m_maxCodeBits);
 
  213    CRYPTOPP_UNUSED(result); 
 
  215    unsigned int codeBits = Decode(reader.PeekBuffer(), value);
 
  216    if (codeBits > reader.BitsBuffered())
 
  218    reader.SkipBits(codeBits);
 
  226    , m_state(PRE_STREAM), m_repeat(repeat), m_eof(0), m_wrappedAround(0)
 
  227    , m_blockType(0xff), m_storedLen(0xffff), m_nextDecode(), m_literal(0)
 
  228    , m_distance(0), m_reader(m_inQueue), m_current(0), m_lastFlush(0)
 
 
  235    m_state = PRE_STREAM;
 
  236    parameters.
GetValue(
"Repeat", m_repeat);
 
  238    m_reader.SkipBits(m_reader.BitsBuffered());
 
 
  241void Inflator::OutputByte(
byte b)
 
  243    m_window[m_current++] = b;
 
  244    if (m_current == m_window.
size())
 
  246        ProcessDecompressedData(m_window + m_lastFlush, m_window.
size() - m_lastFlush);
 
  249        m_wrappedAround = 
true;
 
  253void Inflator::OutputString(
const byte *
string, 
size_t length)
 
  258        std::memcpy(m_window + m_current, 
string, len);
 
  260        if (m_current == m_window.
size())
 
  262            ProcessDecompressedData(m_window + m_lastFlush, m_window.
size() - m_lastFlush);
 
  265            m_wrappedAround = 
true;
 
  272void Inflator::OutputPast(
unsigned int length, 
unsigned int distance)
 
  275    if (distance <= m_current)
 
  276        start = m_current - distance;
 
  277    else if (m_wrappedAround && distance <= m_window.
size())
 
  278        start = m_current + m_window.
size() - distance;
 
  282    if (start + length > m_window.
size())
 
  284        for (; start < m_window.
size(); start++, length--)
 
  285            OutputByte(m_window[start]);
 
  289    if (start + length > m_current || m_current + length >= m_window.
size())
 
  292            OutputByte(m_window[start++]);
 
  296        std::memcpy(m_window + m_current, m_window + start, length);
 
  301size_t Inflator::Put2(
const byte *inString, 
size_t length, 
int messageEnd, 
bool blocking)
 
  307    ProcessInput(messageEnd != 0);
 
  310        if (!(m_state == PRE_STREAM || m_state == AFTER_END))
 
  313    Output(0, NULLPTR, 0, messageEnd, blocking);
 
 
  329void Inflator::ProcessInput(
bool flush)
 
  336            if (!flush && m_inQueue.
CurrentSize() < MaxPrestreamHeaderSize())
 
  338            ProcessPrestreamHeader();
 
  339            m_state = WAIT_HEADER;
 
  340            m_wrappedAround = 
false;
 
  343            m_window.
New(((
size_t) 1) << GetLog2WindowSize());
 
  348            const size_t MAX_HEADER_SIZE = 
BitsToBytes(3+5+5+4+19*7+286*15+19*15);
 
  349            if (m_inQueue.
CurrentSize() < (flush ? 1 : MAX_HEADER_SIZE))
 
  359            if (!flush && m_inQueue.
CurrentSize() < MaxPoststreamTailSize())
 
  361            ProcessPoststreamTail();
 
  362            m_state = m_repeat ? PRE_STREAM : AFTER_END;
 
  374void Inflator::DecodeHeader()
 
  376    if (!m_reader.FillBuffer(3))
 
  377        throw UnexpectedEndErr();
 
  378    m_eof = m_reader.GetBits(1) != 0;
 
  379    m_blockType = (
byte)m_reader.GetBits(2);
 
  385        m_reader.SkipBits(m_reader.BitsBuffered() % 8);
 
  386        if (!m_reader.FillBuffer(32))
 
  387            throw UnexpectedEndErr();
 
  388        m_storedLen = (
word16)m_reader.GetBits(16);
 
  390        if (nlen != (
word16)~m_storedLen)
 
  395        m_nextDecode = LITERAL;
 
  399        if (!m_reader.FillBuffer(5+5+4))
 
  400            throw UnexpectedEndErr();
 
  401        unsigned int hlit = m_reader.GetBits(5);
 
  402        unsigned int hdist = m_reader.GetBits(5);
 
  403        unsigned int hclen = m_reader.GetBits(4);
 
  407        static const unsigned int border[] = {    
 
  408            16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
 
  409        std::fill(codeLengths.
begin(), codeLengths+19, 0);
 
  410        for (i=0; i<hclen+4; ++i)
 
  413            codeLengths[border[i]] = m_reader.GetBits(3);
 
  419            unsigned int k=0, count=0, repeater=0;
 
  421            for (i=0; i < hlit+257+hdist+1; )
 
  423                k = 0, count = 0, repeater = 0;
 
  424                result = codeLengthDecoder.Decode(m_reader, k);
 
  426                    throw UnexpectedEndErr();
 
  435                    if (!m_reader.FillBuffer(2))
 
  436                        throw UnexpectedEndErr();
 
  437                    count = 3 + m_reader.GetBits(2);
 
  440                    repeater = codeLengths[i-1];
 
  443                    if (!m_reader.FillBuffer(3))
 
  444                        throw UnexpectedEndErr();
 
  445                    count = 3 + m_reader.GetBits(3);
 
  449                    if (!m_reader.FillBuffer(7))
 
  450                        throw UnexpectedEndErr();
 
  451                    count = 11 + m_reader.GetBits(7);
 
  455                if (i + count > hlit+257+hdist+1)
 
  457                std::fill(codeLengths + i, codeLengths + i + count, repeater);
 
  460            m_dynamicLiteralDecoder.Initialize(codeLengths, hlit+257);
 
  461            if (hdist == 0 && codeLengths[hlit+257] == 0)
 
  467                m_dynamicDistanceDecoder.Initialize(codeLengths+hlit+257, hdist+1);
 
  468            m_nextDecode = LITERAL;
 
  479    m_state = DECODING_BODY;
 
  482bool Inflator::DecodeBody()
 
  484    bool blockEnd = 
false;
 
  489        while (!m_inQueue.
IsEmpty() && !blockEnd)
 
  492            const byte *block = m_inQueue.
Spy(size);
 
  496            OutputString(block, size);
 
  497            m_inQueue.
Skip(size);
 
  498            m_storedLen = m_storedLen - (
word16)size;
 
  499            if (m_storedLen == 0)
 
  505        static const unsigned int lengthStarts[] = {
 
  506            3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
 
  507            35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
 
  508        static const unsigned int lengthExtraBits[] = {
 
  509            0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
 
  510            3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
 
  511        static const unsigned int distanceStarts[] = {
 
  512            1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
 
  513            257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
 
  514            8193, 12289, 16385, 24577};
 
  515        static const unsigned int distanceExtraBits[] = {
 
  516            0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
 
  517            7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
 
  523        switch (m_nextDecode)
 
  528                if (!literalDecoder.Decode(m_reader, m_literal))
 
  530                    m_nextDecode = LITERAL;
 
  534                    OutputByte((
byte)m_literal);
 
  535                else if (m_literal == 256)  
 
  547                    bits = lengthExtraBits[m_literal-257];
 
  548                    if (!m_reader.FillBuffer(bits))
 
  550                        m_nextDecode = LENGTH_BITS;
 
  554                    m_literal = m_reader.GetBits(bits) + lengthStarts[m_literal-257];
 
  556                    if (!distanceDecoder.Decode(m_reader, m_distance))
 
  558                        m_nextDecode = DISTANCE;
 
  563                    if (m_distance >= 
COUNTOF(distanceExtraBits))
 
  564                        throw BadDistanceErr();
 
  565                    bits = distanceExtraBits[m_distance];
 
  566                    if (!m_reader.FillBuffer(bits))
 
  568                        m_nextDecode = DISTANCE_BITS;
 
  572                    if (m_distance >= 
COUNTOF(distanceStarts))
 
  573                        throw BadDistanceErr();
 
  574                    m_distance = m_reader.GetBits(bits) + distanceStarts[m_distance];
 
  575                    OutputPast(m_literal, m_distance);
 
  588            m_reader.SkipBits(m_reader.BitsBuffered()%8);
 
  589            if (m_reader.BitsBuffered())
 
  593                for (
unsigned int i=0; i<buffer.size(); i++)
 
  594                    buffer[i] = (
byte)m_reader.GetBits(8);
 
  595                m_inQueue.
Unget(buffer, buffer.size());
 
  597            m_state = POST_STREAM;
 
  600            m_state = WAIT_HEADER;
 
  605void Inflator::FlushOutput()
 
  607    if (m_state != PRE_STREAM)
 
  610        ProcessDecompressedData(m_window + m_lastFlush, m_current - m_lastFlush);
 
  611        m_lastFlush = m_current;
 
  615void Inflator::CreateFixedLiteralDecoder()
 
  617    unsigned int codeLengths[288];
 
  618    std::fill(codeLengths + 0, codeLengths + 144, 8);
 
  619    std::fill(codeLengths + 144, codeLengths + 256, 9);
 
  620    std::fill(codeLengths + 256, codeLengths + 280, 7);
 
  621    std::fill(codeLengths + 280, codeLengths + 288, 8);
 
  623    m_fixedLiteralDecoder->Initialize(codeLengths, 288);
 
  626void Inflator::CreateFixedDistanceDecoder()
 
  628    unsigned int codeLengths[32];
 
  629    std::fill(codeLengths + 0, codeLengths + 32, 5);
 
  631    m_fixedDistanceDecoder->Initialize(codeLengths, 32);
 
  636    if (m_blockType == 1)
 
  638        if (m_fixedLiteralDecoder.get() == NULLPTR)
 
  639            CreateFixedLiteralDecoder();
 
  640        return *m_fixedLiteralDecoder;
 
  644        return m_dynamicLiteralDecoder;
 
  650    if (m_blockType == 1)
 
  652        if (m_fixedDistanceDecoder.get() == NULLPTR)
 
  653            CreateFixedDistanceDecoder();
 
  654        return *m_fixedDistanceDecoder;
 
  658        return m_dynamicDistanceDecoder;
 
Provides auto signaling support.
 
int GetAutoSignalPropagation() const
Retrieve automatic signal propagation value.
 
lword CurrentSize() const
Determine data size.
 
void Clear()
Empty the queue.
 
void Unget(byte inByte)
Insert data in the queue.
 
bool IsEmpty() const
Determine data availability.
 
const byte * Spy(size_t &contiguousSize) const
Peek data in the queue.
 
Implementation of BufferedTransformation's attachment interface.
 
void Detach(BufferedTransformation *newAttachment=NULL)
Replace an attached transformation.
 
BufferedTransformation * AttachedTransformation()
Retrieve attached transformation.
 
Fixed size stack-based SecBlock.
 
Exception thrown when a truncated stream is encountered.
 
void IsolatedInitialize(const NameValuePairs ¶meters)
Initialize or reinitialize this object, without signal propagation.
 
Inflator(BufferedTransformation *attachment=NULL, bool repeat=false, int autoSignalPropagation=-1)
RFC 1951 Decompressor.
 
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
 
bool IsolatedFlush(bool hardFlush, bool blocking)
Flushes data buffered by this object, without signal propagation.
 
Helper class to finalize Puts on ByteQueue.
 
Interface for retrieving values given their names.
 
bool GetValue(const char *name, T &value) const
Get a named value.
 
iterator begin()
Provides an iterator pointing to the first element in the memory block.
 
void New(size_type newSize)
Change size without preserving contents.
 
size_type size() const
Provides the count of elements in the SecBlock.
 
Stack-based SecBlock that grows into the heap.
 
unsigned char byte
8-bit unsigned datatype
 
unsigned short word16
16-bit unsigned datatype
 
unsigned long long word64
64-bit unsigned datatype
 
byte BitReverse(byte value)
Reverses bits in a 8-bit value.
 
#define COUNTOF(arr)
Counts elements in an array.
 
#define SIZE_MAX
The maximum value of a machine word.
 
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
 
size_t BitsToBytes(size_t bitCount)
Returns the number of 8-bit bytes or octets required for the specified number of bits.
 
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be negative and incorrectly promoted.
 
Crypto++ library namespace.
 
Classes and functions for secure memory allocations.
 
Classes for automatic resource management.
 
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
 
DEFLATE compression and decompression (RFC 1951)