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

Generated on Thu Jul 5 22:21:38 2007 for Crypto++ by  doxygen 1.5.2