Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
4.6 KiB

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