From 93fd5743706bde6ae843838c9ad3ac4188906323 Mon Sep 17 00:00:00 2001 From: Gabriel Studer <gabriel.studer@unibas.ch> Date: Tue, 2 Jan 2024 15:14:03 +0100 Subject: [PATCH] mmcif writer: move stream handling to StarWriter::Write Before, we already opened a file and the respective stream at Writer initialization. This is weird when Write never gets called and and empty file remains on disk. Furthermore, Write just wrote to a stream. That stream was never flushed, so in principle you potentially called Write but even after completion, the file is not necessarily written to disk. Now, the file gets opened in Write, everything is written to the respective stream and once done, the destructor of the stream ensures that everything concludes. --- modules/io/pymod/export_mmcif_io.cc | 11 +++++++--- modules/io/src/mol/mmcif_writer.cc | 4 ---- modules/io/src/mol/mmcif_writer.hh | 2 +- modules/io/src/mol/star_writer.cc | 34 ++++++++++++++--------------- modules/io/src/mol/star_writer.hh | 11 +++++----- 5 files changed, 30 insertions(+), 32 deletions(-) diff --git a/modules/io/pymod/export_mmcif_io.cc b/modules/io/pymod/export_mmcif_io.cc index c192630ad..de498d382 100644 --- a/modules/io/pymod/export_mmcif_io.cc +++ b/modules/io/pymod/export_mmcif_io.cc @@ -65,6 +65,11 @@ void WrapStarLoopAddData(StarWriterLoop& sl, const boost::python::list& l) { sl.AddData(v); } +void WrapStarWriterWrite(StarWriter& writer, const String& data_name, + const String& filename) { + writer.Write(data_name, filename); +} + void export_mmcif_io() { class_<MMCifReader, boost::noncopyable>("MMCifReader", init<const String&, EntityHandle&, const IOProfile&>()) @@ -113,12 +118,12 @@ void export_mmcif_io() .def("AddData", &WrapStarLoopAddData, (arg("data_list"))) ; - class_<StarWriter, boost::noncopyable>("StarWriter", init<const String&>()) + class_<StarWriter>("StarWriter", init<>()) .def("Push", &StarWriter::Push, arg("star_writer_object")) - .def("Write", &StarWriter::Write, arg("data_name")) + .def("Write", &WrapStarWriterWrite, (arg("data_name"), arg("filename"))) ; - class_<MMCifWriter, boost::noncopyable, bases<StarWriter> >("MMCifWriter", init<const String&>()) + class_<MMCifWriter, bases<StarWriter> >("MMCifWriter", init<>()) .def("SetStructure", &MMCifWriter::SetStructure, (arg("ent"), arg("mmcif_conform")=true)) ; diff --git a/modules/io/src/mol/mmcif_writer.cc b/modules/io/src/mol/mmcif_writer.cc index 79ff70034..bcefc0ea1 100644 --- a/modules/io/src/mol/mmcif_writer.cc +++ b/modules/io/src/mol/mmcif_writer.cc @@ -1400,10 +1400,6 @@ int MMCifWriterEntity::GetAsymIdx(const String& asym_id) const { throw ost::io::IOException(err); } -MMCifWriter::MMCifWriter(const String& filename): - StarWriter(filename), - structure_set_(false) { } - void MMCifWriter::SetStructure(const ost::mol::EntityHandle& ent, bool mmcif_conform) { diff --git a/modules/io/src/mol/mmcif_writer.hh b/modules/io/src/mol/mmcif_writer.hh index 3ff8cbffd..cc44706df 100644 --- a/modules/io/src/mol/mmcif_writer.hh +++ b/modules/io/src/mol/mmcif_writer.hh @@ -69,7 +69,7 @@ struct MMCifWriterEntity { class DLLEXPORT_OST_IO MMCifWriter : public StarWriter { public: - MMCifWriter(const String& filename); + MMCifWriter(): structure_set_(false) { } virtual ~MMCifWriter() { } diff --git a/modules/io/src/mol/star_writer.cc b/modules/io/src/mol/star_writer.cc index b06270bb8..4b64bd370 100644 --- a/modules/io/src/mol/star_writer.cc +++ b/modules/io/src/mol/star_writer.cc @@ -25,39 +25,37 @@ namespace ost{ namespace io{ -StarWriter::StarWriter(std::ostream& stream): filename_("<stream>") { +void StarWriter::Write(const String& data_name, std::ostream& stream) { if(!stream) { std::stringstream ss; ss << "Cannot open stream: [Errno " << errno << "] " << strerror(errno) << std::endl; throw IOException(ss.str()); } - stream_.push(stream); + // write data header + stream << "data_" << data_name << std::endl; + // write StarWriterObjects + for(auto star_obj : categories_to_write_) { + star_obj->ToStream(stream); + stream << String("#") << std::endl; + } } -StarWriter::StarWriter(const String& filename): filename_(filename), - fstream_(filename.c_str()) { - if (!fstream_) { +void StarWriter::Write(const String& data_name, const String& filename) { + std::ofstream fstream(filename.c_str()); + if (!fstream) { std::stringstream ss; - ss << "Cannot open " << filename_ << ": [Errno " << errno << "] " + ss << "Cannot open " << filename << ": [Errno " << errno << "] " << strerror(errno) << std::endl; throw IOException(ss.str()); } + boost::iostreams::filtering_stream<boost::iostreams::output> stream; if (boost::iequals(".gz", boost::filesystem::extension(filename))) { - stream_.push(boost::iostreams::gzip_compressor()); - } - stream_.push(fstream_); -} - -void StarWriter::Write(const String& data_name) { - // write data header - stream_ << "data_" << data_name << std::endl; - - for(auto star_obj : categories_to_write_) { - star_obj->ToStream(stream_); - stream_ << String("#") << std::endl; + stream.push(boost::iostreams::gzip_compressor()); } + stream.push(fstream); + this->Write(data_name, stream); } }} // ns diff --git a/modules/io/src/mol/star_writer.hh b/modules/io/src/mol/star_writer.hh index ea4a396d3..dd8cb5a2a 100644 --- a/modules/io/src/mol/star_writer.hh +++ b/modules/io/src/mol/star_writer.hh @@ -228,16 +228,15 @@ private: class DLLEXPORT_OST_IO StarWriter { public: - StarWriter(std::ostream& stream); - StarWriter(const String& filename); + StarWriter() { } virtual ~StarWriter() { } void Push(StarWriterObjectPtr obj) { categories_to_write_.push_back(obj); } - void Write(const String& data_name); + + void Write(const String& data_name, const String& filename); + void Write(const String& data_name, std::ostream& stream); + private: - String filename_; - std::ofstream fstream_; - boost::iostreams::filtering_stream<boost::iostreams::output> stream_; std::vector<StarWriterObjectPtr> categories_to_write_; }; -- GitLab