source: trunk/gcc/zlib/contrib/iostream2/zstream.h

Last change on this file was 1477, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1476,
which included commits to RCS files with non-trunk default branches.

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