CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/DetectorDescription/Parser/src/DDLMap.cc

Go to the documentation of this file.
00001 /***************************************************************************
00002                           DDLMap.cc  -  description
00003                              -------------------
00004     begin                : Friday Nov. 21, 2003
00005     email                : case@ucdhep.ucdavis.edu
00006  ***************************************************************************/
00007 
00008 // Boost parser, spirit, for parsing the std::vector elements.
00009 
00010 #include "DetectorDescription/Parser/src/DDLMap.h"
00011 
00012 #include "DetectorDescription/Base/interface/DDdebug.h"
00013 #include "DetectorDescription/ExprAlgo/interface/ExprEvalSingleton.h"
00014 
00015 using namespace boost::spirit::classic;
00016 
00017 //  The "real" DDLMap members.
00018 DDLMap::DDLMap( DDLElementRegistry* myreg )
00019   : DDXMLElement( myreg )
00020 {}
00021 
00022 DDLMap::~DDLMap( void )
00023 {}
00024  
00025 template <typename ScannerT> struct Mapper::definition
00026 {
00027   definition(Mapper const& self)
00028     {
00029       mapSet
00030         =   ppair[MapPair()]
00031         >> *((',' >> ppair)[MapPair()])
00032         ;
00033       
00034       ppair
00035         =   name
00036         >> ch_p('=') >> value
00037         ;
00038       
00039       name
00040         =   (alpha_p >> *alnum_p)[MapMakeName()]
00041         ;
00042       
00043       value
00044         =   (+(anychar_p - ','))[MapMakeDouble()]
00045         ;     
00046     }
00047 
00048   rule<ScannerT> mapSet, ppair, name, value;
00049     
00050   rule<ScannerT> const&
00051   start() const { return mapSet; }    
00052 };
00053 
00054 void
00055 MapPair::operator() (char const* str, char const* end) const
00056 { 
00057   DDLMap* myDDLMap = dynamic_cast < DDLMap* > (DDLGlobalRegistry::instance().getElement("Map"));
00058   myDDLMap->do_pair(str, end);
00059 }
00060 
00061 void
00062 MapMakeName::operator() (char const* str, char const* end) const
00063 {
00064   DDLMap* myDDLMap = dynamic_cast < DDLMap* > (DDLGlobalRegistry::instance().getElement("Map"));
00065   myDDLMap->do_makeName(str, end);
00066 }
00067 
00068 void
00069 MapMakeDouble::operator() (char const* str, char const* end)const
00070 {
00071   DDLMap* myDDLMap = dynamic_cast < DDLMap* > (DDLGlobalRegistry::instance().getElement("Map"));
00072   myDDLMap->do_makeDouble(str, end);
00073 }
00074 
00075 void
00076 DDLMap::preProcessElement( const std::string& name, const std::string& nmspace, DDCompactView& cpv )
00077 {
00078   pName = "";
00079   pMap.clear() ;
00080   //pMapMap.clear(); only the DDLAlgorithm is allowed to clear this guy!
00081   pDouble = 0.0;
00082   pNameSpace = nmspace;
00083 }
00084 
00085 void
00086 DDLMap::processElement( const std::string& name, const std::string& nmspace, DDCompactView& cpv )
00087 {
00088   DCOUT_V('P', "DDLMap::processElement started");
00089 
00090   std::string tTextToParse = getText();
00091   DDXMLAttribute atts = getAttributeSet();
00092   std::string tName = atts.find("name")->second;
00093 
00094   if (tTextToParse.size() == 0)
00095   {
00096     errorOut("No std::string to parse!");
00097   }
00098 
00099   // NOT IMPLEMENTED YET
00100   if (atts.find("type") != atts.end() && atts.find("type")->second == "string")
00101   {
00102     errorOut("Map of type std::string is not supported yet.");
00103   }
00104 
00105   Mapper mapGrammar;
00106   
00107   pMap.clear();
00108 
00109   parse_info<> info = boost::spirit::classic::parse(tTextToParse.c_str(), mapGrammar >> end_p, space_p);
00110   if (!info.full)
00111   {
00112     errorOut("Does not conform to name=value, name=value... etc. of ddl Map element.");
00113   }
00114 
00115   if (parent() == "Algorithm" || parent() == "SpecPar")
00116   {
00117     pMapMap[tName] = pMap;
00118   }
00119   else if (parent() == "ConstantsSection" || parent() == "DDDefinition") 
00120   {
00121     dd_map_type * tMap = new dd_map_type;
00122     for (std::map<std::string, double>::const_iterator it = pMap.begin(); it != pMap.end(); ++it)
00123     {
00124       (*tMap)[it->first] = it->second;
00125     }
00126     DDMap m ( getDDName(pNameSpace) , tMap);
00127     // clear the map of maps, because in these elements we only have ONE at a time.
00128     pMapMap.clear(); 
00129   }
00130 
00131   std::string nEntries = atts.find("nEntries")->second;
00132   if (pMap.size() != 
00133       size_t(ExprEvalSingleton::instance().eval(pNameSpace, nEntries)))
00134   {
00135     errorOut("Number of entries found in Map text does not match number in attribute nEntries.");
00136   }
00137   clear();
00138   
00139   DCOUT_V('P', "DDLMap::processElement completed");
00140 }
00141 
00142 void
00143 DDLMap::do_pair( char const* str, char const* end )
00144 {
00145   pMap[pName] = pDouble;
00146 }
00147 
00148 void
00149 DDLMap::do_makeName( char const* str, char const* end )    
00150 {
00151   pName = std::string(str, end); 
00152 }
00153 
00154 void
00155 DDLMap::do_makeDouble( char const* str, char const* end )
00156 {
00157   std::string ts(str, end);
00158   pDouble = ExprEvalSingleton::instance().eval(pNameSpace, ts);
00159 }
00160 
00161 void
00162 DDLMap::errorOut( const char* str )
00163 {
00164   std::string msg("\nDDLMap: Failed to parse the following: \n");
00165   msg+= std::string(str);
00166   msg+="\n as a Map element (comma separated list of name=value).";
00167   throwError(msg);
00168 }
00169 
00170 ReadMapType< std::map<std::string,double> > &
00171 DDLMap::getMapOfMaps( void ) 
00172 {
00173   return pMapMap;
00174 }