Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

zinflate.h

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, /* out */ 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;     // for LENGTH_BITS or DISTANCE_BITS
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

Generated at Mon Jan 15 01:16:38 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000