00001 #ifndef CRYPTOPP_ZINFLATE_H
00002 #define CRYPTOPP_ZINFLATE_H
00003
00004 #include "filters.h"
00005 #include <vector>
00006
00007 NAMESPACE_BEGIN(CryptoPP)
00008
00009
00010 class LowFirstBitReader
00011 {
00012 public:
00013 LowFirstBitReader(BufferedTransformation &store)
00014 : m_store(store), m_buffer(0), m_bitsBuffered(0) {}
00015
00016 unsigned int BitsBuffered() const {return m_bitsBuffered;}
00017 unsigned long PeekBuffer() const {return m_buffer;}
00018 bool FillBuffer(unsigned int length);
00019 unsigned long PeekBits(unsigned int length);
00020 void SkipBits(unsigned int length);
00021 unsigned long GetBits(unsigned int length);
00022
00023 private:
00024 BufferedTransformation &m_store;
00025 unsigned long m_buffer;
00026 unsigned int m_bitsBuffered;
00027 };
00028
00029 struct CodeLessThan;
00030
00031
00032 class HuffmanDecoder
00033 {
00034 public:
00035 typedef unsigned int code_t;
00036 typedef unsigned int value_t;
00037 enum {MAX_CODE_BITS = sizeof(code_t)*8};
00038
00039 class Err : public Exception {public: Err(const std::string &what) : Exception(INVALID_DATA_FORMAT, "HuffmanDecoder: " + what) {}};
00040
00041 HuffmanDecoder() {}
00042 HuffmanDecoder(const unsigned int *codeBitLengths, unsigned int nCodes) {Initialize(codeBitLengths, nCodes);}
00043
00044 void Initialize(const unsigned int *codeBitLengths, unsigned int nCodes);
00045 unsigned int Decode(code_t code, value_t &value) const;
00046 bool Decode(LowFirstBitReader &reader, value_t &value) const;
00047
00048 private:
00049 friend struct CodeLessThan;
00050
00051 struct CodeInfo
00052 {
00053 CodeInfo(code_t code=0, unsigned int len=0, value_t value=0) : code(code), len(len), value(value) {}
00054 inline bool operator<(const CodeInfo &rhs) const {return code < rhs.code;}
00055 code_t code;
00056 unsigned int len;
00057 value_t value;
00058 };
00059
00060 struct LookupEntry
00061 {
00062 unsigned int type;
00063 union
00064 {
00065 value_t value;
00066 const CodeInfo *begin;
00067 };
00068 union
00069 {
00070 unsigned int len;
00071 const CodeInfo *end;
00072 };
00073 };
00074
00075 static code_t NormalizeCode(code_t code, unsigned int codeBits);
00076 void FillCacheEntry(LookupEntry &entry, code_t normalizedCode) const;
00077
00078 unsigned int m_maxCodeBits, m_cacheBits, m_cacheMask, m_normalizedCacheMask;
00079 std::vector<CodeInfo, AllocatorWithCleanup<CodeInfo> > m_codeToValue;
00080 mutable std::vector<LookupEntry, AllocatorWithCleanup<LookupEntry> > m_cache;
00081 };
00082
00083
00084
00085 class Inflator : public AutoSignaling<Filter>
00086 {
00087 public:
00088 class Err : public Exception
00089 {
00090 public:
00091 Err(ErrorType e, const std::string &s)
00092 : Exception(e, s) {}
00093 };
00094 class UnexpectedEndErr : public Err {public: UnexpectedEndErr() : Err(INVALID_DATA_FORMAT, "Inflator: unexpected end of compressed block") {}};
00095 class BadBlockErr : public Err {public: BadBlockErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in compressed block") {}};
00096
00097
00098
00099
00100 Inflator(BufferedTransformation *attachment = NULL, bool repeat = false, int autoSignalPropagation = -1);
00101
00102 void IsolatedInitialize(const NameValuePairs ¶meters);
00103 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
00104 bool IsolatedFlush(bool hardFlush, bool blocking);
00105
00106 virtual unsigned int GetLog2WindowSize() const {return 15;}
00107
00108 protected:
00109 ByteQueue m_inQueue;
00110
00111 private:
00112 virtual unsigned int MaxPrestreamHeaderSize() const {return 0;}
00113 virtual void ProcessPrestreamHeader() {}
00114 virtual void ProcessDecompressedData(const byte *string, size_t length)
00115 {AttachedTransformation()->Put(string, length);}
00116 virtual unsigned int MaxPoststreamTailSize() const {return 0;}
00117 virtual void ProcessPoststreamTail() {}
00118
00119 void ProcessInput(bool flush);
00120 void DecodeHeader();
00121 bool DecodeBody();
00122 void FlushOutput();
00123 void OutputByte(byte b);
00124 void OutputString(const byte *string, size_t length);
00125 void OutputPast(unsigned int length, unsigned int distance);
00126
00127 static const HuffmanDecoder *FixedLiteralDecoder();
00128 static const HuffmanDecoder *FixedDistanceDecoder();
00129
00130 const HuffmanDecoder& GetLiteralDecoder() const;
00131 const HuffmanDecoder& GetDistanceDecoder() const;
00132
00133 enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END};
00134 State m_state;
00135 bool m_repeat, m_eof, m_wrappedAround;
00136 byte m_blockType;
00137 word16 m_storedLen;
00138 enum NextDecode {LITERAL, LENGTH_BITS, DISTANCE, DISTANCE_BITS};
00139 NextDecode m_nextDecode;
00140 unsigned int m_literal, m_distance;
00141 HuffmanDecoder m_dynamicLiteralDecoder, m_dynamicDistanceDecoder;
00142 LowFirstBitReader m_reader;
00143 SecByteBlock m_window;
00144 size_t m_current, m_lastFlush;
00145 };
00146
00147 NAMESPACE_END
00148
00149 #endif