Blender V2.61 - r43446

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