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