/* Cfour (C++ Common Console Classes)
 * Copyright (C) 2001 Jeffrey Bakker
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 *  Author:              Jeffrey Bakker
 *  Filename:            cffile.cpp
 *  File version:        1.2
 *
 *  ===========================================================================
 *
 *  Created on:  August 21st, 2001
 *
 *
 *  Modified on: September 2nd, 2001
 *
 *             - Added a new read(), rline(), and write() methods for reading
 *               and writing to and from a file.
 *
 *  ===========================================================================
 *
 *  Remark:
 *
 *  This is the implementation of the CFfile class.
 *
 *  ===========================================================================
 *
 *  CFfile():
 *
 *   Description: default constructor.
 *
 *  ===========================================================================
 *
 *  CFfile(string filename, char io):
 *
 *   Description: Overloaded constructor that takes a filename and anI/O mode.
 *                This constructor calls open(string,char).
 *
 *   Input:
 *
 *    Parameter 1
 *    - Name:        filename
 *    - Type:        string
 *    - Description: the name of the file to open
 *
 *
 *    Parameter 2
 *    - Name:        io
 *    - Type:        char
 *    - Description: the mode in which to open the file ('i'/'o'). 
 *
 *  ===========================================================================
 *
 *  bool open(string filename, char io):
 *
 *   Description: Depending on the mode selected, it passes the filename to
 *                openR(string) or openW(string).
 *
 *   Input:
 *
 *    Parameter 1
 *    - Name:        filename
 *    - Type:        string
 *    - Description: the name of the file to open
 *
 *
 *    Parameter 2
 *    - Name:        io
 *    - Type:        char
 *    - Description: the mode in which to open the file ('i'/'o'). 
 *
 *   Output:
 *    - returns true if file opened correctly, false otherwise.
 *
 *  ===========================================================================
 *
 *  bool openR(string filename):
 *
 *   Description: This opens the specified file for reading and returns true,
 *                if the file exists. If not, it will return false.
 *
 *   Input:
 *
 *    Parameter 1
 *    - Name:        filename
 *    - Type:        string
 *    - Description: the name of the file to open
 *
 *   Output:
 *    - returns true if file opened correctly, false otherwise.
 *
 *  ===========================================================================
 *
 *  bool openW(string filename):
 *
 *   Description: This opens the specified file for writing. If the file
 *                already exists, it asks the user whether to overwrite.
 *
 *   Input:
 *
 *    Parameter 1
 *    - Name:        filename
 *    - Type:        string
 *    - Description: the name of the file to open
 *
 *   Output:
 *    - returns true if file opened correctly, false otherwise.
 *
 *  ===========================================================================
 *
 *  void read(string &buffer):
 *
 *   Description: reads a string from the file into the buffer.
 *
 *   Input:
 *
 *    Parameter 1
 *    - Name:        buffer
 *    - Type:        address of a string
 *    - Description: the string in which to store the data
 *
 *  ===========================================================================
 *
 *  void rline(string &buffer):
 *
 *   Description: reads a whole line from the file into the buffer.
 *
 *   Input:
 *
 *    Parameter 1
 *    - Name:        buffer
 *    - Type:        address of a string
 *    - Description: the string in which to store the data
 *
 *  ===========================================================================
 *
 *  void write(string buffer):
 *
 *   Description: writes from the string buffer to the file.
 *
 *   Input:
 *
 *    Parameter 1
 *    - Name:        buffer
 *    - Type:        string
 *    - Description: the string in which to write from
 *
 *  ===========================================================================
 *
 *  void backup(string fname, string bname):
 *
 *   Description: creates a backup of a file.
 *
 *
 *   Input:
 *
 *    Parameter 1
 *    - Name:        fname
 *    - Type:        string
 *    - Description: the name of the file to copy from
 *
 *
 *    Parameter 2
 *    - Name:        bname
 *    - Type:        string
 *    - Description: the name of the backup file
 *
 *  ===========================================================================
 *
 *  bool exists(string fname):
 *
 *   Description: checks whether or not a file exists
 *
 *   Input:
 *
 *    Parameter 1
 *    - Name:        fname
 *    - Type:        string
 *    - Description: the name of the file to check
 *
 *   Output:
 *    - returns true if file exists, false otherwise.
 *
 *  ===========================================================================
 *
 *  void closeR():
 *
 *   Description: closes the input stream _if_ it is open.
 *
 *  ===========================================================================
 *
 *  void closeW():
 *
 *   Description: closes the output stream _if_ it is open.
 *
 *  ===========================================================================
 *
 *  void close():
 *
 *   Description: calls closeR() and closeW().
 *
 *  ===========================================================================
 * _______. ..
 */


