File indexing completed on 2023-10-25 09:48:37
0001 #include <iostream>
0002 #include <memory>
0003 #include <string>
0004 #include <vector>
0005 #include <cstring>
0006
0007 #include "Utilities/Xerces/interface/Xerces.h"
0008 #include <xercesc/util/XMLString.hpp>
0009 #include <xercesc/util/XMLUni.hpp>
0010 #include <xercesc/sax2/SAX2XMLReader.hpp>
0011 #include <xercesc/sax2/XMLReaderFactory.hpp>
0012
0013 #include "FWCore/Utilities/interface/Exception.h"
0014 #include "FWCore/Utilities/interface/EDMException.h"
0015
0016 #include "Utilities/StorageFactory/interface/IOTypes.h"
0017 #include "Utilities/StorageFactory/interface/Storage.h"
0018
0019 #include "XMLUtils.h"
0020
0021 XERCES_CPP_NAMESPACE_USE
0022
0023 using namespace edm::storage;
0024 namespace lhef {
0025
0026 StorageWrap::StorageWrap(std::unique_ptr<Storage> storage) : storage(std::move(storage)) {}
0027
0028 StorageWrap::~StorageWrap() { storage->close(); }
0029
0030 unsigned int XMLDocument::XercesPlatform::instances = 0;
0031
0032 XMLDocument::XercesPlatform::XercesPlatform() {
0033 if (!instances++) {
0034 try {
0035 cms::concurrency::xercesInitialize();
0036 } catch (const XMLException &e) {
0037 throw cms::Exception("XMLDocument") << "cms::concurrency::xercesInitialize failed "
0038 "because of: "
0039 << XMLSimpleStr(e.getMessage()) << std::endl;
0040 }
0041 }
0042 }
0043
0044 XMLDocument::XercesPlatform::~XercesPlatform() {
0045 if (!--instances)
0046 cms::concurrency::xercesTerminate();
0047 }
0048
0049 XMLDocument::XMLDocument(std::unique_ptr<std::istream> &in, Handler &handler)
0050 : platform(new XercesPlatform()),
0051 source(new STLInputSource(in)),
0052 parser(XMLReaderFactory::createXMLReader()),
0053 done(false) {
0054 init(handler);
0055 }
0056
0057 XMLDocument::XMLDocument(std::unique_ptr<StorageWrap> &in, Handler &handler)
0058 : platform(new XercesPlatform()),
0059 source(new StorageInputSource(in)),
0060 parser(XMLReaderFactory::createXMLReader()),
0061 done(false) {
0062 init(handler);
0063 }
0064
0065 void XMLDocument::init(Handler &handler) {
0066 try {
0067 parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
0068 parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, false);
0069 parser->setFeature(XMLUni::fgXercesSchema, false);
0070 parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
0071
0072 parser->setContentHandler(&handler);
0073 parser->setLexicalHandler(&handler);
0074 parser->setErrorHandler(&handler);
0075
0076 if (!parser->parseFirst(*source, token))
0077 throw cms::Exception("XMLParseError") << "SAXParser::parseFirst failed" << std::endl;
0078 } catch (const XMLException &e) {
0079 throw cms::Exception("XMLDocument")
0080 << "cms::concurrency::xercesInitialize failed because of " << XMLSimpleStr(e.getMessage()) << std::endl;
0081 } catch (const SAXException &e) {
0082 throw cms::Exception("XMLDocument")
0083 << "XML parser reported: " << XMLSimpleStr(e.getMessage()) << "." << std::endl;
0084 }
0085 }
0086
0087 XMLDocument::~XMLDocument() {}
0088
0089 bool XMLDocument::parse() {
0090 try {
0091 if (done || parser->getErrorCount())
0092 return false;
0093
0094 done = !parser->parseNext(token);
0095 } catch (const XMLException &e) {
0096 throw cms::Exception("XMLDocument")
0097 << "cms::concurrency::xercesInitialize failed because of " << XMLSimpleStr(e.getMessage()) << std::endl;
0098 } catch (const SAXException &e) {
0099 throw cms::Exception("XMLDocument")
0100 << "XML parser reported: " << XMLSimpleStr(e.getMessage()) << "." << std::endl;
0101 }
0102
0103 return !done;
0104 }
0105
0106 CBInputStream::Reader::~Reader() {}
0107
0108 CBInputStream::CBInputStream(Reader &reader) : reader(reader) {}
0109
0110 CBInputStream::~CBInputStream() {}
0111
0112 XMLSize_t CBInputStream::readBytes(XMLByte *const buf, const XMLSize_t size) {
0113 char *rawBuf = reinterpret_cast<char *>(buf);
0114 unsigned int bytes = size * sizeof(XMLByte);
0115 unsigned int read = 0;
0116
0117 while (read < bytes) {
0118 if (buffer.empty()) {
0119 buffer = reader.data();
0120 if (buffer.empty())
0121 break;
0122 }
0123
0124 unsigned int len = buffer.length();
0125 unsigned int rem = bytes - read;
0126 if (rem < len) {
0127 std::memcpy(rawBuf + read, buffer.c_str(), rem);
0128 buffer.erase(0, rem);
0129 read += rem;
0130 break;
0131 }
0132
0133 std::memcpy(rawBuf + read, buffer.c_str(), len);
0134 buffer.clear();
0135 read += len;
0136 }
0137
0138 read /= sizeof(XMLByte);
0139 pos += read;
0140
0141 return read;
0142 }
0143
0144 STLInputStream::STLInputStream(std::istream &in) : in(in) {
0145 if (in.bad())
0146 throw cms::Exception("FileStreamError") << "I/O stream bad in STLInputStream::STLInputStream()" << std::endl;
0147 }
0148
0149 STLInputStream::~STLInputStream() {}
0150
0151 XMLSize_t STLInputStream::readBytes(XMLByte *const buf, const XMLSize_t size) {
0152 char *rawBuf = reinterpret_cast<char *>(buf);
0153 unsigned int bytes = size * sizeof(XMLByte);
0154 in.read(rawBuf, bytes);
0155 unsigned int readBytes = in.gcount();
0156
0157 if (in.bad())
0158 throw cms::Exception("FileStreamError") << "I/O stream bad in STLInputStream::readBytes()" << std::endl;
0159
0160 unsigned int read = (unsigned int)(readBytes / sizeof(XMLByte));
0161 unsigned int rest = (unsigned int)(readBytes % sizeof(XMLByte));
0162 for (unsigned int i = 1; i <= rest; i++)
0163 in.putback(rawBuf[readBytes - i]);
0164
0165 pos += read;
0166 return read;
0167 }
0168
0169 StorageInputStream::StorageInputStream(StorageWrap &in)
0170 : in(in), lstr(LZMA_STREAM_INIT), compression_(false), lasttotal_(0) {
0171 buffer_.reserve(bufferSize_);
0172
0173 char header[6];
0174 in->read(header, 6);
0175 in->position(0, Storage::SET);
0176
0177 if (header[1] == '7' && header[2] == 'z' && header[3] == 'X' && header[4] == 'Z') {
0178 compression_ = true;
0179 lstr = LZMA_STREAM_INIT;
0180
0181
0182
0183 #if LZMA_VERSION <= UINT32_C(49990030)
0184 int ret = lzma_auto_decoder(&lstr, NULL, NULL);
0185 #else
0186 int ret = lzma_auto_decoder(&lstr, -1, 0);
0187 #endif
0188
0189 if (ret != LZMA_OK) {
0190 lzma_end(&lstr);
0191 throw cms::Exception("IO") << "Error while reading compressed LHE file";
0192 }
0193 }
0194 }
0195
0196 StorageInputStream::~StorageInputStream() { lzma_end(&(lstr)); }
0197
0198 XMLSize_t StorageInputStream::readBytes(XMLByte *const buf, const XMLSize_t size) {
0199
0200 assert(sizeof(XMLByte) == sizeof(unsigned char));
0201
0202 if (!(buffLoc_ < buffTotal_)) {
0203 int rd = in->read((void *)&buffer_[0], buffer_.capacity());
0204
0205 if (rd < 0) {
0206 edm::Exception ex(edm::errors::FileReadError);
0207 ex << "Error while reading buffered LHE file";
0208 throw ex;
0209 }
0210 buffLoc_ = 0;
0211 buffTotal_ = rd;
0212 if (buffTotal_ == 0) {
0213 return 0;
0214 }
0215 }
0216 unsigned int dataRead;
0217 if (!compression_) {
0218 dataRead = std::min(buffTotal_ - buffLoc_, static_cast<unsigned int>(size));
0219 memcpy(buf, &buffer_[buffLoc_], dataRead);
0220 buffLoc_ += dataRead;
0221 } else {
0222 dataRead = buffTotal_ - buffLoc_;
0223 lstr.next_in = &buffer_[buffLoc_];
0224 lstr.avail_in = dataRead;
0225 lstr.next_out = buf;
0226 lstr.avail_out = size;
0227 int ret = lzma_code(&lstr, LZMA_RUN);
0228 if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
0229 lzma_end(&lstr);
0230 throw cms::Exception("IO") << "Error while reading compressed LHE file (error code " << ret << ")";
0231 }
0232 dataRead -= lstr.avail_in;
0233 buffLoc_ += dataRead;
0234
0235
0236 if (!dataRead) {
0237
0238 in->position(-(IOOffset)(lstr.avail_in), Storage::CURRENT);
0239 buffLoc_ = 0;
0240 buffTotal_ = 0;
0241 return readBytes(buf, size);
0242 }
0243 dataRead = (size - lstr.avail_out);
0244 }
0245 return dataRead;
0246 }
0247
0248 }