CCompressedStream.h 2.9 KB

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