Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

ZlibInStream.cxx 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21. #include <assert.h>
  22. #include <rdr/ZlibInStream.h>
  23. #include <rdr/Exception.h>
  24. #include <zlib.h>
  25. using namespace rdr;
  26. ZlibInStream::ZlibInStream()
  27. : underlying(0), zs(NULL), bytesIn(0)
  28. {
  29. init();
  30. }
  31. ZlibInStream::~ZlibInStream()
  32. {
  33. deinit();
  34. }
  35. void ZlibInStream::setUnderlying(InStream* is, size_t bytesIn_)
  36. {
  37. underlying = is;
  38. bytesIn = bytesIn_;
  39. skip(avail());
  40. }
  41. void ZlibInStream::flushUnderlying()
  42. {
  43. while (bytesIn > 0) {
  44. if (!hasData(1))
  45. throw Exception("ZlibInStream: failed to flush remaining stream data");
  46. skip(avail());
  47. }
  48. setUnderlying(NULL, 0);
  49. }
  50. void ZlibInStream::reset()
  51. {
  52. deinit();
  53. init();
  54. }
  55. void ZlibInStream::init()
  56. {
  57. assert(zs == NULL);
  58. zs = new z_stream;
  59. zs->zalloc = Z_NULL;
  60. zs->zfree = Z_NULL;
  61. zs->opaque = Z_NULL;
  62. zs->next_in = Z_NULL;
  63. zs->avail_in = 0;
  64. if (inflateInit(zs) != Z_OK) {
  65. delete zs;
  66. zs = NULL;
  67. throw Exception("ZlibInStream: inflateInit failed");
  68. }
  69. }
  70. void ZlibInStream::deinit()
  71. {
  72. assert(zs != NULL);
  73. setUnderlying(NULL, 0);
  74. inflateEnd(zs);
  75. delete zs;
  76. zs = NULL;
  77. }
  78. bool ZlibInStream::fillBuffer()
  79. {
  80. if (!underlying)
  81. throw Exception("ZlibInStream overrun: no underlying stream");
  82. zs->next_out = (uint8_t*)end;
  83. zs->avail_out = availSpace();
  84. if (!underlying->hasData(1))
  85. return false;
  86. size_t length = underlying->avail();
  87. if (length > bytesIn)
  88. length = bytesIn;
  89. zs->next_in = (uint8_t*)underlying->getptr(length);
  90. zs->avail_in = length;
  91. int rc = inflate(zs, Z_SYNC_FLUSH);
  92. if (rc < 0) {
  93. throw Exception("ZlibInStream: inflate failed");
  94. }
  95. bytesIn -= length - zs->avail_in;
  96. end = zs->next_out;
  97. underlying->setptr(length - zs->avail_in);
  98. return true;
  99. }