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