1#ifndef CRYPTOPP_ZINFLATE_H
2#define CRYPTOPP_ZINFLATE_H
3
4#include "filters.h"
5#include <vector>
6
7NAMESPACE_BEGIN(CryptoPP)
8
9//! _
10class LowFirstBitReader
11{
12public:
13	LowFirstBitReader(BufferedTransformation &store)
14		: m_store(store), m_buffer(0), m_bitsBuffered(0) {}
15//	unsigned long BitsLeft() const {return m_store.MaxRetrievable() * 8 + m_bitsBuffered;}
16	unsigned int BitsBuffered() const {return m_bitsBuffered;}
17	unsigned long PeekBuffer() const {return m_buffer;}
18	bool FillBuffer(unsigned int length);
19	unsigned long PeekBits(unsigned int length);
20	void SkipBits(unsigned int length);
21	unsigned long GetBits(unsigned int length);
22
23private:
24	BufferedTransformation &m_store;
25	unsigned long m_buffer;
26	unsigned int m_bitsBuffered;
27};
28
29struct CodeLessThan;
30
31//! Huffman Decoder
32class HuffmanDecoder
33{
34public:
35	typedef unsigned int code_t;
36	typedef unsigned int value_t;
37	enum {MAX_CODE_BITS = sizeof(code_t)*8};
38
39	class Err : public Exception {public: Err(const std::string &what) : Exception(INVALID_DATA_FORMAT, "HuffmanDecoder: " + what) {}};
40
41	HuffmanDecoder() {}
42	HuffmanDecoder(const unsigned int *codeBitLengths, unsigned int nCodes)	{Initialize(codeBitLengths, nCodes);}
43
44	void Initialize(const unsigned int *codeBitLengths, unsigned int nCodes);
45	unsigned int Decode(code_t code, /* out */ value_t &value) const;
46	bool Decode(LowFirstBitReader &reader, value_t &value) const;
47
48private:
49	friend struct CodeLessThan;
50
51	struct CodeInfo
52	{
53		CodeInfo(code_t code=0, unsigned int len=0, value_t value=0) : code(code), len(len), value(value) {}
54		inline bool operator<(const CodeInfo &rhs) const {return code < rhs.code;}
55		code_t code;
56		unsigned int len;
57		value_t value;
58	};
59
60	struct LookupEntry
61	{
62		unsigned int type;
63		union
64		{
65			value_t value;
66			const CodeInfo *begin;
67		};
68		union
69		{
70			unsigned int len;
71			const CodeInfo *end;
72		};
73	};
74
75	static code_t NormalizeCode(code_t code, unsigned int codeBits);
76	void FillCacheEntry(LookupEntry &entry, code_t normalizedCode) const;
77
78	unsigned int m_maxCodeBits, m_cacheBits, m_cacheMask, m_normalizedCacheMask;
79	std::vector<CodeInfo, AllocatorWithCleanup<CodeInfo> > m_codeToValue;
80	mutable std::vector<LookupEntry, AllocatorWithCleanup<LookupEntry> > m_cache;
81};
82
83//! DEFLATE (RFC 1951) decompressor
84
85class Inflator : public AutoSignaling<Filter>
86{
87public:
88	class Err : public Exception
89	{
90	public:
91		Err(ErrorType e, const std::string &s)
92			: Exception(e, s) {}
93	};
94	class UnexpectedEndErr : public Err {public: UnexpectedEndErr() : Err(INVALID_DATA_FORMAT, "Inflator: unexpected end of compressed block") {}};
95	class BadBlockErr : public Err {public: BadBlockErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in compressed block") {}};
96
97	/*! \param repeat decompress multiple compressed streams in series
98		\param autoSignalPropagation 0 to turn off MessageEnd signal
99	*/
100	Inflator(BufferedTransformation *attachment = NULL, bool repeat = false, int autoSignalPropagation = -1);
101
102	void IsolatedInitialize(const NameValuePairs &parameters);
103	size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
104	bool IsolatedFlush(bool hardFlush, bool blocking);
105
106	virtual unsigned int GetLog2WindowSize() const {return 15;}
107
108protected:
109	ByteQueue m_inQueue;
110
111private:
112	virtual unsigned int MaxPrestreamHeaderSize() const {return 0;}
113	virtual void ProcessPrestreamHeader() {}
114	virtual void ProcessDecompressedData(const byte *string, size_t length)
115		{AttachedTransformation()->Put(string, length);}
116	virtual unsigned int MaxPoststreamTailSize() const {return 0;}
117	virtual void ProcessPoststreamTail() {}
118
119	void ProcessInput(bool flush);
120	void DecodeHeader();
121	bool DecodeBody();
122	void FlushOutput();
123	void OutputByte(byte b);
124	void OutputString(const byte *string, size_t length);
125	void OutputPast(unsigned int length, unsigned int distance);
126
127	static const HuffmanDecoder *FixedLiteralDecoder();
128	static const HuffmanDecoder *FixedDistanceDecoder();
129
130	const HuffmanDecoder& GetLiteralDecoder() const;
131	const HuffmanDecoder& GetDistanceDecoder() const;
132
133	enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END};
134	State m_state;
135	bool m_repeat, m_eof, m_wrappedAround;
136	byte m_blockType;
137	word16 m_storedLen;
138	enum NextDecode {LITERAL, LENGTH_BITS, DISTANCE, DISTANCE_BITS};
139	NextDecode m_nextDecode;
140	unsigned int m_literal, m_distance;	// for LENGTH_BITS or DISTANCE_BITS
141	HuffmanDecoder m_dynamicLiteralDecoder, m_dynamicDistanceDecoder;
142	LowFirstBitReader m_reader;
143	SecByteBlock m_window;
144	size_t m_current, m_lastFlush;
145};
146
147NAMESPACE_END
148
149#endif
150