|
Isis 3.0 Object Programmers' Reference |
Home |
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