source: trunk/third/gcc/zlib/contrib/iostream2/zstream.h @ 18474

Revision 18474, 9.1 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18473, which included commits to RCS files with non-trunk default branches.
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.1.2 2003-01-22 21:25:15 ghudson 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.