#ifndef __JROOTFILE__ #define __JROOTFILE__ #include #include #include #include "TFile.h" #include "TError.h" #include "JLang/JAccessible.hh" #include "JLang/JException.hh" #include "JLang/JThrow.hh" #include "JLang/JStorage.hh" /** * \author mdejong */ namespace JROOT {} namespace JPP { using namespace JROOT; } namespace JROOT { using JLANG::JAccessible; using JLANG::JStorage; using JLANG::JFileOpenException; using JLANG::JFileRecoveryException; using JLANG::JThrow; /** * Environment variable to disable ROOT file recovery. * * If not set or set to 0, allow recovery of ROOT file, else do not. */ static const char* const ROOT_FILE_RECOVERY_DISABLE = "ROOT_FILE_RECOVERY_DISABLE"; /** * ROOT file. * * This class implements the method is_open() of the JLANG::JAccessible interface. */ class JRootFile : public virtual JAccessible, public JStorage { protected: /** * Default constructor. * The printing of ROOT errors is suppressed. */ JRootFile() { gErrorIgnoreLevel = kError; } public: /** * Get file. * * \return pointer to file */ TFile* getFile() const { return get(); } /** * Check is file is open. * * \return true if open; else false */ virtual bool is_open() const override { return (getFile() != NULL && getFile()->IsOpen()); } private: JRootFile(const JRootFile&); JRootFile(JRootFile&&); JRootFile& operator=(const JRootFile&); JRootFile& operator=(JRootFile&&); }; /** * ROOT input file. * * This class implements the methods open() and close() of the JLANG::JAccessible interface. */ class JRootInputFile : public JRootFile { public: /** * Default constructor. */ JRootInputFile() : JRootFile() {} /** * Constructor. * * \param file_name file name */ JRootInputFile(const char* file_name) : JRootFile() { do_open(file_name); } /** * Destructor. * * The destructor closes the file if it is still open. */ ~JRootInputFile() { do_close(); } /** * Open file. * The file is not opened when no file exists with the given name. * * \param file_name file name */ virtual void open(const char* file_name) override { do_open(file_name); } /** * Close file. */ virtual void close() override { do_close(); } private: /** * Open file. * The file is not opened when no file exists with the given name. * * \param file_name file name */ void do_open(const char* file_name) { set(TFile::Open(file_name, "READ")); if (!is_open()) { Throw(MAKE_EXCEPTION(JFileOpenException, "Error opening file " << file_name)); } if (getFile()->TestBit(TFile::kRecovered)) { const char* const value = getenv(ROOT_FILE_RECOVERY_DISABLE); if (value != NULL && strcmp(value,"0") != 0) { Throw(MAKE_EXCEPTION(JFileRecoveryException, "Error recovery file " << file_name << " disabled")); } } } /** * Close file. */ void do_close() { if (getFile() != NULL && getFile()->IsOpen()) { getFile()->Close(); } reset(); } }; /** * ROOT output file. * * This class implements the methods open() and close() of the JLANG::JAccessible interface. */ class JRootOutputFile : public JRootFile { public: /** * Default constructor. */ JRootOutputFile() : JRootFile() {} /** * Constructor. * * \param file_name file name */ JRootOutputFile(const char* file_name) : JRootFile() { do_open(file_name); } /** * Destructor. * * The destructor writes and closes the file if it is still open. */ ~JRootOutputFile() { do_close(); } /** * Open file. * The file is not opened when a file exists with the given name. * * \param file_name file name */ virtual void open(const char* file_name) override { do_open(file_name); } /** * Close file. * This method calls the TFile::Write method before closing the file. */ virtual void close() override { do_close(); } private: /** * Open file. * The file is not opened when a file exists with the given name. * * \param file_name file name */ void do_open(const char* file_name) { set(TFile::Open(file_name, "CREATE")); if (!is_open()) { Throw(MAKE_EXCEPTION(JFileOpenException, "Error opening file " << file_name)); } } /** * Close file. * This method calls the TFile::Write method before closing the file. */ void do_close() { if (getFile() != NULL && getFile()->IsOpen()) { getFile()->Write(); getFile()->Close(); } reset(); } }; } #endif