//: TDocFile.C /* @(#)root/base:$Name: $:$Id: TDocFile.C,v 1.2 2004-12-05 17:22:05+01 veghj Exp $ */ /* \author (c) János Végh, MTA ATOMKI, Debrecen, Hungary (veghj@users.sf.net) \since Dec 13, 2004 $Id: TDocFile.C,v 1.2 2004-12-05 17:22:05+01 veghj Exp $ */ #if !defined(__CINT__) #include "Riostream.h" #include "TObject.h" #include "TString.h" #include "TObjString" #endif // Define the document file class class TDocFile : public TObject { protected: TString fFileName; // Name of the file ifstream *fstream; // The input stream int fNoOfTokens; // Tokens in this line int fCurrentTokenNo; // Seq no of current token int fCurrentLineNo; // Seq no of current text line TString fCurrentLine; // Current text line TObjArray* fTokens; // Token in current line TString fDelimiters; // Delimiters for token reading private: void Reset(void); // Reset internal variables void LoadCurrentLine(char *buf); // Load current line with buffer public: TDocFile(void); TDocFile(TString FName); ~TDocFile(void); void EmptyTokenBuffer(void); Int_t GetASCIIDouble(Double_t &D); Int_t GetASCIILong(Long_t &L); Bool_t GetASCIIString(TString &T, int &length); Bool_t GetBinaryByte(unsigned char &C); Bool_t GetBinaryDouble(double &D); Bool_t GetCurrentLine(TString &T); Bool_t GetCurrentToken(TString &T); TString &GetDelimiters(void); static Int_t GetFileLength(TString FName); int GetFormError(void); TString GetNextToken(void); static Int_t GetNoOfLines(TString FName); Bool_t HasMoreTokens(void); Bool_t HasMoreTokensInLine(void); Bool_t IsOpen(ifstream *stream = NULL); Bool_t ReadNextLine(void); // Read next text line from stream void SetDelimiters(TString Delim); void SetFileName(TString FName); //#if !defined(__CINT__) // Define the class for the cint dictionary ClassDef(TDocFile,1); //#endif }; /// Define form errors enum TextNumberErrors { feOK = 0, feNoArg = 1, feFloat = 2, feInteger = 3 }; // Call ClassImp to give TDocFile class RTTI // and full I/O capabilities #if !defined(__CINT__) ClassImp(TDocFile); #endif TDocFile::TDocFile(void) { Reset(); } TDocFile::TDocFile(TString FName) { Reset(); SetFileName(FName); fstream = new ifstream(FName.Data(), ios::in | ios::binary); } void TDocFile::Reset(void) { fstream = (ifstream *)NULL; fNoOfTokens = 0; // Tokens in this line fCurrentTokenNo = 0; // Seq no of current token fCurrentLineNo = 0; // Seq no of current text line fTokens = (TObjArray*)NULL; SetFileName(""); SetDelimiters(" \t\n;"); } TDocFile::~TDocFile(void) { if(fstream) delete fstream; } void TDocFile::EmptyTokenBuffer(void) { LoadCurrentLine(""); } TString &TDocFile::GetDelimiters(void) { return fDelimiters; } // Return the number of lines in the document file static Int_t TDocFile::GetNoOfLines(TString FName) { Int_t Index = 0; char buf[500]; ifstream *stream = new ifstream(FName.Data()); if(!IsOpen(stream)) { delete stream; return -1;} while (!stream->eof()) { stream->getline(buf,sizeof(buf)); ++Index; } delete stream; return Index; } // Return the number of characters in the file static Int_t TDocFile::GetFileLength(TString FName) { ifstream *stream = new ifstream(FName.Data(), ios::in | ios::binary); if(!IsOpen(stream)) { delete stream; return -1;} stream->seekg(0,ios::end); // Set to the end long kf = stream->tellg(); // Determine file length delete stream; return kf; } // Return error code in case of format error and clears error code int TDocFile::GetFormError(void) { int i = m_FormError; m_FormError = 0; return i;} // Return true if there are more tokens in the stream Bool_t TDocFile::HasMoreTokens(void) { return !fstream->eof() || HasMoreTokensInLine(); } // Return true if there are more token in the current line Bool_t TDocFile::HasMoreTokensInLine(void) { return fNoOfTokens > fCurrentTokenNo; } // Return true if the stream is open and can be read Bool_t TDocFile::IsOpen(ifstream *stream) { if(!stream) stream = fstream; return stream->tellg()<0 ? kFALSE : kTRUE; } // Return the current line Bool_t TDocFile::GetCurrentLine(TString &T) { if(!IsOpen()) return kFALSE; if(fstream->eof()) return kFALSE; T = fCurrentLine; } // Return the current token Bool_t TDocFile::GetCurrentToken(TString &T) { if(!IsOpen()) return kFALSE; if(fstream->eof()) return kFALSE; if(!fTokens) return kFALSE; TObjString* OS = (TObjString*)((*fTokens)[fCurrentTokenNo]); // printf("GetCurrentToken from '%s'[%d/%d] @%x\n", fCurrentLine.Data(), fCurrentTokenNo, fNoOfTokens, OS); if(!OS) return kFALSE; // printf("GetCurrentToken: %s\n",OS->GetString().Data()); T = (OS->GetString()); return kTRUE; } // Read in the next token in T; return true of OK Bool_t TDocFile::GetNextToken(TString &T) { if(!IsOpen()) return kFALSE; if(fstream->eof()) return kFALSE; // printf("GetNextToken from line '%s'\n", fCurrentLine.Data()); again: if(!HasMoreTokensInLine()) { // No more tokens in this line if(!ReadNextLine()) return kFALSE; if(!fCurrentLine.Length()) { if(fstream->eof()) return kFALSE; goto again; } } if(!GetCurrentToken(T)) { if(fstream->eof()) return kFALSE; goto again; } fCurrentTokenNo++; return kTRUE; } /// Read an ASCII long integer from the stream Int_t TDocFile::GetASCIILong(Long_t &L) { TString a; char *endptr; if(!GetNextToken(a) || !a.Length()) return -feNoArg; L = strtol(a.Data(), &endptr, 10); printf("GetASCIILong: '%s'=%ld\n", a.Data(), L); if (!(*endptr)) return feOK; return -feInteger; }//GetASCIIInt /// Read an ASCII long integer from the stream Int_t TDocFile::GetASCIIDouble(Double_t &D) { TString a; char *endptr; if(!GetNextToken(a) || !a.Length()) return -feNoArg; // correct for the possible syntactical problems if ('.' == a.Data()[0]) a = '0'+a; if (('-' == a.Data()[0]) && ('.' == a.Data()[1])) a.Insert(1,'0'); D = strtod(a.Data(), &endptr); printf("GetASCIIDouble: '%s' = %f\n", a.Data(), D); if (!(*endptr)) return feOK; return -feInteger; }//GetASCIIDouble // Read an ASCII string (of max length 'length') from the file Bool_t TDocFile::GetASCIIString(TString &T, int &length) { Bool_t b = GetNextToken(T); int maxlength = length; if((T.Length() < maxlength) || (maxlength==0)) maxlength = a.Length(); T = T.Remove(maxlength); return b; } /* * Read arguments from file, in binary form */ // Read in a single byte Bool_t TDocFile::GetBinaryByte(unsigned char &C) { fstream->read((unsigned char*)C,1); return !fstream->eof(); }//TDocFile::GetBinaryByte // Read in 64-bit double float Bool_t TDocFile::GetBinaryDouble(double &D) { fstream->read((char*)&D,sizeof(D)); return !fstream->eof(); }//TDocFile::GetBinaryDouble // Load "Current line" with the content of "buf" void TDocFile::LoadCurrentLine(char *buf) { fCurrentLine = buf; fCurrentLineNo++; fTokens = fCurrentLine.Tokenize(fDelimiters.Data()); fNoOfTokens = fTokens->GetEntriesFast(); } // Read next text line from stream Bool_t TDocFile::ReadNextLine(void) { char buf[500]; fCurrentTokenNo = 0; fNoOfTokens = 0; if(!fTokens) { delete fTokens; fTokens = NULL; } // delete old token array if(!IsOpen()) return kFALSE; if(fstream->eof()) return kFALSE; fstream->getline(buf,sizeof(buf)); LoadCurrentLine(buf); // printf("ReadNextLine = '%s', %d tokens\n",buf, fNoOfTokens); return kTRUE; }// ReadNextLine void TDocFile::SetDelimiters(TString Delim) { fDelimiters = Delim; // Delimiters for token reading } void TDocFile::SetFileName(TString FName) { fFileName = FName; // printf("File name is '%s'\n",fFileName.Data()); }