CCompressedStream.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #pragma once
  2. /*
  3. * CCompressedStream.h, part of VCMI engine
  4. *
  5. * Authors: listed in file AUTHORS in main folder
  6. *
  7. * License: GNU General Public License v2.0 or later
  8. * Full text of license available in license.txt file, in main folder
  9. *
  10. */
  11. #include "CInputStream.h"
  12. struct z_stream_s;
  13. /// Abstract class that provides buffer for one-directional input streams (e.g. compressed data)
  14. /// Used for zip archives support and in .lod deflate compression
  15. class CBufferedStream : public CInputStream
  16. {
  17. public:
  18. CBufferedStream();
  19. /**
  20. * Reads n bytes from the stream into the data buffer.
  21. *
  22. * @param data A pointer to the destination data array.
  23. * @param size The number of bytes to read.
  24. * @return the number of bytes read actually.
  25. *
  26. * @throws std::runtime_error if the file decompression was not successful
  27. */
  28. si64 read(ui8 * data, si64 size) override;
  29. /**
  30. * Seeks the internal read pointer to the specified position.
  31. * This will cause decompressing data till this position is found
  32. *
  33. * @param position The read position from the beginning.
  34. * @return the position actually moved to, -1 on error.
  35. */
  36. si64 seek(si64 position) override;
  37. /**
  38. * Gets the current read position in the stream.
  39. *
  40. * @return the read position.
  41. */
  42. si64 tell() override;
  43. /**
  44. * Skips delta numbers of bytes.
  45. *
  46. * @param delta The count of bytes to skip.
  47. * @return the count of bytes skipped actually.
  48. */
  49. si64 skip(si64 delta) override;
  50. /**
  51. * Gets the length in bytes of the stream.
  52. * Causes complete data decompression
  53. *
  54. * @return the length in bytes of the stream.
  55. */
  56. si64 getSize() override;
  57. protected:
  58. /**
  59. * @brief virtual method to get more data into the buffer
  60. * @return amount of bytes actually read, non-positive values are considered to be end-of-file mark
  61. */
  62. virtual si64 readMore(ui8 * data, si64 size) = 0;
  63. /// resets all internal state
  64. void reset();
  65. private:
  66. /// ensures that buffer contains at lest size of bytes. Calls readMore() to fill remaining part
  67. void ensureSize(si64 size);
  68. /** buffer with already decompressed data */
  69. std::vector<ui8> buffer;
  70. /** Current read position */
  71. si64 position;
  72. bool endOfFileReached;
  73. };
  74. /**
  75. * A class which provides method definitions for reading a gzip-compressed file
  76. * This class implements lazy loading - data will be decompressed (and cached) only by request
  77. */
  78. class DLL_LINKAGE CCompressedStream : public CBufferedStream
  79. {
  80. public:
  81. /**
  82. * C-tor.
  83. *
  84. * @param stream - stream with compresed data
  85. * @param gzip - this is gzipp'ed file e.g. campaign or maps, false for files in lod
  86. * @param decompressedSize - optional parameter to hint size of decompressed data
  87. */
  88. CCompressedStream(std::unique_ptr<CInputStream> stream, bool gzip, size_t decompressedSize=0);
  89. ~CCompressedStream();
  90. /**
  91. * Prepare stream for decompression of next block (e.g. next part of h3c)
  92. * Applicable only for streams that contain multiple concatenated compressed data
  93. *
  94. * @return false if next block was not found, true othervice
  95. */
  96. bool getNextBlock();
  97. private:
  98. /**
  99. * Decompresses data to ensure that buffer has newSize bytes or end of stream was reached
  100. */
  101. si64 readMore(ui8 * data, si64 size) override;
  102. /** The file stream with compressed data. */
  103. std::unique_ptr<CInputStream> gzipStream;
  104. /** buffer with not yet decompressed data*/
  105. std::vector<ui8> compressedBuffer;
  106. /** struct with current zlib inflate state */
  107. z_stream_s * inflateState;
  108. enum EState
  109. {
  110. ERROR_OCCURED,
  111. INITIALIZED,
  112. IN_PROGRESS,
  113. STREAM_END,
  114. FINISHED
  115. };
  116. };