#ifndef autil__simple_fstream_hh
#define autil__simple_fstream_hh

#include <string>
#include <cstdio>
#include <cctype>

// SimpleFstream is a very simple fstream look alike. 
//
// It offers similar functionality of an fstream but it is not a proper
// stream.  I created it because I needed to be able to get to the
// underlying fileno for doing some low-level functions for the file
// but the C++ or Posix standard provide no way to do so with C++
// streams so I created a simply raper cast which simply provides a
// wrapper around a C stream to make it behave more like a C++ stream.

namespace autil {

  using namespace std;

  class SimpleFstream
  {
  private:
    FILE * file_;

    friend SimpleFstream & operator>> (SimpleFstream &, string &);
    friend SimpleFstream & operator>> (SimpleFstream &, char &);
    friend SimpleFstream & operator>> (SimpleFstream &, unsigned int &);
    friend SimpleFstream & operator<< (SimpleFstream &, const string &);
    friend SimpleFstream & operator<< (SimpleFstream &, char);
    friend SimpleFstream & operator<< (SimpleFstream &, unsigned int);
    friend void getline(SimpleFstream &, string &, char delem = '\n');
  public:
    SimpleFstream() : file_(0) {}
    void open(const string &, const char *);
    SimpleFstream(const string & name, const char * mode) {open(name,mode);}
    void close();
    ~SimpleFstream() {close();}
    
    operator bool() {return file_ != 0 && !feof(file_) && !ferror(file_);}
    int get() {return getc(file_);}
    void ignore() {getc(file_);}
    int peek() {int c = getc(file_); ungetc(c, file_); return c;}
    void skipws();
    int file_no();
    void flush() {fflush(file_);}
    void restart();
    void read(char *, unsigned int i);
    void write(const char *, unsigned int i);
  };

  inline SimpleFstream & operator>> (SimpleFstream & in, char & c)
  {
    in.skipws();
    c = getc(in.file_);
    return in;
  }

  inline SimpleFstream & operator<< (SimpleFstream & out, char c)
  {
    putc(c, out.file_);
    return out;
  }

}

#endif
