- Main Page
- Namespaces
- Classes
- Files

# zinflate.h

    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 //      unsigned long BitsLeft() const {return m_store.MaxRetrievable() * 8 + m_bitsBuffered;}
    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 //! Huffman Decoder
    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, /* out */ 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 //! DEFLATE (RFC 1951) decompressor
    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         /*! \param repeat decompress multiple compressed streams in series
    00098                 \param autoSignalPropagation 0 to turn off MessageEnd signal
    00099         */
    00100         Inflator(BufferedTransformation *attachment = NULL, bool repeat = false, int autoSignalPropagation = -1);
    00101
    00102         void IsolatedInitialize(const NameValuePairs &parameters);
    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;     // for LENGTH_BITS or DISTANCE_BITS
    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