00001 #include "CaloOnlineTools/HcalOnlineDb/interface/ConfigurationDatabaseStandardXMLParser.hh"
00002 #include <xercesc/sax2/SAX2XMLReader.hpp>
00003 #include <xercesc/sax2/XMLReaderFactory.hpp>
00004 #include "xercesc/sax2/DefaultHandler.hpp"
00005 #include "xercesc/sax2/Attributes.hpp"
00006
00007 #include <iostream>
00008 using namespace std;
00009
00010 ConfigurationDatabaseStandardXMLParser::ConfigurationDatabaseStandardXMLParser() : m_parser(0) {
00011 }
00012 #include <xercesc/framework/MemBufInputSource.hpp>
00013 XERCES_CPP_NAMESPACE_USE
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 class ConfigurationDBHandler : public DefaultHandler {
00039 enum { md_Idle, md_Parameter, md_Data } m_mode;
00040 public:
00041 ConfigurationDBHandler(std::list<ConfigurationDatabaseStandardXMLParser::Item>& items) : m_items(items) {
00042 m_mode=md_Idle;
00043 xc_Parameter=XMLString::transcode("Parameter");
00044 xc_Data=XMLString::transcode("Data");
00045 xc_name=XMLString::transcode("name");
00046 xc_type=XMLString::transcode("type");
00047 xc_elements=XMLString::transcode("elements");
00048 xc_encoding=XMLString::transcode("encoding");
00049 xc_header[0]=XMLString::transcode("CFGBrick");
00050 xc_header[1]=XMLString::transcode("LUT");
00051 xc_header[2]=XMLString::transcode("Pattern");
00052 m_items.clear();
00053 }
00054 virtual ~ConfigurationDBHandler() {
00055 XMLString::release(&xc_Parameter);
00056 XMLString::release(&xc_Data);
00057 XMLString::release(&xc_name);
00058 XMLString::release(&xc_type);
00059 XMLString::release(&xc_elements);
00060 XMLString::release(&xc_encoding);
00061 for (int i=0; i<ITEMELEMENTNAMES; i++)
00062 XMLString::release(&xc_header[i]);
00063 }
00064 virtual void startElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname, const Attributes &attrs);
00065 virtual void endElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname);
00066 virtual void characters(const XMLCh* const chars, const unsigned int length);
00067 virtual void ignorableWhitespace(const XMLCh* chars, const unsigned int length);
00068 private:
00069 inline bool cvt2String(const XMLCh* val, std::string& ou) {
00070 if (val==0) return false;
00071 char* tool=XMLString::transcode(val);
00072 ou=tool;
00073 XMLString::release(&tool);
00074 return true;
00075 }
00076 XMLCh *xc_Parameter, *xc_Data, *xc_name, *xc_type, *xc_elements, *xc_encoding;
00077 static const int ITEMELEMENTNAMES=3;
00078 XMLCh *xc_header[ITEMELEMENTNAMES];
00079 std::string m_pname, m_ptype, m_text;
00080 int n_elements;
00081 ConfigurationDatabaseStandardXMLParser::Item m_workitem;
00082 std::list<ConfigurationDatabaseStandardXMLParser::Item>& m_items;
00083
00084
00085
00086 char m_workc[512];
00087 XMLCh m_workx[256];
00088 bool isItemElement(const XMLCh* const localname) {
00089 for (int i=0; i<ITEMELEMENTNAMES; i++)
00090 if (!XMLString::compareIString(localname,xc_header[i])) return true;
00091 return false;
00092 }
00093 };
00094
00095 void ConfigurationDBHandler::startElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname, const Attributes &attrs) {
00096 if (m_mode!=md_Idle) return;
00097 std::string work;
00098 cvt2String(localname,work);
00099 if (isItemElement(localname)) {
00100 m_workitem.parameters.clear();
00101 m_workitem.items.clear();
00102 m_workitem.encoding.clear();
00103 } else if (!XMLString::compareIString(localname,xc_Parameter)) {
00104
00105 if (!cvt2String(attrs.getValue(xc_name),m_pname)) return;
00106
00107 if (!cvt2String(attrs.getValue(xc_type),m_ptype)) return;
00108
00109 m_mode=md_Parameter;
00110 m_text="";
00111 } else if (!XMLString::compareIString(localname,xc_Data)) {
00112 m_workitem.items.clear();
00113
00114 std::string strElements;
00115 if (!cvt2String(attrs.getValue(xc_elements),strElements)) return;
00116 n_elements=atoi(strElements.c_str());
00117
00118 m_workitem.encoding="";
00119 cvt2String(attrs.getValue(xc_encoding),m_workitem.encoding);
00120
00121 m_mode=md_Data;
00122 m_text="";
00123
00124 for (unsigned int jj=0; jj<attrs.getLength(); jj++) {
00125 if (!XMLString::compareIString(xc_elements,attrs.getValue(jj)) ||
00126 !XMLString::compareIString(xc_encoding,attrs.getValue(jj)))
00127 continue;
00128 std::string atkey,atvalue;
00129 cvt2String(attrs.getLocalName(jj),atkey);
00130 cvt2String(attrs.getValue(jj),atvalue);
00131 m_workitem.parameters[atkey]=atvalue;
00132 }
00133 }
00134
00135 }
00136 void ConfigurationDBHandler::endElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname) {
00137 if (m_mode==md_Idle) return;
00138
00139 if (isItemElement(localname)) {
00140 } else if (m_mode==md_Parameter) {
00141 m_workitem.parameters[m_pname]=m_text;
00142 } else if (m_mode==md_Data) {
00143
00144 std::string entry;
00145 for (std::string::iterator q=m_text.begin(); q!=m_text.end(); q++) {
00146 if (isspace(*q)) {
00147 if (entry.empty()) continue;
00148 m_workitem.items.push_back(entry);
00149 entry="";
00150 } else entry+=*q;
00151 }
00152 if (!entry.empty()) m_workitem.items.push_back(entry);
00153 m_items.push_back(m_workitem);
00154 }
00155
00156 m_mode=md_Idle;
00157 }
00158 void ConfigurationDBHandler::ignorableWhitespace(const XMLCh* chars, const unsigned int length) {
00159 if (m_mode==md_Idle) return;
00160 m_text+=' ';
00161 }
00162 void ConfigurationDBHandler::characters(const XMLCh* chars, const unsigned int length) {
00163 if (m_mode==md_Idle) return;
00164 unsigned int offset=0;
00165 while (offset<length) {
00166 unsigned int i=0;
00167 for (i=0; i<length-offset && i<255; i++) m_workx[i]=chars[i+offset];
00168 m_workx[i]=0;
00169 XMLString::transcode(m_workx,m_workc,511);
00170 m_text+=m_workc;
00171 offset+=i;
00172 }
00173 }
00174
00175 void ConfigurationDatabaseStandardXMLParser::parse(const std::string& xmlDocument, std::map<std::string,std::string>& parameters, std::vector<std::string>& items, std::string& encoding) throw (hcal::exception::ConfigurationDatabaseException) {
00176
00177 std::list<Item> theItems;
00178 ConfigurationDBHandler handler(theItems);
00179
00180 try {
00181 if (m_parser==0) {
00182 m_parser=xercesc::XMLReaderFactory::createXMLReader();
00183 }
00184
00185 MemBufInputSource src((const unsigned char*)xmlDocument.c_str(), xmlDocument.length(),"hcal::ConfigurationDatabase");
00186 m_parser->setContentHandler(&handler);
00187 m_parser->parse(src);
00188 } catch (std::exception& ex) {
00189 XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,ex.what());
00190 }
00191 if (theItems.size()==0) {
00192 XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,"No data found");
00193 } else if (theItems.size()>1) {
00194 XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,"Multiple items found");
00195 } else {
00196 parameters=theItems.front().parameters;
00197 items=theItems.front().items;
00198 encoding=theItems.front().encoding;
00199 }
00200 }
00201
00202
00203
00204 void ConfigurationDatabaseStandardXMLParser::parseMultiple(const std::string& xmlDocument, std::list<Item>& items) throw (hcal::exception::ConfigurationDatabaseException) {
00205
00206 ConfigurationDBHandler handler(items);
00207
00208 try {
00209 if (m_parser==0) {
00210 m_parser=xercesc::XMLReaderFactory::createXMLReader();
00211 }
00212
00213 MemBufInputSource src((const unsigned char*)xmlDocument.c_str(), xmlDocument.length(),"hcal::ConfigurationDatabase");
00214 m_parser->setContentHandler(&handler);
00215 m_parser->parse(src);
00216 } catch (std::exception& ex) {
00217 XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,ex.what());
00218 }
00219 }
00220
00221 std::vector<unsigned int> ConfigurationDatabaseStandardXMLParser::Item::convert() const {
00222 std::vector<unsigned int> values;
00223 int strtol_base=0;
00224 if (encoding=="hex") strtol_base=16;
00225 else if (encoding=="dec") strtol_base=10;
00226
00227
00228 for (unsigned int j=0; j<items.size(); j++)
00229 values.push_back(strtol(items[j].c_str(),0,strtol_base));
00230 return values;
00231 }