Crypto++  8.2
Free C++ class library of cryptographic schemes
zinflate.h
Go to the documentation of this file.
1 // zinflate.h - originally written and placed in the public domain by Wei Dai
2 
3 /// \file zinflate.h
4 /// \brief DEFLATE compression and decompression (RFC 1951)
5 
6 #ifndef CRYPTOPP_ZINFLATE_H
7 #define CRYPTOPP_ZINFLATE_H
8 
9 #include "cryptlib.h"
10 #include "secblock.h"
11 #include "filters.h"
12 #include "stdcpp.h"
13 
14 NAMESPACE_BEGIN(CryptoPP)
15 
16 /// \since Crypto++ 1.0
18 {
19 public:
21  : m_store(store), m_buffer(0), m_bitsBuffered(0) {}
22  unsigned int BitsBuffered() const {return m_bitsBuffered;}
23  unsigned long PeekBuffer() const {return m_buffer;}
24  bool FillBuffer(unsigned int length);
25  unsigned long PeekBits(unsigned int length);
26  void SkipBits(unsigned int length);
27  unsigned long GetBits(unsigned int length);
28 
29 private:
30  BufferedTransformation &m_store;
31  unsigned long m_buffer;
32  unsigned int m_bitsBuffered;
33 };
34 
35 struct CodeLessThan;
36 
37 /// \brief Huffman Decoder
38 /// \since Crypto++ 1.0
40 {
41 public:
42  typedef unsigned int code_t;
43  typedef unsigned int value_t;
44  enum {MAX_CODE_BITS = sizeof(code_t)*8};
45 
46  class Err : public Exception {public: Err(const std::string &what) : Exception(INVALID_DATA_FORMAT, "HuffmanDecoder: " + what) {}};
47 
48  HuffmanDecoder() : m_maxCodeBits(0), m_cacheBits(0), m_cacheMask(0), m_normalizedCacheMask(0) {}
49  HuffmanDecoder(const unsigned int *codeBitLengths, unsigned int nCodes)
50  : m_maxCodeBits(0), m_cacheBits(0), m_cacheMask(0), m_normalizedCacheMask(0)
51  {Initialize(codeBitLengths, nCodes);}
52 
53  void Initialize(const unsigned int *codeBitLengths, unsigned int nCodes);
54  unsigned int Decode(code_t code, /* out */ value_t &value) const;
55  bool Decode(LowFirstBitReader &reader, value_t &value) const;
56 
57 private:
58  friend struct CodeLessThan;
59 
60  struct CodeInfo
61  {
62  CodeInfo(code_t code=0, unsigned int len=0, value_t value=0) : code(code), len(len), value(value) {}
63  inline bool operator<(const CodeInfo &rhs) const {return code < rhs.code;}
64  code_t code;
65  unsigned int len;
66  value_t value;
67  };
68 
69  struct LookupEntry
70  {
71  unsigned int type;
72  union
73  {
74  value_t value;
75  const CodeInfo *begin;
76  };
77  union
78  {
79  unsigned int len;
80  const CodeInfo *end;
81  };
82  };
83 
84  static code_t NormalizeCode(code_t code, unsigned int codeBits);
85  void FillCacheEntry(LookupEntry &entry, code_t normalizedCode) const;
86 
87  unsigned int m_maxCodeBits, m_cacheBits, m_cacheMask, m_normalizedCacheMask;
88  std::vector<CodeInfo, AllocatorWithCleanup<CodeInfo> > m_codeToValue;
89  mutable std::vector<LookupEntry, AllocatorWithCleanup<LookupEntry> > m_cache;
90 };
91 
92 /// \brief DEFLATE decompressor (RFC 1951)
93 /// \since Crypto++ 1.0
94 class Inflator : public AutoSignaling<Filter>
95 {
96 public:
97  class Err : public Exception
98  {
99  public:
100  Err(ErrorType e, const std::string &s)
101  : Exception(e, s) {}
102  };
103  /// \brief Exception thrown when a truncated stream is encountered
104  class UnexpectedEndErr : public Err {public: UnexpectedEndErr() : Err(INVALID_DATA_FORMAT, "Inflator: unexpected end of compressed block") {}};
105  /// \brief Exception thrown when a bad block is encountered
106  class BadBlockErr : public Err {public: BadBlockErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in compressed block") {}};
107  /// \brief Exception thrown when an invalid distance is encountered
108  class BadDistanceErr : public Err {public: BadDistanceErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in bit distance") {}};
109 
110  /// \brief RFC 1951 Decompressor
111  /// \param attachment the filter's attached transformation
112  /// \param repeat decompress multiple compressed streams in series
113  /// \param autoSignalPropagation 0 to turn off MessageEnd signal
114  Inflator(BufferedTransformation *attachment = NULLPTR, bool repeat = false, int autoSignalPropagation = -1);
115 
116  void IsolatedInitialize(const NameValuePairs &parameters);
117  size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
118  bool IsolatedFlush(bool hardFlush, bool blocking);
119 
120  virtual unsigned int GetLog2WindowSize() const {return 15;}
121 
122 protected:
123  ByteQueue m_inQueue;
124 
125 private:
126  virtual unsigned int MaxPrestreamHeaderSize() const {return 0;}
127  virtual void ProcessPrestreamHeader() {}
128  virtual void ProcessDecompressedData(const byte *string, size_t length)
129  {AttachedTransformation()->Put(string, length);}
130  virtual unsigned int MaxPoststreamTailSize() const {return 0;}
131  virtual void ProcessPoststreamTail() {}
132 
133  void ProcessInput(bool flush);
134  void DecodeHeader();
135  bool DecodeBody();
136  void FlushOutput();
137  void OutputByte(byte b);
138  void OutputString(const byte *string, size_t length);
139  void OutputPast(unsigned int length, unsigned int distance);
140 
141  void CreateFixedDistanceDecoder();
142  void CreateFixedLiteralDecoder();
143 
144  const HuffmanDecoder& GetLiteralDecoder();
145  const HuffmanDecoder& GetDistanceDecoder();
146 
147  enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END};
148  State m_state;
149  bool m_repeat, m_eof, m_wrappedAround;
150  byte m_blockType;
151  word16 m_storedLen;
152  enum NextDecode {LITERAL, LENGTH_BITS, DISTANCE, DISTANCE_BITS};
153  NextDecode m_nextDecode;
154  unsigned int m_literal, m_distance; // for LENGTH_BITS or DISTANCE_BITS
155  HuffmanDecoder m_dynamicLiteralDecoder, m_dynamicDistanceDecoder;
156  member_ptr<HuffmanDecoder> m_fixedLiteralDecoder, m_fixedDistanceDecoder;
157  LowFirstBitReader m_reader;
158  SecByteBlock m_window;
159  size_t m_current, m_lastFlush;
160 };
161 
162 NAMESPACE_END
163 
164 #endif
Inflator(BufferedTransformation *attachment=NULL, bool repeat=false, int autoSignalPropagation=-1)
RFC 1951 Decompressor.
Definition: zinflate.cpp:224
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:158
ErrorType
Error types or categories.
Definition: cryptlib.h:163
const char * what() const
Retrieves a C-string describing the exception.
Definition: cryptlib.h:186
Exception thrown when a truncated stream is encountered.
Definition: zinflate.h:104
Exception(ErrorType errorType, const std::string &s)
Construct a new Exception.
Definition: cryptlib.h:183
Abstract base classes that provide a uniform interface to this library.
bool IsolatedFlush(bool hardFlush, bool blocking)
Flushes data buffered by this object, without signal propagation.
Definition: zinflate.cpp:317
Common C++ header files.
SecBlock<byte> typedef.
Definition: secblock.h:1058
Interface for buffered transformations.
Definition: cryptlib.h:1627
Classes and functions for secure memory allocations.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
Definition: zinflate.cpp:233
Input data was received that did not conform to expected format.
Definition: cryptlib.h:173
bool operator<(const OID &lhs, const OID &rhs)
Compare two OIDs for ordering.
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1649
BufferedTransformation * AttachedTransformation()
Retrieve attached transformation.
Definition: filters.cpp:36
Exception thrown when an invalid distance is encountered.
Definition: zinflate.h:108
Huffman Decoder.
Definition: zinflate.h:39
Data structure used to store byte strings.
Definition: queue.h:18
Implementation of BufferedTransformation's attachment interface.
DEFLATE decompressor (RFC 1951)
Definition: zinflate.h:94
Provides auto signaling support.
Definition: simple.h:349
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Definition: zinflate.cpp:301
Crypto++ library namespace.
Exception thrown when a bad block is encountered.
Definition: zinflate.h:106
Interface for retrieving values given their names.
Definition: cryptlib.h:321