CMS 3D CMS Logo

ConfigurationDatabaseStandardXMLParser.cc
Go to the documentation of this file.
1 #include "CaloOnlineTools/HcalOnlineDb/interface/ConfigurationDatabaseStandardXMLParser.hh"
2 #include <xercesc/sax2/SAX2XMLReader.hpp>
3 #include <xercesc/sax2/XMLReaderFactory.hpp>
4 #include "xercesc/sax2/DefaultHandler.hpp"
5 #include "xercesc/sax2/Attributes.hpp"
6 
7 #include <iostream>
8 using namespace std;
9 
10 ConfigurationDatabaseStandardXMLParser::ConfigurationDatabaseStandardXMLParser() : m_parser(nullptr) {
11 }
12 #include <xercesc/framework/MemBufInputSource.hpp>
14 
15  /*
16  Example
17  <pre>
18  <CFGBrick>
19  <Parameter name='IETA' type='int'>14</Parameter>
20  <Parameter name='IPHI' type='int'>2</Parameter>
21  <Parameter name='DEPTH' type='int'>1</Parameter>
22  <Parameter name='CRATE' type='int'>1</Parameter>
23  <Parameter name='SLOT' type='int'>8</Parameter>
24  <Parameter name='TOPBOTTOM' type='int'>2</Parameter>
25  <Parameter name='CHANNEL' type='int'>6</Parameter>
26  <Parameter name='LUT_TYPE' type='int'>1</Parameter>
27  <Parameter name='CREATIONTAG' type='string'>Identity</Parameter>
28  <Parameter name='CREATIONSTAMP' type='string'>2005-03-08 11:44:34</Parameter>
29  <Parameter name='FORMATREVISION' type='string'>1</Parameter>
30  <Parameter name='TARGETFIRMWARE' type='string'>0</Parameter>
31  <Parameter name='GENERALIZEDINDEX' type='int'>140211</Parameter>
32  <Data elements='128' encoding='hex'> .. </Data>
33  <Data elements='1' encoding='hex' rm=' ' card=' ' qie=' '></Data>
34  </CFGBrick>
35  </pre>
36  */
37 
38  class ConfigurationDBHandler : public DefaultHandler {
40  public:
41  ConfigurationDBHandler(std::list<ConfigurationDatabaseStandardXMLParser::Item>& items) : m_items(items) {
42  m_mode=md_Idle;
43  xc_Parameter=XMLString::transcode("Parameter");
44  xc_Data=XMLString::transcode("Data");
45  xc_name=XMLString::transcode("name");
46  xc_type=XMLString::transcode("type");
47  xc_elements=XMLString::transcode("elements");
48  xc_encoding=XMLString::transcode("encoding");
49  xc_header[0]=XMLString::transcode("CFGBrick");
50  xc_header[1]=XMLString::transcode("LUT");
51  xc_header[2]=XMLString::transcode("Pattern");
52  m_items.clear();
53  }
61  for (int i=0; i<ITEMELEMENTNAMES; i++)
63  }
64  void startElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname, const Attributes &attrs) override;
65  void endElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname) override;
66  void characters (const XMLCh *const chars, const XMLSize_t length) override;
67  void ignorableWhitespace (const XMLCh *const chars, const XMLSize_t length) override;
68  private:
69  inline bool cvt2String(const XMLCh* val, std::string& ou) {
70  if (val==nullptr) return false;
71  char* tool=XMLString::transcode(val);
72  ou=tool;
73  XMLString::release(&tool);
74  return true;
75  }
77  static const int ITEMELEMENTNAMES=3;
81  ConfigurationDatabaseStandardXMLParser::Item m_workitem;
82  std::list<ConfigurationDatabaseStandardXMLParser::Item>& m_items;
83  // std::string& m_dataEncoding;
84  // std::vector<std::string>& m_items;
85  //std::map<std::string,std::string>& m_parameters;
86  char m_workc[512];
87  XMLCh m_workx[256];
88  bool isItemElement(const XMLCh* const localname) {
89  for (int i=0; i<ITEMELEMENTNAMES; i++)
90  if (!XMLString::compareIString(localname,xc_header[i])) return true;
91  return false;
92  }
93  };
94 
95  void ConfigurationDBHandler::startElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname, const Attributes &attrs) {
96  if (m_mode!=md_Idle) return;
98  cvt2String(localname,work);
99  if (isItemElement(localname)) {
100  m_workitem.parameters.clear();
101  m_workitem.items.clear();
102  m_workitem.encoding.clear();
103  } else if (!XMLString::compareIString(localname,xc_Parameter)) {
104  // parameter name
105  if (!cvt2String(attrs.getValue(xc_name),m_pname)) return;
106  // parameter type
107  if (!cvt2String(attrs.getValue(xc_type),m_ptype)) return;
108  // switch mode
110  m_text="";
111  } else if (!XMLString::compareIString(localname,xc_Data)) {
112  m_workitem.items.clear();
113  // elements
114  std::string strElements;
115  if (!cvt2String(attrs.getValue(xc_elements),strElements)) return;
116  n_elements=atoi(strElements.c_str());
117  // encoding
118  m_workitem.encoding="";
119  cvt2String(attrs.getValue(xc_encoding),m_workitem.encoding);
120  // switch mode
121  m_mode=md_Data;
122  m_text="";
123  // other attributes
124  for (unsigned int jj=0; jj<attrs.getLength(); jj++) {
125  if (!XMLString::compareIString(xc_elements,attrs.getValue(jj)) ||
126  !XMLString::compareIString(xc_encoding,attrs.getValue(jj)))
127  continue; // already handled these two
128  std::string atkey,atvalue;
129  cvt2String(attrs.getLocalName(jj),atkey);
130  cvt2String(attrs.getValue(jj),atvalue);
131  m_workitem.parameters[atkey]=atvalue;
132  }
133  }
134 
135  }
136  void ConfigurationDBHandler::endElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname) {
137  if (m_mode==md_Idle) return;
138 
139  if (isItemElement(localname)) {
140  } else if (m_mode==md_Parameter) {
141  m_workitem.parameters[m_pname]=m_text; // ignore the type for now...
142  } else if (m_mode==md_Data) {
143  // parse the text
145  for (std::string::iterator q=m_text.begin(); q!=m_text.end(); q++) {
146  if (isspace(*q)) {
147  if (entry.empty()) continue;
148  m_workitem.items.push_back(entry);
149  entry="";
150  } else entry+=*q;
151  }
152  if (!entry.empty()) m_workitem.items.push_back(entry);
153  m_items.push_back(m_workitem); // save it
154  }
155 
156  m_mode=md_Idle;
157  }
158  void ConfigurationDBHandler::ignorableWhitespace(const XMLCh* chars, const XMLSize_t length) {
159  if (m_mode==md_Idle) return;
160  m_text+=' ';
161  }
162  void ConfigurationDBHandler::characters(const XMLCh* chars, const XMLSize_t length) {
163  if (m_mode==md_Idle) return;
164  unsigned int offset=0;
165  while (offset<length) {
166  unsigned int i=0;
167  for (i=0; i<length-offset && i<255; i++) m_workx[i]=chars[i+offset];
168  m_workx[i]=0; // terminate string
169  XMLString::transcode(m_workx,m_workc,511);
170  m_text+=m_workc;
171  offset+=i;
172  }
173  }
174 
175 void ConfigurationDatabaseStandardXMLParser::parse(const std::string& xmlDocument, std::map<std::string,std::string>& parameters, std::vector<std::string>& items, std::string& encoding) noexcept(false) {
176  // uses XERCES SAX2 parser
177  std::list<Item> theItems;
178  ConfigurationDBHandler handler(theItems);
179 
180  try {
181  if (m_parser==nullptr) {
182  m_parser=xercesc::XMLReaderFactory::createXMLReader();
183  }
184 
185  MemBufInputSource src((const unsigned char*)xmlDocument.c_str(), xmlDocument.length(),"hcal::ConfigurationDatabase");
186  m_parser->setContentHandler(&handler);
187  m_parser->parse(src);
188  } catch (std::exception& ex) {
189  XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,ex.what());
190  }
191  if (theItems.empty()) {
192  XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,"No data found");
193  } else if (theItems.size()>1) {
194  XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,"Multiple items found");
195  } else {
196  parameters=theItems.front().parameters;
197  items=theItems.front().items;
198  encoding=theItems.front().encoding;
199  }
200 }
201 
202 
203 
204 void ConfigurationDatabaseStandardXMLParser::parseMultiple(const std::string& xmlDocument, std::list<Item>& items) noexcept(false) {
205  // uses XERCES SAX2 parser
206  ConfigurationDBHandler handler(items);
207 
208  try {
209  if (m_parser==nullptr) {
210  m_parser=xercesc::XMLReaderFactory::createXMLReader();
211  }
212 
213  MemBufInputSource src((const unsigned char*)xmlDocument.c_str(), xmlDocument.length(),"hcal::ConfigurationDatabase");
214  m_parser->setContentHandler(&handler);
215  m_parser->parse(src);
216  } catch (std::exception& ex) {
217  XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,ex.what());
218  }
219 }
220 
221 std::vector<unsigned int> ConfigurationDatabaseStandardXMLParser::Item::convert() const {
222  std::vector<unsigned int> values;
223  int strtol_base=0;
224  if (encoding=="hex") strtol_base=16;
225  else if (encoding=="dec") strtol_base=10;
226 
227  // convert the data
228  for (unsigned int j=0; j<items.size(); j++)
229  values.push_back(strtol(items[j].c_str(),nullptr,strtol_base));
230  return values;
231 }
bool cvt2String(const XMLCh *val, std::string &ou)
#define noexcept
ConfigurationDatabaseStandardXMLParser::Item m_workitem
#define nullptr
void characters(const XMLCh *const chars, const XMLSize_t length) override
enum ConfigurationDBHandler::@66 m_mode
void ignorableWhitespace(const XMLCh *const chars, const XMLSize_t length) override
def convert(infile, ofile)
std::list< ConfigurationDatabaseStandardXMLParser::Item > & m_items
def parse(path, config)
Definition: dumpparser.py:13
bool isItemElement(const XMLCh *const localname)
void startElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname, const Attributes &attrs) override
ConfigurationDBHandler(std::list< ConfigurationDatabaseStandardXMLParser::Item > &items)
void endElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname) override