Chemical Data Processing Library C++ API - Version 1.4.0
CompressionStreams.hpp
Go to the documentation of this file.
1 /*
2  * CompressionStreams.hpp
3  *
4  * This file is part of the Chemical Data Processing Toolkit
5  *
6  * Copyright (C) 2003 Thomas Seidel <thomas.seidel@univie.ac.at>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library 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 GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; see the file COPYING. If not, write to
20  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23 
29 #ifndef CDPL_UTIL_COMPRESSIONSTREAMS_HPP
30 #define CDPL_UTIL_COMPRESSIONSTREAMS_HPP
31 
32 #include <fstream>
33 
34 #include <boost/iostreams/copy.hpp>
35 #include <boost/iostreams/filtering_stream.hpp>
36 #include <boost/iostreams/filter/gzip.hpp>
37 #include <boost/iostreams/filter/bzip2.hpp>
38 
41 
42 
43 namespace CDPL
44 {
45 
46  namespace Util
47  {
48 
53  {
54 
58  BZIP2
59  };
60 
66  template <CompressionAlgo CompAlgo>
68 
72  template <>
74  {
75 
77  typedef boost::iostreams::gzip_decompressor DecompFilter;
79  typedef boost::iostreams::gzip_compressor CompFilter;
80  };
81 
85  template <>
87  {
88 
90  typedef boost::iostreams::bzip2_decompressor DecompFilter;
92  typedef boost::iostreams::bzip2_compressor CompFilter;
93  };
94 
104  template <CompressionAlgo CompAlgo, typename StreamType>
105  class CompressionStreamBase : public StreamType
106  {
107 
108  public:
110  typedef typename StreamType::char_type char_type;
112  typedef typename StreamType::traits_type traits_type;
114  typedef typename StreamType::int_type int_type;
116  typedef typename StreamType::pos_type pos_type;
118  typedef typename StreamType::off_type off_type;
120  typedef std::basic_istream<char_type, traits_type> IStreamType;
122  typedef std::basic_ostream<char_type, traits_type> OStreamType;
123 
128 
129  protected:
131 
132  void closeTmpFile();
133  void openTmpFile();
134 
137 
138  private:
139  typedef std::basic_filebuf<char_type, traits_type> FileBufType;
140 
141  FileBufType tmpFileBuf;
142  };
143 
151  template <CompressionAlgo CompAlgo, typename CharT = char, typename TraitsT = std::char_traits<CharT> >
152  class DecompressionIStream : public CompressionStreamBase<CompAlgo, std::basic_istream<CharT, TraitsT> >
153  {
154 
155  public:
157  typedef typename std::basic_istream<CharT, TraitsT> StreamType;
159  typedef typename StreamType::char_type char_type;
161  typedef typename StreamType::traits_type traits_type;
163  typedef typename StreamType::int_type int_type;
165  typedef typename StreamType::pos_type pos_type;
167  typedef typename StreamType::off_type off_type;
168 
173 
178  DecompressionIStream(StreamType& stream);
179 
184  void open(StreamType& stream);
185 
189  void close();
190  };
191 
200  template <CompressionAlgo CompAlgo, typename CharT = char, typename TraitsT = std::char_traits<CharT> >
201  class CompressionOStream : public CompressionStreamBase<CompAlgo, std::basic_ostream<CharT, TraitsT> >
202  {
203 
204  public:
206  typedef typename std::basic_ostream<CharT, TraitsT> StreamType;
208  typedef typename StreamType::char_type char_type;
210  typedef typename StreamType::traits_type traits_type;
212  typedef typename StreamType::int_type int_type;
214  typedef typename StreamType::pos_type pos_type;
216  typedef typename StreamType::off_type off_type;
217 
222 
227  CompressionOStream(StreamType& stream);
228 
233 
238  void open(StreamType& stream);
239 
243  void close();
244 
245  private:
246  StreamType* stream;
247  off_type outPos;
248  };
249 
258  template <CompressionAlgo CompAlgo, typename CharT = char, typename TraitsT = std::char_traits<CharT> >
259  class CompressedIOStream : public CompressionStreamBase<CompAlgo, std::basic_iostream<CharT, TraitsT> >
260  {
261 
262  public:
264  typedef typename std::basic_iostream<CharT, TraitsT> StreamType;
266  typedef typename StreamType::char_type char_type;
268  typedef typename StreamType::traits_type traits_type;
270  typedef typename StreamType::int_type int_type;
272  typedef typename StreamType::pos_type pos_type;
274  typedef typename StreamType::off_type off_type;
275 
280 
285  CompressedIOStream(StreamType& stream);
286 
291 
296  void open(StreamType& stream);
297 
301  void close();
302 
303  private:
304  StreamType* stream;
305  off_type outPos;
306  };
307 
320  } // namespace Util
321 } // namespace CDPL
322 
323 
324 // CompressionStreamBase Implementation
325 
326 template <CDPL::Util::CompressionAlgo CompAlgo, typename StreamType>
328  StreamType(&tmpFileBuf)
329 {}
330 
331 template <CDPL::Util::CompressionAlgo CompAlgo, typename StreamType>
333 {
334  if (!tmpFileBuf.close())
335  this->setstate(std::ios_base::failbit);
336  else
337  this->clear();
338 }
339 
340 template <CDPL::Util::CompressionAlgo CompAlgo, typename StreamType>
342 {
343  FileRemover tmp_file_rem(genCheckedTempFilePath());
344 
345  if (!tmpFileBuf.open(tmp_file_rem.getPath().c_str(),
346  std::ios_base::in | std::ios_base::out |
347  std::ios_base::trunc | std::ios_base::binary))
348  this->setstate(std::ios_base::failbit);
349  else
350  this->clear(std::ios_base::goodbit);
351 }
352 
353 template <CDPL::Util::CompressionAlgo CompAlgo, typename StreamType>
355 {
356  off_type rpos = is.tellg();
357 
358  is.seekg(0, std::ios_base::end);
359 
360  off_type rend = is.tellg();
361 
362  if (!is.good()) {
363  this->setstate(std::ios_base::failbit);
364  return;
365  }
366 
367  if (rpos == rend)
368  return;
369 
370  is.seekg(rpos);
371 
372  boost::iostreams::filtering_stream<boost::iostreams::input, char_type, traits_type> fs;
373 
375  fs.push(is);
376 
377  boost::iostreams::copy(fs, *this->rdbuf());
378 
379  if (this->tmpFileBuf.pubseekpos(0, std::ios_base::in | std::ios_base::out) != 0)
380  this->setstate(std::ios_base::failbit);
381 
382  this->setstate(is.rdstate() | fs.rdstate());
383 }
384 
385 template <CDPL::Util::CompressionAlgo CompAlgo, typename StreamType>
387 {
388  if (tmpFileBuf.pubseekpos(0, std::ios_base::in) != 0) {
389  this->setstate(std::ios_base::failbit);
390  return;
391  }
392 
393  boost::iostreams::filtering_stream<boost::iostreams::output, char_type, traits_type> fs;
394 
396  fs.push(os);
397 
398  boost::iostreams::copy(*this->rdbuf(), fs);
399 
400  this->setstate(os.rdstate() | fs.rdstate());
401 }
402 
403 // DecompressionIStream Implementation
404 
405 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
407 {}
408 
409 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
411 {
412  open(stream);
413 }
414 
415 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
417 {
418  this->openTmpFile();
419 
420  if (this->good())
421  this->decompInput(stream);
422 }
423 
424 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
426 {
427  this->closeTmpFile();
428 }
429 
430 // CompressionOStream Implementation
431 
432 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
434  stream(0)
435 {}
436 
437 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
439  stream(0)
440 {
441  open(stream);
442 }
443 
444 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
446 {
447  if (stream) {
448  try {
449  stream->seekp(outPos);
450  this->compOutput(*stream);
451  } catch (...) {}
452  }
453 }
454 
455 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
457 {
458  this->openTmpFile();
459 
460  if (!this->good())
461  return;
462 
463  outPos = stream.tellp();
464  this->setstate(stream.rdstate());
465 
466  if (this->good())
467  this->stream = &stream;
468 }
469 
470 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
472 {
473  if (stream) {
474  stream->seekp(outPos);
475  this->compOutput(*stream);
476 
477  if (!this->good())
478  return;
479 
480  stream = 0;
481  }
482 
483  this->closeTmpFile();
484 }
485 
486 // CompressedIOStream Implementation
487 
488 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
490  stream(0)
491 {}
492 
493 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
495  stream(0)
496 {
497  open(stream);
498 }
499 
500 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
502 {
503  if (stream) {
504  try {
505  stream->seekp(outPos);
506  this->compOutput(*stream);
507  } catch (...) {}
508  }
509 }
510 
511 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
513 {
514  this->openTmpFile();
515 
516  if (!this->good())
517  return;
518 
519  outPos = stream.tellp();
520  this->setstate(stream.rdstate());
521 
522  if (!this->good())
523  return;
524 
525  this->decompInput(stream);
526 
527  if (this->good())
528  this->stream = &stream;
529 }
530 
531 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
533 {
534  if (stream) {
535  stream->seekp(outPos);
536  this->compOutput(*stream);
537 
538  if (!this->good())
539  return;
540 
541  stream = 0;
542  }
543 
544  this->closeTmpFile();
545 }
546 
547 #endif // CDPL_UTIL_COMPRESSIONSTREAMS_HPP
Declaration of filesystem-related functions.
Definition of class CDPL::Util::FileRemover.
Bidirectional stream wrapper that decompresses data read from stream into a temporary buffer and re-c...
Definition: CompressionStreams.hpp:260
void close()
Closes the stream and writes any pending modifications back as compressed output.
Definition: CompressionStreams.hpp:532
CompressedIOStream()
Constructs the CompressedIOStream instance without an associated source/sink stream.
Definition: CompressionStreams.hpp:489
StreamType::char_type char_type
The character type of the stream.
Definition: CompressionStreams.hpp:266
~CompressedIOStream()
Destructor. Flushes any pending modifications back to the sink stream as compressed output.
Definition: CompressionStreams.hpp:501
StreamType::off_type off_type
The type used to represent stream offsets.
Definition: CompressionStreams.hpp:274
StreamType::traits_type traits_type
The character traits type of the stream.
Definition: CompressionStreams.hpp:268
void open(StreamType &stream)
Opens the bidirectional compression stream on stream.
Definition: CompressionStreams.hpp:512
StreamType::pos_type pos_type
The type used to represent stream positions.
Definition: CompressionStreams.hpp:272
StreamType::int_type int_type
The integer type used to represent characters and EOF.
Definition: CompressionStreams.hpp:270
Output stream wrapper that transparently compresses data and writes it to an underlying sink stream w...
Definition: CompressionStreams.hpp:202
StreamType::int_type int_type
The integer type used to represent characters and EOF.
Definition: CompressionStreams.hpp:212
~CompressionOStream()
Destructor. Flushes any buffered data to the sink stream as compressed output.
Definition: CompressionStreams.hpp:445
StreamType::traits_type traits_type
The character traits type of the stream.
Definition: CompressionStreams.hpp:210
CompressionOStream()
Constructs the CompressionOStream instance without an associated sink stream.
Definition: CompressionStreams.hpp:433
StreamType::off_type off_type
The type used to represent stream offsets.
Definition: CompressionStreams.hpp:216
StreamType::pos_type pos_type
The type used to represent stream positions.
Definition: CompressionStreams.hpp:214
StreamType::char_type char_type
The character type of the stream.
Definition: CompressionStreams.hpp:208
void close()
Closes the compression stream and writes the compressed output to the sink stream.
Definition: CompressionStreams.hpp:471
void open(StreamType &stream)
Opens the compression stream on stream.
Definition: CompressionStreams.hpp:456
Base class for stream wrappers that buffer (de)compressed data through a temporary file.
Definition: CompressionStreams.hpp:106
std::basic_istream< char_type, traits_type > IStreamType
Input-stream type with matching character and traits types.
Definition: CompressionStreams.hpp:120
void decompInput(IStreamType &is)
Definition: CompressionStreams.hpp:354
StreamType::off_type off_type
The type used to represent stream offsets.
Definition: CompressionStreams.hpp:118
StreamType::char_type char_type
The character type of the wrapped stream.
Definition: CompressionStreams.hpp:110
StreamType::traits_type traits_type
The character traits type of the wrapped stream.
Definition: CompressionStreams.hpp:112
StreamType::pos_type pos_type
The type used to represent stream positions.
Definition: CompressionStreams.hpp:116
void openTmpFile()
Definition: CompressionStreams.hpp:341
std::basic_ostream< char_type, traits_type > OStreamType
Output-stream type with matching character and traits types.
Definition: CompressionStreams.hpp:122
void closeTmpFile()
Definition: CompressionStreams.hpp:332
StreamType::int_type int_type
The integer type used to represent characters and EOF.
Definition: CompressionStreams.hpp:114
CompressionStreamBase()
Constructs the CompressionStreamBase instance and installs the temporary-file buffer.
Definition: CompressionStreams.hpp:327
void compOutput(OStreamType &os)
Definition: CompressionStreams.hpp:386
virtual ~CompressionStreamBase()
Definition: CompressionStreams.hpp:130
Input stream wrapper that transparently decompresses data read from an underlying compressed source s...
Definition: CompressionStreams.hpp:153
void open(StreamType &stream)
Opens the decompression stream on stream.
Definition: CompressionStreams.hpp:416
StreamType::char_type char_type
The character type of the stream.
Definition: CompressionStreams.hpp:159
StreamType::traits_type traits_type
The character traits type of the stream.
Definition: CompressionStreams.hpp:161
StreamType::int_type int_type
The integer type used to represent characters and EOF.
Definition: CompressionStreams.hpp:163
StreamType::off_type off_type
The type used to represent stream offsets.
Definition: CompressionStreams.hpp:167
StreamType::pos_type pos_type
The type used to represent stream positions.
Definition: CompressionStreams.hpp:165
void close()
Closes the decompression stream and releases the temporary buffer.
Definition: CompressionStreams.hpp:425
DecompressionIStream()
Constructs the DecompressionIStream instance without an associated source stream.
Definition: CompressionStreams.hpp:406
RAII helper that deletes a file when the FileRemover instance goes out of scope (unless released befo...
Definition: FileRemover.hpp:48
const std::string & getPath() const
Returns the file-system path currently guarded by the FileRemover.
CDPL_UTIL_API std::string genCheckedTempFilePath(const std::string &dir="", const std::string &ptn="%%%%-%%%%-%%%%-%%%%")
Generates a temporary file path inside dir whose basename matches the supplied randomization ptn and ...
CompressedIOStream< GZIP > GZipIOStream
Bidirectional stream that transparently (de)compresses gzip data.
Definition: CompressionStreams.hpp:317
CompressionAlgo
Identifiers for the compression algorithms supported by the Util compression-stream wrappers.
Definition: CompressionStreams.hpp:53
@ BZIP2
Identifier for the bzip2 compression algorithm.
Definition: CompressionStreams.hpp:58
@ GZIP
Identifier for the gzip compression algorithm.
Definition: CompressionStreams.hpp:56
DecompressionIStream< GZIP > GZipIStream
Input stream that transparently decompresses gzip-compressed data.
Definition: CompressionStreams.hpp:309
CompressionOStream< BZIP2 > BZip2OStream
Output stream that transparently writes bzip2-compressed data.
Definition: CompressionStreams.hpp:315
DecompressionIStream< BZIP2 > BZip2IStream
Input stream that transparently decompresses bzip2-compressed data.
Definition: CompressionStreams.hpp:311
CompressionOStream< GZIP > GZipOStream
Output stream that transparently writes gzip-compressed data.
Definition: CompressionStreams.hpp:313
CompressedIOStream< BZIP2 > BZip2IOStream
Bidirectional stream that transparently (de)compresses bzip2 data.
Definition: CompressionStreams.hpp:319
The namespace of the Chemical Data Processing Library.
boost::iostreams::bzip2_compressor CompFilter
Compression filter type (bzip2).
Definition: CompressionStreams.hpp:92
boost::iostreams::bzip2_decompressor DecompFilter
Decompression filter type (bzip2).
Definition: CompressionStreams.hpp:90
boost::iostreams::gzip_compressor CompFilter
Compression filter type (gzip).
Definition: CompressionStreams.hpp:79
boost::iostreams::gzip_decompressor DecompFilter
Decompression filter type (gzip).
Definition: CompressionStreams.hpp:77
Traits-style template selecting the boost::iostreams compression/decompression filters that implement...
Definition: CompressionStreams.hpp:67