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  class BadDistanceErr : public Err {public: BadDistanceErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in bit distance") {}};
97 
98  /*! \param repeat decompress multiple compressed streams in series
99  \param autoSignalPropagation 0 to turn off MessageEnd signal
100  */
101  Inflator(BufferedTransformation *attachment = NULL, bool repeat = false, int autoSignalPropagation = -1);
102 
103  void IsolatedInitialize(const NameValuePairs &parameters);
104  size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
105  bool IsolatedFlush(bool hardFlush, bool blocking);
106 
107  virtual unsigned int GetLog2WindowSize() const {return 15;}
108 
109 protected:
110  ByteQueue m_inQueue;
111 
112 private:
113  virtual unsigned int MaxPrestreamHeaderSize() const {return 0;}
114  virtual void ProcessPrestreamHeader() {}
115  virtual void ProcessDecompressedData(const byte *string, size_t length)
116  {AttachedTransformation()->Put(string, length);}
117  virtual unsigned int MaxPoststreamTailSize() const {return 0;}
118  virtual void ProcessPoststreamTail() {}
119 
120  void ProcessInput(bool flush);
121  void DecodeHeader();
122  bool DecodeBody();
123  void FlushOutput();
124  void OutputByte(byte b);
125  void OutputString(const byte *string, size_t length);
126  void OutputPast(unsigned int length, unsigned int distance);
127 
128  static const HuffmanDecoder *FixedLiteralDecoder();
129  static const HuffmanDecoder *FixedDistanceDecoder();
130 
131  const HuffmanDecoder& GetLiteralDecoder() const;
132  const HuffmanDecoder& GetDistanceDecoder() const;
133 
134  enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END};
135  State m_state;
136  bool m_repeat, m_eof, m_wrappedAround;
137  byte m_blockType;
138  word16 m_storedLen;
139  enum NextDecode {LITERAL, LENGTH_BITS, DISTANCE, DISTANCE_BITS};
140  NextDecode m_nextDecode;
141  unsigned int m_literal, m_distance; // for LENGTH_BITS or DISTANCE_BITS
142  HuffmanDecoder m_dynamicLiteralDecoder, m_dynamicDistanceDecoder;
143  LowFirstBitReader m_reader;
144  SecByteBlock m_window;
145  size_t m_current, m_lastFlush;
146 };
147 
148 NAMESPACE_END
149 
150 #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&#39;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