1#ifndef CRYPTOPP_ZINFLATE_H 2#define CRYPTOPP_ZINFLATE_H 3 4#include "filters.h" 5#include <vector> 6 7NAMESPACE_BEGIN(CryptoPP) 8 9//! _ 10class LowFirstBitReader 11{ 12public: 13 LowFirstBitReader(BufferedTransformation &store) 14 : m_store(store), m_buffer(0), m_bitsBuffered(0) {} 15// unsigned long BitsLeft() const {return m_store.MaxRetrievable() * 8 + m_bitsBuffered;} 16 unsigned int BitsBuffered() const {return m_bitsBuffered;} 17 unsigned long PeekBuffer() const {return m_buffer;} 18 bool FillBuffer(unsigned int length); 19 unsigned long PeekBits(unsigned int length); 20 void SkipBits(unsigned int length); 21 unsigned long GetBits(unsigned int length); 22 23private: 24 BufferedTransformation &m_store; 25 unsigned long m_buffer; 26 unsigned int m_bitsBuffered; 27}; 28 29struct CodeLessThan; 30 31//! Huffman Decoder 32class HuffmanDecoder 33{ 34public: 35 typedef unsigned int code_t; 36 typedef unsigned int value_t; 37 enum {MAX_CODE_BITS = sizeof(code_t)*8}; 38 39 class Err : public Exception {public: Err(const std::string &what) : Exception(INVALID_DATA_FORMAT, "HuffmanDecoder: " + what) {}}; 40 41 HuffmanDecoder() {} 42 HuffmanDecoder(const unsigned int *codeBitLengths, unsigned int nCodes) {Initialize(codeBitLengths, nCodes);} 43 44 void Initialize(const unsigned int *codeBitLengths, unsigned int nCodes); 45 unsigned int Decode(code_t code, /* out */ value_t &value) const; 46 bool Decode(LowFirstBitReader &reader, value_t &value) const; 47 48private: 49 friend struct CodeLessThan; 50 51 struct CodeInfo 52 { 53 CodeInfo(code_t code=0, unsigned int len=0, value_t value=0) : code(code), len(len), value(value) {} 54 inline bool operator<(const CodeInfo &rhs) const {return code < rhs.code;} 55 code_t code; 56 unsigned int len; 57 value_t value; 58 }; 59 60 struct LookupEntry 61 { 62 unsigned int type; 63 union 64 { 65 value_t value; 66 const CodeInfo *begin; 67 }; 68 union 69 { 70 unsigned int len; 71 const CodeInfo *end; 72 }; 73 }; 74 75 static code_t NormalizeCode(code_t code, unsigned int codeBits); 76 void FillCacheEntry(LookupEntry &entry, code_t normalizedCode) const; 77 78 unsigned int m_maxCodeBits, m_cacheBits, m_cacheMask, m_normalizedCacheMask; 79 std::vector<CodeInfo, AllocatorWithCleanup<CodeInfo> > m_codeToValue; 80 mutable std::vector<LookupEntry, AllocatorWithCleanup<LookupEntry> > m_cache; 81}; 82 83//! DEFLATE (RFC 1951) decompressor 84 85class Inflator : public AutoSignaling<Filter> 86{ 87public: 88 class Err : public Exception 89 { 90 public: 91 Err(ErrorType e, const std::string &s) 92 : Exception(e, s) {} 93 }; 94 class UnexpectedEndErr : public Err {public: UnexpectedEndErr() : Err(INVALID_DATA_FORMAT, "Inflator: unexpected end of compressed block") {}}; 95 class BadBlockErr : public Err {public: BadBlockErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in compressed block") {}}; 96 97 /*! \param repeat decompress multiple compressed streams in series 98 \param autoSignalPropagation 0 to turn off MessageEnd signal 99 */ 100 Inflator(BufferedTransformation *attachment = NULL, bool repeat = false, int autoSignalPropagation = -1); 101 102 void IsolatedInitialize(const NameValuePairs ¶meters); 103 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); 104 bool IsolatedFlush(bool hardFlush, bool blocking); 105 106 virtual unsigned int GetLog2WindowSize() const {return 15;} 107 108protected: 109 ByteQueue m_inQueue; 110 111private: 112 virtual unsigned int MaxPrestreamHeaderSize() const {return 0;} 113 virtual void ProcessPrestreamHeader() {} 114 virtual void ProcessDecompressedData(const byte *string, size_t length) 115 {AttachedTransformation()->Put(string, length);} 116 virtual unsigned int MaxPoststreamTailSize() const {return 0;} 117 virtual void ProcessPoststreamTail() {} 118 119 void ProcessInput(bool flush); 120 void DecodeHeader(); 121 bool DecodeBody(); 122 void FlushOutput(); 123 void OutputByte(byte b); 124 void OutputString(const byte *string, size_t length); 125 void OutputPast(unsigned int length, unsigned int distance); 126 127 static const HuffmanDecoder *FixedLiteralDecoder(); 128 static const HuffmanDecoder *FixedDistanceDecoder(); 129 130 const HuffmanDecoder& GetLiteralDecoder() const; 131 const HuffmanDecoder& GetDistanceDecoder() const; 132 133 enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END}; 134 State m_state; 135 bool m_repeat, m_eof, m_wrappedAround; 136 byte m_blockType; 137 word16 m_storedLen; 138 enum NextDecode {LITERAL, LENGTH_BITS, DISTANCE, DISTANCE_BITS}; 139 NextDecode m_nextDecode; 140 unsigned int m_literal, m_distance; // for LENGTH_BITS or DISTANCE_BITS 141 HuffmanDecoder m_dynamicLiteralDecoder, m_dynamicDistanceDecoder; 142 LowFirstBitReader m_reader; 143 SecByteBlock m_window; 144 size_t m_current, m_lastFlush; 145}; 146 147NAMESPACE_END 148 149#endif 150