Base.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                              SOFA :: Framework                              *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
00026 ******************************************************************************/
00027 //
00028 // C++ Implementation: Base
00029 //
00030 // Description:
00031 //
00032 //
00033 // Author: The SOFA team </www.sofa-framework.org>, (C) 2006
00034 //
00035 // Copyright: See COPYING file that comes with this distribution
00036 //
00037 //
00038 #include <sofa/core/objectmodel/Base.h>
00039 #include <sofa/helper/Factory.h>
00040 #include <map>
00041 #include <typeinfo>
00042 #ifdef __GNUC__
00043 #include <cxxabi.h>
00044 #endif
00045 
00046 #include <string.h>
00047 namespace sofa
00048 {
00049 
00050 namespace core
00051 {
00052 
00053 namespace objectmodel
00054 {
00055 
00056 using std::string;
00057 
00058 Base::Base()
00059 {
00060     name = initData(&name,std::string("unnamed"),"name","object name");
00061 }
00062 
00063 Base::~Base()
00064 {}
00065 
00066 std::string Base::getName() const
00067 {
00068     //if( name.getValue().empty() )
00069     //    return getTypeName();
00070     return name.getValue();
00071 }
00072 
00073 void Base::setName(const std::string& na)
00074 {
00075     name.setValue(na);
00076 }
00077 
00078 
00080 std::string Base::decodeTypeName(const std::type_info& t)
00081 {
00082     std::string name = t.name();
00083     const char* realname = NULL;
00084     char* allocname = strdup(name.c_str());
00085 #ifdef __GNUC__
00086     int status;
00087     realname = allocname = abi::__cxa_demangle(allocname, 0, 0, &status);
00088     if (realname==NULL)
00089 #endif
00090         realname = allocname;
00091     int len = strlen(realname);
00092     char* newname = (char*)malloc(len+1);
00093     int start = 0;
00094     int dest = 0;
00095     char cprev = '\0';
00096     //std::cout << "name = "<<realname<<std::endl;
00097     for (int i=0; i<len; i++)
00098     {
00099         char c = realname[i];
00100         if (c == ':') // && cprev == ':')
00101         {
00102             start = i+1;
00103         }
00104         else if (c == ' ' && i >= 5 && realname[i-5] == 'c' && realname[i-4] == 'l' && realname[i-3] == 'a' && realname[i-2] == 's' && realname[i-1] == 's')
00105         {
00106             start = i+1;
00107         }
00108         else if (c != ':' && c != '_' && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z'))
00109         {
00110             // write result
00111             while (start < i)
00112             {
00113                 newname[dest++] = realname[start++];
00114                 newname[dest] = 0;
00115             }
00116         }
00117         cprev = c;
00118         //std::cout << "i = "<<i<<" start = "<<start<<" dest = "<<dest<<" newname = "<<newname<<std::endl;
00119     }
00120     while (start < len)
00121     {
00122         newname[dest++] = realname[start++];
00123         newname[dest] = 0;
00124     }
00125     newname[dest] = '\0';
00126     //std::cout << "newname = "<<newname<<std::endl;
00127     name = newname;
00128     free(newname);
00129     //if (allocname)
00130     //    free(allocname);
00131     return name;
00132 /*
00133     // Remove namespaces
00134     std::string cname;
00135     for(;;)
00136     {
00137         std::string::size_type pos = name.find("::");
00138         if (pos == std::string::npos) break;
00139         std::string::size_type first = name.find_last_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",pos-1);
00140         if (first == std::string::npos) first = 0;
00141         else first++;
00142         name.erase(first,pos-first+2);
00143         //std::cout << "name="<<name<<std::endl;
00144     }
00145     // Remove "class "
00146     for(;;)
00147     {
00148         std::string::size_type pos = name.find("class ");
00149         if (pos == std::string::npos) break;
00150         name.erase(pos,6);
00151     }
00152     //std::cout << "TYPE NAME="<<name<<std::endl;
00153     return name;
00154 */
00155 }
00156 
00158 std::string Base::decodeClassName(const std::type_info& t)
00159 {
00160     std::string name = t.name();
00161     const char* realname = NULL;
00162     char* allocname = strdup(name.c_str());
00163 #ifdef __GNUC__
00164     int status;
00165     realname = allocname = abi::__cxa_demangle(allocname, 0, 0, &status);
00166     if (realname==NULL)
00167 #endif
00168     realname = allocname;
00169     int len = strlen(realname);
00170     char* newname = (char*)malloc(len+1);
00171     int start = 0;
00172     int dest = 0;
00173     int i;
00174     char cprev = '\0';
00175     //std::cout << "name = "<<realname<<std::endl;
00176     for (i=0; i<len; i++)
00177     {
00178         char c = realname[i];
00179         if (c == '<') break;
00180         if (c == ':') // && cprev == ':')
00181         {
00182             start = i+1;
00183         }
00184         else if (c == ' ' && i >= 5 && realname[i-5] == 'c' && realname[i-4] == 'l' && realname[i-3] == 'a' && realname[i-2] == 's' && realname[i-1] == 's')
00185         {
00186             start = i+1;
00187         }
00188         else if (c == ' ' && i >= 6 && realname[i-6] == 's' && realname[i-5] == 't' && realname[i-4] == 'r' && realname[i-3] == 'u' && realname[i-2] == 'c' && realname[i-1] == 't')
00189         {
00190             start = i+1;
00191         }
00192         else if (c != ':' && c != '_' && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z'))
00193         {
00194             // write result
00195             while (start < i)
00196             {
00197                 newname[dest++] = realname[start++];
00198                 newname[dest] = 0;
00199             }
00200         }
00201         cprev = c;
00202         //std::cout << "i = "<<i<<" start = "<<start<<" dest = "<<dest<<" newname = "<<newname<<std::endl;
00203     }
00204 
00205     while (start < i)
00206     {
00207         newname[dest++] = realname[start++];
00208         newname[dest] = 0;
00209     }
00210     newname[dest] = '\0';
00211     //std::cout << "newname = "<<newname<<std::endl;
00212     name = newname;
00213     free(newname);
00214     //if (allocname)
00215     //    free(allocname);
00216     return name;
00217 /*
00218     std::string name = decodeTypeName(t);
00219     // Find template
00220     std::string::size_type pos = name.find("<");
00221     if (pos != std::string::npos)
00222     {
00223         name.erase(pos,name.length()-pos);
00224     }
00225     //std::cout << "CLASS NAME="<<name<<std::endl;
00226     return name;
00227 */
00228 }
00229 
00231 std::string Base::decodeNamespaceName(const std::type_info& t)
00232 {
00233     std::string name = t.name();
00234     const char* realname = NULL;
00235     char* allocname = strdup(name.c_str());
00236 #ifdef __GNUC__
00237     int status;
00238     realname = allocname = abi::__cxa_demangle(allocname, 0, 0, &status);
00239     if (realname==NULL)
00240 #endif
00241         realname = allocname;
00242     int len = strlen(realname);
00243     int start = 0;
00244     int last = len-1;
00245     int i;
00246     for (i=0; i<len; i++)
00247     {
00248         char c = realname[i];
00249         if (c == ' ' && i >= 5 && realname[i-5] == 'c' && realname[i-4] == 'l' && realname[i-3] == 'a' && realname[i-2] == 's' && realname[i-1] == 's')
00250         {
00251             start = i+1;
00252         }
00253     else if (c == ':' && (i<1 || realname[i-1]!=':'))
00254     {
00255         last = i-1;
00256     }
00257         else if (c != ':' && c != '_' && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z'))
00258         {
00259             // write result
00260         break;
00261         }
00262     }
00263     name.assign(realname+start, realname+last+1);
00264     //if (allocname)
00265     //    free(allocname);
00266     return name;
00267 }
00268 
00270 std::string Base::decodeTemplateName(const std::type_info& t)
00271 {
00272     std::string name = t.name();
00273     const char* realname = NULL;
00274     char* allocname = strdup(name.c_str());
00275 #ifdef __GNUC__
00276     int status;
00277     realname = allocname = abi::__cxa_demangle(allocname, 0, 0, &status);
00278     if (realname==NULL)
00279 #endif
00280         realname = allocname;
00281     int len = strlen(realname);
00282     char* newname = (char*)malloc(len+1);
00283     newname[0] = '\0';
00284     int start = 0;
00285     int dest = 0;
00286     int i = 0;
00287     char cprev = '\0';
00288     //std::cout << "name = "<<realname<<std::endl;
00289     while (i < len && realname[i]!='<')
00290         ++i;
00291     start = i+1; ++i;
00292     for (; i<len; i++)
00293     {
00294         char c = realname[i];
00295         //if (c == '<') break;
00296         if (c == ':') // && cprev == ':')
00297         {
00298             start = i+1;
00299         }
00300         else if (c == ' ' && i >= 5 && realname[i-5] == 'c' && realname[i-4] == 'l' && realname[i-3] == 'a' && realname[i-2] == 's' && realname[i-1] == 's')
00301         {
00302             start = i+1;
00303         }
00304         else if (c != ':' && c != '_' && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z'))
00305         {
00306             // write result
00307             while (start <= i)
00308             {
00309                 newname[dest++] = realname[start++];
00310                 newname[dest] = 0;
00311             }
00312         }
00313         cprev = c;
00314         //std::cout << "i = "<<i<<" start = "<<start<<" dest = "<<dest<<" newname = "<<newname<<std::endl;
00315     }
00316     while (start < i)
00317     {
00318         newname[dest++] = realname[start++];
00319         newname[dest] = 0;
00320     }
00321     newname[dest] = '\0';
00322     //std::cout << "newname = "<<newname<<std::endl;
00323     name = newname;
00324     free(newname);
00325     //if (allocname)
00326     //    free(allocname);
00327     return name;
00328 /*
00329     std::string name = decodeTypeName(t);
00330     // Find template
00331     std::string::size_type pos = name.find("<");
00332     if (pos != std::string::npos)
00333     {
00334         name = name.substr(pos+1,name.length()-pos-2);
00335     }
00336     else
00337     {
00338         name = "";
00339     }
00340     //std::cout << "TEMPLATE NAME="<<name<<std::endl;
00341     return name;
00342 */
00343 }
00344 
00345 void  Base::parseFields ( std::list<std::string> str )
00346 {
00347     string name;
00348     while( !str.empty() ) {
00349         name = str.front();
00350         str.pop_front();
00351 
00352         // field name
00353     unsigned int index = findField(name);
00354         if( index!=m_fieldVec.size() ) {
00355             std::string s = str.front();
00356             if( !(m_fieldVec[ index ].second->read( s )))
00357                 std::cerr<< "ERROR: could not read value for option " << name <<": "<< s << std::endl;
00358         } else {
00359             str.pop_front();
00360             std::cerr << "\nUnknown option: " << name << std::endl << std::endl;
00361         }
00362     }
00363 }
00364 
00365 void  Base::parseFields ( const std::map<std::string,std::string*>& args )
00366 {
00367     // build  std::list<std::string> str
00368     using std::string;
00369     string key,val;
00370     for( std::map<string,string*>::const_iterator i=args.begin(), iend=args.end(); i!=iend; i++ ) {
00371         if( (*i).second!=NULL ) {
00372             key=(*i).first;
00373             val=*(*i).second;
00374         unsigned int index = findField(key);
00375             if( index!=m_fieldVec.size() ) {
00376                 if( !(m_fieldVec[ index ].second->read( val )))
00377                     std::cerr<< "ERROR: could not read value for option " << key <<": "<< val << std::endl;
00378             } else {
00379                 if ((key!="name") && (key!="type"))
00380                     std::cerr <<"\nUnknown option: " << key << std::endl;
00381             }
00382         }
00383     }
00384 }
00385 
00387 void  Base::parse ( BaseObjectDescription* arg )
00388 {
00389     //this->parseFields ( arg->getAttributeMap() );
00390   for (unsigned int i=0;i<m_fieldVec.size();i++)
00391     {
00392         const char* val = arg->getAttribute(m_fieldVec[i].first);
00393         if (val)
00394         {
00395             string valueString = val;
00396             if( !(m_fieldVec[ i ].second->read( valueString )))
00397                 std::cerr<< "ERROR: could not read value for option " << m_fieldVec[ i ].first <<": "<< val << std::endl;
00398         }
00399     }
00400 }
00401 
00402 void  Base::writeDatas ( std::map<std::string,std::string*>& args )
00403 {
00404 //     for( std::map<string,BaseData*>::const_iterator a=m_fieldMap.begin(), aend=m_fieldMap.end(); a!=aend; ++a ) {
00405   for (unsigned int i=0;i<m_fieldVec.size();i++)
00406     {
00407         string valueString;
00408         BaseData* field = m_fieldVec[i].second;
00409 
00410         if( args[m_fieldVec[i].first] != NULL )
00411             *args[ m_fieldVec[i].first] = field->getValueString();
00412         else
00413             args[ m_fieldVec[i].first] =  new string(field->getValueString());
00414     }
00415 }
00416 
00417 void  Base::writeDatas ( std::ostream& out )
00418 {
00419 //     for( std::map<string,BaseData*>::const_iterator a=m_fieldMap.begin(), aend=m_fieldMap.end(); a!=aend; ++a ) {
00420   for (unsigned int i=0;i<m_fieldVec.size();i++)
00421     {
00422         BaseData* field = m_fieldVec[ i ].second;
00423         if( field->isSet() && !field->getValueString().empty())
00424       out << "<Attribute " << m_fieldVec[ i ].first << "=\""<< field->getValueString() << "\"/>";
00425     }
00426 }
00427 
00428 void Base::xmlWriteNodeDatas (std::ostream& out, unsigned level )
00429 {
00430   for (unsigned int i=0;i<m_fieldVec.size();i++)
00431   {
00432     BaseData* field = m_fieldVec[ i ].second;
00433     if( field->isSet() && !field->getValueString().empty()){
00434       for (unsigned l=0;i!=0 && l<level;l++)
00435     out << "\t";
00436       out << m_fieldVec[ i ].first << "=\""<< field->getValueString() << "\" "<<std::endl;
00437     }
00438   }
00439 }
00440 void  Base::xmlWriteDatas ( std::ostream& out, unsigned level )
00441 {
00442 //     for( std::map<string,BaseData*>::const_iterator a=m_fieldMap.begin(), aend=m_fieldMap.end(); a!=aend; ++a ) {
00443   for (unsigned int i=0;i<m_fieldVec.size();i++)
00444     {
00445         BaseData* field = m_fieldVec[ i ].second;
00446         if( field->isSet() && !field->getValueString().empty()){
00447             for (unsigned l=0;l<level;l++)
00448                 out << "\t";
00449             out << "<Attribute type=\"" << m_fieldVec[ i ].first << "\">\n" ;
00450         
00451         for (unsigned l=0;l<=level;l++)
00452           out << "\t";
00453         out  << "<Data value=\"" << field->getValueString() << "\"/>\n";
00454         
00455         for (unsigned l=0;l<level;l++)
00456           out << "\t";
00457         out << "</Attribute>\n";
00458         }
00459     }
00460 }
00461 
00462 } // namespace objectmodel
00463 
00464 } // namespace core
00465 
00466 } // namespace sofa
00467 

Generated on Sun Nov 23 02:29:25 2008 for Sofa by  doxygen 1.5.7.1