00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef ZSTREAM__H
00020 #define ZSTREAM__H
00021
00022
00023
00024
00025
00026
00027 #include <strstream.h>
00028 #include <string.h>
00029 #include <stdio.h>
00030 #include "zlib.h"
00031
00032 #if defined(_WIN32)
00033 # include <fcntl.h>
00034 # include <io.h>
00035 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
00036 #else
00037 # define SET_BINARY_MODE(file)
00038 #endif
00039
00040 class zstringlen {
00041 public:
00042 zstringlen(class izstream&);
00043 zstringlen(class ozstream&, const char*);
00044 size_t value() const { return val.word; }
00045 private:
00046 struct Val { unsigned char byte; size_t word; } val;
00047 };
00048
00049
00050
00051 class izstream
00052 {
00053 public:
00054 izstream() : m_fp(0) {}
00055 izstream(FILE* fp) : m_fp(0) { open(fp); }
00056 izstream(const char* name) : m_fp(0) { open(name); }
00057 ~izstream() { close(); }
00058
00059
00060
00061
00062
00063
00064
00065 void open(const char* name) {
00066 if (m_fp) close();
00067 m_fp = ::gzopen(name, "rb");
00068 }
00069
00070 void open(FILE* fp) {
00071 SET_BINARY_MODE(fp);
00072 if (m_fp) close();
00073 m_fp = ::gzdopen(fileno(fp), "rb");
00074 }
00075
00076
00077
00078
00079
00080 int close() {
00081 int r = ::gzclose(m_fp);
00082 m_fp = 0; return r;
00083 }
00084
00085
00086
00087 int read(void* buf, size_t len) {
00088 return ::gzread(m_fp, buf, len);
00089 }
00090
00091
00092
00093
00094
00095
00096
00097 const char* error(int* errnum) {
00098 return ::gzerror(m_fp, errnum);
00099 }
00100
00101 gzFile fp() { return m_fp; }
00102
00103 private:
00104 gzFile m_fp;
00105 };
00106
00107
00108
00109
00110
00111
00112
00113
00114 template <class T, class Items>
00115 inline int read(izstream& zs, T* x, Items items) {
00116 return ::gzread(zs.fp(), x, items*sizeof(T));
00117 }
00118
00119
00120
00121
00122 template <class T>
00123 inline izstream& operator>(izstream& zs, T& x) {
00124 ::gzread(zs.fp(), &x, sizeof(T));
00125 return zs;
00126 }
00127
00128
00129 inline zstringlen::zstringlen(izstream& zs) {
00130 zs > val.byte;
00131 if (val.byte == 255) zs > val.word;
00132 else val.word = val.byte;
00133 }
00134
00135
00136
00137
00138 inline izstream& operator>(izstream& zs, char* x) {
00139 zstringlen len(zs);
00140 ::gzread(zs.fp(), x, len.value());
00141 x[len.value()] = '\0';
00142 return zs;
00143 }
00144
00145 inline char* read_string(izstream& zs) {
00146 zstringlen len(zs);
00147 char* x = new char[len.value()+1];
00148 ::gzread(zs.fp(), x, len.value());
00149 x[len.value()] = '\0';
00150 return x;
00151 }
00152
00153
00154
00155 class ozstream
00156 {
00157 public:
00158 ozstream() : m_fp(0), m_os(0) {
00159 }
00160 ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION)
00161 : m_fp(0), m_os(0) {
00162 open(fp, level);
00163 }
00164 ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION)
00165 : m_fp(0), m_os(0) {
00166 open(name, level);
00167 }
00168 ~ozstream() {
00169 close();
00170 }
00171
00172
00173
00174
00175
00176
00177 void open(const char* name, int level = Z_DEFAULT_COMPRESSION) {
00178 char mode[4] = "wb\0";
00179 if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
00180 if (m_fp) close();
00181 m_fp = ::gzopen(name, mode);
00182 }
00183
00184
00185
00186 void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) {
00187 SET_BINARY_MODE(fp);
00188 char mode[4] = "wb\0";
00189 if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
00190 if (m_fp) close();
00191 m_fp = ::gzdopen(fileno(fp), mode);
00192 }
00193
00194
00195
00196
00197
00198 int close() {
00199 if (m_os) {
00200 ::gzwrite(m_fp, m_os->str(), m_os->pcount());
00201 delete[] m_os->str(); delete m_os; m_os = 0;
00202 }
00203 int r = ::gzclose(m_fp); m_fp = 0; return r;
00204 }
00205
00206
00207
00208 int write(const void* buf, size_t len) {
00209 return ::gzwrite(m_fp, (voidp) buf, len);
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219 int flush(int _flush) {
00220 os_flush();
00221 return ::gzflush(m_fp, _flush);
00222 }
00223
00224
00225
00226
00227
00228
00229
00230 const char* error(int* errnum) {
00231 return ::gzerror(m_fp, errnum);
00232 }
00233
00234 gzFile fp() { return m_fp; }
00235
00236 ostream& os() {
00237 if (m_os == 0) m_os = new ostrstream;
00238 return *m_os;
00239 }
00240
00241 void os_flush() {
00242 if (m_os && m_os->pcount()>0) {
00243 ostrstream* oss = new ostrstream;
00244 oss->fill(m_os->fill());
00245 oss->flags(m_os->flags());
00246 oss->precision(m_os->precision());
00247 oss->width(m_os->width());
00248 ::gzwrite(m_fp, m_os->str(), m_os->pcount());
00249 delete[] m_os->str(); delete m_os; m_os = oss;
00250 }
00251 }
00252
00253 private:
00254 gzFile m_fp;
00255 ostrstream* m_os;
00256 };
00257
00258
00259
00260
00261
00262
00263 template <class T, class Items>
00264 inline int write(ozstream& zs, const T* x, Items items) {
00265 return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T));
00266 }
00267
00268
00269
00270
00271 template <class T>
00272 inline ozstream& operator<(ozstream& zs, const T& x) {
00273 ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));
00274 return zs;
00275 }
00276
00277 inline zstringlen::zstringlen(ozstream& zs, const char* x) {
00278 val.byte = 255; val.word = ::strlen(x);
00279 if (val.word < 255) zs < (val.byte = val.word);
00280 else zs < val;
00281 }
00282
00283
00284
00285
00286 inline ozstream& operator<(ozstream& zs, const char* x) {
00287 zstringlen len(zs, x);
00288 ::gzwrite(zs.fp(), (voidp) x, len.value());
00289 return zs;
00290 }
00291
00292 #ifdef _MSC_VER
00293 inline ozstream& operator<(ozstream& zs, char* const& x) {
00294 return zs < (const char*) x;
00295 }
00296 #endif
00297
00298
00299
00300
00301 template <class T>
00302 inline ostream& operator<<(ozstream& zs, const T& x) {
00303 zs.os_flush();
00304 return zs.os() << x;
00305 }
00306
00307 #endif