From 80686d4e567bae579ea39e009826a2de92cd4ace Mon Sep 17 00:00:00 2001 From: redpony Date: Wed, 11 Aug 2010 02:37:10 +0000 Subject: major refactor, break bad circular deps git-svn-id: https://ws10smt.googlecode.com/svn/trunk@509 ec762483-ff6d-05da-a07a-a48fb63a330f --- utils/filelib.h | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 utils/filelib.h (limited to 'utils/filelib.h') diff --git a/utils/filelib.h b/utils/filelib.h new file mode 100644 index 00000000..b9fef9a7 --- /dev/null +++ b/utils/filelib.h @@ -0,0 +1,106 @@ +#ifndef _FILELIB_H_ +#define _FILELIB_H_ + +#include +#include +#include +#include +#include +#include +#include "gzstream.h" +#include "null_deleter.h" + +bool FileExists(const std::string& file_name); +bool DirectoryExists(const std::string& dir_name); + +// reads from standard in if filename is - +// uncompresses if file ends with .gz +// otherwise, reads from a normal file + +template +struct BaseFile { + typedef Stream S; + typedef boost::shared_ptr PS; + void Reset() { + ps_.reset(); + } + bool is_null() const { return !ps_; } + operator bool() const { + return ps_; + } + S* stream() { return ps_.get(); } + S* operator->() { return ps_.get(); } // compat with old ReadFile * -> new Readfile. remove? + S &operator *() const { return get(); } + S &get() const { return *ps_; } + bool is_std() { + return filename_=="-"; + } + std::string filename_; +protected: + void error(std::string const& reason,std::string const& filename) { + throw std::runtime_error("File "+filename+" - "+reason); + } + + PS ps_; + static bool EndsWith(const std::string& f, const std::string& suf) { + return (f.size() > suf.size()) && (f.rfind(suf) == f.size() - suf.size()); + } +}; + +class ReadFile : public BaseFile { + public: + ReadFile() { } + explicit ReadFile(const std::string& filename) { + Init(filename); + } + void Init(const std::string& filename) { + filename_=filename; + if (is_std()) { + ps_=PS(&std::cin,null_deleter()); + } else { + if (!FileExists(filename)) { + std::cerr << "File does not exist: " << filename << std::endl; + error(filename," couldn't read nonexistant file."); + abort(); + } + char const* file=filename_.c_str(); // just in case the gzstream keeps using the filename for longer than the constructor, e.g. inflateReset2. warning in valgrind that I'm hoping will disappear - it makes no sense. + ps_=PS(EndsWith(filename, ".gz") ? + static_cast(new igzstream(file)) : + static_cast(new std::ifstream(file))); + if (!*ps_) { + std::cerr << "Failed to open " << filename << std::endl; + error(filename," open for reading failed."); + abort(); + } + } + } + +}; + +class WriteFile : public BaseFile { + public: + WriteFile() {} + explicit WriteFile(std::string const& filename) { Init(filename); } + void Init(const std::string& filename) { + filename_=filename; + if (is_std()) { + ps_=PS(&std::cout,null_deleter()); + } else { + char const* file=filename_.c_str(); // just in case the gzstream keeps using the filename for longer than the constructor, e.g. inflateReset2. warning in valgrind that I'm hoping will disappear - it makes no sense. + ps_=PS(EndsWith(filename, ".gz") ? + static_cast(new ogzstream(file)) : + static_cast(new std::ofstream(file))); + if (!*ps_) { + std::cerr << "Failed to open " << filename << std::endl; + error(filename," open for writing failed."); + abort(); + } + } + } + ~WriteFile() { + if (ps_) + get() << std::flush; + } +}; + +#endif -- cgit v1.2.3