diff --git a/src/Reader.cc b/src/Reader.cc --- a/src/Reader.cc +++ b/src/Reader.cc @@ -1,38 +1,37 @@ // -*- C++ -*- // // This file is part of YODA -- Yet more Objects for Data Analysis // Copyright (C) 2008-2017 The YODA collaboration (see AUTHORS for details) // #include "YODA/Reader.h" #include "YODA/ReaderYODA.h" #include "YODA/ReaderAIDA.h" #include "YODA/ReaderFLAT.h" #include "YODA/Config/DummyConfig.h" using namespace std; namespace YODA { Reader& mkReader(const string& name) { - /// @todo Handle possible double-extensions better + // Determine the format from the string (a file or file extension) const size_t lastdot = name.find_last_of("."); - const size_t lastbutonedot = (lastdot == string::npos) ? string::npos : name.find_last_of(".", lastdot-1); - const string fmt = Utils::toLower((lastdot == string::npos) ? name : name.substr(lastdot+1)); - const string fmtex = Utils::toLower((lastbutonedot == string::npos) ? name : name.substr(lastbutonedot+1)); - // cout << "File extension: " << fmt << endl; - if (fmt == "yoda") return ReaderYODA::create(); - if (fmt == "aida") return ReaderAIDA::create(); - if (fmt == "dat" || fmt == "flat") return ReaderFLAT::create(); - if (fmtex == "yoda.gz") { - #ifdef HAVE_LIBZ - return ReaderYODA::create(); - #else - throw UserError("YODA was compiled without zlib support"); + string fmt = Utils::toLower(lastdot == string::npos ? name : name.substr(lastdot+1)); + if (fmt == "gz") { + #ifndef HAVE_LIBZ + throw UserError("YODA was compiled without zlib support: can't read " + name); #endif + const size_t lastbutonedot = (lastdot == string::npos) ? string::npos : name.find_last_of(".", lastdot-1); + fmt = Utils::toLower(lastbutonedot == string::npos ? name : name.substr(lastbutonedot+1)); } + // Create the appropriate Reader + if (Utils::startswith(fmt, "yoda")) return ReaderYODA::create(); + if (Utils::startswith(fmt, "aida")) return ReaderAIDA::create(); + if (Utils::startswith(fmt, "dat" )) return ReaderFLAT::create(); + if (Utils::startswith(fmt, "flat")) return ReaderFLAT::create(); throw UserError("Format cannot be identified from string '" + name + "'"); } } diff --git a/src/Writer.cc b/src/Writer.cc --- a/src/Writer.cc +++ b/src/Writer.cc @@ -1,106 +1,109 @@ // -*- C++ -*- // // This file is part of YODA -- Yet more Objects for Data Analysis // Copyright (C) 2008-2017 The YODA collaboration (see AUTHORS for details) // #include "YODA/Writer.h" #include "YODA/WriterYODA.h" #include "YODA/WriterAIDA.h" #include "YODA/WriterFLAT.h" #include "YODA/Config/BuildConfig.h" #ifdef HAVE_LIBZ #define _XOPEN_SOURCE 700 #include "zstr/src/zstr.hpp" #endif #include <iostream> #include <typeinfo> #include <sstream> using namespace std; namespace YODA { Writer& mkWriter(const string& name) { - /// @todo There's got to be a better way of handling possible double-extensions... + // Determine the format from the string (a file or file extension) const size_t lastdot = name.find_last_of("."); - const size_t lastbutonedot = (lastdot == string::npos) ? string::npos : name.find_last_of(".", lastdot-1); - const string fmt = Utils::toLower((lastdot == string::npos) ? name : name.substr(lastdot+1)); - const string fmtex = Utils::toLower((lastbutonedot == string::npos) ? name : name.substr(lastbutonedot+1)); - - // cout << "File extension: " << fmt << endl; - #define FMTCHK(f) (fmt == f || Utils::startswith(fmtex, f)) - if (FMTCHK("yoda")) return WriterYODA::create(); - if (FMTCHK("aida")) return WriterAIDA::create(); - if (FMTCHK("dat") || FMTCHK("flat")) return WriterFLAT::create(); - #undef FMTCHK + string fmt = Utils::toLower(lastdot == string::npos ? name : name.substr(lastdot+1)); + if (fmt == "gz") { + #ifndef HAVE_LIBZ + throw UserError("YODA was compiled without zlib support: can't write " + name); + #endif + const size_t lastbutonedot = (lastdot == string::npos) ? string::npos : name.find_last_of(".", lastdot-1); + fmt = Utils::toLower(lastbutonedot == string::npos ? name : name.substr(lastbutonedot+1)); + } + // Create the appropriate Writer + if (Utils::startswith(fmt, "yoda")) return WriterYODA::create(); + if (Utils::startswith(fmt, "aida")) return WriterAIDA::create(); + if (Utils::startswith(fmt, "dat" )) return WriterFLAT::create(); + if (Utils::startswith(fmt, "flat")) return WriterFLAT::create(); throw UserError("Format cannot be identified from string '" + name + "'"); } void Writer::write(ostream& stream, const AnalysisObject& ao) { writeHeader(stream); writeBody(stream, ao); writeFooter(stream); } void Writer::write(const string& filename, const AnalysisObject& ao) { ostream* stream = nullptr; if (Utils::endswith(filename, ".gz")) { #ifdef HAVE_LIBZ stream = new zstr::ofstream(filename); #else throw WriteError("Not compiled with libz, so can't write compressed file " + filename); #endif } else { ofstream* ofs = new ofstream(); ofs->open(filename.c_str()); stream = ofs; } stream->exceptions(ifstream::failbit | ifstream::badbit); try { write(*stream, ao); //stream->close(); delete stream; } catch(ifstream::failure e) { throw WriteError("Writing to filename " + filename + " failed: " + e.what()); } } void Writer::writeBody(ostream& stream, const AnalysisObject* ao) { if (!ao) throw WriteError("Attempting to write a null AnalysisObject"); writeBody(stream,*ao); } void Writer::writeBody(ostream& stream, const AnalysisObject& ao) { const string aotype = ao.type(); if (aotype == "Counter") { writeCounter(stream, dynamic_cast<const Counter&>(ao)); } else if (aotype == "Histo1D") { writeHisto1D(stream, dynamic_cast<const Histo1D&>(ao)); } else if (aotype == "Histo2D") { writeHisto2D(stream, dynamic_cast<const Histo2D&>(ao)); } else if (aotype == "Profile1D") { writeProfile1D(stream, dynamic_cast<const Profile1D&>(ao)); } else if (aotype == "Profile2D") { writeProfile2D(stream, dynamic_cast<const Profile2D&>(ao)); } else if (aotype == "Scatter1D") { writeScatter1D(stream, dynamic_cast<const Scatter1D&>(ao)); } else if (aotype == "Scatter2D") { writeScatter2D(stream, dynamic_cast<const Scatter2D&>(ao)); } else if (aotype == "Scatter3D") { writeScatter3D(stream, dynamic_cast<const Scatter3D&>(ao)); } else if (aotype[0] == '_') { // Skip writing AO types with underscore prefixes (needed e.g. for Rivet wrappers) // maybe write a comment line in the output } else { ostringstream oss; oss << "Unrecognised analysis object type " << aotype << " in Writer::write"; throw Exception(oss.str()); } } }