// @(#)root/base:$Id$ // Author: Fons Rademakers 04/08/95 /************************************************************************* * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ ////////////////////////////////////////////////////////////////////////// // // // TString Input/Output functions, put here so the linker will include // // them only if I/O is done. // // // ////////////////////////////////////////////////////////////////////////// #include // Looking for isspace() #include "Riostream.h" #include "TString.h" //______________________________________________________________________________ istream& TString::ReadFile(istream& strm) { // Replace string with the contents of strm, stopping at an EOF. // get file size Ssiz_t end, cur = strm.tellg(); strm.seekg(0, ios::end); end = strm.tellg(); strm.seekg(cur); // any positive number of reasonable size for a file const Ssiz_t incr = 256; Clobber(end-cur); while(1) { Ssiz_t len = Length(); Ssiz_t cap = Capacity(); strm.read(GetPointer()+len, cap-len); SetSize(len + strm.gcount()); if (!strm.good()) break; // EOF encountered // If we got here, the read must have stopped because // the buffer was going to overflow. Resize and keep // going. cap = AdjustCapacity(cap, cap+incr); Capacity(cap); } GetPointer()[Length()] = '\0'; // Add null terminator return strm; } //______________________________________________________________________________ istream& TString::ReadLine(istream& strm, Bool_t skipWhite) { // Read a line from stream upto newline skipping any whitespace. if (skipWhite) strm >> ws; return ReadToDelim(strm, '\n'); } //______________________________________________________________________________ istream& TString::ReadString(istream& strm) { // Read a line from stream upto \0, including any newline. return ReadToDelim(strm, '\0'); } //______________________________________________________________________________ istream& TString::ReadToDelim(istream& strm, char delim) { // Read up to an EOF, or a delimiting character, whichever comes // first. The delimiter is not stored in the string, // but is removed from the input stream. // Because we don't know how big a string to expect, we first read // as much as we can and then, if the EOF or null hasn't been // encountered, do a resize and keep reading. // any positive number of reasonable size for a string const Ssiz_t incr = 32; Clobber(incr); int p = strm.peek(); // Check if we are already at delim if (p == delim) { strm.get(); // eat the delimiter, and return \0. } else { while (1) { Ssiz_t len = Length(); Ssiz_t cap = Capacity(); strm.get(GetPointer()+len, // Address of next byte cap-len+1, // Space available (+1 for terminator) delim); // Delimiter SetSize(len + strm.gcount()); if (!strm.good()) break; // Check for EOF or stream failure p = strm.peek(); if (p == delim) { // Check for delimiter strm.get(); // eat the delimiter. break; } // Delimiter not seen. Resize and keep going: cap = AdjustCapacity(cap, cap+incr); Capacity(cap); } } GetPointer()[Length()] = '\0'; // Add null terminator return strm; } //______________________________________________________________________________ istream& TString::ReadToken(istream& strm) { // Read a token, delimited by whitespace, from the input stream. // any positive number of reasonable size for a token const Ssiz_t incr = 16; Clobber(incr); strm >> ws; // Eat whitespace UInt_t wid = strm.width(0); char c; Int_t hitSpace = 0; while ((wid == 0 || Length() < (Int_t)wid) && strm.get(c).good() && (hitSpace = isspace((Int_t)c)) == 0) { // Check for overflow: Ssiz_t len = Length(); Ssiz_t cap = Capacity(); if (len == cap) { cap = AdjustCapacity(cap, cap+incr); Capacity(cap); } GetPointer()[len] = c; len++; SetSize(len); } if (hitSpace) strm.putback(c); GetPointer()[Length()] = '\0'; // Add null terminator return strm; } //______________________________________________________________________________ istream& operator>>(istream& strm, TString& s) { // Read string from stream. return s.ReadToken(strm); } //______________________________________________________________________________ ostream& operator<<(ostream& os, const TString& s) { // Write string to stream. if (os.good()) { if (os.tie()) os.tie()->flush(); // instead of opfx UInt_t len = s.Length(); UInt_t wid = os.width(); wid = (len < wid) ? wid - len : 0; os.width(wid); long flags = os.flags(); if (wid && !(flags & ios::left)) os << ""; // let the ostream fill os.write((char*)s.Data(), s.Length()); if (wid && (flags & ios::left)) os << ""; // let the ostream fill } // instead of os.osfx(); if (os.flags() & ios::unitbuf) os.flush(); return os; } // ------------------- C I/O ------------------------------------ //______________________________________________________________________________ Bool_t TString::Gets(FILE *fp, Bool_t chop) { // Read one line from the stream, including the \n, or until EOF. // Remove the trailing \n if chop is true. Returns kTRUE if data was read. char buf[256]; Bool_t r = kFALSE; Clobber(256); do { if (fgets(buf, sizeof(buf), fp) == 0) break; *this += buf; r = kTRUE; } while (!ferror(fp) && !feof(fp) && strchr(buf,'\n') == 0); if (chop && EndsWith("\n")) Chop(); return r; } //______________________________________________________________________________ void TString::Puts(FILE *fp) { // Write string to the stream. fputs(GetPointer(), fp); }