lineparser.h

00001 /*************************************************************************************
00002  * MechSys - A C++ library to simulate (Continuum) Mechanical Systems                *
00003  * Copyright (C) 2005 Dorival de Moraes Pedroso <dorival.pedroso at gmail.com>       *
00004  * Copyright (C) 2005 Raul Dario Durand Farfan  <raul.durand at gmail.com>           *
00005  *                                                                                   *
00006  * This file is part of MechSys.                                                     *
00007  *                                                                                   *
00008  * MechSys is free software; you can redistribute it and/or modify it under the      *
00009  * terms of the GNU General Public License as published by the Free Software         *
00010  * Foundation; either version 2 of the License, or (at your option) any later        *
00011  * version.                                                                          *
00012  *                                                                                   *
00013  * MechSys is distributed in the hope that it will be useful, but WITHOUT ANY        *
00014  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A   *
00015  * PARTICULAR PURPOSE. See the GNU General Public License for more details.          *
00016  *                                                                                   *
00017  * You should have received a copy of the GNU General Public License along with      *
00018  * MechSys; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, *
00019  * Fifth Floor, Boston, MA 02110-1301, USA                                           *
00020  *************************************************************************************/
00021 
00022 #ifndef MECHSYS_LINEPARSER_H
00023 #define MECHSYS_LINEPARSER_H
00024 
00025 #include <string>
00026 #include <fstream>
00027 #include <sstream>
00028 #include <algorithm>
00029 
00030 #include "util/array.h"
00031 #include "util/string.h"
00032 #include "util/exception.h"
00033 
00034 class LineParser : public std::istringstream
00035 {
00036 public:
00037     LineParser(std::string const & Line) : std::istringstream(Line)          {}
00038     LineParser(     String const & Line) : std::istringstream(Line.GetSTL()) {}
00039     void Reset(     String const & Line) { Reset(Line.GetSTL()); }
00040     void Reset(std::string const & Line)
00041     {
00042         (*this).clear();
00043         (*this).str(Line);
00044     }
00045     void ReplaceAllChars(char OldChar, char NewChar)
00046     {
00047         std::string tmp(std::istringstream::str());
00048         std::replace(tmp.begin(), tmp.end(), OldChar, NewChar);
00049         std::istringstream::str(tmp);
00050     }
00051 
00052     void Set(String const & S)
00053     {
00054         this->str(S.GetSTL());
00055     }
00056 
00057     template<typename Type>
00058     void ToArray(Array<Type> & A);
00059 
00060     template<typename Type>
00061     void StructuredLine(int & A, int & B, Array< Array<Type> > & C);
00062 
00063     void SeparatedLine(std::string const & Separator, Array<std::string> & Res);
00064     void SeparatedLine(     String const & Separator, Array<     String> & Res);
00065 
00066     template<typename Type1, typename Type2>
00067     bool BreakExpressions(Array<Type1> & lvalue, Array<Type2> & rvalue);
00068 private:
00069 }; // class LineParser
00070 
00071 
00073 
00074 
00075 template<typename Type>
00076 inline void LineParser::ToArray(Array<Type> & A) // {{{
00077 {
00078     // Fill A array with iss.str() values
00079     A.resize(0);
00080     Type tmp;
00081     while ((*this)>>tmp)
00082     {
00083         A.push_back(tmp);
00084     }
00085 } // }}}
00086 
00087 template<typename Type>
00088 inline void LineParser::StructuredLine(int & A, int & B, Array< Array<Type> > & C) // {{{
00089 {
00090     // Ex.:
00091     //      7  5  { 1 2 3 } { 4 5 6 8 0 1 }
00092     //      A  B     C[0]        C[1]
00093 
00094     C.resize(0);
00095     std::string str_open_key;
00096     (*this) >> A >> B >> str_open_key;
00097     if (str_open_key[0]!='{')
00098         throw new Fatal(_("LineParser::StructuredLine: Line is not corrected formatted. Line=< %s >"),this->str().c_str());
00099     
00100     Array<Type> a_inner;
00101     std::string str_tmp;
00102     while ((*this)>>str_tmp)
00103     {
00104         if (str_tmp[0]=='}')
00105         {
00106             (*this)>>str_open_key; // read next '{'
00107             C.push_back(a_inner);
00108             a_inner.resize(0);
00109         }
00110         else
00111         {
00112             std::istringstream iss(str_tmp);
00113             Type tmp; iss>>tmp;
00114             a_inner.push_back(tmp);
00115         }
00116     }
00117 } // }}}
00118 
00119 inline void LineParser::SeparatedLine(std::string const & Separator, Array<std::string> & Res) // {{{
00120 {
00121     /* Ex.:
00122      *         /home/dorival/teste/An File.txt 
00123      *          R[0]  R[1]   R[2]     R[3]
00124      *
00125      *         ->1234->456a->789as
00126      *           R[0]  R[1]  R[2]
00127      */
00128 
00129     // Clear result array
00130     Res.resize(0);
00131 
00132     // Fill result array
00133     if (Separator.empty())
00134         Res.push_back(this->str());
00135     else if (!this->str().empty())
00136     {
00137         // Loop along the line
00138         size_t start = 0;
00139         size_t end   = this->str().find(Separator, start);
00140         while (end!=std::string::npos)
00141         {
00142             Res.push_back(this->str().substr(start, end - start));
00143             start = end + Separator.size();
00144               end = this->str().find(Separator, start);
00145         }
00146         Res.push_back(this->str().substr(start));
00147         // Clear the line (all extracted)
00148         this->clear(); this->str("");
00149     }
00150 } // }}}
00151 
00152 inline void LineParser::SeparatedLine(String const & Separator, Array<String> & Res) // {{{
00153 {
00154     std::string        sep = Separator.GetSTL();
00155     Array<std::string> arr;
00156     SeparatedLine(sep,arr);
00157     size_t len = arr.size();
00158     Res.resize(len);
00159     for (size_t i=0; i<len; ++i)
00160         Res[i] = String(arr[i]);
00161 } // }}}
00162 
00163 template<typename Type1, typename Type2>
00164 inline bool LineParser::BreakExpressions(Array<Type1> & Lvalue, Array<Type2> & Rvalue) // {{{
00165 {
00166     /* For:  this->str() == "var1=value1 var2=value3 var3=value4"
00167      *
00168      * with:  var1,   var2   and var3   of Type1
00169      * and    value1, value2 and value3 of Type2
00170      *
00171      * result:
00172      *           Lvalue={var1,var2,var3}
00173      *      and  Rvalue={value1,value2,value3}
00174      * return:
00175      *           false if some problem occurred with istringstream, i.e: format is invalid
00176      */
00177 
00178     Lvalue.resize(0);
00179     Rvalue.resize(0);
00180     ReplaceAllChars('=',' ');
00181 
00182     // Parse bry marks
00183     Type1 lval;
00184     Type2 rval;
00185     while ((*this)>>lval)
00186     {
00187         if (((*this)>>rval))
00188         {
00189             Lvalue.push_back(lval);
00190             Rvalue.push_back(rval);
00191         }
00192         else return false;
00193     }
00194     if (Lvalue.size()==Rvalue.size()) return true;
00195     else                              return false;
00196 } // }}}
00197 
00198 #endif //MECHSYS_FILEPARSER
00199 
00200 // vim:fdm=marker

Generated on Wed Jan 24 15:56:27 2007 for MechSys by  doxygen 1.4.7