Isis 3 Programmer Reference
TextFile.cpp
Go to the documentation of this file.
1 
23 #include "IException.h"
24 #include "IException.h"
25 #include "FileName.h"
26 #include "Message.h"
27 #include "TextFile.h"
28 #include "IString.h"
29 
30 #include <iostream>
31 
32 #include <QFileInfo>
33 
34 using namespace std;
35 namespace Isis {
36 
38  TextFile::TextFile() {
39  }
40 
57  TextFile::TextFile(const QString &filename,
58  const char *openmode, const char *extension) {
59  SetComment();
60  SetNewLine();
61  Open(filename, openmode, extension);
62  }
63 
88  TextFile::TextFile(const QString &filename, const char *openmode,
89  std::vector<QString> &lines, const int &maxLinesToReadWrite,
90  const bool skipComments) {
91  SetComment();
92  SetNewLine();
93  Open(filename, openmode);
94  if(p_openmode == 1) {
95  GetFile(lines, maxLinesToReadWrite, skipComments);
96  }
97  else {
98  PutFile(lines, maxLinesToReadWrite);
99  }
100  }
125  TextFile::TextFile(const char *filename, const char *openmode,
126  std::vector<QString> &lines, const int &maxLinesToReadWrite,
127  const bool skipComments) {
128  TextFile(QString(filename), openmode, lines, maxLinesToReadWrite, skipComments);
129  }
130 
156  TextFile::TextFile(const QString &filename, const char *openmode,
157  QString *lines, const int &maxLinesToReadWrite,
158  const bool skipComments) {
159  SetComment();
160  SetNewLine();
161  Open(filename, openmode);
162  if(p_openmode == 1) {
163  GetFile(lines, maxLinesToReadWrite, skipComments);
164  }
165  else {
166  PutFile(lines, maxLinesToReadWrite);
167  }
168  }
169 
194  TextFile::TextFile(const char *filename, const char *openmode,
195  QString *lines, const int &maxLinesToReadWrite,
196  const bool skipComments) {
197  TextFile(QString(filename), openmode, lines, maxLinesToReadWrite, skipComments);
198  }
199 
200 
202  TextFile::~TextFile() {
203  Close();
204  }
205 
206 
207  // Methods
208 
233  void TextFile::Open(const QString &filename, const char *openmode,
234  const char *extension) {
235  // Open (filename [,openmode] [, with_extension ])
236  // default openmode = 'input'
237  // default extension = 'txt'; extension = "" opens without default
238 
239  // note: in append mode, the input and output pointers move together
240 
241 
242  // Don't open if it already is
243  if(p_stream.is_open()) {
244  QString message = "TextFile:Open:-> Already opened with this object: ["
245  + QString(openmode) + "]:[" + p_filename + "]";
246  throw IException(IException::Programmer, message, _FILEINFO_);
247  }
248 
249  p_openmode = 0;
250 
251  // Save the filename for error messages
252 
253  Isis::FileName filenameTmp(filename);
254  filenameTmp.addExtension(extension);
255  p_filename = filenameTmp.expanded();
256 
257 
258  // input, output, overwrite, append
259 
260  string chkOpenmode = Isis::IString(openmode).DownCase();
261  if(chkOpenmode == "input") {
262  p_openmode = 1;
263  }
264  else if(chkOpenmode == "output") {
265  p_openmode = 2;
266  }
267  else if(chkOpenmode == "overwrite") {
268  p_openmode = 3;
269  }
270  else if(chkOpenmode == "append") {
271  p_openmode = 4;
272  }
273  else {
274  QString message = "TextFile::-> Unknown openmode: (input, output, overwrite, append):["
275  + QString(openmode) + "]:[" + p_filename + "]";
276  throw IException(IException::Programmer, message, _FILEINFO_);
277  }
278 
279  // Input
280  if(p_openmode == 1) {
281  p_stream.open(p_filename.toLatin1().data(), fstream::in);
282  }
283  // Output
284  else if(p_openmode == 2) {
285  // first check if file already exists
286  if(filenameTmp.fileExists() && QFileInfo(filenameTmp.toString()).size() > 0) {
287  QString message = "TextFile:Open: -> Output file already exists ["
288  + QString(openmode) + "]:[" + p_filename + "]";
289  throw IException(IException::Io, message, _FILEINFO_);
290  }
291 
292  p_stream.open(p_filename.toLatin1().data(), fstream::in | fstream::out | fstream::trunc);
293  p_stream.clear();
294  }
295  // Overwrite
296  else if(p_openmode == 3) {
297  p_stream.open(p_filename.toLatin1().data(), fstream::in | fstream::out | fstream::trunc);
298  }
299  // Append
300  else if(p_openmode == 4) {
301  // Open in append if it does exist, otherwise, open in overwrite mode
302  if(filenameTmp.fileExists()) {
303  p_stream.open(p_filename.toLatin1().data(), fstream::in | fstream::out | fstream::ate);
304  }
305  else {
306  p_stream.open(p_filename.toLatin1().data(), fstream::in | fstream::out | fstream::trunc);
307  }
308  }
309 
310  if(!p_stream.is_open()) {
311  QString message = "TextFile:Open:-> Unable to open: ["
312  + QString(openmode) + "]:[" + p_filename + "]";
313  throw IException(IException::Io, message, _FILEINFO_);
314  }
315  }
316 
317  bool TextFile::OpenChk(bool bailIfNotOpen) {
318  if(p_stream.is_open()) {
319  return(true);
320  }
321  else {
322  if(bailIfNotOpen) {
323  QString message = "TextFile::-> File not open: [" + p_filename + "]";
324  throw IException(IException::Programmer, message, _FILEINFO_);
325  }
326  else {
327  return(false);
328  }
329  }
330  }
331 
333  void TextFile::Rewind() {
334  OpenChk(true);
335  if(p_stream.eof()) {
336  p_stream.clear();
337  }
338  p_stream.seekg(0, ios_base::beg);
339  }
340 
342  void TextFile::Close() {
343  if(p_stream.is_open()) {
344  p_stream.flush();
345  p_stream.close();
346  }
347  }
348 
349  // vector array
350  void TextFile::GetFile(std::vector<QString> &lines, const int &maxLinesToRead,
351  const bool skipComments) {
352  OpenChk(true);
353  QString line;
354  int lineCount = 0;
355  while(GetLine(line, skipComments)) {
356  if(maxLinesToRead > 0) {
357  if(lineCount++ >= maxLinesToRead) {
358  break;
359  };
360  }
361  lines.push_back(line);
362  }
363  }
364 
365  // string array
366  void TextFile::GetFile(QString *lines, const int &maxLinesToRead,
367  const bool skipComments) {
368  OpenChk(true);
369  QString line;
370  int lineCount = 0;
371  while(GetLine(line, skipComments)) {
372  if(maxLinesToRead > 0) {
373  if(lineCount > maxLinesToRead) {
374  break;
375  };
376  }
377  else if(lines[lineCount] == "\0") {
378  break;
379  }
380  lines[lineCount] = line;
381  lineCount++;
382  }
383  }
384 
385  // vector array
386  void TextFile::PutFile(std::vector<QString> &lines, const int &maxLinesToWrite) {
387  OpenChk(true);
388  for(int lineCount = 0; lineCount < (int) lines.size(); lineCount++) {
389  if(maxLinesToWrite > 0) {
390  if(lineCount > maxLinesToWrite) {
391  break;
392  };
393  }
394  PutLine(lines[lineCount]);
395  }
396  }
397 
398  // string array
399  void TextFile::PutFile(const QString *lines, const int &maxLinesToWrite) {
400  OpenChk(true);
401  int lineCount = 0;
402  while(true) {
403  if(maxLinesToWrite > 0) {
404  if(lineCount > maxLinesToWrite) {
405  break;
406  };
407  }
408  else if(lines[lineCount] == "\0") {
409  break;
410  }
411  PutLine(lines[lineCount]);
412  lineCount++;
413  }
414  }
415 
427  bool TextFile::GetLine(QString &line, bool skipComments) {
428  return (p_GetLine(line, skipComments));
429  }
430 
440  bool TextFile::GetLine(bool skipComments) {
441  QString line;
442  return (p_GetLine(line, skipComments));
443  }
444 
453  bool TextFile::GetLineNoFilter(QString &line) {
454  return (p_GetLine(line, false));
455  }
456 
463  bool TextFile::GetLineNoFilter() {
464  QString line;
465  return (p_GetLine(line, false));
466  }
467 
479  bool TextFile::p_GetLine(QString &line, bool chkComment) {
480  OpenChk(true);
481 
482  line = "";
483 
484  // Try to read the next line
485  std::string lineStdString;
486  getline(p_stream, lineStdString);
487  line = lineStdString.c_str();
488 
489  // Check for end of file
490  if(p_stream.eof()) {
491  return false;
492  }
493 
494  // See if an error occured
495  if(!p_stream.good()) {
496  line = "";
497  QString message = "TextFile:GetLine: -> Error reading text file: ["
498  + p_filename + "]";
499  throw IException(IException::Io, message, _FILEINFO_);
500  }
501 
502  // See if we have a comment and if we need to ignore
503  if(chkComment) {
504  if(p_commentString.length()) {
505  int locComment = line.indexOf(p_commentString);
506  if(locComment != -1) {
507  int afterWhiteSpace = line.indexOf(QRegExp("[^\\s]"));
508  if((locComment == 0) || (locComment == afterWhiteSpace)) {
509  return p_GetLine(line, chkComment);
510  }
511  }
512  }
513  }
514 
515  // We have a good line
516  return true;
517  }
518 
524  void TextFile::PutLine(const QString &line) {
525  PutLine(line.toLatin1().data());
526  }
527 
538  void TextFile::PutLine(const char *line) {
539  OpenChk(true);
540 
541  // Try to write the next line
542  p_stream << line << p_newLineString;
543  // See if an error occured
544  if(!p_stream.good()) {
545  if(p_openmode != 1) {
546  QString message = "TextFile:PutLine: -> Error writing text file: ["
547  + p_filename + "]";
548  throw IException(IException::Io, message, _FILEINFO_);
549  }
550  else {
551  QString message =
552  "TextFile:PutLine: -> Attempt to write to INPUT - Read Only text file: ["
553  + p_filename + "]";
554  throw IException(IException::Programmer, message, _FILEINFO_);
555  }
556  }
557  }
558 
565  void TextFile::PutLineComment(const QString &line) {
566  PutLine(p_commentString + line);
567  }
568 
575  void TextFile::PutLineComment(const char *line) {
576  PutLine(p_commentString + QString(line));
577  }
578 
579 
580  QString TextFile::GetComment() {
581  return(p_commentString);
582  }
583 
584 
593  void TextFile::SetComment(const char *commentString) {
594  p_commentString = commentString;
595  }
596 
597 
598  QString TextFile::GetNewLine() {
599  return(p_newLineString);
600  }
601 
609  void TextFile::SetNewLine(const char *newLineString) {
610  p_newLineString = newLineString;
611  }
612 
623  int TextFile::LineCount(const int &maxLinesToRead) {
624  OpenChk(true);
625 
626  // LineCount ( [maxLinesToRead] ) --- returns number of lines in open file
627 
628  bool eofStat = false;
629  if(p_stream.eof()) { // current state of stream is 'eof'
630  eofStat = true;
631  p_stream.clear();
632  }
633 
634  streampos savePos = p_stream.tellg();
635  p_stream.seekg(0, ios_base::beg);
636 
637  int lineCount = 0;
638  string tmpLine;
639  if(maxLinesToRead > 0) {
640  while((getline(p_stream, tmpLine)) && (lineCount <= maxLinesToRead)) {
641  lineCount++;
642  }
643  }
644  else {
645  while(getline(p_stream, tmpLine)) {
646  lineCount++;
647  }
648  }
649 
650  if(p_stream.eof()) {
651  p_stream.clear();
652  }
653 
654  p_stream.seekg(savePos, ios_base::beg);
655 
656  if(eofStat) { // restore current state of stream 'eof'
657  p_stream.seekg(0, ios_base::end);
658  p_stream.get();
659  }
660  return lineCount;
661  }
662 
668  streamsize TextFile::Size() {
669  OpenChk(true);
670 
671  // Size () --- returns file size in bytes
672 
673  bool eofStat = false;
674  if(p_stream.eof()) { // current state of stream is 'eof'
675  eofStat = true;
676  p_stream.clear();
677  }
678 
679  streampos savePos = p_stream.tellg();
680  p_stream.seekg(0, ios_base::end);
681  streamsize bytes = p_stream.tellg();
682  p_stream.seekg(savePos, ios_base::beg);
683 
684  if(eofStat) { // restore current state of stream 'eof'
685  p_stream.seekg(0, ios_base::end);
686  p_stream.get();
687  }
688  return bytes;
689  }
690 } // end namespace isis
691 
692 
File name manipulation and expansion.
Definition: FileName.h:116
FileName addExtension(const QString &extension) const
Adds a new extension to the file name.
Definition: FileName.cpp:241
Namespace for the standard library.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
IString DownCase()
Converts all upper case letters in the object IString into lower case characters. ...
Definition: IString.cpp:659
Provides access to sequential ASCII stream I/O.
Definition: TextFile.h:54
QString toString() const
Returns a QString of the full file name including the file path, excluding the attributes with any Is...
Definition: FileName.cpp:531
Isis exception class.
Definition: IException.h:107
Adds specific functionality to C++ strings.
Definition: IString.h:181
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:465