Rizin
unix-like reverse engineering framework and cli tools
zstream.h
Go to the documentation of this file.
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 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $
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 
40 class zstringlen {
41 public:
42  zstringlen(class izstream&);
43  zstringlen(class ozstream&, const char*);
44  size_t value() const { return val.word; }
45 private:
46  struct Val { unsigned char byte; size_t word; } val;
47 };
48 
49 // ----------------------------- izstream -----------------------------
50 
51 class 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) {
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) {
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:
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  */
114 template <class T, class Items>
115 inline 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  */
122 template <class T>
123 inline izstream& operator>(izstream& zs, T& x) {
124  ::gzread(zs.fp(), &x, sizeof(T));
125  return zs;
126 }
127 
128 
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  */
138 inline 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 
145 inline 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 
155 class ozstream
156 {
157  public:
158  ozstream() : m_fp(0), m_os(0) {
159  }
161  : m_fp(0), m_os(0) {
162  open(fp, level);
163  }
165  : m_fp(0), m_os(0) {
166  open(name, level);
167  }
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  */
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) {
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:
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  */
263 template <class T, class Items>
264 inline 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  */
271 template <class T>
272 inline ozstream& operator<(ozstream& zs, const T& x) {
273  ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));
274  return zs;
275 }
276 
277 inline 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  */
286 inline 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
293 inline 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  */
301 template <class T>
302 inline ostream& operator<<(ozstream& zs, const T& x) {
303  zs.os_flush();
304  return zs.os() << x;
305 }
306 
307 #endif
size_t len
Definition: 6502dis.c:15
#define T(op)
gzFile fp()
Definition: zstream.h:101
const char * error(int *errnum)
Definition: zstream.h:97
void open(FILE *fp)
Definition: zstream.h:70
izstream(const char *name)
Definition: zstream.h:56
void open(const char *name)
Definition: zstream.h:65
gzFile m_fp
Definition: zstream.h:104
~izstream()
Definition: zstream.h:57
int read(void *buf, size_t len)
Definition: zstream.h:87
izstream()
Definition: zstream.h:54
izstream(FILE *fp)
Definition: zstream.h:55
int close()
Definition: zstream.h:80
int flush(int _flush)
Definition: zstream.h:219
const char * error(int *errnum)
Definition: zstream.h:230
gzFile m_fp
Definition: zstream.h:254
int close()
Definition: zstream.h:198
int write(const void *buf, size_t len)
Definition: zstream.h:208
~ozstream()
Definition: zstream.h:168
ozstream()
Definition: zstream.h:158
ostrstream * m_os
Definition: zstream.h:255
void open(FILE *fp, int level=Z_DEFAULT_COMPRESSION)
Definition: zstream.h:186
void os_flush()
Definition: zstream.h:241
gzFile fp()
Definition: zstream.h:234
ostream & os()
Definition: zstream.h:236
ozstream(FILE *fp, int level=Z_DEFAULT_COMPRESSION)
Definition: zstream.h:160
void open(const char *name, int level=Z_DEFAULT_COMPRESSION)
Definition: zstream.h:177
ozstream(const char *name, int level=Z_DEFAULT_COMPRESSION)
Definition: zstream.h:164
struct zstringlen::Val val
size_t value() const
Definition: zstream.h:44
zstringlen(class izstream &)
Definition: zstream.h:129
#define r
Definition: crypto_rc6.c:12
int ZEXPORT gzclose(gzFile file)
Definition: gzclose.c:11
gzFile ZEXPORT gzopen(char *path, const char *mode) const
Definition: gzlib.c:272
gzFile ZEXPORT gzdopen(int fd, const char *mode)
Definition: gzlib.c:288
const char *ZEXPORT gzerror(gzFile file, int *errnum)
Definition: gzlib.c:534
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len)
Definition: gzread.c:375
int ZEXPORT gzflush(gzFile file, int flush)
Definition: gzwrite.c:565
int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len)
Definition: gzwrite.c:255
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
int x
Definition: mipsasm.c:20
string FILE
Definition: benchmark.py:21
Definition: z80asm.h:102
unsigned char byte
Definition: zstream.h:46
size_t word
Definition: zstream.h:46
static int level
Definition: vmenus.c:2424
Byte * voidp
Definition: zconf.h:414
#define Z_DEFAULT_COMPRESSION
Definition: zlib.h:193
izstream & operator>(izstream &zs, T &x)
Definition: zstream.h:123
#define SET_BINARY_MODE(file)
Definition: zstream.h:37
int write(ozstream &zs, const T *x, Items items)
Definition: zstream.h:264
ostream & operator<<(ozstream &zs, const T &x)
Definition: zstream.h:302
ozstream & operator<(ozstream &zs, const T &x)
Definition: zstream.h:272
char * read_string(izstream &zs)
Definition: zstream.h:145
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115