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 
59 
63  BZIP2
64  };
65 
71  template <CompressionAlgo CompAlgo>
73 
77  template <>
79  {
80 
84  typedef boost::iostreams::gzip_decompressor DecompFilter;
85 
89  typedef boost::iostreams::gzip_compressor CompFilter;
90  };
91 
95  template <>
97  {
98 
102  typedef boost::iostreams::bzip2_decompressor DecompFilter;
103 
107  typedef boost::iostreams::bzip2_compressor CompFilter;
108  };
109 
119  template <CompressionAlgo CompAlgo, typename StreamType>
120  class CompressionStreamBase : public StreamType
121  {
122 
123  public:
127  typedef typename StreamType::char_type char_type;
128 
132  typedef typename StreamType::traits_type traits_type;
133 
137  typedef typename StreamType::int_type int_type;
138 
142  typedef typename StreamType::pos_type pos_type;
143 
147  typedef typename StreamType::off_type off_type;
148 
152  typedef std::basic_istream<char_type, traits_type> IStreamType;
153 
157  typedef std::basic_ostream<char_type, traits_type> OStreamType;
158 
163 
164  protected:
166 
167  void closeTmpFile();
168  void openTmpFile();
169 
172 
173  private:
174  typedef std::basic_filebuf<char_type, traits_type> FileBufType;
175 
176  FileBufType tmpFileBuf;
177  };
178 
186  template <CompressionAlgo CompAlgo, typename CharT = char, typename TraitsT = std::char_traits<CharT> >
187  class DecompressionIStream : public CompressionStreamBase<CompAlgo, std::basic_istream<CharT, TraitsT> >
188  {
189 
190  public:
194  typedef typename std::basic_istream<CharT, TraitsT> StreamType;
195 
199  typedef typename StreamType::char_type char_type;
200 
204  typedef typename StreamType::traits_type traits_type;
205 
209  typedef typename StreamType::int_type int_type;
210 
214  typedef typename StreamType::pos_type pos_type;
215 
219  typedef typename StreamType::off_type off_type;
220 
225 
230  DecompressionIStream(StreamType& stream);
231 
236  void open(StreamType& stream);
237 
241  void close();
242  };
243 
252  template <CompressionAlgo CompAlgo, typename CharT = char, typename TraitsT = std::char_traits<CharT> >
253  class CompressionOStream : public CompressionStreamBase<CompAlgo, std::basic_ostream<CharT, TraitsT> >
254  {
255 
256  public:
260  typedef typename std::basic_ostream<CharT, TraitsT> StreamType;
261 
265  typedef typename StreamType::char_type char_type;
266 
270  typedef typename StreamType::traits_type traits_type;
271 
275  typedef typename StreamType::int_type int_type;
276 
280  typedef typename StreamType::pos_type pos_type;
281 
285  typedef typename StreamType::off_type off_type;
286 
291 
296  CompressionOStream(StreamType& stream);
297 
302 
307  void open(StreamType& stream);
308 
312  void close();
313 
314  private:
315  StreamType* stream;
316  off_type outPos;
317  };
318 
327  template <CompressionAlgo CompAlgo, typename CharT = char, typename TraitsT = std::char_traits<CharT> >
328  class CompressedIOStream : public CompressionStreamBase<CompAlgo, std::basic_iostream<CharT, TraitsT> >
329  {
330 
331  public:
335  typedef typename std::basic_iostream<CharT, TraitsT> StreamType;
336 
340  typedef typename StreamType::char_type char_type;
341 
345  typedef typename StreamType::traits_type traits_type;
346 
350  typedef typename StreamType::int_type int_type;
351 
355  typedef typename StreamType::pos_type pos_type;
356 
360  typedef typename StreamType::off_type off_type;
361 
366 
371  CompressedIOStream(StreamType& stream);
372 
377 
382  void open(StreamType& stream);
383 
387  void close();
388 
389  private:
390  StreamType* stream;
391  off_type outPos;
392  };
393 
398 
403 
408 
413 
418 
423  } // namespace Util
424 } // namespace CDPL
425 
426 
427 // CompressionStreamBase Implementation
428 
429 template <CDPL::Util::CompressionAlgo CompAlgo, typename StreamType>
431  StreamType(&tmpFileBuf)
432 {}
433 
434 template <CDPL::Util::CompressionAlgo CompAlgo, typename StreamType>
436 {
437  if (!tmpFileBuf.close())
438  this->setstate(std::ios_base::failbit);
439  else
440  this->clear();
441 }
442 
443 template <CDPL::Util::CompressionAlgo CompAlgo, typename StreamType>
445 {
446  FileRemover tmp_file_rem(genCheckedTempFilePath());
447 
448  if (!tmpFileBuf.open(tmp_file_rem.getPath().c_str(),
449  std::ios_base::in | std::ios_base::out |
450  std::ios_base::trunc | std::ios_base::binary))
451  this->setstate(std::ios_base::failbit);
452  else
453  this->clear(std::ios_base::goodbit);
454 }
455 
456 template <CDPL::Util::CompressionAlgo CompAlgo, typename StreamType>
458 {
459  off_type rpos = is.tellg();
460 
461  is.seekg(0, std::ios_base::end);
462 
463  off_type rend = is.tellg();
464 
465  if (!is.good()) {
466  this->setstate(std::ios_base::failbit);
467  return;
468  }
469 
470  if (rpos == rend)
471  return;
472 
473  is.seekg(rpos);
474 
475  boost::iostreams::filtering_stream<boost::iostreams::input, char_type, traits_type> fs;
476 
478  fs.push(is);
479 
480  boost::iostreams::copy(fs, *this->rdbuf());
481 
482  if (this->tmpFileBuf.pubseekpos(0, std::ios_base::in | std::ios_base::out) != 0)
483  this->setstate(std::ios_base::failbit);
484 
485  this->setstate(is.rdstate() | fs.rdstate());
486 }
487 
488 template <CDPL::Util::CompressionAlgo CompAlgo, typename StreamType>
490 {
491  if (tmpFileBuf.pubseekpos(0, std::ios_base::in) != 0) {
492  this->setstate(std::ios_base::failbit);
493  return;
494  }
495 
496  boost::iostreams::filtering_stream<boost::iostreams::output, char_type, traits_type> fs;
497 
499  fs.push(os);
500 
501  boost::iostreams::copy(*this->rdbuf(), fs);
502 
503  this->setstate(os.rdstate() | fs.rdstate());
504 }
505 
506 // DecompressionIStream Implementation
507 
508 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
510 {}
511 
512 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
514 {
515  open(stream);
516 }
517 
518 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
520 {
521  this->openTmpFile();
522 
523  if (this->good())
524  this->decompInput(stream);
525 }
526 
527 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
529 {
530  this->closeTmpFile();
531 }
532 
533 // CompressionOStream Implementation
534 
535 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
537  stream(0)
538 {}
539 
540 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
542  stream(0)
543 {
544  open(stream);
545 }
546 
547 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
549 {
550  if (stream) {
551  try {
552  stream->seekp(outPos);
553  this->compOutput(*stream);
554  } catch (...) {}
555  }
556 }
557 
558 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
560 {
561  this->openTmpFile();
562 
563  if (!this->good())
564  return;
565 
566  outPos = stream.tellp();
567  this->setstate(stream.rdstate());
568 
569  if (this->good())
570  this->stream = &stream;
571 }
572 
573 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
575 {
576  if (stream) {
577  stream->seekp(outPos);
578  this->compOutput(*stream);
579 
580  if (!this->good())
581  return;
582 
583  stream = 0;
584  }
585 
586  this->closeTmpFile();
587 }
588 
589 // CompressedIOStream Implementation
590 
591 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
593  stream(0)
594 {}
595 
596 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
598  stream(0)
599 {
600  open(stream);
601 }
602 
603 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
605 {
606  if (stream) {
607  try {
608  stream->seekp(outPos);
609  this->compOutput(*stream);
610  } catch (...) {}
611  }
612 }
613 
614 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
616 {
617  this->openTmpFile();
618 
619  if (!this->good())
620  return;
621 
622  outPos = stream.tellp();
623  this->setstate(stream.rdstate());
624 
625  if (!this->good())
626  return;
627 
628  this->decompInput(stream);
629 
630  if (this->good())
631  this->stream = &stream;
632 }
633 
634 template <CDPL::Util::CompressionAlgo CompAlgo, typename CharT, typename TraitsT>
636 {
637  if (stream) {
638  stream->seekp(outPos);
639  this->compOutput(*stream);
640 
641  if (!this->good())
642  return;
643 
644  stream = 0;
645  }
646 
647  this->closeTmpFile();
648 }
649 
650 #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:329
void close()
Closes the stream and writes any pending modifications back as compressed output.
Definition: CompressionStreams.hpp:635
CompressedIOStream()
Constructs the CompressedIOStream instance without an associated source/sink stream.
Definition: CompressionStreams.hpp:592
StreamType::char_type char_type
The character type of the stream.
Definition: CompressionStreams.hpp:340
~CompressedIOStream()
Destructor. Flushes any pending modifications back to the sink stream as compressed output.
Definition: CompressionStreams.hpp:604
StreamType::off_type off_type
The type used to represent stream offsets.
Definition: CompressionStreams.hpp:360
StreamType::traits_type traits_type
The character traits type of the stream.
Definition: CompressionStreams.hpp:345
void open(StreamType &stream)
Opens the bidirectional compression stream on stream.
Definition: CompressionStreams.hpp:615
StreamType::pos_type pos_type
The type used to represent stream positions.
Definition: CompressionStreams.hpp:355
StreamType::int_type int_type
The integer type used to represent characters and EOF.
Definition: CompressionStreams.hpp:350
Output stream wrapper that transparently compresses data and writes it to an underlying sink stream w...
Definition: CompressionStreams.hpp:254
StreamType::int_type int_type
The integer type used to represent characters and EOF.
Definition: CompressionStreams.hpp:275
~CompressionOStream()
Destructor. Flushes any buffered data to the sink stream as compressed output.
Definition: CompressionStreams.hpp:548
StreamType::traits_type traits_type
The character traits type of the stream.
Definition: CompressionStreams.hpp:270
CompressionOStream()
Constructs the CompressionOStream instance without an associated sink stream.
Definition: CompressionStreams.hpp:536
StreamType::off_type off_type
The type used to represent stream offsets.
Definition: CompressionStreams.hpp:285
StreamType::pos_type pos_type
The type used to represent stream positions.
Definition: CompressionStreams.hpp:280
StreamType::char_type char_type
The character type of the stream.
Definition: CompressionStreams.hpp:265
void close()
Closes the compression stream and writes the compressed output to the sink stream.
Definition: CompressionStreams.hpp:574
void open(StreamType &stream)
Opens the compression stream on stream.
Definition: CompressionStreams.hpp:559
Base class for stream wrappers that buffer (de)compressed data through a temporary file.
Definition: CompressionStreams.hpp:121
std::basic_istream< char_type, traits_type > IStreamType
Input-stream type with matching character and traits types.
Definition: CompressionStreams.hpp:152
void decompInput(IStreamType &is)
Definition: CompressionStreams.hpp:457
StreamType::off_type off_type
The type used to represent stream offsets.
Definition: CompressionStreams.hpp:147
StreamType::char_type char_type
The character type of the wrapped stream.
Definition: CompressionStreams.hpp:127
StreamType::traits_type traits_type
The character traits type of the wrapped stream.
Definition: CompressionStreams.hpp:132
StreamType::pos_type pos_type
The type used to represent stream positions.
Definition: CompressionStreams.hpp:142
void openTmpFile()
Definition: CompressionStreams.hpp:444
std::basic_ostream< char_type, traits_type > OStreamType
Output-stream type with matching character and traits types.
Definition: CompressionStreams.hpp:157
void closeTmpFile()
Definition: CompressionStreams.hpp:435
StreamType::int_type int_type
The integer type used to represent characters and EOF.
Definition: CompressionStreams.hpp:137
CompressionStreamBase()
Constructs the CompressionStreamBase instance and installs the temporary-file buffer.
Definition: CompressionStreams.hpp:430
void compOutput(OStreamType &os)
Definition: CompressionStreams.hpp:489
virtual ~CompressionStreamBase()
Definition: CompressionStreams.hpp:165
Input stream wrapper that transparently decompresses data read from an underlying compressed source s...
Definition: CompressionStreams.hpp:188
void open(StreamType &stream)
Opens the decompression stream on stream.
Definition: CompressionStreams.hpp:519
StreamType::char_type char_type
The character type of the stream.
Definition: CompressionStreams.hpp:199
StreamType::traits_type traits_type
The character traits type of the stream.
Definition: CompressionStreams.hpp:204
StreamType::int_type int_type
The integer type used to represent characters and EOF.
Definition: CompressionStreams.hpp:209
StreamType::off_type off_type
The type used to represent stream offsets.
Definition: CompressionStreams.hpp:219
StreamType::pos_type pos_type
The type used to represent stream positions.
Definition: CompressionStreams.hpp:214
void close()
Closes the decompression stream and releases the temporary buffer.
Definition: CompressionStreams.hpp:528
DecompressionIStream()
Constructs the DecompressionIStream instance without an associated source stream.
Definition: CompressionStreams.hpp:509
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:417
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:63
@ GZIP
Identifier for the gzip compression algorithm.
Definition: CompressionStreams.hpp:58
DecompressionIStream< GZIP > GZipIStream
Input stream that transparently decompresses gzip-compressed data.
Definition: CompressionStreams.hpp:397
CompressionOStream< BZIP2 > BZip2OStream
Output stream that transparently writes bzip2-compressed data.
Definition: CompressionStreams.hpp:412
DecompressionIStream< BZIP2 > BZip2IStream
Input stream that transparently decompresses bzip2-compressed data.
Definition: CompressionStreams.hpp:402
CompressionOStream< GZIP > GZipOStream
Output stream that transparently writes gzip-compressed data.
Definition: CompressionStreams.hpp:407
CompressedIOStream< BZIP2 > BZip2IOStream
Bidirectional stream that transparently (de)compresses bzip2 data.
Definition: CompressionStreams.hpp:422
The namespace of the Chemical Data Processing Library.
boost::iostreams::bzip2_compressor CompFilter
Compression filter type (bzip2).
Definition: CompressionStreams.hpp:107
boost::iostreams::bzip2_decompressor DecompFilter
Decompression filter type (bzip2).
Definition: CompressionStreams.hpp:102
boost::iostreams::gzip_compressor CompFilter
Compression filter type (gzip).
Definition: CompressionStreams.hpp:89
boost::iostreams::gzip_decompressor DecompFilter
Decompression filter type (gzip).
Definition: CompressionStreams.hpp:84
Traits-style template selecting the boost::iostreams compression/decompression filters that implement...
Definition: CompressionStreams.hpp:72