diff --git a/src/dwarfs/filesystem_writer.cpp b/src/dwarfs/filesystem_writer.cpp index 6f8d6b26..e869c8f4 100644 --- a/src/dwarfs/filesystem_writer.cpp +++ b/src/dwarfs/filesystem_writer.cpp @@ -49,6 +49,20 @@ namespace dwarfs { namespace { +size_t copy_stream(std::istream& is, std::ostream& os) { + std::streambuf* rdbuf = is.rdbuf(); + std::streamsize count{0}; + std::streamsize transferred; + char buffer[1024]; + + while ((transferred = rdbuf->sgetn(buffer, sizeof(buffer))) > 0) { + os.write(buffer, transferred); + count += transferred; + } + + return count; +} + class compression_progress : public progress::context { public: using status = progress::context::status; @@ -534,7 +548,7 @@ class filesystem_writer_ final : public filesystem_writer::impl { void write_compressed_section(fs_section sec, std::span data) override; void flush() override; - size_t size() const override { return os_.tellp(); } + size_t size() const override { return image_size_; } private: using block_merger_type = @@ -563,6 +577,7 @@ class filesystem_writer_ final : public filesystem_writer::impl { size_t mem_used() const; std::ostream& os_; + size_t image_size_{0}; std::istream* header_; worker_group& wg_; progress& prog_; @@ -607,8 +622,7 @@ filesystem_writer_::filesystem_writer_( if (options_.remove_header) { LOG_WARN << "header will not be written because remove_header is set"; } else { - os_ << header_->rdbuf(); - header_size_ = os_.tellp(); + image_size_ = header_size_ = copy_stream(*header_, os_); } } @@ -703,6 +717,7 @@ template void filesystem_writer_::write(const char* data, size_t size) { // TODO: error handling :-) os_.write(data, size); + image_size_ += size; prog_.compressed_size += size; } @@ -987,7 +1002,7 @@ void filesystem_writer_::copy_header( LOG_WARN << "replacing old header"; } else { write(header); - header_size_ = os_.tellp(); + header_size_ = size(); } } } @@ -1051,7 +1066,7 @@ void filesystem_writer_::flush() { template void filesystem_writer_::push_section_index(section_type type) { section_index_.push_back((static_cast(type) << 48) | - static_cast(os_.tellp() - header_size_)); + static_cast(size() - header_size_)); } template