CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/DetectorDescription/Parser/src/DDLVector.cc

Go to the documentation of this file.
00001 /***************************************************************************
00002                           DDLVector.cc  -  description
00003                              -------------------
00004     begin                : Friday Nov. 21, 2003
00005     email                : case@ucdhep.ucdavis.edu
00006  ***************************************************************************/
00007 
00008 #include "DetectorDescription/Parser/src/DDLVector.h"
00009 
00010 #include "DetectorDescription/Core/interface/DDStrVector.h"
00011 #include "DetectorDescription/Base/interface/DDdebug.h"
00012 
00013 #include "DetectorDescription/ExprAlgo/interface/ExprEvalSingleton.h"
00014 
00015 // Boost parser, spirit, for parsing the std::vector elements.
00016 #include "boost/spirit/include/classic.hpp"
00017 
00018 namespace boost { namespace spirit { namespace classic { } } } using namespace boost::spirit::classic;
00019 
00020 using namespace boost::spirit;
00021 
00022 struct VectorMakeDouble
00023 {
00024   void operator() (char const* str, char const* end) const
00025     {
00026       ddlVector_->do_makeDouble(str, end);
00027     }
00028   
00029   VectorMakeDouble() {
00030     ddlVector_ = dynamic_cast < DDLVector* > (DDLGlobalRegistry::instance().getElement("Vector"));
00031   }
00032   
00033   DDLVector * ddlVector_;
00034 };
00035 
00036 struct VectorMakeString
00037 {
00038   void operator() (char const* str, char const* end) const
00039     {
00040       ddlVector_->do_makeString(str, end);
00041     }
00042   
00043   VectorMakeString() {
00044     ddlVector_ = dynamic_cast < DDLVector* > (DDLGlobalRegistry::instance().getElement("Vector"));
00045   }
00046   
00047   DDLVector * ddlVector_;
00048 };
00049 
00050 bool
00051 DDLVector::parse_numbers(char const* str) const
00052 {
00053   static VectorMakeDouble makeDouble;
00054   return parse(str,
00055                ((+(anychar_p - ','))[makeDouble] 
00056                 >> *(',' >> (+(anychar_p - ','))[makeDouble]))
00057                >> end_p
00058                , space_p).full;
00059 }
00060 
00061 bool
00062 DDLVector::parse_strings(char const* str) const
00063 {
00064   static VectorMakeString makeString;
00065   return parse(str,
00066                ((+(anychar_p - ','))[makeString] 
00067                 >> *(',' >> (+(anychar_p - ','))[makeString])) 
00068                >> end_p
00069                , space_p).full;
00070 }
00071 
00072 DDLVector::DDLVector( DDLElementRegistry* myreg )
00073   : DDXMLElement( myreg )
00074 {}
00075 
00076 DDLVector::~DDLVector( void )
00077 {}
00078  
00079 void
00080 DDLVector::preProcessElement( const std::string& name, const std::string& nmspace, DDCompactView& cpv )
00081 {
00082   pVector.clear();
00083   pStrVector.clear();
00084   pNameSpace = nmspace;
00085 }
00086 
00087 void
00088 DDLVector::processElement( const std::string& name, const std::string& nmspace, DDCompactView& cpv )
00089 {
00090   DCOUT_V('P', "DDLVector::processElement started");
00091 
00092   DDXMLAttribute atts = getAttributeSet();
00093   bool isNumVec((atts.find("type") == atts.end() 
00094                  || atts.find("type")->second == "numeric")
00095                 ?  true : false);
00096   bool isStringVec((!isNumVec && atts.find("type") != atts.end() 
00097                     && atts.find("type")->second == "string")
00098                    ? true : false);
00099   std::string tTextToParse = getText();
00100   //  cout << "tTextToParse is |"<< tTextToParse << "|" << endl;
00101   if (tTextToParse.size() == 0) {
00102     errorOut(" EMPTY STRING ");
00103   }
00104   
00105   if (isNumVec) {//(atts.find("type") == atts.end() || atts.find("type")->second == "numeric") {
00106     if (!parse_numbers(tTextToParse.c_str())) {
00107       errorOut(tTextToParse.c_str());
00108     }
00109   }
00110   else if (isStringVec) { //(atts.find("type")->second == "string") {
00111     if (!parse_strings(tTextToParse.c_str())) {
00112       errorOut(tTextToParse.c_str());
00113     }
00114   }
00115   else {
00116     errorOut("Unexpected std::vector type. Only \"numeric\" and \"string\" are allowed.");
00117   }
00118 
00119 
00120   if (parent() == "Algorithm" || parent() == "SpecPar")
00121   {
00122     if (isNumVec) { //(atts.find("type") != atts.end() || atts.find("type")->second == "numeric") {
00123       //        std::cout << "adding to pVecMap name= " << atts.find("name")->second << std::endl;
00124       //        for (std::vector<double>::const_iterator it = pVector.begin(); it != pVector.end(); ++it)
00125       //          std::cout << *it << "\t" << std::endl;
00126       pVecMap[atts.find("name")->second] = pVector;
00127       //        std::cout << "size: " << pVecMap.size() << std::endl;
00128     }
00129     else if (isStringVec) { //(atts.find("type")->second == "string") {
00130       pStrVecMap[atts.find("name")->second] = pStrVector;
00131       //        cout << "it is a string, name is: " << atts.find("name")->second << endl;
00132     }
00133     size_t expNEntries = 0;
00134     if (atts.find("nEntries") != atts.end()) {
00135       std::string nEntries = atts.find("nEntries")->second;
00136       expNEntries = size_t (ExprEvalSingleton::instance().eval(pNameSpace, nEntries));
00137     }
00138     if ( (isNumVec && pVector.size() != expNEntries)
00139          || (isStringVec && pStrVector.size() != expNEntries) )
00140     {
00141       std::string msg ("Number of entries found in Vector text does not match number in attribute nEntries.");
00142       msg += "\n\tnEntries = " + atts.find("nEntries")->second;
00143       msg += "\n------------------text---------\n";
00144       msg += tTextToParse;
00145       msg += "\n------------------text---------\n";
00146       errorOut(msg.c_str());
00147     }
00148   }
00149   else if (parent() == "ConstantsSection" || parent() == "DDDefinition")
00150   {
00151     if (atts.find("type") == atts.end() || atts.find("type")->second == "numeric") {
00152       DDVector v(getDDName(nmspace), new std::vector<double>(pVector));
00153     }
00154     else {
00155       DDStrVector v(getDDName(nmspace), new std::vector<std::string>(pStrVector));
00156     }
00157   }
00158   clear();
00159   DCOUT_V('P', "DDLVector::processElement completed");
00160 }
00161 
00162 ReadMapType< std::vector<double> > &
00163 DDLVector::getMapOfVectors( void ) 
00164 {
00165   return pVecMap;
00166 }
00167 
00168 ReadMapType< std::vector<std::string> > &
00169 DDLVector::getMapOfStrVectors( void )
00170 {
00171   return pStrVecMap;
00172 }
00173 
00174 void
00175 DDLVector::do_makeDouble( char const* str, char const* end )
00176 {
00177   std::string ts(str, end);
00178   double td = ExprEvalSingleton::instance().eval(pNameSpace, ts);
00179   pVector.push_back(td);
00180 }
00181 
00182 void
00183 DDLVector::do_makeString( char const* str, char const* end )
00184 {
00185   std::string ts(str, end);
00186   pStrVector.push_back(ts);
00187 }
00188 
00189 void
00190 DDLVector::errorOut( const char* str ) const
00191 {
00192   std::string e("Failed to parse the following: \n");
00193   e+= std::string(str);
00194   e+="\n as a Vector element (comma separated list).";
00195   throwError (e);
00196 }
00197 
00198 void
00199 DDLVector::clearall( void )
00200 {
00201   DDXMLElement::clear();
00202   pVecMap.clear();
00203   pStrVecMap.clear();
00204 }