#include "cffile.h" 

// constructors ----------------------------------------------------------------
CFfile::CFfile() {}
CFfile::CFfile(string filename, char io) {

 if(io != 'i' || io != 'o') {
  cout << "\nError: invalid I/O type.\n";
 } else if (io == 'i') {
  openR(filename);
 } else if (io == 'o') {
  openW(filename);
 }
}
// -----------------------------------------------------------------------------
CFfile::CFfile(string in, string out) {

 openR(in);
 openW(out);
}
// destructor ------------------------------------------------------------------
CFfile::~CFfile() {close();}
// -----------------------------------------------------------------------------
// open methods ----------------------------------------------------------------
bool CFfile::open(string filename, char io)  {

 switch (io) {
  case 'i': return openR(filename);
  case 'o': return openW(filename);
  default: cout << "\nInvalid I/O mode.\n"; return false;
 }

 return true;
} // ---------------------------------------------------------------------------
bool CFfile::openR(string INfile)  {

 if (exists(INfile)) {
  ifile.open(INfile.data());
  return true;
 } else {
  cout << "\n\a" << INfile << " cannot be opened.\n";
  return false;
 }
} // ---------------------------------------------------------------------------
bool CFfile::openW(string OUTfile) {

 if (exists(OUTfile)) {
  char write;
  do {
   cout << "\n" << OUTfile << " already exists. Overwrite? (Y/N) ";
   cin  >> write;
   if (write == 'N' || write == 'n') {return false;}
  } while (!(write == 'Y' || write == 'y'));
 }
 ofile.open(OUTfile.data());
 return true;
}
// -----------------------------------------------------------------------------
// read/write string -----------------------------------------------------------
void CFfile::read(string &buffer)   {ifile >> buffer;}
void CFfile::rline(string &buffer)  {getline(ifile,buffer);}
void CFfile::write(string buffer)  {ofile << buffer;}
// -----------------------------------------------------------------------------
// backup a file ---------------------------------------------------------------
void CFfile::backup(string fname, string bname) {

 ifstream bin;
 ofstream bout;
 string linebuf;

 bin.open(fname.data());
 bout.open(bname.data());

 getline(bin,linebuf);
 while (bin) {
  bout << linebuf;
  getline(bin,linebuf);
  if (bin) bout << endl;
 }
 bin.close();
 bout.close();
}
// -----------------------------------------------------------------------------
// checks if a file exists -----------------------------------------------------
bool CFfile::exists(string fname) {

 ifstream chk;
 chk.open(fname.data());

 if(!chk) {
  chk.close();
  return false;
 }

 chk.close();
 return true;
} //----------------------------------------------------------------------------
/* close methods ---------------------------------------------------------------
 *  Normally, trying to close a stream which is NOT currently open would cause 
 *  a program to segfault. With these close methods below, it closes the stream
 *  if and only if, the stream appears to be open.
 */
void CFfile::closeR() {if(ifile) ifile.close();}
void CFfile::closeW() {if(ofile) ofile.close();}
void CFfile::close()  {closeR(); closeW();}
// -----------------------------------------------------------------------------