Fossil SCM

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

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button