annotate src/zlib-1.2.7/contrib/iostream2/zstream.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 e13257ea84a4
children
rev   line source
Chris@4 1 /*
Chris@4 2 *
Chris@4 3 * Copyright (c) 1997
Chris@4 4 * Christian Michelsen Research AS
Chris@4 5 * Advanced Computing
Chris@4 6 * Fantoftvegen 38, 5036 BERGEN, Norway
Chris@4 7 * http://www.cmr.no
Chris@4 8 *
Chris@4 9 * Permission to use, copy, modify, distribute and sell this software
Chris@4 10 * and its documentation for any purpose is hereby granted without fee,
Chris@4 11 * provided that the above copyright notice appear in all copies and
Chris@4 12 * that both that copyright notice and this permission notice appear
Chris@4 13 * in supporting documentation. Christian Michelsen Research AS makes no
Chris@4 14 * representations about the suitability of this software for any
Chris@4 15 * purpose. It is provided "as is" without express or implied warranty.
Chris@4 16 *
Chris@4 17 */
Chris@4 18
Chris@4 19 #ifndef ZSTREAM__H
Chris@4 20 #define ZSTREAM__H
Chris@4 21
Chris@4 22 /*
Chris@4 23 * zstream.h - C++ interface to the 'zlib' general purpose compression library
Chris@4 24 * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $
Chris@4 25 */
Chris@4 26
Chris@4 27 #include <strstream.h>
Chris@4 28 #include <string.h>
Chris@4 29 #include <stdio.h>
Chris@4 30 #include "zlib.h"
Chris@4 31
Chris@4 32 #if defined(_WIN32)
Chris@4 33 # include <fcntl.h>
Chris@4 34 # include <io.h>
Chris@4 35 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
Chris@4 36 #else
Chris@4 37 # define SET_BINARY_MODE(file)
Chris@4 38 #endif
Chris@4 39
Chris@4 40 class zstringlen {
Chris@4 41 public:
Chris@4 42 zstringlen(class izstream&);
Chris@4 43 zstringlen(class ozstream&, const char*);
Chris@4 44 size_t value() const { return val.word; }
Chris@4 45 private:
Chris@4 46 struct Val { unsigned char byte; size_t word; } val;
Chris@4 47 };
Chris@4 48
Chris@4 49 // ----------------------------- izstream -----------------------------
Chris@4 50
Chris@4 51 class izstream
Chris@4 52 {
Chris@4 53 public:
Chris@4 54 izstream() : m_fp(0) {}
Chris@4 55 izstream(FILE* fp) : m_fp(0) { open(fp); }
Chris@4 56 izstream(const char* name) : m_fp(0) { open(name); }
Chris@4 57 ~izstream() { close(); }
Chris@4 58
Chris@4 59 /* Opens a gzip (.gz) file for reading.
Chris@4 60 * open() can be used to read a file which is not in gzip format;
Chris@4 61 * in this case read() will directly read from the file without
Chris@4 62 * decompression. errno can be checked to distinguish two error
Chris@4 63 * cases (if errno is zero, the zlib error is Z_MEM_ERROR).
Chris@4 64 */
Chris@4 65 void open(const char* name) {
Chris@4 66 if (m_fp) close();
Chris@4 67 m_fp = ::gzopen(name, "rb");
Chris@4 68 }
Chris@4 69
Chris@4 70 void open(FILE* fp) {
Chris@4 71 SET_BINARY_MODE(fp);
Chris@4 72 if (m_fp) close();
Chris@4 73 m_fp = ::gzdopen(fileno(fp), "rb");
Chris@4 74 }
Chris@4 75
Chris@4 76 /* Flushes all pending input if necessary, closes the compressed file
Chris@4 77 * and deallocates all the (de)compression state. The return value is
Chris@4 78 * the zlib error number (see function error() below).
Chris@4 79 */
Chris@4 80 int close() {
Chris@4 81 int r = ::gzclose(m_fp);
Chris@4 82 m_fp = 0; return r;
Chris@4 83 }
Chris@4 84
Chris@4 85 /* Binary read the given number of bytes from the compressed file.
Chris@4 86 */
Chris@4 87 int read(void* buf, size_t len) {
Chris@4 88 return ::gzread(m_fp, buf, len);
Chris@4 89 }
Chris@4 90
Chris@4 91 /* Returns the error message for the last error which occurred on the
Chris@4 92 * given compressed file. errnum is set to zlib error number. If an
Chris@4 93 * error occurred in the file system and not in the compression library,
Chris@4 94 * errnum is set to Z_ERRNO and the application may consult errno
Chris@4 95 * to get the exact error code.
Chris@4 96 */
Chris@4 97 const char* error(int* errnum) {
Chris@4 98 return ::gzerror(m_fp, errnum);
Chris@4 99 }
Chris@4 100
Chris@4 101 gzFile fp() { return m_fp; }
Chris@4 102
Chris@4 103 private:
Chris@4 104 gzFile m_fp;
Chris@4 105 };
Chris@4 106
Chris@4 107 /*
Chris@4 108 * Binary read the given (array of) object(s) from the compressed file.
Chris@4 109 * If the input file was not in gzip format, read() copies the objects number
Chris@4 110 * of bytes into the buffer.
Chris@4 111 * returns the number of uncompressed bytes actually read
Chris@4 112 * (0 for end of file, -1 for error).
Chris@4 113 */
Chris@4 114 template <class T, class Items>
Chris@4 115 inline int read(izstream& zs, T* x, Items items) {
Chris@4 116 return ::gzread(zs.fp(), x, items*sizeof(T));
Chris@4 117 }
Chris@4 118
Chris@4 119 /*
Chris@4 120 * Binary input with the '>' operator.
Chris@4 121 */
Chris@4 122 template <class T>
Chris@4 123 inline izstream& operator>(izstream& zs, T& x) {
Chris@4 124 ::gzread(zs.fp(), &x, sizeof(T));
Chris@4 125 return zs;
Chris@4 126 }
Chris@4 127
Chris@4 128
Chris@4 129 inline zstringlen::zstringlen(izstream& zs) {
Chris@4 130 zs > val.byte;
Chris@4 131 if (val.byte == 255) zs > val.word;
Chris@4 132 else val.word = val.byte;
Chris@4 133 }
Chris@4 134
Chris@4 135 /*
Chris@4 136 * Read length of string + the string with the '>' operator.
Chris@4 137 */
Chris@4 138 inline izstream& operator>(izstream& zs, char* x) {
Chris@4 139 zstringlen len(zs);
Chris@4 140 ::gzread(zs.fp(), x, len.value());
Chris@4 141 x[len.value()] = '\0';
Chris@4 142 return zs;
Chris@4 143 }
Chris@4 144
Chris@4 145 inline char* read_string(izstream& zs) {
Chris@4 146 zstringlen len(zs);
Chris@4 147 char* x = new char[len.value()+1];
Chris@4 148 ::gzread(zs.fp(), x, len.value());
Chris@4 149 x[len.value()] = '\0';
Chris@4 150 return x;
Chris@4 151 }
Chris@4 152
Chris@4 153 // ----------------------------- ozstream -----------------------------
Chris@4 154
Chris@4 155 class ozstream
Chris@4 156 {
Chris@4 157 public:
Chris@4 158 ozstream() : m_fp(0), m_os(0) {
Chris@4 159 }
Chris@4 160 ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION)
Chris@4 161 : m_fp(0), m_os(0) {
Chris@4 162 open(fp, level);
Chris@4 163 }
Chris@4 164 ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION)
Chris@4 165 : m_fp(0), m_os(0) {
Chris@4 166 open(name, level);
Chris@4 167 }
Chris@4 168 ~ozstream() {
Chris@4 169 close();
Chris@4 170 }
Chris@4 171
Chris@4 172 /* Opens a gzip (.gz) file for writing.
Chris@4 173 * The compression level parameter should be in 0..9
Chris@4 174 * errno can be checked to distinguish two error cases
Chris@4 175 * (if errno is zero, the zlib error is Z_MEM_ERROR).
Chris@4 176 */
Chris@4 177 void open(const char* name, int level = Z_DEFAULT_COMPRESSION) {
Chris@4 178 char mode[4] = "wb\0";
Chris@4 179 if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
Chris@4 180 if (m_fp) close();
Chris@4 181 m_fp = ::gzopen(name, mode);
Chris@4 182 }
Chris@4 183
Chris@4 184 /* open from a FILE pointer.
Chris@4 185 */
Chris@4 186 void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) {
Chris@4 187 SET_BINARY_MODE(fp);
Chris@4 188 char mode[4] = "wb\0";
Chris@4 189 if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
Chris@4 190 if (m_fp) close();
Chris@4 191 m_fp = ::gzdopen(fileno(fp), mode);
Chris@4 192 }
Chris@4 193
Chris@4 194 /* Flushes all pending output if necessary, closes the compressed file
Chris@4 195 * and deallocates all the (de)compression state. The return value is
Chris@4 196 * the zlib error number (see function error() below).
Chris@4 197 */
Chris@4 198 int close() {
Chris@4 199 if (m_os) {
Chris@4 200 ::gzwrite(m_fp, m_os->str(), m_os->pcount());
Chris@4 201 delete[] m_os->str(); delete m_os; m_os = 0;
Chris@4 202 }
Chris@4 203 int r = ::gzclose(m_fp); m_fp = 0; return r;
Chris@4 204 }
Chris@4 205
Chris@4 206 /* Binary write the given number of bytes into the compressed file.
Chris@4 207 */
Chris@4 208 int write(const void* buf, size_t len) {
Chris@4 209 return ::gzwrite(m_fp, (voidp) buf, len);
Chris@4 210 }
Chris@4 211
Chris@4 212 /* Flushes all pending output into the compressed file. The parameter
Chris@4 213 * _flush is as in the deflate() function. The return value is the zlib
Chris@4 214 * error number (see function gzerror below). flush() returns Z_OK if
Chris@4 215 * the flush_ parameter is Z_FINISH and all output could be flushed.
Chris@4 216 * flush() should be called only when strictly necessary because it can
Chris@4 217 * degrade compression.
Chris@4 218 */
Chris@4 219 int flush(int _flush) {
Chris@4 220 os_flush();
Chris@4 221 return ::gzflush(m_fp, _flush);
Chris@4 222 }
Chris@4 223
Chris@4 224 /* Returns the error message for the last error which occurred on the
Chris@4 225 * given compressed file. errnum is set to zlib error number. If an
Chris@4 226 * error occurred in the file system and not in the compression library,
Chris@4 227 * errnum is set to Z_ERRNO and the application may consult errno
Chris@4 228 * to get the exact error code.
Chris@4 229 */
Chris@4 230 const char* error(int* errnum) {
Chris@4 231 return ::gzerror(m_fp, errnum);
Chris@4 232 }
Chris@4 233
Chris@4 234 gzFile fp() { return m_fp; }
Chris@4 235
Chris@4 236 ostream& os() {
Chris@4 237 if (m_os == 0) m_os = new ostrstream;
Chris@4 238 return *m_os;
Chris@4 239 }
Chris@4 240
Chris@4 241 void os_flush() {
Chris@4 242 if (m_os && m_os->pcount()>0) {
Chris@4 243 ostrstream* oss = new ostrstream;
Chris@4 244 oss->fill(m_os->fill());
Chris@4 245 oss->flags(m_os->flags());
Chris@4 246 oss->precision(m_os->precision());
Chris@4 247 oss->width(m_os->width());
Chris@4 248 ::gzwrite(m_fp, m_os->str(), m_os->pcount());
Chris@4 249 delete[] m_os->str(); delete m_os; m_os = oss;
Chris@4 250 }
Chris@4 251 }
Chris@4 252
Chris@4 253 private:
Chris@4 254 gzFile m_fp;
Chris@4 255 ostrstream* m_os;
Chris@4 256 };
Chris@4 257
Chris@4 258 /*
Chris@4 259 * Binary write the given (array of) object(s) into the compressed file.
Chris@4 260 * returns the number of uncompressed bytes actually written
Chris@4 261 * (0 in case of error).
Chris@4 262 */
Chris@4 263 template <class T, class Items>
Chris@4 264 inline int write(ozstream& zs, const T* x, Items items) {
Chris@4 265 return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T));
Chris@4 266 }
Chris@4 267
Chris@4 268 /*
Chris@4 269 * Binary output with the '<' operator.
Chris@4 270 */
Chris@4 271 template <class T>
Chris@4 272 inline ozstream& operator<(ozstream& zs, const T& x) {
Chris@4 273 ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));
Chris@4 274 return zs;
Chris@4 275 }
Chris@4 276
Chris@4 277 inline zstringlen::zstringlen(ozstream& zs, const char* x) {
Chris@4 278 val.byte = 255; val.word = ::strlen(x);
Chris@4 279 if (val.word < 255) zs < (val.byte = val.word);
Chris@4 280 else zs < val;
Chris@4 281 }
Chris@4 282
Chris@4 283 /*
Chris@4 284 * Write length of string + the string with the '<' operator.
Chris@4 285 */
Chris@4 286 inline ozstream& operator<(ozstream& zs, const char* x) {
Chris@4 287 zstringlen len(zs, x);
Chris@4 288 ::gzwrite(zs.fp(), (voidp) x, len.value());
Chris@4 289 return zs;
Chris@4 290 }
Chris@4 291
Chris@4 292 #ifdef _MSC_VER
Chris@4 293 inline ozstream& operator<(ozstream& zs, char* const& x) {
Chris@4 294 return zs < (const char*) x;
Chris@4 295 }
Chris@4 296 #endif
Chris@4 297
Chris@4 298 /*
Chris@4 299 * Ascii write with the << operator;
Chris@4 300 */
Chris@4 301 template <class T>
Chris@4 302 inline ostream& operator<<(ozstream& zs, const T& x) {
Chris@4 303 zs.os_flush();
Chris@4 304 return zs.os() << x;
Chris@4 305 }
Chris@4 306
Chris@4 307 #endif