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