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