You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

329 lines
4.9 KiB

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