token.cpp

Go to the documentation of this file.
00001 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005 Copyright (C) 2006  Bernd Opitz
00006 Exclusive copyright is granted to Klaus Schmidt
00007 
00008 This library is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU Lesser General Public
00010 License as published by the Free Software Foundation; either
00011 version 2.1 of the License, or (at your option) any later version.
00012 
00013 This library is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 Lesser General Public License for more details.
00017 
00018 You should have received a copy of the GNU Lesser General Public
00019 License along with this library; if not, write to the Free Software
00020 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00021 
00022 
00023 #include "token.h"
00024 
00025 namespace faudes {
00026 
00027 // Token::Token()
00028 Token::Token(void) : 
00029   mType(None), 
00030   mStringValue(""), 
00031   mIntegerValue(0), 
00032   mFloatValue(0) { 
00033 }
00034 
00035 // destructor
00036 Token::~Token(void){
00037 }
00038 
00039 // Token::SetNone()
00040 void Token::SetNone(void ) {
00041   mType=None; mStringValue=""; mIntegerValue=0; mFloatValue=0;
00042 }
00043 
00044 // Token::SetString(str)
00045 void Token::SetString(const std::string& rName) {
00046   mType=String; mStringValue=rName; mIntegerValue=0; mFloatValue=0;
00047 }
00048 
00049 // Token::SetBegin(str)
00050 void Token::SetBegin(const std::string& rName) {
00051   mType=Begin; mStringValue=rName; mIntegerValue=0; mFloatValue=0;
00052 }
00053 
00054 // Token::SetEnd(str)
00055 void Token::SetEnd(const std::string& rName) {
00056   mType=End; mStringValue=rName; mIntegerValue=0; mFloatValue=0;
00057 }
00058 
00059 // Token::SetOption(str)
00060 void Token::SetOption(const std::string& rName) {
00061   mType=Option; mStringValue=rName; mIntegerValue=0; mFloatValue=0;
00062 }
00063 
00064 // Token::SetInteger(number)
00065 void Token::SetInteger(const long int number) {
00066   mType=Integer; mStringValue=""; mIntegerValue=number; mFloatValue=number;
00067 }
00068 
00069 // Token::SetInteger16(number)
00070 void Token::SetInteger16(const long int number) {
00071   mType=Integer16; mStringValue=""; mIntegerValue=number; mFloatValue=number;
00072 }
00073 
00074 // Token::SetFloat(number)
00075 void Token::SetFloat(const double number) {
00076   mType=Float; mStringValue=""; mIntegerValue=(long int) number; mFloatValue=number;
00077 }
00078 
00079 // ReadNumber(pStream)
00080 bool Token::ReadNumber(std::istream* pStream){
00081   char c, vc;
00082   double fv=0;
00083   long int iv=0;
00084   bool comma = false;
00085   bool minus = false;
00086   int  base=10;
00087   bool ok=false;
00088   int cnt=0;
00089   // check the whole pStream
00090   while(*pStream){
00091     // check eof
00092     if (pStream->eof()) 
00093       {mType=None; return(false);}; 
00094     // check next charakter
00095     c = pStream->peek();                 
00096     cnt++;
00097     // break if space
00098     if (isspace(c)) break;
00099     // change base on x
00100     if(c=='x' && iv==0 && cnt==2 && !comma && !minus) 
00101       {pStream->get(); base = 16; continue;}
00102     // change sign on -
00103     if(c=='-' && cnt==1) 
00104       {pStream->get(); minus = true; continue;}
00105     // record comma
00106     if(c=='.' && comma==false && base==10) 
00107       {pStream->get(); comma = true; continue;}
00108     // break if it is not a digit
00109     if (!isdigit(c) && base==10) break;
00110     if (!isxdigit(c) && base==16) break;
00111     // get the next charakter
00112     pStream->get();
00113     // compute the value of c
00114     vc=0;
00115     if(c>='0' && c<= '9') vc = c-'0';
00116     else if(c>='a' && c<= 'f') vc = c-'a' + 10;
00117     else if(c>='A' && c<= 'F') vc = c-'A' + 10;
00118     // compute the corresponding number
00119     iv = base * iv + vc;
00120     fv = base * fv + vc;
00121     if(comma) { 
00122       iv=iv/base;
00123       fv=fv/base;
00124     }
00125     ok = true; 
00126   } // termination with the end of the pStream or a non-digit or a space
00127   // assign the numeric value and type in Token
00128   if(minus) {
00129     iv=-iv;
00130     fv=-fv;
00131   }
00132   mIntegerValue = iv;
00133   mFloatValue = fv;
00134   mType= (comma || minus) ? Float : Integer;
00135   if(base == 16) mType = Integer16;
00136   return(ok);
00137 }
00138 
00139 // Write(pStream)
00140 void Token::Write(std::ostream* pStream){
00141   FD_DV("Token::Write: mType=" << (int) mType 
00142   << "\" mStringValue=\"" << mStringValue 
00143   << "\" mIntegerValue=" <<mIntegerValue 
00144   << "\" mFloatValue=" <<mFloatValue <<"\n");
00145   // distuingish the token type
00146   switch (mType) {
00147     // <mStringValue> 
00148   case Begin:
00149     *pStream << '<' << mStringValue << '>';
00150     break;
00151     // </mStringValue>
00152   case End:
00153     *pStream << "</" << mStringValue << '>';
00154     break;
00155     // "mStringValue"
00156   case String:
00157     *pStream <<  ExpandString("\""+mStringValue+"\"", FD_NAMELEN);
00158     break;
00159     // "mStringValue"
00160   case Option:
00161     *pStream <<  ExpandString("+"+mStringValue+"+", FD_NAMELEN);
00162     break;
00163     // mIntegerValue
00164   case Integer:
00165     *pStream << ExpandString(ToStringInteger(mIntegerValue), FD_NAMELEN);
00166     break;
00167     // mIntegerValue
00168   case Integer16:
00169     *pStream << ExpandString(ToStringInteger16(mIntegerValue), FD_NAMELEN);
00170     break;
00171     // mFloatValue
00172   case Float:
00173     *pStream << ExpandString(ToStringFloat(mFloatValue), FD_NAMELEN);
00174     break;
00175     // all other unexpected cases
00176   default:
00177     assert(0);
00178   }
00179 }
00180 
00181 // ReadString(pStream, char)
00182 bool Token::ReadString(std::istream* pStream, char stop){
00183   char c;
00184   std::string v = "";
00185   // check the whole pStream
00186   while (*pStream) {
00187     // check eof
00188     if (pStream->eof()) {mType=None; return false;}; 
00189     // look one charakter ahead
00190     c = pStream->peek();
00191     // unsuccessful termination if c is a control character
00192     if (iscntrl(c)) return false;
00193     // else get the next character
00194     pStream->get(); 
00195     // break if the stop character is reached
00196     if(c == stop) break; 
00197     // else append the character to the current string
00198     v.append(1,c);
00199   } 
00200   // assign the string value in Token
00201   mStringValue = v;
00202   return(true);
00203 }
00204 
00205 
00206 // ReadSpace(pStream)
00207 int Token::ReadSpace(std::istream* pStream){
00208   char c = '\0';
00209   int lc = 0;
00210   // check the whole pStream
00211   while (*pStream) {
00212     while (*pStream) {
00213       // check eof
00214       if (pStream->eof()) {return(lc);}; 
00215       // look one character ahead
00216       c = pStream->peek();
00217       // break if the next character is 
00218       if((! isspace(c)) && (! iscntrl(c))) break;
00219       // not a space or a control character
00220       // get the next space or control character
00221       pStream->get();
00222       // count the next lines
00223       if(c == '\n') ++lc;
00224     }
00225     // if the next charakter starts a comment
00226     if (c != '%') break;
00227     while (*pStream) {
00228       // check eof
00229       if (pStream->eof()) {return(lc);}; 
00230       // get the next character
00231       c = pStream->get();
00232       // count the next lines
00233       if (c == '\n') ++lc;
00234       // terminate with the next control character
00235       if (iscntrl(c)) break;
00236     }
00237   }
00238   // termination if the next character is not a space, a control character 
00239   //or a '%'.
00240   return (lc); 
00241 }
00242 
00243 // Read(pStream)
00244 int Token::Read(std::istream* pStream){
00245   char c1, c2;
00246   int lc = 0;
00247   // the token is initialized with the type "None"
00248   SetNone();
00249   // check eof
00250   if (pStream->eof()) return(lc); 
00251   // read all spaces in the pStream
00252   lc += ReadSpace(pStream);
00253   // check eof
00254   if (pStream->eof()) return(lc);
00255   // get the first useful character
00256   c1 = pStream->peek();
00257   if (isdigit(c1) || (c1=='-') ) {
00258     // token is a number if the character is a digit
00259     ReadNumber(pStream);
00260   } 
00261   // token is a string if it starts with '"'
00262   else if (c1 == '"') {
00263     pStream->get();
00264     // read the string until '"'
00265     if(ReadString(pStream,'"')) mType = String;
00266   } 
00267   // token is an option string if it starts with '+'
00268   else if (c1 == '+') {
00269     pStream->get();
00270     // read the string until '"'
00271     if(ReadString(pStream,'+')) mType = Option;
00272   } 
00273   // token is of type begin or end if it starts with <
00274   else if (c1 == '<') {
00275     pStream->get();
00276     // check eof
00277     if (pStream->eof()) return(lc); 
00278     c2 = pStream->peek(); 
00279     // token is of type "begin" if it starts with <
00280     if (c2 != '/') {
00281       if (ReadString(pStream,'>')) mType = Begin;
00282     } 
00283     else {  
00284       pStream->get();
00285       // token is of type "end" if it starts with </
00286       c2=pStream->peek();
00287       // read the string until '>'
00288       if (ReadString(pStream,'>')) mType = End;
00289     }
00290   } 
00291   FD_DV("Token::Read: char1='"  << c1 << "' mType=" << (int) mType 
00292   << "\" mStringValue=\"" << mStringValue 
00293   << "\" mIntegerValue="  << mIntegerValue 
00294   << "\" mFloatValue="    << mFloatValue <<"\n");
00295   return(lc);
00296 }
00297 
00298 } // namespace faudes

Generated on Fri May 9 11:26:47 2008 for libFAUDES 2.09b by  doxygen 1.4.4