CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/IORawData/CaloPatterns/src/HcalPatternXMLParser.cc

Go to the documentation of this file.
00001 #include "xercesc/sax2/SAX2XMLReader.hpp"
00002 #include <xercesc/sax2/XMLReaderFactory.hpp>
00003 #include "xercesc/sax2/DefaultHandler.hpp"
00004 #include "xercesc/sax2/Attributes.hpp"
00005 #include "FWCore/Utilities/interface/Exception.h"
00006 #include <xercesc/framework/MemBufInputSource.hpp>
00007 XERCES_CPP_NAMESPACE_USE
00008 #include "IORawData/CaloPatterns/interface/HcalPatternXMLParser.h"
00009 #include <ostream>
00010 
00011 class HcalPatternXMLParserImpl {
00012 public:
00013   std::auto_ptr<SAX2XMLReader> parser;
00014 };
00015 
00016 HcalPatternXMLParser::HcalPatternXMLParser() {
00017   m_parser=0;
00018 }
00019 HcalPatternXMLParser::~HcalPatternXMLParser() {
00020   if (m_parser!=0) delete m_parser;
00021 }
00022 
00023   /*
00024     Example
00025     <pre>
00026     <CFGBrick>
00027       <Parameter name='IETA' type='int'>14</Parameter>
00028       <Parameter name='IPHI' type='int'>2</Parameter>
00029       <Parameter name='DEPTH' type='int'>1</Parameter>
00030       <Parameter name='CRATE' type='int'>1</Parameter>
00031       <Parameter name='SLOT' type='int'>8</Parameter>
00032       <Parameter name='TOPBOTTOM' type='int'>0</Parameter>
00033       <Parameter name='CHANNEL' type='int'>6</Parameter>
00034       <Parameter name='LUT_TYPE' type='int'>1</Parameter>
00035       <Parameter name='CREATIONTAG' type='string'>Identity</Parameter>
00036       <Parameter name='CREATIONSTAMP' type='string'>2005-03-08 11:44:34</Parameter>
00037       <Parameter name='FORMATREVISION' type='string'>1</Parameter>
00038       <Parameter name='TARGETFIRMWARE' type='string'>0</Parameter>
00039       <Parameter name='GENERALIZEDINDEX' type='int'>140211</Parameter>
00040       <Data elements='128' encoding='hex'> .. </Data>
00041     </CFGBrick>
00042     </pre>
00043   */
00044 
00045   class ConfigurationDBHandler : public DefaultHandler {
00046     enum { md_Idle, md_Parameter, md_Data } m_mode;
00047   public:
00048     ConfigurationDBHandler(std::map<std::string,std::string>& parameters, std::vector<std::string>& items, std::string& encoding) : m_dataEncoding(encoding), m_items(items), m_parameters(parameters) {
00049       m_mode=md_Idle;
00050       xc_Parameter=XMLString::transcode("Parameter");
00051       xc_Data=XMLString::transcode("Data");
00052       xc_name=XMLString::transcode("name");
00053       xc_type=XMLString::transcode("type");
00054       xc_elements=XMLString::transcode("elements");      
00055       xc_encoding=XMLString::transcode("encoding");
00056       m_items.clear();
00057       m_parameters.clear();
00058     }
00059     virtual ~ConfigurationDBHandler() {
00060       XMLString::release(&xc_Parameter);
00061       XMLString::release(&xc_Data);
00062       XMLString::release(&xc_name);
00063       XMLString::release(&xc_type);
00064       XMLString::release(&xc_elements);
00065       XMLString::release(&xc_encoding);
00066     }
00067     virtual void startElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname, const Attributes &attrs);
00068     virtual void endElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname);
00069     virtual void characters(const   XMLCh* const    chars, const unsigned int length);
00070     virtual void ignorableWhitespace(const   XMLCh* chars, const unsigned int length);
00071   private:
00072     inline bool cvt2String(const XMLCh* val, std::string& ou) {
00073       if (val==0) return false;
00074       char* tool=XMLString::transcode(val);
00075       ou=tool;
00076       XMLString::release(&tool);
00077       return true;
00078     }
00079     XMLCh *xc_Parameter, *xc_Data, *xc_name, *xc_type, *xc_elements, *xc_encoding;
00080     std::string m_pname, m_ptype, m_text;
00081     int n_elements;
00082     std::string& m_dataEncoding;
00083     std::vector<std::string>& m_items;
00084     std::map<std::string,std::string>& m_parameters;
00085     char m_workc[512];
00086     XMLCh m_workx[256];
00087   };
00088 
00089   void ConfigurationDBHandler::startElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname, const Attributes &attrs) {
00090     if (m_mode!=md_Idle) return; 
00091     if (!XMLString::compareIString(localname,xc_Parameter)) {
00092       // parameter name
00093       if (!cvt2String(attrs.getValue(xc_name),m_pname)) return;
00094       // parameter type
00095       if (!cvt2String(attrs.getValue(xc_type),m_ptype)) return;
00096       // switch mode
00097       m_mode=md_Parameter;
00098       m_text="";
00099     } else if (!XMLString::compareIString(localname,xc_Data)) {
00100       // elements
00101       std::string strElements;
00102       if (!cvt2String(attrs.getValue(xc_elements),strElements)) return;
00103       n_elements=atoi(strElements.c_str());
00104       // encoding
00105       m_dataEncoding="";
00106       cvt2String(attrs.getValue(xc_encoding),m_dataEncoding);
00107       // switch mode
00108       m_mode=md_Data;
00109       m_text="";
00110     }
00111    
00112   }
00113   void ConfigurationDBHandler::endElement (const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname) {
00114     if (m_mode==md_Idle) return;
00115 
00116     if (m_mode==md_Parameter) {
00117       m_parameters[m_pname]=m_text; // ignore the type for now...
00118     } else if (m_mode==md_Data) {
00119       // parse the text
00120       std::string entry;
00121       for (std::string::iterator q=m_text.begin(); q!=m_text.end(); q++) {
00122         if (isspace(*q)) {
00123           if (entry.empty()) continue;
00124           m_items.push_back(entry);
00125           entry="";
00126         } else entry+=*q;
00127       }
00128     }
00129 
00130     m_mode=md_Idle;
00131   }
00132   void ConfigurationDBHandler::ignorableWhitespace(const   XMLCh* chars, const unsigned int length) {
00133     if (m_mode==md_Idle) return;
00134     m_text+=' ';
00135   }
00136   void ConfigurationDBHandler::characters(const XMLCh* chars, const unsigned int length) {
00137     if (m_mode==md_Idle) return;
00138     unsigned int offset=0;
00139     while (offset<length) {
00140       unsigned int i=0;
00141       for (i=0; i<length-offset && i<255; i++) m_workx[i]=chars[i+offset];
00142       m_workx[i]=0; // terminate string
00143       XMLString::transcode(m_workx,m_workc,511);
00144       m_text+=m_workc;
00145       offset+=i;
00146     }
00147   }
00148 
00149 void HcalPatternXMLParser::parse(const std::string& xmlDocument, std::map<std::string,std::string>& parameters, std::vector<std::string>& items, std::string& encoding) {
00150     // uses XERCES SAX2 parser
00151     ConfigurationDBHandler handler(parameters,items,encoding);
00152     
00153     try {
00154       if (m_parser==0) {
00155         m_parser=new HcalPatternXMLParserImpl();
00156         m_parser->parser=std::auto_ptr<xercesc::SAX2XMLReader>(xercesc::XMLReaderFactory::createXMLReader());
00157       }
00158          
00159       MemBufInputSource src((const unsigned char*)xmlDocument.c_str(), xmlDocument.length(),"hcal::PatternReader");
00160       m_parser->parser->setContentHandler(&handler);
00161       m_parser->parser->parse(src);
00162     } catch (std::exception& ex) {
00163       throw cms::Exception("ParseError") << ex.what();
00164     }
00165   }
00166 
00167 void HcalPatternXMLParser::parse(const std::string& xmlDocument, std::map<std::string,std::string>& parameters, std::vector<uint32_t>& data) {
00168   std::vector<std::string> items;
00169   std::string encoding;
00170 
00171   this->parse(xmlDocument,parameters,items,encoding);
00172   int formatting=0;
00173   if (encoding=="dec") formatting=10;
00174   if (encoding=="hex") formatting=16;
00175 
00176   data.clear();
00177   for (std::vector<std::string>::const_iterator i=items.begin(); i!=items.end(); i++)
00178     data.push_back(strtol(i->c_str(),0,formatting));
00179 
00180 }