zfstream.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. #include "zfstream.h"
  2. gzfilebuf::gzfilebuf() :
  3. file(NULL),
  4. mode(0),
  5. own_file_descriptor(0)
  6. { }
  7. gzfilebuf::~gzfilebuf() {
  8. sync();
  9. if ( own_file_descriptor )
  10. close();
  11. }
  12. gzfilebuf *gzfilebuf::open( const char *name,
  13. int io_mode ) {
  14. if ( is_open() )
  15. return NULL;
  16. char char_mode[10];
  17. char *p = char_mode;
  18. if ( io_mode & ios::in ) {
  19. mode = ios::in;
  20. *p++ = 'r';
  21. } else if ( io_mode & ios::app ) {
  22. mode = ios::app;
  23. *p++ = 'a';
  24. } else {
  25. mode = ios::out;
  26. *p++ = 'w';
  27. }
  28. if ( io_mode & ios::binary ) {
  29. mode |= ios::binary;
  30. *p++ = 'b';
  31. }
  32. // Hard code the compression level
  33. if ( io_mode & (ios::out|ios::app )) {
  34. *p++ = '9';
  35. }
  36. // Put the end-of-string indicator
  37. *p = '\0';
  38. if ( (file = gzopen(name, char_mode)) == NULL )
  39. return NULL;
  40. own_file_descriptor = 1;
  41. return this;
  42. }
  43. gzfilebuf *gzfilebuf::attach( int file_descriptor,
  44. int io_mode ) {
  45. if ( is_open() )
  46. return NULL;
  47. char char_mode[10];
  48. char *p = char_mode;
  49. if ( io_mode & ios::in ) {
  50. mode = ios::in;
  51. *p++ = 'r';
  52. } else if ( io_mode & ios::app ) {
  53. mode = ios::app;
  54. *p++ = 'a';
  55. } else {
  56. mode = ios::out;
  57. *p++ = 'w';
  58. }
  59. if ( io_mode & ios::binary ) {
  60. mode |= ios::binary;
  61. *p++ = 'b';
  62. }
  63. // Hard code the compression level
  64. if ( io_mode & (ios::out|ios::app )) {
  65. *p++ = '9';
  66. }
  67. // Put the end-of-string indicator
  68. *p = '\0';
  69. if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
  70. return NULL;
  71. own_file_descriptor = 0;
  72. return this;
  73. }
  74. gzfilebuf *gzfilebuf::close() {
  75. if ( is_open() ) {
  76. sync();
  77. gzclose( file );
  78. file = NULL;
  79. }
  80. return this;
  81. }
  82. int gzfilebuf::setcompressionlevel( int comp_level ) {
  83. return gzsetparams(file, comp_level, -2);
  84. }
  85. int gzfilebuf::setcompressionstrategy( int comp_strategy ) {
  86. return gzsetparams(file, -2, comp_strategy);
  87. }
  88. streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
  89. return streampos(EOF);
  90. }
  91. int gzfilebuf::underflow() {
  92. // If the file hasn't been opened for reading, error.
  93. if ( !is_open() || !(mode & ios::in) )
  94. return EOF;
  95. // if a buffer doesn't exists, allocate one.
  96. if ( !base() ) {
  97. if ( (allocate()) == EOF )
  98. return EOF;
  99. setp(0,0);
  100. } else {
  101. if ( in_avail() )
  102. return (unsigned char) *gptr();
  103. if ( out_waiting() ) {
  104. if ( flushbuf() == EOF )
  105. return EOF;
  106. }
  107. }
  108. // Attempt to fill the buffer.
  109. int result = fillbuf();
  110. if ( result == EOF ) {
  111. // disable get area
  112. setg(0,0,0);
  113. return EOF;
  114. }
  115. return (unsigned char) *gptr();
  116. }
  117. int gzfilebuf::overflow( int c ) {
  118. if ( !is_open() || !(mode & ios::out) )
  119. return EOF;
  120. if ( !base() ) {
  121. if ( allocate() == EOF )
  122. return EOF;
  123. setg(0,0,0);
  124. } else {
  125. if (in_avail()) {
  126. return EOF;
  127. }
  128. if (out_waiting()) {
  129. if (flushbuf() == EOF)
  130. return EOF;
  131. }
  132. }
  133. int bl = blen();
  134. setp( base(), base() + bl);
  135. if ( c != EOF ) {
  136. *pptr() = c;
  137. pbump(1);
  138. }
  139. return 0;
  140. }
  141. int gzfilebuf::sync() {
  142. if ( !is_open() )
  143. return EOF;
  144. if ( out_waiting() )
  145. return flushbuf();
  146. return 0;
  147. }
  148. int gzfilebuf::flushbuf() {
  149. int n;
  150. char *q;
  151. q = pbase();
  152. n = pptr() - q;
  153. if ( gzwrite( file, q, n) < n )
  154. return EOF;
  155. setp(0,0);
  156. return 0;
  157. }
  158. int gzfilebuf::fillbuf() {
  159. int required;
  160. char *p;
  161. p = base();
  162. required = blen();
  163. int t = gzread( file, p, required );
  164. if ( t <= 0) return EOF;
  165. setg( base(), base(), base()+t);
  166. return t;
  167. }
  168. gzfilestream_common::gzfilestream_common() :
  169. ios( gzfilestream_common::rdbuf() )
  170. { }
  171. gzfilestream_common::~gzfilestream_common()
  172. { }
  173. void gzfilestream_common::attach( int fd, int io_mode ) {
  174. if ( !buffer.attach( fd, io_mode) )
  175. clear( ios::failbit | ios::badbit );
  176. else
  177. clear();
  178. }
  179. void gzfilestream_common::open( const char *name, int io_mode ) {
  180. if ( !buffer.open( name, io_mode ) )
  181. clear( ios::failbit | ios::badbit );
  182. else
  183. clear();
  184. }
  185. void gzfilestream_common::close() {
  186. if ( !buffer.close() )
  187. clear( ios::failbit | ios::badbit );
  188. }
  189. gzfilebuf *gzfilestream_common::rdbuf()
  190. {
  191. return &buffer;
  192. }
  193. gzifstream::gzifstream() :
  194. ios( gzfilestream_common::rdbuf() )
  195. {
  196. clear( ios::badbit );
  197. }
  198. gzifstream::gzifstream( const char *name, int io_mode ) :
  199. ios( gzfilestream_common::rdbuf() )
  200. {
  201. gzfilestream_common::open( name, io_mode );
  202. }
  203. gzifstream::gzifstream( int fd, int io_mode ) :
  204. ios( gzfilestream_common::rdbuf() )
  205. {
  206. gzfilestream_common::attach( fd, io_mode );
  207. }
  208. gzifstream::~gzifstream() { }
  209. gzofstream::gzofstream() :
  210. ios( gzfilestream_common::rdbuf() )
  211. {
  212. clear( ios::badbit );
  213. }
  214. gzofstream::gzofstream( const char *name, int io_mode ) :
  215. ios( gzfilestream_common::rdbuf() )
  216. {
  217. gzfilestream_common::open( name, io_mode );
  218. }
  219. gzofstream::gzofstream( int fd, int io_mode ) :
  220. ios( gzfilestream_common::rdbuf() )
  221. {
  222. gzfilestream_common::attach( fd, io_mode );
  223. }
  224. gzofstream::~gzofstream() { }