Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

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 unsigned int Put2(const byte *inString, unsigned int 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, unsigned int 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, unsigned int 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 unsigned int m_current, m_lastFlush; 00145 }; 00146 00147 NAMESPACE_END 00148 00149 #endif

Generated on Fri Aug 27 13:36:40 2004 for Crypto++ by doxygen 1.3.8