Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
z.h
Go to the documentation of this file.
1 /*! \file xstream/z.h
2  *
3  * \brief C++ streambuf interface to read and write file formats supported by Zlib
4  *
5  */
6 
7 #ifndef __XSTREAM_Z_H
8 #define __XSTREAM_Z_H
9 
10 #include <xstream/config.h>
11 
12 #if HAVE_LIBZ
13 
14 #include <xstream/common.h>
15 #include <streambuf>
16 #include <sstream>
17 
18 namespace xstream{
19 /*!
20  * \brief zlib's compression/decompression (inflate/deflate) classes
21  *
22  */
23 namespace z{
24 
25 // just a simple forward declaration so as to not include any zlib headers
26 struct pimpl;
27 
28 /*!
29  * \brief flush methods for deflate
30  *
31  */
32 
33 enum flush_kind{
34  no_sync, /*!< flush the minimum possible data */
35  normal_sync, /*!< flushes all output possible so that decompressor can get the data written so far*/
36  full_sync, /*!< same as \c normal_sync but also writes "dictionary" data, so that even in case of corruption at a previous position , data can be decompressed from this point onward*/
37  finish_sync, /*!< write all data so that the stream can be closed*/
38  block_sync /*!< unknown */
39 };
40 
41 /*!
42  * \brief \e private class to factor some common code related with aquisition and release of zlib objects
43  */
44 class common: public xstream::common_buffer
45 {
46  protected:
47  pimpl* z_strm; /*!< zlib stream "object" */
48 
49  std::streampos block_start;
50  std::streamoff block_offset;
51  pthread_mutex_t *streambuf_mutex;
52 
53  /*!
54  * \brief grows the output buffer
55  *
56  * \param factor increase the size of buffer by factor times
57  *
58  * takes care of copying the valid data in the old buffer and freeing it
59  * as well of updating zlibs stream object to use the new buffers
60  *
61  * */
62  void grow_out(unsigned int factor=2);
63 
64  /*!
65  * \brief construct using a streambuf
66  */
67  common(std::streambuf* sb);
68 
69  public:
70  /*!
71  * \brief number of bytes of output so far
72  *
73  */
74  unsigned long int output_count() const;
75 
76  /*!
77  * \brief number of bytes of input so far
78  *
79  */
80  unsigned long int input_count() const;
81 
82  /*!
83  * \brief checksum of uncompressed data so far
84  *
85  * on gzip streams the checksum is a crc32, otherwise the method is adler32
86  *
87  */
88  unsigned long int checksum() const;
89 
90  /*!
91  * \brief dealocates the zlib stream
92  *
93  */
94  ~common();
95 
96  std::streamoff get_block_start() {
97  return block_start;
98  }
99  std::streamoff get_block_offset() {
100  return block_offset;
101  }
102  pthread_mutex_t *get_streambuf_mutex() {
103  return streambuf_mutex;
104  }
105  void set_streambuf_mutex(pthread_mutex_t *mutex) {
106  streambuf_mutex = mutex;
107  }
108 };
109 
110 
111 /*!
112  * \brief ouput Zlib stream class
113  *
114  * Just a thin wrapper for streambuf to deflate (compress) data
115  * doesn't use zlib's fstream like interface, so no unnecessary buffer layer added
116  * doesn't write gzip streams (yet)
117  *
118  */
119 class ostreambuf: public common, public xstream::ostreambuf {
120  private:
121  int level; /*!< compression level */
122 
123  /*!
124  * \brief inspect zlib error status and raise exception in case of error
125  *
126  */
127  void raise_error(int err);
128 
129  void init(void);
130 
131  /*!
132  * \brief flush as much data as possible (overloaded from streambuf)
133  *
134  * */
135  int sync();
136 
137  /*!
138  * \brief write a character that surpasses buffer end (overloaded from streambuf)
139  *
140  */
141  int overflow(int c);
142 
143  /*!
144  * \brief write an entire buffer (overloaded from streambuf)
145  *
146  */
147  std::streamsize xsputn(const char *buffer, std::streamsize n);
148 
149  /*!
150  * \brief fine tuned flushing of stream
151  *
152  * \param f kind of flush to do see flush_kind
153  *
154  */
155  int flush(flush_kind f, const char *appendbuf=0, int appendsize=0);
156 
157  public:
158  /*!
159  * \brief construct using a streambuf
160  */
161  ostreambuf(std::streambuf* sb);
162 
163  /*! \brief construct specifying the compression level
164  *
165  * \param sb streambuf to use
166  * \param level
167  *
168  * \note level should be between 1(worst compression) and 9 (best compression)
169  */
170  ostreambuf(std::streambuf* sb, int level);
171 
172  /*!
173  * \brief closes the zlib stream
174  *
175  */
176  ~ostreambuf();
177 
178  std::streambuf *get_streambuf() {
179  return _sb;
180  }
181 };
182 
183 /*!
184  * \brief input Zlib stream class
185  *
186  * Just a thin wrapper for streambuf to inflate previously deflated data
187  * doesn't use zlib's fstream like interface, so no unnecessary buffer layer added
188  *
189  */
190 
191 class istreambuf: public common, public std::streambuf{
192  private:
193 
194  /*!
195  * \brief inspect zlib error status and raise exception in case of error
196  *
197  */
198  void raise_error(int err);
199 
200 
201  bool end; /*!<signals if stream has reached the end */
202 
203  std::streamsize block_size;
204  std::streampos block_next;
205  std::streamoff new_block_start;
206  unsigned int new_block_offset;
207  typedef struct {
208  int len;
209  char buf[64];
210  } leftovers_buf;
211  leftovers_buf *leftovers;
212 
213  /*!
214  * \brief requests that input buffer be reloaded (overloaded from streambuf)
215  *
216  */
217  int underflow();
218 
219  /*!
220  * \brief encapsulates call to inflate and does error handling
221  *
222  */
223  void inflate(const flush_kind f = normal_sync);
224 
225  /*!
226  * \brief reads data and inflates it
227  */
228  void read_inflate(const flush_kind f = normal_sync);
229 
230  /*!
231  * \brief reads \c n characters to \c buffer (overloaded from streambuf)
232  *
233  */
234  std::streamsize xsgetn(char *buffer, std::streamsize n);
235 
236  public:
237  /*!
238  * \brief construct using a streambuf
239  */
240  istreambuf(std::streambuf* sb, int* left=0, unsigned int left_size=0);
241 
242  /*!
243  * \brief closes the zlib stream
244  *
245  */
246  ~istreambuf();
247 
248  std::streambuf *get_streambuf() {
249  return _sb;
250  }
251  std::streamsize get_block_size() {
252  return block_size;
253  }
254  void set_new_position(std::streamoff start, unsigned int offset) {
255  new_block_start = start;
256  new_block_offset = offset;
257  }
258 };
259 
260 
261 }//namespace z
262 }//namespace xstream
263 
264 /*!
265  * \example z_decompress.cpp
266  *
267  * shows how to use the xstream::z::istreambuf to decompress an ordinary istream with data compressed in zlib or gzip format
268  *
269  * it can decompress from standard input to standard output or from file to file
270  *
271  */
272 
273 /*!
274  * \example z_compress.cpp
275  *
276  * shows how to use the xstream::z::ostreambuf to compress data into zlib format
277  *
278  * it can decompress from standard input to standard output or from file to file
279  *
280  */
281 
282 
283 #endif //have zlib
284 
285 #endif
common base for objects that manage input and output buffers to use with zlib and bzlib ...
Definition: common.h:91
#define c
TF1 * f
Definition: FitGains.C:21
static const size_t block_size
Definition: src/md5.cpp:54
common objects