SHORE API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
xzx.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 XZINDEX_HPP__
26 #define XZINDEX_HPP__
27 
28 #ifdef HAVE_CONFIG_H
29  #include "config.h"
30 #endif
31 
32 #ifndef WITHOUT_LZMA
33 
34 #include <iostream>
35 #include <map>
36 #include <vector>
37 
38 #include <lzma.h>
39 
40 #include <boost/iostreams/concepts.hpp>
41 #include <boost/iostreams/traits.hpp>
42 
43 #include "shore/stream/streams.hpp"
44 
45 namespace shore {
46 
48 class xzbase
49 {
50  protected:
51 
53  static const size_t BUFSIZE=16384;
54 
56  union buffer_t
57  {
58  char c8[BUFSIZE];
59  uint8_t u8[BUFSIZE];
60  uint32_t u32[BUFSIZE>>2];
61  uint64_t u64[BUFSIZE>>3];
62 
64  void clear_head()
65  {
66  u64[0]=u64[1]=0;
67  }
68  };
69 
71  static const ::lzma_stream STREAM_INIT;
72 
74  ::lzma_ret m_xzstat;
75 
76 
78  void xz_error(const std::string &msg);
80  void xzstat_error(const std::string &msg);
81 };
82 
85 :public xzbase
86 {
87  private:
88 
90  ::lzma_stream m_strm;
91 
93  std::ostream& m_os;
94 
96  size_t m_blocksize;
98  bool m_syncblocks;
99 
101  uint32_t m_preset;
102 
104  uint8_t* m_inbuf;
106  uint8_t* m_outbuf;
107 
109  xzdeflater(const xzdeflater&);
110 
112  void deflate_block();
113 
114  public:
115 
117  xzdeflater(std::ostream& os,const bool syncblocks=true,
118  const size_t bs=131072,
119  const int level=6,const bool extreme=false);
120 
122  ~xzdeflater();
123 
125  void finish();
126 
128  void write(const char* s,size_t n);
129 };
130 
133 :public boost::iostreams::sink
134 {
135  private:
136 
138  xzdeflater* m_def;
139 
140  public:
141 
143  xzdeflater_sink(xzdeflater*const def);
145  std::streamsize write(const char* s,std::streamsize n);
147  void close();
148 };
149 
152 :public boost::iostreams::stream<xzdeflater_sink>
153 {
154  private:
155 
157  xzdeflater m_def;
158 
159  public:
160 
161  xz_ostream(std::ostream* os,const bool syncblocks=true,const size_t bs=131072);
162  ~xz_ostream();
163 };
164 
166 class xzindex
167 :public xzbase
168 {
169  public:
170 
172  class iterator
173  :public xzbase
174  {
175  private:
176 
177  friend class xzindex;
178 
180  const xzindex *m_parent;
182  ::lzma_index_iter m_iter_core;
184  bool m_eof;
185 
187  iterator(const xzindex *const parent);
188 
190  void init();
191 
192  public:
193 
195  class detail
196  {
197  private:
198 
199  friend class xzinflater;
200 
202  static const ::lzma_stream_flags &stream_flags(const iterator &it)
203  {
204  return *it.m_iter_core.stream.flags;
205  }
206  };
207 
209  iterator();
211  iterator(const iterator &other);
213  iterator &operator=(const iterator &other);
214 
216  void locate(const uint64_t uncompressed_pos);
218  void next_block();
220  void next_stream();
222  void rewind();
223 
225  bool eof() const;
226 
228  uint64_t compressed_file_offset() const;
230  uint64_t uncompressed_file_offset() const;
232  uint64_t stream_number() const;
234  uint64_t block_number() const;
235  };
236 
237  private:
238 
240  buffer_t m_readbuf;
241 
242  ::lzma_stream m_strm;
243 
244  ::lzma_index *m_index;
245 
246  bool m_valid;
247 
248 
250  void parse_recursive(std::istream &is);
252  void dealloc();
253 
254  public:
255 
257  xzindex(std::istream *const is);
258  ~xzindex();
259 
260  bool valid() const;
261 
263  size_t get_stream_count() const;
265  size_t get_block_count() const;
267  uint64_t get_uncompressed_size() const;
268 
270  iterator begin() const;
271 
273  void print(std::ostream &os) const;
274 };
275 
278 :public xzbase
279 {
280  private:
281 
283  static const size_t MAX_BLOCK_HEADER_SIZE=1024;
284 
289  static const size_t MAX_BLOCK_READ=BUFSIZE-MAX_BLOCK_HEADER_SIZE;
290 
291  enum
292  {
293  SEQ_STREAM_HEADER,
294  SEQ_BLOCK_HEADER,
295  SEQ_BLOCK,
296  SEQ_INDEX_FOOTER_PADDING
297  } m_sequence;
298 
299  buffer_t m_readbuf;
300  buffer_t m_writebuf;
301  size_t m_writebuf_limit;
302 
307  ::lzma_stream m_strm;
308 
309  ::lzma_stream_flags m_header;
310  ::lzma_block m_block_options;
311  ::lzma_filter m_filters[LZMA_FILTERS_MAX+1];
312  ::lzma_stream_flags m_footer;
313 
314  uint64_t m_skip;
315 
316  std::istream &m_is;
317 
318  xzindex m_index;
319  xzindex::iterator m_index_iter;
320 
322  uint64_t m_inflpos;
323  uint64_t m_stream_number;
324  uint64_t m_block_number;
325 
326 
327  xzinflater(const xzinflater &);
328 
329  void get_input(const size_t n,const std::string &label);
330 
332  bool read_stream_header();
333  void read_block_header();
334  void read_stream_footer();
335  void read_stream_padding();
336 
338  void process_input(size_t n);
339 
342  bool process_output(char **s,size_t nmax);
343 
344  public:
345 
346  xzinflater(std::istream &is,const bool raw_seekable);
347 
348  ~xzinflater();
349 
354  std::streamsize read(char *s,size_t n);
355 
357  std::streampos seek(int64_t ofs,std::ios_base::seekdir way);
358 
359  const xzindex &get_index() const;
360 };
361 
364 :public boost::iostreams::device<boost::iostreams::input_seekable>
365 {
366  private:
367 
368  xzinflater *m_inf;
369 
370  public:
371 
372  xzinflater_source(xzinflater *const inf);
374 
375  std::streamsize read(char *s,std::streamsize n);
376 
377  std::streampos seek(boost::iostreams::stream_offset off,
378  std::ios_base::seekdir way);
379 };
380 
383 :public boost::iostreams::stream<xzinflater_source>
384 {
385  private:
386 
387  xzinflater m_inf;
388 
389  public:
390 
391  xz_istream(std::istream *is,const bool raw_seekable);
392 
393  ~xz_istream();
394 
395  const xzindex &get_index() const;
396 
397  static std::string inflate(const std::string &zdata);
398 };
399 
400 } // namespace shore
401 
402 #endif // WITHOUT_LZMA
403 #endif // XZINDEX_HPP__
404 
405