#include <iostream> /* I/O Streaming */
#include <stdio.h>
#include <string> /* C++ string */
#include <errno.h> /* errror number */
#include <string.h> /* for strerror() */
#include <sys/stat.h> /* stat() the file */
#include <stdexcept>
class FileException : public std::exception {
public:
FileException(const std::string& error) throw() { m_error = error + " " + std::string(strerror(errno)); }
~FileException() throw() { } /* do nothing */
const char *what() const throw() { return m_error.c_str(); }
private:
std::string m_error;
};
class File {
/// Disable copying and/or assignments
File(const File& file);
File& operator=(const File& f);
public:
enum FileOpenMode {
OpenRead,
OpenWrite,
OpenReadWrite
};
File(const std::string& name)
: m_file(NULL), m_fileName(name)
{ }
~File() { close(); }
void open(File::FileOpenMode _mode) {
std::string mode;
switch (_mode) {
case File::OpenRead: mode = "r"; break;
case File::OpenWrite: mode = "w"; break;
case File::OpenReadWrite: mode = "rw"; break;
default: /* work around for invalid modes */
throw FileException("Invalid file open mode");
}
m_file = fopen(m_fileName.c_str(), mode.c_str());
if (!m_file)
throw FileException("failed to open file");
}
void close() {
if (m_file && fclose(m_file))
throw FileException("failed to close file");
}
void write(const std::string& str, int len = -1) {
if (len == -1) len = str.length();
if (!m_file)
throw FileException("write() called when file is not open");
if (fputs(str.c_str(), m_file) != len)
throw FileException("cannot write to file");
}
void read(std::string& str, int len) {
if (!m_file)
throw FileException("read() called when file is not open");
char buff[len+1];
if (!fgets(buff, len, m_file))
throw FileException("cannot read from file");
buff[len] = '\0';
str = buff;
}
int size() {
struct stat st;
if (stat(m_fileName.c_str(), &st) != 0)
throw FileException("cannot stat() the file");
return st.st_size;
}
private:
FILE *m_file;
std::string m_fileName;
};
int main(int argc, char *argv[]) {
std::string fname = "hello.txt";
if (argc > 1)
fname = argv[1];
std::clog << "Opening " << fname << std::endl;
File f(fname);
f.open(File::OpenRead);
std::string str;
f.read(str, f.size());
std::clog << "read: " << str << std::endl;
return 0;
}