00001 #include <iostream>
00002 #include <memory>
00003 #include <string>
00004
00005 #include <xercesc/util/PlatformUtils.hpp>
00006 #include <xercesc/util/XMLString.hpp>
00007 #include <xercesc/util/XMLUni.hpp>
00008 #include <xercesc/sax2/SAX2XMLReader.hpp>
00009 #include <xercesc/sax2/XMLReaderFactory.hpp>
00010
00011 #include "FWCore/Utilities/interface/Exception.h"
00012
00013 #include "Utilities/StorageFactory/interface/IOTypes.h"
00014 #include "Utilities/StorageFactory/interface/Storage.h"
00015
00016 #include "XMLUtils.h"
00017
00018 XERCES_CPP_NAMESPACE_USE
00019
00020 namespace lhef {
00021
00022 StorageWrap::StorageWrap(Storage *storage) :
00023 storage(storage)
00024 {
00025 }
00026
00027 StorageWrap::~StorageWrap()
00028 {
00029 storage->close();
00030 }
00031
00032 unsigned int XMLDocument::XercesPlatform::instances = 0;
00033
00034 XMLDocument::XercesPlatform::XercesPlatform()
00035 {
00036 if (!instances++) {
00037 try {
00038 XMLPlatformUtils::Initialize();
00039 } catch(const XMLException &e) {
00040 throw cms::Exception("XMLDocument")
00041 << "XMLPlatformUtils::Initialize failed "
00042 "because of: "
00043 << XMLSimpleStr(e.getMessage()) << std::endl;
00044 }
00045 }
00046 }
00047
00048 XMLDocument::XercesPlatform::~XercesPlatform()
00049 {
00050 if (!--instances)
00051 XMLPlatformUtils::Terminate();
00052 }
00053
00054 XMLDocument::XMLDocument(std::auto_ptr<std::istream> &in, Handler &handler) :
00055 platform(new XercesPlatform()),
00056 source(new STLInputSource(in)),
00057 parser(XMLReaderFactory::createXMLReader()),
00058 done(false)
00059 {
00060 init(handler);
00061 }
00062
00063 XMLDocument::XMLDocument(std::auto_ptr<StorageWrap> &in, Handler &handler) :
00064 platform(new XercesPlatform()),
00065 source(new StorageInputSource(in)),
00066 parser(XMLReaderFactory::createXMLReader()),
00067 done(false)
00068 {
00069 init(handler);
00070 }
00071
00072 void XMLDocument::init(Handler &handler)
00073 {
00074 try {
00075 parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
00076 parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, false);
00077 parser->setFeature(XMLUni::fgXercesSchema, false);
00078 parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
00079
00080 parser->setContentHandler(&handler);
00081 parser->setLexicalHandler(&handler);
00082 parser->setErrorHandler(&handler);
00083
00084 if (!parser->parseFirst(*source, token))
00085 throw cms::Exception("XMLParseError")
00086 << "SAXParser::parseFirst failed" << std::endl;
00087 } catch(const XMLException &e) {
00088 throw cms::Exception("XMLDocument")
00089 << "XMLPlatformUtils::Initialize failed because of "
00090 << XMLSimpleStr(e.getMessage()) << std::endl;
00091 } catch(const SAXException &e) {
00092 throw cms::Exception("XMLDocument")
00093 << "XML parser reported: "
00094 << XMLSimpleStr(e.getMessage()) << "." << std::endl;
00095 }
00096 }
00097
00098 XMLDocument::~XMLDocument()
00099 {
00100 }
00101
00102 bool XMLDocument::parse()
00103 {
00104 try {
00105 if (done || parser->getErrorCount())
00106 return false;
00107
00108 done = !parser->parseNext(token);
00109 } catch(const XMLException &e) {
00110 throw cms::Exception("XMLDocument")
00111 << "XMLPlatformUtils::Initialize failed because of "
00112 << XMLSimpleStr(e.getMessage()) << std::endl;
00113 } catch(const SAXException &e) {
00114 throw cms::Exception("XMLDocument")
00115 << "XML parser reported: "
00116 << XMLSimpleStr(e.getMessage()) << "." << std::endl;
00117 }
00118
00119 return !done;
00120 }
00121
00122 CBInputStream::Reader::~Reader()
00123 {
00124 }
00125
00126 CBInputStream::CBInputStream(Reader &reader) :
00127 reader(reader)
00128 {
00129 }
00130
00131 CBInputStream::~CBInputStream()
00132 {
00133 }
00134
00135 unsigned int CBInputStream::readBytes(XMLByte* const buf,
00136 const unsigned int size)
00137 {
00138 char *rawBuf = reinterpret_cast<char*>(buf);
00139 unsigned int bytes = size * sizeof(XMLByte);
00140 unsigned int read = 0;
00141
00142 while(read < bytes) {
00143 if (buffer.empty()) {
00144 buffer = reader.data();
00145 if (buffer.empty())
00146 break;
00147 }
00148
00149 unsigned int len = buffer.length();
00150 unsigned int rem = bytes - read;
00151 if (rem < len) {
00152 std::memcpy(rawBuf + read, buffer.c_str(), rem);
00153 buffer.erase(0, rem);
00154 read += rem;
00155 break;
00156 }
00157
00158 std::memcpy(rawBuf + read, buffer.c_str(), len);
00159 buffer.clear();
00160 read += len;
00161 }
00162
00163 read /= sizeof(XMLByte);
00164 pos += read;
00165
00166 return read;
00167 }
00168
00169 STLInputStream::STLInputStream(std::istream &in) :
00170 in(in)
00171 {
00172 if (in.bad())
00173 throw cms::Exception("FileStreamError")
00174 << "I/O stream bad in STLInputStream::STLInputStream()"
00175 << std::endl;
00176 }
00177
00178 STLInputStream::~STLInputStream()
00179 {
00180 }
00181
00182 unsigned int STLInputStream::readBytes(XMLByte* const buf,
00183 const unsigned int size)
00184 {
00185 char *rawBuf = reinterpret_cast<char*>(buf);
00186 unsigned int bytes = size * sizeof(XMLByte);
00187 in.read(rawBuf, bytes);
00188 unsigned int readBytes = in.gcount();
00189
00190 if (in.bad())
00191 throw cms::Exception("FileStreamError")
00192 << "I/O stream bad in STLInputStream::readBytes()"
00193 << std::endl;
00194
00195 unsigned int read = (unsigned int)(readBytes / sizeof(XMLByte));
00196 unsigned int rest = (unsigned int)(readBytes % sizeof(XMLByte));
00197 for(unsigned int i = 1; i <= rest; i++)
00198 in.putback(rawBuf[readBytes - i]);
00199
00200 pos += read;
00201 return read;
00202 }
00203
00204 StorageInputStream::StorageInputStream(StorageWrap &in) :
00205 in(in)
00206 {
00207 }
00208
00209 StorageInputStream::~StorageInputStream()
00210 {
00211 }
00212
00213 unsigned int StorageInputStream::readBytes(XMLByte* const buf,
00214 const unsigned int size)
00215 {
00216 void *rawBuf = reinterpret_cast<void*>(buf);
00217 unsigned int bytes = size * sizeof(XMLByte);
00218 unsigned int readBytes = in->read(rawBuf, bytes);
00219
00220 unsigned int read = (unsigned int)(readBytes / sizeof(XMLByte));
00221 unsigned int rest = (unsigned int)(readBytes % sizeof(XMLByte));
00222 if (rest)
00223 in->position(-(IOOffset)rest, Storage::CURRENT);
00224
00225 pos += read;
00226 return read;
00227 }
00228
00229 }