Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:05:33

0001 #include "DetectorDescription/Parser/src/DDLVector.h"
0002 
0003 #include <cstddef>
0004 #include <map>
0005 #include <memory>
0006 #include <utility>
0007 
0008 #include "DetectorDescription/Core/interface/DDStrVector.h"
0009 #include "DetectorDescription/Core/interface/DDVector.h"
0010 #include "DetectorDescription/Core/interface/ClhepEvaluator.h"
0011 #include "DetectorDescription/Parser/interface/DDLElementRegistry.h"
0012 #include "DetectorDescription/Parser/src/DDXMLElement.h"
0013 
0014 class DDCompactView;
0015 
0016 namespace {
0017   template <typename F>
0018   void parse(char const* str, F&& f) {
0019     auto ptr = str;
0020 
0021     while (*ptr != 0) {
0022       //remove any leading spaces
0023       while (std::isspace(*ptr)) {
0024         ++ptr;
0025       }
0026       char const* strt = ptr;
0027 
0028       //find either the end of the char array
0029       // or a comma. Spaces are allowed
0030       // between characters.
0031       while ((*ptr != 0) and (*ptr != ',')) {
0032         ++ptr;
0033       }
0034       char const* end = ptr;
0035       if (*ptr == ',') {
0036         ++ptr;
0037       }
0038 
0039       if (strt == end) {
0040         break;
0041       }
0042 
0043       //strip off any ending spaces
0044       while (strt != end - 1 and std::isspace(*(end - 1))) {
0045         --end;
0046       }
0047       f(strt, end);
0048     }
0049   }
0050 }  // namespace
0051 
0052 bool DDLVector::parse_numbers(char const* str) {
0053   parse(str, [this](char const* st, char const* end) { do_makeDouble(st, end); });
0054   return true;
0055 }
0056 
0057 bool DDLVector::parse_strings(char const* str) {
0058   parse(str, [this](char const* st, char const* end) { do_makeString(st, end); });
0059   return true;
0060 }
0061 
0062 DDLVector::DDLVector(DDLElementRegistry* myreg) : DDXMLElement(myreg) {}
0063 
0064 void DDLVector::preProcessElement(const std::string& name, const std::string& nmspace, DDCompactView& cpv) {
0065   pVector.clear();
0066   pStrVector.clear();
0067   pNameSpace = nmspace;
0068 }
0069 
0070 void DDLVector::processElement(const std::string& name, const std::string& nmspace, DDCompactView& cpv) {
0071   DDXMLAttribute atts = getAttributeSet();
0072   bool isNumVec((atts.find("type") == atts.end() || atts.find("type")->second == "numeric") ? true : false);
0073   bool isStringVec((!isNumVec && atts.find("type") != atts.end() && atts.find("type")->second == "string") ? true
0074                                                                                                            : false);
0075   std::string tTextToParse = getText();
0076 
0077   if (tTextToParse.empty()) {
0078     errorOut(" EMPTY STRING ");
0079   }
0080 
0081   if (isNumVec) {
0082     if (!parse_numbers(tTextToParse.c_str())) {
0083       errorOut(tTextToParse.c_str());
0084     }
0085   } else if (isStringVec) {
0086     if (!parse_strings(tTextToParse.c_str())) {
0087       errorOut(tTextToParse.c_str());
0088     }
0089   } else {
0090     errorOut("Unexpected std::vector type. Only \"numeric\" and \"string\" are allowed.");
0091   }
0092 
0093   if (parent() == "Algorithm" || parent() == "SpecPar") {
0094     if (isNumVec) {
0095       pVecMap[atts.find("name")->second] = pVector;
0096     } else if (isStringVec) {
0097       pStrVecMap[atts.find("name")->second] = pStrVector;
0098     }
0099     size_t expNEntries = 0;
0100     if (atts.find("nEntries") != atts.end()) {
0101       std::string nEntries = atts.find("nEntries")->second;
0102       expNEntries = size_t(myRegistry_->evaluator().eval(pNameSpace, nEntries));
0103     }
0104     if ((isNumVec && pVector.size() != expNEntries) || (isStringVec && pStrVector.size() != expNEntries)) {
0105       std::string msg("Number of entries found in Vector text does not match number in attribute nEntries.");
0106       msg += "\n\tnEntries = " + atts.find("nEntries")->second;
0107       msg += "\n------------------text---------\n";
0108       msg += tTextToParse;
0109       msg += "\n------------------text---------\n";
0110       errorOut(msg.c_str());
0111     }
0112   } else if (parent() == "ConstantsSection" || parent() == "DDDefinition") {
0113     if (atts.find("type") == atts.end() || atts.find("type")->second == "numeric") {
0114       DDVector v(getDDName(nmspace), std::make_unique<std::vector<double>>(pVector));
0115     } else {
0116       DDStrVector v(getDDName(nmspace), std::make_unique<std::vector<std::string>>(pStrVector));
0117     }
0118   }
0119   clear();
0120 }
0121 
0122 ReadMapType<std::vector<double>>& DDLVector::getMapOfVectors(void) { return pVecMap; }
0123 
0124 ReadMapType<std::vector<std::string>>& DDLVector::getMapOfStrVectors(void) { return pStrVecMap; }
0125 
0126 void DDLVector::do_makeDouble(char const* str, char const* end) {
0127   std::string ts(str, end);
0128   double td = myRegistry_->evaluator().eval(pNameSpace, ts);
0129   pVector.emplace_back(td);
0130 }
0131 
0132 void DDLVector::do_makeString(char const* str, char const* end) {
0133   std::string ts(str, end);
0134   pStrVector.emplace_back(ts);
0135 }
0136 
0137 void DDLVector::errorOut(const char* str) const {
0138   std::string e("Failed to parse the following: \n");
0139   e += std::string(str);
0140   e += "\n as a Vector element (comma separated list).";
0141   throwError(e);
0142 }
0143 
0144 void DDLVector::clearall(void) {
0145   DDXMLElement::clear();
0146   pVecMap.clear();
0147   pStrVecMap.clear();
0148 }