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