File indexing completed on 2024-04-06 12:00: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
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
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
0089
0090
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
0115 if (!cvt2String(attrs.getValue(xc_name), m_pname))
0116 return;
0117
0118 if (!cvt2String(attrs.getValue(xc_type), m_ptype))
0119 return;
0120
0121 m_mode = md_Parameter;
0122 m_text = "";
0123 } else if (!XMLString::compareIString(localname, xc_Data)) {
0124 m_workitem.items.clear();
0125
0126 std::string strElements;
0127 if (!cvt2String(attrs.getValue(xc_elements), strElements))
0128 return;
0129 n_elements = atoi(strElements.c_str());
0130
0131 m_workitem.encoding = "";
0132 cvt2String(attrs.getValue(xc_encoding), m_workitem.encoding);
0133
0134 m_mode = md_Data;
0135 m_text = "";
0136
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;
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;
0157 } else if (m_mode == md_Data) {
0158
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);
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;
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> ¶meters,
0198 std::vector<std::string> &items,
0199 std::string &encoding) noexcept(false) {
0200
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
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
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 }