zfstream.cc 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "zfstream.h"
  2. #include <zlib.h>
  3. #include <cassert>
  4. ozstream::ozstream(vostream *output)
  5. : output(output)
  6. {
  7. zstream.zalloc = Z_NULL;
  8. zstream.zfree = Z_NULL;
  9. zstream.opaque = Z_NULL;
  10. int ret = deflateInit(&zstream, level);
  11. assert(ret == Z_OK);
  12. }
  13. ozstream::~ozstream()
  14. {
  15. doCompress(true);
  16. deflateEnd(&zstream);
  17. delete output;
  18. }
  19. void ozstream::write(const char* s, std::streamsize n)
  20. {
  21. zstream.next_in = (Bytef*)s;
  22. zstream.avail_in = n;
  23. doCompress(false);
  24. }
  25. void ozstream::doCompress(bool finish)
  26. {
  27. /* Consume all data in zstream.next_in and write it to the output stream */
  28. int ret;
  29. do
  30. {
  31. zstream.next_out = (Bytef*)buffer;
  32. zstream.avail_out = chunksize;
  33. ret = deflate(&zstream, finish ? Z_FINISH : Z_NO_FLUSH);
  34. assert(ret != Z_STREAM_ERROR);
  35. output->write(buffer, chunksize - zstream.avail_out);
  36. } while(zstream.avail_out == 0);
  37. assert(zstream.avail_in == 0); /* all input will be used */
  38. if (finish)
  39. assert(ret == Z_STREAM_END);
  40. }
  41. izstream::izstream(vistream *input)
  42. : input(input)
  43. , m_eof(false)
  44. , m_fail(false)
  45. , peek_valid(false)
  46. {
  47. zstream.zalloc = Z_NULL;
  48. zstream.zfree = Z_NULL;
  49. zstream.opaque = Z_NULL;
  50. zstream.avail_in = 0;
  51. zstream.next_in = Z_NULL;
  52. int ret = inflateInit(&zstream);
  53. assert(ret == Z_OK);
  54. }
  55. izstream::~izstream()
  56. {
  57. inflateEnd(&zstream);
  58. delete input;
  59. }
  60. void izstream::read(char* s, std::streamsize n)
  61. {
  62. if (peek_valid)
  63. {
  64. s[0] = peek_value;
  65. peek_valid = false;
  66. ++s;
  67. --n;
  68. }
  69. if (n == 0)
  70. return;
  71. zstream.next_out = (Bytef*)s;
  72. zstream.avail_out = n;
  73. do
  74. {
  75. if (zstream.avail_in == 0) // If input data was left over from the previous call, use that up first
  76. {
  77. input->read(buffer, chunksize);
  78. zstream.next_in = (Bytef*)buffer;
  79. zstream.avail_in = chunksize;
  80. }
  81. int ret = inflate(&zstream, Z_NO_FLUSH);
  82. if (ret == Z_STREAM_END) {
  83. m_eof = true;
  84. if (zstream.avail_out)
  85. {
  86. m_fail = true;
  87. return;
  88. }
  89. } else
  90. assert(ret == Z_OK);
  91. } while(zstream.avail_out != 0);
  92. }
  93. int izstream::peek()
  94. {
  95. if (peek_valid == true)
  96. return peek_value;
  97. read(&peek_value, 1);
  98. peek_valid = true;
  99. return peek_value;
  100. }