annotate src/zlib-1.2.7/contrib/iostream3/zfstream.h @ 169:223a55898ab9 tip default

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