utility_io.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  *  \author 
00003  *      Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
00004  *
00005  *  \version 
00006  *              ORO_Geometry V0.2
00007  *
00008  *      \par History
00009  *              - $log$
00010  *
00011  *      \par Release
00012  *              $Id: utility_io.cpp,v 1.1.1.1.2.4 2003/06/26 15:23:59 psoetens Exp $
00013  *              $Name:  $ 
00014  * \todo
00015  *   make IO routines more robust against the differences between DOS/UNIX end-of-line style.
00016  ****************************************************************************/
00017 
00018 
00019 #include "utility_io.h"
00020 #include "error.h"
00021 
00022 #include <stdlib.h>
00023 #include <ctype.h>
00024 #include <string.h>
00025 
00026 namespace KDL {
00027 
00028 //
00029 //  _functions are private functions 
00030 //
00031 
00032     void _check_istream(std::istream& is)
00033     {
00034         if ((!is.good())&&(is.eof()) )
00035             {
00036             throw Error_BasicIO_File();
00037             }
00038     }
00039 // Eats until the end of the line
00040         int _EatUntilEndOfLine( std::istream& is, int* countp=NULL) {
00041     int ch;
00042     int count;
00043     count = 0;
00044     do {
00045         ch = is.get();
00046         count++;
00047         _check_istream(is);
00048     } while (ch!='\n');
00049     if (countp!=NULL) *countp = count;
00050     return ch;
00051 }
00052 
00053 // Eats until the end of the comment
00054         int _EatUntilEndOfComment( std::istream& is, int* countp=NULL) {
00055     int ch;
00056     int count;
00057     count = 0;
00058     int prevch;
00059     ch = 0;
00060     do {
00061         prevch = ch;
00062         ch = is.get();
00063         count++;
00064         _check_istream(is);
00065         if ((prevch=='*')&&(ch=='/')) {
00066             break;
00067         }
00068     } while (true);
00069     if (countp!=NULL) *countp = count;
00070     ch = is.get();
00071     return ch;
00072 }
00073 
00074 // Eats space-like characters and comments
00075 // possibly returns the number of space-like characters eaten.
00076 int _EatSpace( std::istream& is,int* countp=NULL) {
00077     int ch;
00078     int count;
00079     count=-1;
00080     do { 
00081         _check_istream(is);
00082 
00083         ch = is.get(); 
00084         count++;
00085         if (ch == '#') {
00086             ch = _EatUntilEndOfLine(is,&count);
00087         }
00088         if (ch == '/') {
00089             ch = is.get();
00090             if (ch == '/') {
00091                 ch = _EatUntilEndOfLine(is,&count);
00092             } else  if (ch == '*') {
00093                 ch = _EatUntilEndOfComment(is,&count);
00094             } else {
00095                 is.putback(ch);
00096                 ch = '/';
00097             }
00098         }
00099     } while ((ch==' ')||(ch=='\n')||(ch=='\t'));
00100     if (countp!=NULL) *countp =  count;
00101     return ch;
00102 }
00103 
00104 
00105 
00106 // Eats whites, returns, tabs and the delim character
00107 //  Checks wether delim char. is encountered.
00108 void Eat( std::istream& is, int delim )
00109 {   
00110     int ch;
00111     ch=_EatSpace(is);
00112     if (ch != delim) {
00113        throw Error_BasicIO_Exp_Delim();
00114     }
00115     ch=_EatSpace(is);   
00116     is.putback(ch);
00117 }
00118 
00119 // Eats whites, returns, tabs and the delim character
00120 //  Checks wether delim char. is encountered.
00121 // EatEnd does not eat all space-like char's at the end.
00122 void EatEnd( std::istream& is, int delim )
00123 {   
00124     int ch;
00125     ch=_EatSpace(is);
00126     if (ch != delim) {
00127        throw Error_BasicIO_Exp_Delim();
00128     }
00129 }
00130 
00131 
00132 
00133 // For each space in descript, this routine eats whites,tabs, and newlines (at least one)
00134 // There should be no consecutive spaces in the description.
00135 // for each letter in descript, its reads the corresponding letter in the output
00136 // the routine is case insensitive.
00137 
00138 
00139 // Simple routine, enough for our purposes.
00140 //  works with ASCII chars
00141 inline char Upper(char ch) 
00142 {
00143     /*if (('a'<=ch)&&(ch<='z'))
00144         return (ch-'a'+'A');
00145     else
00146         return ch;
00147     */
00148     return toupper(ch);
00149 }
00150 
00151 void Eat(std::istream& is,const char* descript)
00152 {
00153     // eats whites before word
00154     char ch;
00155     char chdescr;
00156     ch=_EatSpace(is);   
00157     is.putback(ch);
00158     const char* p;
00159     p = descript;
00160     while ((*p)!=0) {
00161         chdescr = (char)Upper(*p);
00162         if (chdescr==' ') {
00163             int count=0;
00164             ch=_EatSpace(is,&count);
00165             is.putback(ch);
00166             if (count==0) {
00167                 throw Error_BasicIO_Not_A_Space();
00168             }
00169         } else {
00170             ch=(char)is.get();
00171             if (chdescr!=Upper(ch)) {
00172                throw Error_BasicIO_Unexpected();
00173             }
00174         }
00175         p++;
00176     }
00177     
00178 }
00179 
00180 
00181 
00182 void EatWord(std::istream& is,const char* delim,char* storage,int maxsize)
00183 {
00184     int ch;
00185     char* p;
00186     int size;
00187     // eat white before word
00188     ch=_EatSpace(is);
00189     p = storage;
00190     size=0;
00191     int count = 0;
00192     while ((count==0)&&(strchr(delim,ch)==NULL)) {
00193         *p = (char) toupper(ch);
00194         ++p;
00195         if (size==maxsize) {
00196            throw Error_BasicIO_ToBig();
00197         }
00198         _check_istream(is);
00199         ++size;
00200         //ch = is.get();
00201         ch =_EatSpace(is,&count);
00202     }
00203     *p=0;
00204     is.putback(ch);
00205 }
00206 
00207 
00208 }

Generated on Wed Nov 23 19:00:56 2011 for FreeCAD by  doxygen 1.6.1