annotate src/zlib-1.2.8/contrib/iostream3/zfstream.h @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 5ea0608b923f
children
rev   line source
Chris@43 1 /*
Chris@43 2 * A C++ I/O streams interface to the zlib gz* functions
Chris@43 3 *
Chris@43 4 * by Ludwig Schwardt <schwardt@sun.ac.za>
Chris@43 5 * original version by Kevin Ruland <kevin@rodin.wustl.edu>
Chris@43 6 *
Chris@43 7 * This version is standard-compliant and compatible with gcc 3.x.
Chris@43 8 */
Chris@43 9
Chris@43 10 #ifndef ZFSTREAM_H
Chris@43 11 #define ZFSTREAM_H
Chris@43 12
Chris@43 13 #include <istream> // not iostream, since we don't need cin/cout
Chris@43 14 #include <ostream>
Chris@43 15 #include "zlib.h"
Chris@43 16
Chris@43 17 /*****************************************************************************/
Chris@43 18
Chris@43 19 /**
Chris@43 20 * @brief Gzipped file stream buffer class.
Chris@43 21 *
Chris@43 22 * This class implements basic_filebuf for gzipped files. It doesn't yet support
Chris@43 23 * seeking (allowed by zlib but slow/limited), putback and read/write access
Chris@43 24 * (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
Chris@43 25 * file streambuf.
Chris@43 26 */
Chris@43 27 class gzfilebuf : public std::streambuf
Chris@43 28 {
Chris@43 29 public:
Chris@43 30 // Default constructor.
Chris@43 31 gzfilebuf();
Chris@43 32
Chris@43 33 // Destructor.
Chris@43 34 virtual
Chris@43 35 ~gzfilebuf();
Chris@43 36
Chris@43 37 /**
Chris@43 38 * @brief Set compression level and strategy on the fly.
Chris@43 39 * @param comp_level Compression level (see zlib.h for allowed values)
Chris@43 40 * @param comp_strategy Compression strategy (see zlib.h for allowed values)
Chris@43 41 * @return Z_OK on success, Z_STREAM_ERROR otherwise.
Chris@43 42 *
Chris@43 43 * Unfortunately, these parameters cannot be modified separately, as the
Chris@43 44 * previous zfstream version assumed. Since the strategy is seldom changed,
Chris@43 45 * it can default and setcompression(level) then becomes like the old
Chris@43 46 * setcompressionlevel(level).
Chris@43 47 */
Chris@43 48 int
Chris@43 49 setcompression(int comp_level,
Chris@43 50 int comp_strategy = Z_DEFAULT_STRATEGY);
Chris@43 51
Chris@43 52 /**
Chris@43 53 * @brief Check if file is open.
Chris@43 54 * @return True if file is open.
Chris@43 55 */
Chris@43 56 bool
Chris@43 57 is_open() const { return (file != NULL); }
Chris@43 58
Chris@43 59 /**
Chris@43 60 * @brief Open gzipped file.
Chris@43 61 * @param name File name.
Chris@43 62 * @param mode Open mode flags.
Chris@43 63 * @return @c this on success, NULL on failure.
Chris@43 64 */
Chris@43 65 gzfilebuf*
Chris@43 66 open(const char* name,
Chris@43 67 std::ios_base::openmode mode);
Chris@43 68
Chris@43 69 /**
Chris@43 70 * @brief Attach to already open gzipped file.
Chris@43 71 * @param fd File descriptor.
Chris@43 72 * @param mode Open mode flags.
Chris@43 73 * @return @c this on success, NULL on failure.
Chris@43 74 */
Chris@43 75 gzfilebuf*
Chris@43 76 attach(int fd,
Chris@43 77 std::ios_base::openmode mode);
Chris@43 78
Chris@43 79 /**
Chris@43 80 * @brief Close gzipped file.
Chris@43 81 * @return @c this on success, NULL on failure.
Chris@43 82 */
Chris@43 83 gzfilebuf*
Chris@43 84 close();
Chris@43 85
Chris@43 86 protected:
Chris@43 87 /**
Chris@43 88 * @brief Convert ios open mode int to mode string used by zlib.
Chris@43 89 * @return True if valid mode flag combination.
Chris@43 90 */
Chris@43 91 bool
Chris@43 92 open_mode(std::ios_base::openmode mode,
Chris@43 93 char* c_mode) const;
Chris@43 94
Chris@43 95 /**
Chris@43 96 * @brief Number of characters available in stream buffer.
Chris@43 97 * @return Number of characters.
Chris@43 98 *
Chris@43 99 * This indicates number of characters in get area of stream buffer.
Chris@43 100 * These characters can be read without accessing the gzipped file.
Chris@43 101 */
Chris@43 102 virtual std::streamsize
Chris@43 103 showmanyc();
Chris@43 104
Chris@43 105 /**
Chris@43 106 * @brief Fill get area from gzipped file.
Chris@43 107 * @return First character in get area on success, EOF on error.
Chris@43 108 *
Chris@43 109 * This actually reads characters from gzipped file to stream
Chris@43 110 * buffer. Always buffered.
Chris@43 111 */
Chris@43 112 virtual int_type
Chris@43 113 underflow();
Chris@43 114
Chris@43 115 /**
Chris@43 116 * @brief Write put area to gzipped file.
Chris@43 117 * @param c Extra character to add to buffer contents.
Chris@43 118 * @return Non-EOF on success, EOF on error.
Chris@43 119 *
Chris@43 120 * This actually writes characters in stream buffer to
Chris@43 121 * gzipped file. With unbuffered output this is done one
Chris@43 122 * character at a time.
Chris@43 123 */
Chris@43 124 virtual int_type
Chris@43 125 overflow(int_type c = traits_type::eof());
Chris@43 126
Chris@43 127 /**
Chris@43 128 * @brief Installs external stream buffer.
Chris@43 129 * @param p Pointer to char buffer.
Chris@43 130 * @param n Size of external buffer.
Chris@43 131 * @return @c this on success, NULL on failure.
Chris@43 132 *
Chris@43 133 * Call setbuf(0,0) to enable unbuffered output.
Chris@43 134 */
Chris@43 135 virtual std::streambuf*
Chris@43 136 setbuf(char_type* p,
Chris@43 137 std::streamsize n);
Chris@43 138
Chris@43 139 /**
Chris@43 140 * @brief Flush stream buffer to file.
Chris@43 141 * @return 0 on success, -1 on error.
Chris@43 142 *
Chris@43 143 * This calls underflow(EOF) to do the job.
Chris@43 144 */
Chris@43 145 virtual int
Chris@43 146 sync();
Chris@43 147
Chris@43 148 //
Chris@43 149 // Some future enhancements
Chris@43 150 //
Chris@43 151 // virtual int_type uflow();
Chris@43 152 // virtual int_type pbackfail(int_type c = traits_type::eof());
Chris@43 153 // virtual pos_type
Chris@43 154 // seekoff(off_type off,
Chris@43 155 // std::ios_base::seekdir way,
Chris@43 156 // std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
Chris@43 157 // virtual pos_type
Chris@43 158 // seekpos(pos_type sp,
Chris@43 159 // std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
Chris@43 160
Chris@43 161 private:
Chris@43 162 /**
Chris@43 163 * @brief Allocate internal buffer.
Chris@43 164 *
Chris@43 165 * This function is safe to call multiple times. It will ensure
Chris@43 166 * that a proper internal buffer exists if it is required. If the
Chris@43 167 * buffer already exists or is external, the buffer pointers will be
Chris@43 168 * reset to their original state.
Chris@43 169 */
Chris@43 170 void
Chris@43 171 enable_buffer();
Chris@43 172
Chris@43 173 /**
Chris@43 174 * @brief Destroy internal buffer.
Chris@43 175 *
Chris@43 176 * This function is safe to call multiple times. It will ensure
Chris@43 177 * that the internal buffer is deallocated if it exists. In any
Chris@43 178 * case, it will also reset the buffer pointers.
Chris@43 179 */
Chris@43 180 void
Chris@43 181 disable_buffer();
Chris@43 182
Chris@43 183 /**
Chris@43 184 * Underlying file pointer.
Chris@43 185 */
Chris@43 186 gzFile file;
Chris@43 187
Chris@43 188 /**
Chris@43 189 * Mode in which file was opened.
Chris@43 190 */
Chris@43 191 std::ios_base::openmode io_mode;
Chris@43 192
Chris@43 193 /**
Chris@43 194 * @brief True if this object owns file descriptor.
Chris@43 195 *
Chris@43 196 * This makes the class responsible for closing the file
Chris@43 197 * upon destruction.
Chris@43 198 */
Chris@43 199 bool own_fd;
Chris@43 200
Chris@43 201 /**
Chris@43 202 * @brief Stream buffer.
Chris@43 203 *
Chris@43 204 * For simplicity this remains allocated on the free store for the
Chris@43 205 * entire life span of the gzfilebuf object, unless replaced by setbuf.
Chris@43 206 */
Chris@43 207 char_type* buffer;
Chris@43 208
Chris@43 209 /**
Chris@43 210 * @brief Stream buffer size.
Chris@43 211 *
Chris@43 212 * Defaults to system default buffer size (typically 8192 bytes).
Chris@43 213 * Modified by setbuf.
Chris@43 214 */
Chris@43 215 std::streamsize buffer_size;
Chris@43 216
Chris@43 217 /**
Chris@43 218 * @brief True if this object owns stream buffer.
Chris@43 219 *
Chris@43 220 * This makes the class responsible for deleting the buffer
Chris@43 221 * upon destruction.
Chris@43 222 */
Chris@43 223 bool own_buffer;
Chris@43 224 };
Chris@43 225
Chris@43 226 /*****************************************************************************/
Chris@43 227
Chris@43 228 /**
Chris@43 229 * @brief Gzipped file input stream class.
Chris@43 230 *
Chris@43 231 * This class implements ifstream for gzipped files. Seeking and putback
Chris@43 232 * is not supported yet.
Chris@43 233 */
Chris@43 234 class gzifstream : public std::istream
Chris@43 235 {
Chris@43 236 public:
Chris@43 237 // Default constructor
Chris@43 238 gzifstream();
Chris@43 239
Chris@43 240 /**
Chris@43 241 * @brief Construct stream on gzipped file to be opened.
Chris@43 242 * @param name File name.
Chris@43 243 * @param mode Open mode flags (forced to contain ios::in).
Chris@43 244 */
Chris@43 245 explicit
Chris@43 246 gzifstream(const char* name,
Chris@43 247 std::ios_base::openmode mode = std::ios_base::in);
Chris@43 248
Chris@43 249 /**
Chris@43 250 * @brief Construct stream on already open gzipped file.
Chris@43 251 * @param fd File descriptor.
Chris@43 252 * @param mode Open mode flags (forced to contain ios::in).
Chris@43 253 */
Chris@43 254 explicit
Chris@43 255 gzifstream(int fd,
Chris@43 256 std::ios_base::openmode mode = std::ios_base::in);
Chris@43 257
Chris@43 258 /**
Chris@43 259 * Obtain underlying stream buffer.
Chris@43 260 */
Chris@43 261 gzfilebuf*
Chris@43 262 rdbuf() const
Chris@43 263 { return const_cast<gzfilebuf*>(&sb); }
Chris@43 264
Chris@43 265 /**
Chris@43 266 * @brief Check if file is open.
Chris@43 267 * @return True if file is open.
Chris@43 268 */
Chris@43 269 bool
Chris@43 270 is_open() { return sb.is_open(); }
Chris@43 271
Chris@43 272 /**
Chris@43 273 * @brief Open gzipped file.
Chris@43 274 * @param name File name.
Chris@43 275 * @param mode Open mode flags (forced to contain ios::in).
Chris@43 276 *
Chris@43 277 * Stream will be in state good() if file opens successfully;
Chris@43 278 * otherwise in state fail(). This differs from the behavior of
Chris@43 279 * ifstream, which never sets the state to good() and therefore
Chris@43 280 * won't allow you to reuse the stream for a second file unless
Chris@43 281 * you manually clear() the state. The choice is a matter of
Chris@43 282 * convenience.
Chris@43 283 */
Chris@43 284 void
Chris@43 285 open(const char* name,
Chris@43 286 std::ios_base::openmode mode = std::ios_base::in);
Chris@43 287
Chris@43 288 /**
Chris@43 289 * @brief Attach to already open gzipped file.
Chris@43 290 * @param fd File descriptor.
Chris@43 291 * @param mode Open mode flags (forced to contain ios::in).
Chris@43 292 *
Chris@43 293 * Stream will be in state good() if attach succeeded; otherwise
Chris@43 294 * in state fail().
Chris@43 295 */
Chris@43 296 void
Chris@43 297 attach(int fd,
Chris@43 298 std::ios_base::openmode mode = std::ios_base::in);
Chris@43 299
Chris@43 300 /**
Chris@43 301 * @brief Close gzipped file.
Chris@43 302 *
Chris@43 303 * Stream will be in state fail() if close failed.
Chris@43 304 */
Chris@43 305 void
Chris@43 306 close();
Chris@43 307
Chris@43 308 private:
Chris@43 309 /**
Chris@43 310 * Underlying stream buffer.
Chris@43 311 */
Chris@43 312 gzfilebuf sb;
Chris@43 313 };
Chris@43 314
Chris@43 315 /*****************************************************************************/
Chris@43 316
Chris@43 317 /**
Chris@43 318 * @brief Gzipped file output stream class.
Chris@43 319 *
Chris@43 320 * This class implements ofstream for gzipped files. Seeking and putback
Chris@43 321 * is not supported yet.
Chris@43 322 */
Chris@43 323 class gzofstream : public std::ostream
Chris@43 324 {
Chris@43 325 public:
Chris@43 326 // Default constructor
Chris@43 327 gzofstream();
Chris@43 328
Chris@43 329 /**
Chris@43 330 * @brief Construct stream on gzipped file to be opened.
Chris@43 331 * @param name File name.
Chris@43 332 * @param mode Open mode flags (forced to contain ios::out).
Chris@43 333 */
Chris@43 334 explicit
Chris@43 335 gzofstream(const char* name,
Chris@43 336 std::ios_base::openmode mode = std::ios_base::out);
Chris@43 337
Chris@43 338 /**
Chris@43 339 * @brief Construct stream on already open gzipped file.
Chris@43 340 * @param fd File descriptor.
Chris@43 341 * @param mode Open mode flags (forced to contain ios::out).
Chris@43 342 */
Chris@43 343 explicit
Chris@43 344 gzofstream(int fd,
Chris@43 345 std::ios_base::openmode mode = std::ios_base::out);
Chris@43 346
Chris@43 347 /**
Chris@43 348 * Obtain underlying stream buffer.
Chris@43 349 */
Chris@43 350 gzfilebuf*
Chris@43 351 rdbuf() const
Chris@43 352 { return const_cast<gzfilebuf*>(&sb); }
Chris@43 353
Chris@43 354 /**
Chris@43 355 * @brief Check if file is open.
Chris@43 356 * @return True if file is open.
Chris@43 357 */
Chris@43 358 bool
Chris@43 359 is_open() { return sb.is_open(); }
Chris@43 360
Chris@43 361 /**
Chris@43 362 * @brief Open gzipped file.
Chris@43 363 * @param name File name.
Chris@43 364 * @param mode Open mode flags (forced to contain ios::out).
Chris@43 365 *
Chris@43 366 * Stream will be in state good() if file opens successfully;
Chris@43 367 * otherwise in state fail(). This differs from the behavior of
Chris@43 368 * ofstream, which never sets the state to good() and therefore
Chris@43 369 * won't allow you to reuse the stream for a second file unless
Chris@43 370 * you manually clear() the state. The choice is a matter of
Chris@43 371 * convenience.
Chris@43 372 */
Chris@43 373 void
Chris@43 374 open(const char* name,
Chris@43 375 std::ios_base::openmode mode = std::ios_base::out);
Chris@43 376
Chris@43 377 /**
Chris@43 378 * @brief Attach to already open gzipped file.
Chris@43 379 * @param fd File descriptor.
Chris@43 380 * @param mode Open mode flags (forced to contain ios::out).
Chris@43 381 *
Chris@43 382 * Stream will be in state good() if attach succeeded; otherwise
Chris@43 383 * in state fail().
Chris@43 384 */
Chris@43 385 void
Chris@43 386 attach(int fd,
Chris@43 387 std::ios_base::openmode mode = std::ios_base::out);
Chris@43 388
Chris@43 389 /**
Chris@43 390 * @brief Close gzipped file.
Chris@43 391 *
Chris@43 392 * Stream will be in state fail() if close failed.
Chris@43 393 */
Chris@43 394 void
Chris@43 395 close();
Chris@43 396
Chris@43 397 private:
Chris@43 398 /**
Chris@43 399 * Underlying stream buffer.
Chris@43 400 */
Chris@43 401 gzfilebuf sb;
Chris@43 402 };
Chris@43 403
Chris@43 404 /*****************************************************************************/
Chris@43 405
Chris@43 406 /**
Chris@43 407 * @brief Gzipped file output stream manipulator class.
Chris@43 408 *
Chris@43 409 * This class defines a two-argument manipulator for gzofstream. It is used
Chris@43 410 * as base for the setcompression(int,int) manipulator.
Chris@43 411 */
Chris@43 412 template<typename T1, typename T2>
Chris@43 413 class gzomanip2
Chris@43 414 {
Chris@43 415 public:
Chris@43 416 // Allows insertor to peek at internals
Chris@43 417 template <typename Ta, typename Tb>
Chris@43 418 friend gzofstream&
Chris@43 419 operator<<(gzofstream&,
Chris@43 420 const gzomanip2<Ta,Tb>&);
Chris@43 421
Chris@43 422 // Constructor
Chris@43 423 gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
Chris@43 424 T1 v1,
Chris@43 425 T2 v2);
Chris@43 426 private:
Chris@43 427 // Underlying manipulator function
Chris@43 428 gzofstream&
Chris@43 429 (*func)(gzofstream&, T1, T2);
Chris@43 430
Chris@43 431 // Arguments for manipulator function
Chris@43 432 T1 val1;
Chris@43 433 T2 val2;
Chris@43 434 };
Chris@43 435
Chris@43 436 /*****************************************************************************/
Chris@43 437
Chris@43 438 // Manipulator function thunks through to stream buffer
Chris@43 439 inline gzofstream&
Chris@43 440 setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
Chris@43 441 {
Chris@43 442 (gzs.rdbuf())->setcompression(l, s);
Chris@43 443 return gzs;
Chris@43 444 }
Chris@43 445
Chris@43 446 // Manipulator constructor stores arguments
Chris@43 447 template<typename T1, typename T2>
Chris@43 448 inline
Chris@43 449 gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
Chris@43 450 T1 v1,
Chris@43 451 T2 v2)
Chris@43 452 : func(f), val1(v1), val2(v2)
Chris@43 453 { }
Chris@43 454
Chris@43 455 // Insertor applies underlying manipulator function to stream
Chris@43 456 template<typename T1, typename T2>
Chris@43 457 inline gzofstream&
Chris@43 458 operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
Chris@43 459 { return (*m.func)(s, m.val1, m.val2); }
Chris@43 460
Chris@43 461 // Insert this onto stream to simplify setting of compression level
Chris@43 462 inline gzomanip2<int,int>
Chris@43 463 setcompression(int l, int s = Z_DEFAULT_STRATEGY)
Chris@43 464 { return gzomanip2<int,int>(&setcompression, l, s); }
Chris@43 465
Chris@43 466 #endif // ZFSTREAM_H