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
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
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
00093 if (!cvt2String(attrs.getValue(xc_name),m_pname)) return;
00094
00095 if (!cvt2String(attrs.getValue(xc_type),m_ptype)) return;
00096
00097 m_mode=md_Parameter;
00098 m_text="";
00099 } else if (!XMLString::compareIString(localname,xc_Data)) {
00100
00101 std::string strElements;
00102 if (!cvt2String(attrs.getValue(xc_elements),strElements)) return;
00103 n_elements=atoi(strElements.c_str());
00104
00105 m_dataEncoding="";
00106 cvt2String(attrs.getValue(xc_encoding),m_dataEncoding);
00107
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;
00118 } else if (m_mode==md_Data) {
00119
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;
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
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 }