Crypto++
zinflate.h
1 #ifndef CRYPTOPP_ZINFLATE_H
2 #define CRYPTOPP_ZINFLATE_H
3 
4 #include "filters.h"
5 #include <vector>
6 
7 NAMESPACE_BEGIN(CryptoPP)
8 
9 //! _
11 {
12 public:
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 
23 private:
24  BufferedTransformation &m_store;
25  unsigned long m_buffer;
26  unsigned int m_bitsBuffered;
27 };
28 
29 struct CodeLessThan;
30 
31 //! Huffman Decoder
33 {
34 public:
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 
48 private:
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 
85 class Inflator : public AutoSignaling<Filter>
86 {
87 public:
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 
108 protected:
109  ByteQueue m_inQueue;
110 
111 private:
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 
147 NAMESPACE_END
148 
149 #endif
base class for all exceptions thrown by Crypto++
Definition: cryptlib.h:109
ErrorType
error types
Definition: cryptlib.h:113
interface for buffered transformations
Definition: cryptlib.h:770
received input data that doesn't conform to expected format
Definition: cryptlib.h:123
size_t Put(byte inByte, bool blocking=true)
input a byte for processing
Definition: cryptlib.h:784
Huffman Decoder.
Definition: zinflate.h:32
bool operator<(const ::PolynomialMod2 &a, const ::PolynomialMod2 &b)
compares degree
Definition: gf2n.h:252
Byte Queue.
Definition: queue.h:16
DEFLATE (RFC 1951) decompressor.
Definition: zinflate.h:85
interface for retrieving values given their names
Definition: cryptlib.h:224