SHORE API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
gzx.hpp
Go to the documentation of this file.
1 
2 /*
3  * Copyright 2008,2009,2010,2011,2012 Stephan Ossowski, Korbinian Schneeberger,
4  * Felix Ott, Joerg Hagmann, Alf Scotland, Sebastian Bender
5  *
6  * This file is part of SHORE.
7  *
8  * SHORE is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * SHORE is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with SHORE. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
24 
25 #ifndef GZIPINDEX_HPP__
26 #define GZIPINDEX_HPP__
27 
28 #include <iostream>
29 #include <map>
30 #include <vector>
31 
32 #include <zlib.h>
33 
34 #include <boost/iostreams/concepts.hpp>
35 #include <boost/iostreams/traits.hpp>
36 
37 #include "shore/stream/streams.hpp"
38 
39 namespace shore {
40 
42 class gzxbase
43 {
44  protected:
45 
47  int m_zstat;
48 
49 
51  void z_error(const std::string &msg);
53  void zstat_error(const std::string &msg);
54 };
55 
57 class gzxindex
58 :public gzxbase
59 {
60  public:
61 
63  class iterator
64  :public gzxbase
65  {
66  private:
67 
68  friend class gzxindex;
69 
71  const gzxindex *m_parent;
73  size_t m_block;
74 
75 
77  iterator(const gzxindex *const parent);
78 
79  void init();
80 
81  public:
82 
84  iterator();
86  iterator(const iterator &other);
88  iterator &operator=(const iterator &other);
89 
91  void locate(const uint64_t uncompressed_pos);
93  void next_block();
95  void next_stream();
97  void rewind();
98 
100  bool eof() const;
101 
103  uint64_t compressed_file_offset() const;
105  uint64_t uncompressed_file_offset() const;
106  };
107 
108  enum ChkType
109  {
110  CHK_CRC32=0,CHK_ALR32=1,CHK_UNKNOWN
111  };
112 
113  private:
114 
116  gzxindex* m_previous;
118  gzxindex* m_next;
120  uint64_t m_inf_offset;
122  uint64_t m_def_offset;
123 
125  uint64_t m_blocksize;
127  uint64_t m_totalsize;
129  uint64_t m_deflatedsize;
131  ChkType m_chktype;
133  std::vector<uint64_t> m_syncofs;
135  std::vector<uint64_t> m_chksums;
136 
137 
139  struct mdparser
140  {
141  gzxindex*const that;
142  bool fmtinit;
143 
144  mdparser(gzxindex*const t):that(t),fmtinit(false) {}
145  void operator()(const std::string& md);
146  }
147  m_mdparse;
148 
149 
150  static bool get_gzxblock(std::string& buf,std::istream& is);
151 
152  void parse(std::istream& in);
153  bool read_record(std::istream& is,const std::streampos endofs=0);
154 
155 
156  gzxindex(gzxindex* nxt);
157 
158  void parse_old(std::istream& in);
159 
160  public:
161 
163  gzxindex(const uint64_t blocksize,const ChkType check);
165  gzxindex(std::istream *const is);
166  ~gzxindex();
167 
168  void append(uint64_t syncoff,uint64_t chksum);
169  void set_totals(const uint64_t inflated,const uint64_t deflated);
170  void write_record(std::ostream& os) const;
171 
172  bool valid() const;
173 
175  size_t get_stream_count() const;
177  size_t get_block_count() const;
179  uint64_t get_uncompressed_size() const;
180 
182  iterator begin() const;
183 
185  void print(std::ostream &os) const;
186 
187 };
188 
191 :public gzxbase
192 {
193  private:
194 
196  static const int WINDOWBITS=15;
198  static const int MEMLEVEL=8;
199 
201  ::z_stream m_strm;
202 
204  std::ostream& m_os;
205 
207  size_t m_blocksize;
209  bool m_syncblocks;
210 
212  uint8_t* m_inbuf;
214  uint8_t* m_outbuf;
215 
217  gzxindex m_syncs;
218 
220  gzxdeflater(const gzxdeflater&);
221 
223  void deflate_block();
224 
225  public:
226 
229  {
230  HEADER_RAW=-1,
231  HEADER_ZLIB=0,
232  HEADER_GZIP=16
233  };
234 
236  enum Strategy
237  {
238  STGY_DEFAULT=Z_DEFAULT_STRATEGY,
239  STGY_FILTERED=Z_FILTERED,
240  STGY_HUFFMAN=Z_HUFFMAN_ONLY,
241  STGY_RLE=Z_RLE,
242  STGY_FIXED=Z_FIXED
243  };
244 
246  gzxdeflater(std::ostream& os,const bool syncblocks=true,
247  const size_t bs=131072,const HeaderType ht=HEADER_GZIP,
248  const Strategy sg=STGY_DEFAULT);
249 
251  ~gzxdeflater();
252 
254  void finish();
255 
257  void write(const char* s,size_t n);
258 
260  const gzxindex &get_syncs() const;
261 };
262 
265 :public boost::iostreams::sink
266 {
267  private:
268 
269  gzxdeflater* m_def;
270 
271  public:
272 
273  gzxdeflater_sink(gzxdeflater*const def);
274  std::streamsize write(const char* s,std::streamsize n);
275  void close();
276 };
277 
280 :public boost::iostreams::stream<gzxdeflater_sink>
281 {
282  private:
283 
284  gzxdeflater m_def;
285 
286  public:
287 
288  gzx_ostream(std::ostream* os,const bool syncblocks=true,
289  const size_t bs=131072);
290 
291  ~gzx_ostream();
292 };
293 
296 :public gzxbase
297 {
298  private:
299 
301  static const int WINDOWBITS=15;
303  static const size_t BUFSIZE=8192;
305  uint8_t* m_inbuf;
307  uint8_t* m_outbuf;
309  size_t m_outofs;
310 
311 
313  enum HeaderType
314  {
315  HEADER_RAW=-1,
316  HEADER_ZLIB=0,
317  HEADER_GZIP=16,
318  HEADER_AUTO=32
319  };
320 
322  ::z_stream m_strm;
323 
324  std::istream& m_is;
325 
326  gzxindex m_gzx;
327  gzxindex::iterator m_gzxiter;
328 
329  uint64_t m_inflpos;
330 
331  enum
332  {
333  INF_STOPPED=0,
334  INF_GZ=1,
335  INF_RAW=2
336  }
337  m_inflatemode;
338 
339 
340  gzxinflater(const gzxinflater&);
341 
342  void inflate_start(const size_t defl_pos=0);
343 
344  void inflate_stop();
345 
346  public:
347 
348  gzxinflater(std::istream& is,const bool raw_seekable=true);
349 
350  ~gzxinflater();
351 
356  std::streamsize read(char* s,size_t n);
357 
359  std::streampos seek(int64_t ofs,std::ios_base::seekdir way);
360 
361  const gzxindex &get_index() const;
362 };
363 
366 :public boost::iostreams::device<boost::iostreams::input_seekable>
367 {
368  private:
369 
370  gzxinflater* m_inf;
371 
372  public:
373 
374  gzxinflater_source(gzxinflater*const inf);
375 
376  std::streamsize read(char* s,std::streamsize n);
377 
378  std::streampos seek(boost::iostreams::stream_offset off,
379  std::ios_base::seekdir way);
380 };
381 
384 :public boost::iostreams::stream<gzxinflater_source>
385 {
386  private:
387 
388  gzxinflater m_inf;
389 
390  public:
391 
392  gzx_istream(std::istream* is,const bool raw_seekable=true);
393 
394  ~gzx_istream();
395 
396  const gzxindex &get_index() const;
397 
398  static std::string inflate(const std::string& zdata);
399 };
400 
401 } // namespace shore
402 
403 #endif // GZIPINDEX_HPP__
404 
405