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