USGS

Isis 3.0 Object Programmers' Reference

Home

TextFile.cpp

Go to the documentation of this file.
00001 
00023 #include "IException.h"
00024 #include "IException.h"
00025 #include "FileName.h"
00026 #include "Message.h"
00027 #include "TextFile.h"
00028 #include "IString.h"
00029 
00030 #include <iostream>
00031 
00032 #include <QFileInfo>
00033 
00034 using namespace std;
00035 namespace Isis {
00036 
00038   TextFile::TextFile() {
00039   }
00040 
00057   TextFile::TextFile(const QString &filename,
00058                      const char *openmode, const char *extension) {
00059     SetComment();
00060     SetNewLine();
00061     Open(filename, openmode, extension);
00062   }
00063 
00088   TextFile::TextFile(const QString &filename, const char *openmode,
00089                      std::vector<QString> &lines, const int &maxLinesToReadWrite,
00090                      const bool skipComments) {
00091     SetComment();
00092     SetNewLine();
00093     Open(filename, openmode);
00094     if(p_openmode == 1) {
00095       GetFile(lines, maxLinesToReadWrite, skipComments);
00096     }
00097     else {
00098       PutFile(lines, maxLinesToReadWrite);
00099     }
00100   }
00125   TextFile::TextFile(const char *filename, const char *openmode,
00126                      std::vector<QString> &lines, const int &maxLinesToReadWrite,
00127                      const bool skipComments) {
00128     TextFile(QString(filename), openmode, lines, maxLinesToReadWrite, skipComments);
00129   }
00130 
00156   TextFile::TextFile(const QString &filename, const char *openmode,
00157                      QString *lines, const int &maxLinesToReadWrite,
00158                      const bool skipComments) {
00159     SetComment();
00160     SetNewLine();
00161     Open(filename, openmode);
00162     if(p_openmode == 1) {
00163       GetFile(lines, maxLinesToReadWrite, skipComments);
00164     }
00165     else {
00166       PutFile(lines, maxLinesToReadWrite);
00167     }
00168   }
00169 
00194   TextFile::TextFile(const char *filename, const char *openmode,
00195                      QString *lines, const int &maxLinesToReadWrite,
00196                      const bool skipComments) {
00197     TextFile(QString(filename), openmode, lines, maxLinesToReadWrite, skipComments);
00198   }
00199 
00200 
00202   TextFile::~TextFile() {
00203     Close();
00204   }
00205 
00206 
00207   // Methods
00208 
00233   void TextFile::Open(const QString &filename, const char *openmode,
00234                       const char *extension) {
00235     // Open (filename [,openmode] [, with_extension ])
00236     // default openmode = 'input'
00237     // default extension = 'txt'; extension = "" opens without default
00238 
00239     // note: in append mode, the input and output pointers move together
00240 
00241 
00242     // Don't open if it already is
00243     if(p_stream.is_open()) {
00244       QString message = "TextFile:Open:-> Already opened with this object: ["
00245                         + QString(openmode) + "]:[" + p_filename + "]";
00246       throw IException(IException::Programmer, message, _FILEINFO_);
00247     }
00248 
00249     p_openmode = 0;
00250 
00251     // Save the filename for error messages
00252 
00253     Isis::FileName filenameTmp(filename);
00254     filenameTmp.addExtension(extension);
00255     p_filename = filenameTmp.expanded();
00256 
00257 
00258     //  input, output, overwrite, append
00259 
00260     string chkOpenmode = Isis::IString(openmode).DownCase();
00261     if(chkOpenmode == "input")      {
00262       p_openmode = 1;
00263     }
00264     else if(chkOpenmode == "output")     {
00265       p_openmode = 2;
00266     }
00267     else if(chkOpenmode == "overwrite")  {
00268       p_openmode = 3;
00269     }
00270     else if(chkOpenmode == "append")     {
00271       p_openmode = 4;
00272     }
00273     else {
00274       QString message = "TextFile::-> Unknown openmode: (input, output, overwrite, append):["
00275                        + QString(openmode) + "]:[" + p_filename + "]";
00276       throw IException(IException::Programmer, message, _FILEINFO_);
00277     }
00278 
00279     // Input
00280     if(p_openmode == 1) {
00281       p_stream.open(p_filename.toAscii().data(), fstream::in);
00282     }
00283     // Output
00284     else if(p_openmode == 2) {
00285       // first check if file already exists
00286       if(filenameTmp.fileExists() && QFileInfo(filenameTmp.toString()).size() > 0) {
00287         QString message = "TextFile:Open: -> Output file already exists ["
00288                           + QString(openmode) + "]:[" + p_filename + "]";
00289         throw IException(IException::Io, message, _FILEINFO_);
00290       }
00291 
00292       p_stream.open(p_filename.toAscii().data(), fstream::in | fstream::out | fstream::trunc);
00293       p_stream.clear();
00294     }
00295     // Overwrite
00296     else if(p_openmode == 3) {
00297       p_stream.open(p_filename.toAscii().data(), fstream::in | fstream::out | fstream::trunc);
00298     }
00299     // Append
00300     else if(p_openmode == 4) {
00301       // Open in append if it does exist, otherwise, open in overwrite mode
00302       if(filenameTmp.fileExists()) {
00303         p_stream.open(p_filename.toAscii().data(), fstream::in | fstream::out | fstream::ate);
00304       }
00305       else {
00306         p_stream.open(p_filename.toAscii().data(), fstream::in | fstream::out | fstream::trunc);
00307       }
00308     }
00309 
00310     if(!p_stream.is_open()) {
00311       QString message = "TextFile:Open:-> Unable to open: ["
00312                        + QString(openmode) + "]:[" + p_filename + "]";
00313       throw IException(IException::Io, message, _FILEINFO_);
00314     }
00315   }
00316 
00317   bool TextFile::OpenChk(bool bailIfNotOpen) {
00318     if(p_stream.is_open()) {
00319       return(true);
00320     }
00321     else {
00322       if(bailIfNotOpen) {
00323         QString message = "TextFile::-> File not open: [" + p_filename + "]";
00324         throw IException(IException::Programmer, message, _FILEINFO_);
00325       }
00326       else {
00327         return(false);
00328       }
00329     }
00330   }
00331 
00333   void TextFile::Rewind() {
00334     OpenChk(true);
00335     if(p_stream.eof()) {
00336       p_stream.clear();
00337     }
00338     p_stream.seekg(0, ios_base::beg);
00339   }
00340 
00342   void TextFile::Close() {
00343     if(p_stream.is_open()) {
00344       p_stream.flush();
00345       p_stream.close();
00346     }
00347   }
00348 
00349   // vector array
00350   void TextFile::GetFile(std::vector<QString> &lines, const int &maxLinesToRead,
00351                          const bool skipComments) {
00352     OpenChk(true);
00353     QString line;
00354     int lineCount = 0;
00355     while(GetLine(line, skipComments)) {
00356       if(maxLinesToRead > 0) {
00357         if(lineCount++ >= maxLinesToRead) {
00358           break;
00359         };
00360       }
00361       lines.push_back(line);
00362     }
00363   }
00364 
00365   // string array
00366   void TextFile::GetFile(QString *lines, const int &maxLinesToRead,
00367                          const bool skipComments) {
00368     OpenChk(true);
00369     QString line;
00370     int lineCount = 0;
00371     while(GetLine(line, skipComments)) {
00372       if(maxLinesToRead > 0) {
00373         if(lineCount > maxLinesToRead) {
00374           break;
00375         };
00376       }
00377       else if(lines[lineCount] == "\0") {
00378         break;
00379       }
00380       lines[lineCount] = line;
00381       lineCount++;
00382     }
00383   }
00384 
00385   // vector array
00386   void TextFile::PutFile(std::vector<QString> &lines, const int &maxLinesToWrite) {
00387     OpenChk(true);
00388     for(int lineCount = 0; lineCount < (int) lines.size(); lineCount++) {
00389       if(maxLinesToWrite > 0) {
00390         if(lineCount > maxLinesToWrite) {
00391           break;
00392         };
00393       }
00394       PutLine(lines[lineCount]);
00395     }
00396   }
00397 
00398   // string array
00399   void TextFile::PutFile(const QString *lines, const int &maxLinesToWrite) {
00400     OpenChk(true);
00401     int lineCount = 0;
00402     while(true) {
00403       if(maxLinesToWrite > 0) {
00404         if(lineCount > maxLinesToWrite) {
00405           break;
00406         };
00407       }
00408       else if(lines[lineCount] == "\0") {
00409         break;
00410       }
00411       PutLine(lines[lineCount]);
00412       lineCount++;
00413     }
00414   }
00415 
00427   bool TextFile::GetLine(QString &line, bool skipComments) {
00428     return (p_GetLine(line, skipComments));
00429   }
00430 
00440   bool TextFile::GetLine(bool skipComments) {
00441     QString line;
00442     return (p_GetLine(line, skipComments));
00443   }
00444 
00453   bool TextFile::GetLineNoFilter(QString &line) {
00454     return (p_GetLine(line, false));
00455   }
00456 
00463   bool TextFile::GetLineNoFilter() {
00464     QString line;
00465     return (p_GetLine(line, false));
00466   }
00467 
00479   bool TextFile::p_GetLine(QString &line, bool chkComment) {
00480     OpenChk(true);
00481 
00482     line = "";
00483 
00484     // Try to read the next line
00485     std::string lineStdString;
00486     getline(p_stream, lineStdString);
00487     line = lineStdString.c_str();
00488 
00489     // Check for end of file
00490     if(p_stream.eof()) {
00491       return false;
00492     }
00493 
00494     // See if an error occured
00495     if(!p_stream.good()) {
00496       line = "";
00497       QString message = "TextFile:GetLine: -> Error reading text file: ["
00498                        + p_filename + "]";
00499       throw IException(IException::Io, message, _FILEINFO_);
00500     }
00501 
00502     // See if we have a comment and if we need to ignore
00503     if(chkComment) {
00504       if(p_commentString.length()) {
00505         int locComment = line.indexOf(p_commentString);
00506         if(locComment != -1) {
00507           int afterWhiteSpace = line.indexOf(QRegExp("[^\\s]"));
00508           if((locComment == 0) || (locComment == afterWhiteSpace)) {
00509             return p_GetLine(line, chkComment);
00510           }
00511         }
00512       }
00513     }
00514 
00515     // We have a good line
00516     return true;
00517   }
00518 
00524   void TextFile::PutLine(const QString &line) {
00525     PutLine(line.toAscii().data());
00526   }
00527 
00538   void TextFile::PutLine(const char *line) {
00539     OpenChk(true);
00540 
00541     // Try to write the next line
00542     p_stream << line << p_newLineString;
00543     // See if an error occured
00544     if(!p_stream.good()) {
00545       if(p_openmode != 1) {
00546         QString message = "TextFile:PutLine: -> Error writing text file: ["
00547                          + p_filename + "]";
00548         throw IException(IException::Io, message, _FILEINFO_);
00549       }
00550       else {
00551         QString message =
00552           "TextFile:PutLine: -> Attempt to write to INPUT - Read Only text file: ["
00553           + p_filename + "]";
00554         throw IException(IException::Programmer, message, _FILEINFO_);
00555       }
00556     }
00557   }
00558 
00565   void TextFile::PutLineComment(const QString &line) {
00566     PutLine(p_commentString + line);
00567   }
00568 
00575   void TextFile::PutLineComment(const char *line) {
00576     PutLine(p_commentString + QString(line));
00577   }
00578 
00579 
00580   QString TextFile::GetComment() {
00581     return(p_commentString);
00582   }
00583 
00584 
00593   void TextFile::SetComment(const char *commentString) {
00594     p_commentString = commentString;
00595   }
00596 
00597 
00598   QString TextFile::GetNewLine() {
00599     return(p_newLineString);
00600   }
00601 
00609   void TextFile::SetNewLine(const char *newLineString) {
00610     p_newLineString = newLineString;
00611   }
00612 
00623   int TextFile::LineCount(const int &maxLinesToRead) {
00624     OpenChk(true);
00625 
00626     // LineCount ( [maxLinesToRead] )  --- returns number of lines in open file
00627 
00628     bool eofStat = false;
00629     if(p_stream.eof()) {  // current state of stream is 'eof'
00630       eofStat = true;
00631       p_stream.clear();
00632     }
00633 
00634     streampos savePos = p_stream.tellg();
00635     p_stream.seekg(0, ios_base::beg);
00636 
00637     int lineCount = 0;
00638     string tmpLine;
00639     if(maxLinesToRead > 0) {
00640       while((getline(p_stream, tmpLine)) && (lineCount <= maxLinesToRead)) {
00641         lineCount++;
00642       }
00643     }
00644     else {
00645       while(getline(p_stream, tmpLine)) {
00646         lineCount++;
00647       }
00648     }
00649 
00650     if(p_stream.eof()) {
00651       p_stream.clear();
00652     }
00653 
00654     p_stream.seekg(savePos, ios_base::beg);
00655 
00656     if(eofStat) {           // restore current state of stream 'eof'
00657       p_stream.seekg(0, ios_base::end);
00658       p_stream.get();
00659     }
00660     return lineCount;
00661   }
00662 
00668   streamsize TextFile::Size() {
00669     OpenChk(true);
00670 
00671     // Size () --- returns file size in bytes
00672 
00673     bool eofStat = false;
00674     if(p_stream.eof()) {  // current state of stream is 'eof'
00675       eofStat = true;
00676       p_stream.clear();
00677     }
00678 
00679     streampos savePos = p_stream.tellg();
00680     p_stream.seekg(0, ios_base::end);
00681     streamsize bytes = p_stream.tellg();
00682     p_stream.seekg(savePos, ios_base::beg);
00683 
00684     if(eofStat) {           // restore current state of stream 'eof'
00685       p_stream.seekg(0, ios_base::end);
00686       p_stream.get();
00687     }
00688     return bytes;
00689   }
00690 } // end namespace isis
00691 
00692