zinflate.h 5.2 KB

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