@@ -473,8 +473,42 @@ g3_istream_close(std::istream &stream)
473473 stream.rdbuf (nullptr );
474474}
475475
476+ class OutputStreamCounter : public std ::streambuf {
477+ public:
478+ OutputStreamCounter (std::streambuf* buffer)
479+ : bytes_(0 ), buffer_(buffer) {
480+ if (!buffer_)
481+ log_fatal (" Input file stream buffer required" );
482+ }
483+
484+ OutputStreamCounter () : bytes_(0 ), buffer_(nullptr ) {}
485+
486+ std::streampos bytes () const { return bytes_; }
487+
488+ protected:
489+ virtual int_type overflow (int_type c) {
490+ if (buffer_->sputc (c) != traits_type::eof ()) {
491+ bytes_++;
492+ return c;
493+ }
494+ return traits_type::eof ();
495+ }
496+
497+ virtual std::streamsize xsputn (const char * s, std::streamsize n) {
498+ std::streamsize nput = buffer_->sputn (s, n);
499+ if (nput > 0 )
500+ bytes_ += nput;
501+ return nput;
502+ }
503+
504+ size_t bytes_;
505+
506+ private:
507+ std::streambuf* buffer_;
508+ };
509+
476510template <typename T, typename C>
477- class Encoder : public std ::streambuf {
511+ class Encoder : public OutputStreamCounter {
478512public:
479513 Encoder (std::ostream &file, size_t size)
480514 : file_(file), inbuf_(size), outbuf_(size) {}
@@ -517,7 +551,9 @@ class Encoder : public std::streambuf {
517551 stream_.next_out = reinterpret_cast <C*>(outbuf_.data ());
518552 if (encode (flush))
519553 return ;
520- file_.write (outbuf_.data (), outbuf_.size () - stream_.avail_out );
554+ size_t n = outbuf_.size () - stream_.avail_out ;
555+ bytes_ += n;
556+ file_.write (outbuf_.data (), n);
521557 } while (stream_.avail_out == 0 );
522558 }
523559
@@ -603,40 +639,9 @@ class LZMAEncoder : public Encoder<lzma_stream, uint8_t> {
603639};
604640#endif
605641
606- class OutputStreamCounter : public std ::streambuf {
607- public:
608- OutputStreamCounter (std::streambuf* buffer)
609- : buffer_(buffer), bytes_(0 ) {}
610-
611- std::streampos bytes () const { return bytes_; }
612-
613- protected:
614- int_type overflow (int_type c) {
615- if (buffer_ && buffer_->sputc (c) != traits_type::eof ()) {
616- bytes_++;
617- return c;
618- }
619- return traits_type::eof ();
620- }
621-
622- std::streamsize xsputn (const char * s, std::streamsize n) {
623- if (!buffer_)
624- return 0 ;
625-
626- std::streamsize nput = buffer_->sputn (s, n);
627- if (nput > 0 )
628- bytes_ += nput;
629- return nput;
630- }
631-
632- private:
633- std::streambuf* buffer_;
634- size_t bytes_;
635- };
636-
637642void
638643g3_ostream_to_path (std::ostream &stream, const std::string &path, bool append,
639- bool counter, size_t buffersize)
644+ size_t buffersize)
640645{
641646 std::ios_base::openmode mode = std::ios::binary;
642647 if (append)
@@ -662,26 +667,18 @@ g3_ostream_to_path(std::ostream &stream, const std::string &path, bool append,
662667 log_fatal (" Cannot append to compressed file." );
663668 sbuf = new LZMAEncoder (*file, buffersize);
664669 } else {
665- sbuf = file->rdbuf ();
666- }
667-
668- std::streambuf *cbuf = nullptr ;
669- if (counter) {
670- cbuf = new OutputStreamCounter (sbuf);
671- stream.rdbuf (cbuf);
672- } else {
673- stream.rdbuf (sbuf);
670+ sbuf = new OutputStreamCounter (file->rdbuf ());
674671 }
675672
673+ stream.rdbuf (sbuf);
676674 stream.pword (0 ) = file;
677675 stream.pword (1 ) = sbuf;
678- stream.pword (2 ) = cbuf;
679676}
680677
681678size_t
682679g3_ostream_count (std::ostream &stream)
683680{
684- OutputStreamCounter* cbuf = static_cast <OutputStreamCounter*>(stream.pword ( 2 ));
681+ OutputStreamCounter* cbuf = static_cast <OutputStreamCounter*>(stream.rdbuf ( ));
685682 if (!cbuf)
686683 log_fatal (" Could not get stream counter" );
687684
@@ -708,21 +705,14 @@ g3_ostream_close(std::ostream &stream)
708705 g3_ostream_flush (stream);
709706
710707 std::ofstream* file = static_cast <std::ofstream*>(stream.pword (0 ));
711- std::streambuf* sbuf = static_cast <std::streambuf*>(stream.pword (1 ));
712- if (sbuf) {
713- if (!file || (sbuf != file->rdbuf ()))
714- delete sbuf;
715- }
716- stream.pword (1 ) = nullptr ;
717-
718708 if (file)
719709 delete file;
720710 stream.pword (0 ) = nullptr ;
721711
722- OutputStreamCounter* cbuf = static_cast <OutputStreamCounter *>(stream.pword (2 ));
723- if (cbuf )
724- delete cbuf ;
725- stream.pword (2 ) = nullptr ;
712+ std::streambuf* sbuf = static_cast <std::streambuf *>(stream.pword (1 ));
713+ if (sbuf )
714+ delete sbuf ;
715+ stream.pword (1 ) = nullptr ;
726716
727717 stream.rdbuf (nullptr );
728718}
0 commit comments