Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:15:07

0001 #include "CaloOnlineTools/HcalOnlineDb/interface/ConfigurationDatabaseStandardXMLParser.hh"
0002 #include <xercesc/sax2/SAX2XMLReader.hpp>
0003 #include <xercesc/sax2/XMLReaderFactory.hpp>
0004 #include "xercesc/sax2/DefaultHandler.hpp"
0005 #include "xercesc/sax2/Attributes.hpp"
0006 
0007 #include <iostream>
0008 using namespace std;
0009 
0010 ConfigurationDatabaseStandardXMLParser::ConfigurationDatabaseStandardXMLParser() : m_parser(nullptr) {}
0011 #include <xercesc/framework/MemBufInputSource.hpp>
0012 XERCES_CPP_NAMESPACE_USE
0013 
0014 /*
0015     Example
0016     <pre>
0017     <CFGBrick>
0018       <Parameter name='IETA' type='int'>14</Parameter>
0019       <Parameter name='IPHI' type='int'>2</Parameter>
0020       <Parameter name='DEPTH' type='int'>1</Parameter>
0021       <Parameter name='CRATE' type='int'>1</Parameter>
0022       <Parameter name='SLOT' type='int'>8</Parameter>
0023       <Parameter name='TOPBOTTOM' type='int'>2</Parameter>
0024       <Parameter name='CHANNEL' type='int'>6</Parameter>
0025       <Parameter name='LUT_TYPE' type='int'>1</Parameter>
0026       <Parameter name='CREATIONTAG' type='string'>Identity</Parameter>
0027       <Parameter name='CREATIONSTAMP' type='string'>2005-03-08 11:44:34</Parameter>
0028       <Parameter name='FORMATREVISION' type='string'>1</Parameter>
0029       <Parameter name='TARGETFIRMWARE' type='string'>0</Parameter>
0030       <Parameter name='GENERALIZEDINDEX' type='int'>140211</Parameter>
0031       <Data elements='128' encoding='hex'> .. </Data>
0032       <Data elements='1' encoding='hex' rm=' ' card=' ' qie=' '></Data>
0033     </CFGBrick>
0034     </pre>
0035   */
0036 
0037 class ConfigurationDBHandler : public DefaultHandler {
0038   enum { md_Idle, md_Parameter, md_Data } m_mode;
0039 
0040 public:
0041   ConfigurationDBHandler(std::list<ConfigurationDatabaseStandardXMLParser::Item> &items) : m_items(items) {
0042     m_mode = md_Idle;
0043     xc_Parameter = XMLString::transcode("Parameter");
0044     xc_Data = XMLString::transcode("Data");
0045     xc_name = XMLString::transcode("name");
0046     xc_type = XMLString::transcode("type");
0047     xc_elements = XMLString::transcode("elements");
0048     xc_encoding = XMLString::transcode("encoding");
0049     xc_header[0] = XMLString::transcode("CFGBrick");
0050     xc_header[1] = XMLString::transcode("LUT");
0051     xc_header[2] = XMLString::transcode("Pattern");
0052     m_items.clear();
0053   }
0054   ~ConfigurationDBHandler() override {
0055     XMLString::release(&xc_Parameter);
0056     XMLString::release(&xc_Data);
0057     XMLString::release(&xc_name);
0058     XMLString::release(&xc_type);
0059     XMLString::release(&xc_elements);
0060     XMLString::release(&xc_encoding);
0061     for (int i = 0; i < ITEMELEMENTNAMES; i++)
0062       XMLString::release(&xc_header[i]);
0063   }
0064   void startElement(const XMLCh *const uri,
0065                     const XMLCh *const localname,
0066                     const XMLCh *const qname,
0067                     const Attributes &attrs) override;
0068   void endElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname) override;
0069   void characters(const XMLCh *const chars, const XMLSize_t length) override;
0070   void ignorableWhitespace(const XMLCh *const chars, const XMLSize_t length) override;
0071 
0072 private:
0073   inline bool cvt2String(const XMLCh *val, std::string &ou) {
0074     if (val == nullptr)
0075       return false;
0076     char *tool = XMLString::transcode(val);
0077     ou = tool;
0078     XMLString::release(&tool);
0079     return true;
0080   }
0081   XMLCh *xc_Parameter, *xc_Data, *xc_name, *xc_type, *xc_elements, *xc_encoding;
0082   static const int ITEMELEMENTNAMES = 3;
0083   XMLCh *xc_header[ITEMELEMENTNAMES];
0084   std::string m_pname, m_ptype, m_text;
0085   int n_elements;
0086   ConfigurationDatabaseStandardXMLParser::Item m_workitem;
0087   std::list<ConfigurationDatabaseStandardXMLParser::Item> &m_items;
0088   //    std::string& m_dataEncoding;
0089   //  std::vector<std::string>& m_items;
0090   //std::map<std::string,std::string>& m_parameters;
0091   char m_workc[512];
0092   XMLCh m_workx[256];
0093   bool isItemElement(const XMLCh *const localname) {
0094     for (int i = 0; i < ITEMELEMENTNAMES; i++)
0095       if (!XMLString::compareIString(localname, xc_header[i]))
0096         return true;
0097     return false;
0098   }
0099 };
0100 
0101 void ConfigurationDBHandler::startElement(const XMLCh *const uri,
0102                                           const XMLCh *const localname,
0103                                           const XMLCh *const qname,
0104                                           const Attributes &attrs) {
0105   if (m_mode != md_Idle)
0106     return;
0107   std::string work;
0108   cvt2String(localname, work);
0109   if (isItemElement(localname)) {
0110     m_workitem.parameters.clear();
0111     m_workitem.items.clear();
0112     m_workitem.encoding.clear();
0113   } else if (!XMLString::compareIString(localname, xc_Parameter)) {
0114     // parameter name
0115     if (!cvt2String(attrs.getValue(xc_name), m_pname))
0116       return;
0117     // parameter type
0118     if (!cvt2String(attrs.getValue(xc_type), m_ptype))
0119       return;
0120     // switch mode
0121     m_mode = md_Parameter;
0122     m_text = "";
0123   } else if (!XMLString::compareIString(localname, xc_Data)) {
0124     m_workitem.items.clear();
0125     // elements
0126     std::string strElements;
0127     if (!cvt2String(attrs.getValue(xc_elements), strElements))
0128       return;
0129     n_elements = atoi(strElements.c_str());
0130     // encoding
0131     m_workitem.encoding = "";
0132     cvt2String(attrs.getValue(xc_encoding), m_workitem.encoding);
0133     // switch mode
0134     m_mode = md_Data;
0135     m_text = "";
0136     // other attributes
0137     for (unsigned int jj = 0; jj < attrs.getLength(); jj++) {
0138       if (!XMLString::compareIString(xc_elements, attrs.getValue(jj)) ||
0139           !XMLString::compareIString(xc_encoding, attrs.getValue(jj)))
0140         continue;  // already handled these two
0141       std::string atkey, atvalue;
0142       cvt2String(attrs.getLocalName(jj), atkey);
0143       cvt2String(attrs.getValue(jj), atvalue);
0144       m_workitem.parameters[atkey] = atvalue;
0145     }
0146   }
0147 }
0148 void ConfigurationDBHandler::endElement(const XMLCh *const uri,
0149                                         const XMLCh *const localname,
0150                                         const XMLCh *const qname) {
0151   if (m_mode == md_Idle)
0152     return;
0153 
0154   if (isItemElement(localname)) {
0155   } else if (m_mode == md_Parameter) {
0156     m_workitem.parameters[m_pname] = m_text;  // ignore the type for now...
0157   } else if (m_mode == md_Data) {
0158     // parse the text
0159     std::string entry;
0160     for (std::string::iterator q = m_text.begin(); q != m_text.end(); q++) {
0161       if (isspace(*q)) {
0162         if (entry.empty())
0163           continue;
0164         m_workitem.items.push_back(entry);
0165         entry = "";
0166       } else
0167         entry += *q;
0168     }
0169     if (!entry.empty())
0170       m_workitem.items.push_back(entry);
0171     m_items.push_back(m_workitem);  // save it
0172   }
0173 
0174   m_mode = md_Idle;
0175 }
0176 void ConfigurationDBHandler::ignorableWhitespace(const XMLCh *chars, const XMLSize_t length) {
0177   if (m_mode == md_Idle)
0178     return;
0179   m_text += ' ';
0180 }
0181 void ConfigurationDBHandler::characters(const XMLCh *chars, const XMLSize_t length) {
0182   if (m_mode == md_Idle)
0183     return;
0184   unsigned int offset = 0;
0185   while (offset < length) {
0186     unsigned int i = 0;
0187     for (i = 0; i < length - offset && i < 255; i++)
0188       m_workx[i] = chars[i + offset];
0189     m_workx[i] = 0;  // terminate string
0190     XMLString::transcode(m_workx, m_workc, 511);
0191     m_text += m_workc;
0192     offset += i;
0193   }
0194 }
0195 
0196 void ConfigurationDatabaseStandardXMLParser::parse(const std::string &xmlDocument,
0197                                                    std::map<std::string, std::string> &parameters,
0198                                                    std::vector<std::string> &items,
0199                                                    std::string &encoding) noexcept(false) {
0200   // uses XERCES SAX2 parser
0201   std::list<Item> theItems;
0202   ConfigurationDBHandler handler(theItems);
0203 
0204   try {
0205     if (m_parser == nullptr) {
0206       m_parser = xercesc::XMLReaderFactory::createXMLReader();
0207     }
0208 
0209     MemBufInputSource src(
0210         (const unsigned char *)xmlDocument.c_str(), xmlDocument.length(), "hcal::ConfigurationDatabase");
0211     m_parser->setContentHandler(&handler);
0212     m_parser->parse(src);
0213   } catch (std::exception &ex) {
0214     XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException, ex.what());
0215   }
0216   if (theItems.empty()) {
0217     XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException, "No data found");
0218   } else if (theItems.size() > 1) {
0219     XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException, "Multiple items found");
0220   } else {
0221     parameters = theItems.front().parameters;
0222     items = theItems.front().items;
0223     encoding = theItems.front().encoding;
0224   }
0225 }
0226 
0227 void ConfigurationDatabaseStandardXMLParser::parseMultiple(const std::string &xmlDocument,
0228                                                            std::list<Item> &items) noexcept(false) {
0229   // uses XERCES SAX2 parser
0230   ConfigurationDBHandler handler(items);
0231 
0232   try {
0233     if (m_parser == nullptr) {
0234       m_parser = xercesc::XMLReaderFactory::createXMLReader();
0235     }
0236 
0237     MemBufInputSource src(
0238         (const unsigned char *)xmlDocument.c_str(), xmlDocument.length(), "hcal::ConfigurationDatabase");
0239     m_parser->setContentHandler(&handler);
0240     m_parser->parse(src);
0241   } catch (std::exception &ex) {
0242     XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException, ex.what());
0243   }
0244 }
0245 
0246 std::vector<unsigned int> ConfigurationDatabaseStandardXMLParser::Item::convert() const {
0247   std::vector<unsigned int> values;
0248   int strtol_base = 0;
0249   if (encoding == "hex")
0250     strtol_base = 16;
0251   else if (encoding == "dec")
0252     strtol_base = 10;
0253 
0254   // convert the data
0255   for (unsigned int j = 0; j < items.size(); j++)
0256     values.push_back(strtol(items[j].c_str(), nullptr, strtol_base));
0257   return values;
0258 }