CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/CaloOnlineTools/HcalOnlineDb/src/ConfigurationDatabaseStandardXMLParser.cc

Go to the documentation of this file.
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     Example
00017     <pre>
00018     <CFGBrick>
00019       <Parameter name='IETA' type='int'>14</Parameter>
00020       <Parameter name='IPHI' type='int'>2</Parameter>
00021       <Parameter name='DEPTH' type='int'>1</Parameter>
00022       <Parameter name='CRATE' type='int'>1</Parameter>
00023       <Parameter name='SLOT' type='int'>8</Parameter>
00024       <Parameter name='TOPBOTTOM' type='int'>2</Parameter>
00025       <Parameter name='CHANNEL' type='int'>6</Parameter>
00026       <Parameter name='LUT_TYPE' type='int'>1</Parameter>
00027       <Parameter name='CREATIONTAG' type='string'>Identity</Parameter>
00028       <Parameter name='CREATIONSTAMP' type='string'>2005-03-08 11:44:34</Parameter>
00029       <Parameter name='FORMATREVISION' type='string'>1</Parameter>
00030       <Parameter name='TARGETFIRMWARE' type='string'>0</Parameter>
00031       <Parameter name='GENERALIZEDINDEX' type='int'>140211</Parameter>
00032       <Data elements='128' encoding='hex'> .. </Data>
00033       <Data elements='1' encoding='hex' rm=' ' card=' ' qie=' '></Data>
00034     </CFGBrick>
00035     </pre>
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     //    std::string& m_dataEncoding;
00084     //  std::vector<std::string>& m_items;
00085     //std::map<std::string,std::string>& m_parameters;
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       // parameter name
00105       if (!cvt2String(attrs.getValue(xc_name),m_pname)) return;
00106       // parameter type
00107       if (!cvt2String(attrs.getValue(xc_type),m_ptype)) return;
00108       // switch mode
00109       m_mode=md_Parameter;
00110       m_text="";
00111     } else if (!XMLString::compareIString(localname,xc_Data)) {
00112       m_workitem.items.clear();
00113       // elements
00114       std::string strElements;
00115       if (!cvt2String(attrs.getValue(xc_elements),strElements)) return;
00116       n_elements=atoi(strElements.c_str());
00117       // encoding
00118       m_workitem.encoding="";
00119       cvt2String(attrs.getValue(xc_encoding),m_workitem.encoding);
00120       // switch mode
00121       m_mode=md_Data;
00122       m_text="";
00123       // other attributes
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; // already handled these two
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; // ignore the type for now...
00142     } else if (m_mode==md_Data) {
00143       // parse the text
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); // save it
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; // terminate string
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   // uses XERCES SAX2 parser
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   // uses XERCES SAX2 parser
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   // convert the data
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 }