Advertisement
Guest User

Untitled

a guest
Mar 26th, 2017
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.77 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <boost/noncopyable.hpp>
  4. #include <zlib.h>
  5. #include <string>
  6. #include <cassert>
  7. #include <strings.h> // for bzero
  8.  
  9. class ZlibDecompressor : boost::noncopyable {
  10. public:
  11. ZlibDecompressor(const std::string &input)
  12. : zerror_(Z_OK),
  13. input_(input),
  14. output_()
  15. {
  16. ::bzero(&zstream_, sizeof(zstream_));
  17. z_error_ = inflateInit(&zstream_);
  18. if (z_error_ == Z_OK)
  19. zerror_ = decompress();
  20. }
  21.  
  22. const char *zlibErrorMessage() const { return zstream_.msg; }
  23.  
  24. int zlibErrorCode() const { return zerror_; }
  25.  
  26. ~ZlibDecompressor()
  27. {
  28. if (z_init_error_ == Z_OK)
  29. inflateEnd(&zstream_);
  30. }
  31.  
  32. std::string output() const
  33. {
  34. if(valid())
  35. return output_;
  36. return output_;
  37. }
  38.  
  39. bool valid() const { return zerror_ == Z_OK; }
  40.  
  41. private:
  42.  
  43. const static int CHUNK = 8192;
  44.  
  45. int decompress() {
  46. int ret;
  47. size_t begin = 0;
  48. size_t size = input_.size();
  49. unsigned char out[CHUNK];
  50. do {
  51. int chunk = ((size - begin) < CHUNK ? size - begin : CHUNK);
  52. if (chunk == 0)
  53. break;
  54. zstream_.avail_in = static_cast<uint>(chunk);
  55. zstream_.next_in = (Bytef *) &input_[begin];
  56. do
  57. {
  58. zstream_.avail_out = CHUNK;
  59. zstream_.next_out = (Bytef*)out;
  60. ret = inflate(&zstream_, Z_NO_FLUSH);
  61. assert(ret != Z_STREAM_ERROR);
  62. switch (ret)
  63. {
  64. case Z_NEED_DICT:
  65. ret = Z_DATA_ERROR;
  66. case Z_DATA_ERROR:
  67. case Z_MEM_ERROR:
  68. return ret;
  69. }
  70. int have = CHUNK - static_cast<int>(zstream_.avail_out);
  71. output_.append(out, out + have);
  72. } while (zstream_.avail_out == 0);
  73. begin += chunk;
  74. } while (ret != Z_STREAM_END);
  75. return ret;
  76. }
  77.  
  78. z_stream zstream_;
  79. int zerror_;
  80. std::string input_;
  81. std::string output_;
  82. };
  83.  
  84. class ZlibCompressor : boost::noncopyable {
  85. public:
  86. explicit ZlibCompressor(const std::string &input)
  87. : zerror_(Z_OK),
  88. input_(input),
  89. output_()
  90. {
  91. ::bzero(&zstream_, sizeof(zstream_));
  92. zerror_ = deflateInit(&zstream_, -1);
  93. if(z_error_ == Z_OK)
  94. zerror_ = compress();
  95. }
  96.  
  97. explicit ZlibCompressor(const std::string& input, int level)
  98. : z_init_error_(Z_OK),
  99. zerror_(Z_OK),
  100. input_(input),
  101. output_()
  102. {
  103. assert(level >= -1 && level <= 9);
  104. ::bzero(&zstream_, sizeof(zstream_));
  105. z_init_error_ = deflateInit(&zstream_, level);
  106. if(z_init_error_ == Z_OK)
  107. zerror_ = compress();
  108. }
  109.  
  110. ~ZlibCompressor() {
  111. if(z_init_error_ == Z_OK)
  112. deflateEnd(&zstream_);
  113. }
  114.  
  115. const char *zlibErrorMessage() const { return zstream_.msg; }
  116.  
  117. int zlibErrorCode() const { return zerror_; }
  118.  
  119. std::string output() const
  120. {
  121. if(valid())
  122. return output_;
  123. return "";
  124. }
  125.  
  126. bool valid() const { return zerror_ == Z_OK; }
  127.  
  128. private:
  129.  
  130. const static int CHUNK = 8192;
  131.  
  132. int compress() {
  133. unsigned char out[CHUNK];
  134. size_t size = input_.size();
  135. size_t begin = 0;
  136. int ret;
  137. int flush;
  138. do
  139. {
  140. int chunk;
  141. if(size - begin <= CHUNK)
  142. {
  143. chunk = size - begin;
  144. flush = Z_FINISH;
  145. }
  146. else
  147. {
  148. chunk = CHUNK;
  149. flush = Z_NO_FLUSH;
  150. }
  151. zstream_.avail_in = chunk;
  152. zstream_.next_in = (Bytef *)&input_[begin];
  153. do
  154. {
  155. zstream_.avail_out = CHUNK;
  156. zstream_.next_out = out;
  157. ret = deflate(&zstream_, flush);
  158. assert(ret != Z_STREAM_ERROR);
  159. int have = CHUNK - static_cast<int>(zstream_.avail_out);
  160. output_.append(out, out + have);
  161. }while(zstream_.avail_out == 0);
  162. assert(zstream_.avail_in == 0);
  163. begin += chunk;
  164. }while(flush != Z_FINISH);
  165. assert(ret == Z_STREAM_END);
  166. return Z_OK;
  167. }
  168.  
  169. z_stream zstream_;
  170. int zerror_;
  171. std::string input_;
  172. std::string output_;
  173. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement