diff options
author | redpony <redpony@ec762483-ff6d-05da-a07a-a48fb63a330f> | 2010-08-11 02:37:10 +0000 |
---|---|---|
committer | redpony <redpony@ec762483-ff6d-05da-a07a-a48fb63a330f> | 2010-08-11 02:37:10 +0000 |
commit | a53461650fbdcd3cfe7543d28af9647ac3e5e47e (patch) | |
tree | e812756c733b34f9c16894265204acfa9f9998a9 /utils/filelib.h | |
parent | 19b59489bb600f438ad96f04ec5d5c5b6616c9c2 (diff) |
major refactor, break bad circular deps
git-svn-id: https://ws10smt.googlecode.com/svn/trunk@509 ec762483-ff6d-05da-a07a-a48fb63a330f
Diffstat (limited to 'utils/filelib.h')
-rw-r--r-- | utils/filelib.h | 106 |
1 files changed, 106 insertions, 0 deletions
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 <cassert> +#include <string> +#include <iostream> +#include <cstdlib> +#include <boost/shared_ptr.hpp> +#include <stdexcept> +#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 <class Stream> +struct BaseFile { + typedef Stream S; + typedef boost::shared_ptr<Stream> 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<std::istream> { + 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<std::istream*>(new igzstream(file)) : + static_cast<std::istream*>(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<std::ostream> { + 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<std::ostream*>(new ogzstream(file)) : + static_cast<std::ostream*>(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 |