CMS 3D CMS Logo

XMLUtils.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <memory>
3 #include <string>
4 #include <vector>
5 #include <cstring>
6 
8 #include <xercesc/util/XMLString.hpp>
9 #include <xercesc/util/XMLUni.hpp>
10 #include <xercesc/sax2/SAX2XMLReader.hpp>
11 #include <xercesc/sax2/XMLReaderFactory.hpp>
12 
15 
18 
19 #include "XMLUtils.h"
20 
22 
23 using namespace edm::storage;
24 namespace lhef {
25 
26  StorageWrap::StorageWrap(std::unique_ptr<Storage> storage) : storage(std::move(storage)) {}
27 
29 
31 
33  if (!instances++) {
34  try {
36  } catch (const XMLException &e) {
37  throw cms::Exception("XMLDocument") << "cms::concurrency::xercesInitialize failed "
38  "because of: "
39  << XMLSimpleStr(e.getMessage()) << std::endl;
40  }
41  }
42  }
43 
45  if (!--instances)
47  }
48 
49  XMLDocument::XMLDocument(std::unique_ptr<std::istream> &in, Handler &handler)
50  : platform(new XercesPlatform()),
51  source(new STLInputSource(in)),
52  parser(XMLReaderFactory::createXMLReader()),
53  done(false) {
54  init(handler);
55  }
56 
57  XMLDocument::XMLDocument(std::unique_ptr<StorageWrap> &in, Handler &handler)
58  : platform(new XercesPlatform()),
60  parser(XMLReaderFactory::createXMLReader()),
61  done(false) {
62  init(handler);
63  }
64 
65  void XMLDocument::init(Handler &handler) {
66  try {
67  parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
68  parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, false);
69  parser->setFeature(XMLUni::fgXercesSchema, false);
70  parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
71 
72  parser->setContentHandler(&handler);
73  parser->setLexicalHandler(&handler);
74  parser->setErrorHandler(&handler);
75 
76  if (!parser->parseFirst(*source, token))
77  throw cms::Exception("XMLParseError") << "SAXParser::parseFirst failed" << std::endl;
78  } catch (const XMLException &e) {
79  throw cms::Exception("XMLDocument")
80  << "cms::concurrency::xercesInitialize failed because of " << XMLSimpleStr(e.getMessage()) << std::endl;
81  } catch (const SAXException &e) {
82  throw cms::Exception("XMLDocument")
83  << "XML parser reported: " << XMLSimpleStr(e.getMessage()) << "." << std::endl;
84  }
85  }
86 
88 
90  try {
91  if (done || parser->getErrorCount())
92  return false;
93 
94  done = !parser->parseNext(token);
95  } catch (const XMLException &e) {
96  throw cms::Exception("XMLDocument")
97  << "cms::concurrency::xercesInitialize failed because of " << XMLSimpleStr(e.getMessage()) << std::endl;
98  } catch (const SAXException &e) {
99  throw cms::Exception("XMLDocument")
100  << "XML parser reported: " << XMLSimpleStr(e.getMessage()) << "." << std::endl;
101  }
102 
103  return !done;
104  }
105 
107 
109 
111 
112  XMLSize_t CBInputStream::readBytes(XMLByte *const buf, const XMLSize_t size) {
113  char *rawBuf = reinterpret_cast<char *>(buf);
114  unsigned int bytes = size * sizeof(XMLByte);
115  unsigned int read = 0;
116 
117  while (read < bytes) {
118  if (buffer.empty()) {
119  buffer = reader.data();
120  if (buffer.empty())
121  break;
122  }
123 
124  unsigned int len = buffer.length();
125  unsigned int rem = bytes - read;
126  if (rem < len) {
127  std::memcpy(rawBuf + read, buffer.c_str(), rem);
128  buffer.erase(0, rem);
129  read += rem;
130  break;
131  }
132 
133  std::memcpy(rawBuf + read, buffer.c_str(), len);
134  buffer.clear();
135  read += len;
136  }
137 
138  read /= sizeof(XMLByte);
139  pos += read;
140 
141  return read;
142  }
143 
145  if (in.bad())
146  throw cms::Exception("FileStreamError") << "I/O stream bad in STLInputStream::STLInputStream()" << std::endl;
147  }
148 
150 
151  XMLSize_t STLInputStream::readBytes(XMLByte *const buf, const XMLSize_t size) {
152  char *rawBuf = reinterpret_cast<char *>(buf);
153  unsigned int bytes = size * sizeof(XMLByte);
154  in.read(rawBuf, bytes);
155  unsigned int readBytes = in.gcount();
156 
157  if (in.bad())
158  throw cms::Exception("FileStreamError") << "I/O stream bad in STLInputStream::readBytes()" << std::endl;
159 
160  unsigned int read = (unsigned int)(readBytes / sizeof(XMLByte));
161  unsigned int rest = (unsigned int)(readBytes % sizeof(XMLByte));
162  for (unsigned int i = 1; i <= rest; i++)
163  in.putback(rawBuf[readBytes - i]);
164 
165  pos += read;
166  return read;
167  }
168 
170  : in(in), lstr(LZMA_STREAM_INIT), compression_(false), lasttotal_(0) {
171  buffer_.reserve(bufferSize_);
172  // Check the kind of file.
173  char header[6];
174  /*unsigned int s = */ in->read(header, 6);
175  in->position(0, Storage::SET);
176  // Let's use lzma to start with.
177  if (header[1] == '7' && header[2] == 'z' && header[3] == 'X' && header[4] == 'Z') {
178  compression_ = true;
179  lstr = LZMA_STREAM_INIT;
180  // We store the beginning of the outBuffer to make sure
181  // we can always update previous results.
182 
183 #if LZMA_VERSION <= UINT32_C(49990030)
184  int ret = lzma_auto_decoder(&lstr, NULL, NULL);
185 #else
186  int ret = lzma_auto_decoder(&lstr, -1, 0);
187 #endif
188 
189  if (ret != LZMA_OK) {
190  lzma_end(&lstr);
191  throw cms::Exception("IO") << "Error while reading compressed LHE file";
192  }
193  }
194  }
195 
197 
198  XMLSize_t StorageInputStream::readBytes(XMLByte *const buf, const XMLSize_t size) {
199  // Compression code is not able to handle sizeof(XMLByte) > 1.
200  assert(sizeof(XMLByte) == sizeof(unsigned char));
201 
202  if (!(buffLoc_ < buffTotal_)) {
203  int rd = in->read((void *)&buffer_[0], buffer_.capacity());
204  // Storage layer is supposed to throw exceptions instead of returning errors; just-in-case
205  if (rd < 0) {
207  ex << "Error while reading buffered LHE file";
208  throw ex;
209  }
210  buffLoc_ = 0;
211  buffTotal_ = rd;
212  if (buffTotal_ == 0) {
213  return 0;
214  }
215  }
216  unsigned int dataRead;
217  if (!compression_) {
218  dataRead = std::min(buffTotal_ - buffLoc_, static_cast<unsigned int>(size));
219  memcpy(buf, &buffer_[buffLoc_], dataRead);
220  buffLoc_ += dataRead;
221  } else {
222  dataRead = buffTotal_ - buffLoc_;
223  lstr.next_in = &buffer_[buffLoc_];
224  lstr.avail_in = dataRead;
225  lstr.next_out = buf;
226  lstr.avail_out = size;
227  int ret = lzma_code(&lstr, LZMA_RUN);
228  if (ret != LZMA_OK && ret != LZMA_STREAM_END) { /* decompression error */
229  lzma_end(&lstr);
230  throw cms::Exception("IO") << "Error while reading compressed LHE file (error code " << ret << ")";
231  }
232  dataRead -= lstr.avail_in;
233  buffLoc_ += dataRead;
234  // Decoder was unable to make progress; reset stream and try again.
235  // If this becomes problematic, we can make the buffer circular.
236  if (!dataRead) {
237  // NOTE: lstr.avail_in == buffTotal-buffLoc_
238  in->position(-(IOOffset)(lstr.avail_in), Storage::CURRENT);
239  buffLoc_ = 0;
240  buffTotal_ = 0;
241  return readBytes(buf, size);
242  }
243  dataRead = (size - lstr.avail_out);
244  }
245  return dataRead;
246  }
247 
248 } // namespace lhef
int64_t IOOffset
Definition: IOTypes.h:20
XMLSize_t readBytes(XMLByte *const buf, const XMLSize_t size) override
Definition: XMLUtils.cc:112
void init(Handler &handler)
Definition: XMLUtils.cc:65
StorageInputStream(StorageWrap &in)
Definition: XMLUtils.cc:169
std::string buffer
Definition: XMLUtils.h:141
ret
prodAgent to be discontinued
void xercesTerminate()
Definition: Xerces.cc:23
virtual ~XMLDocument()
Definition: XMLUtils.cc:87
virtual const std::string & data()=0
CBInputStream(Reader &in)
Definition: XMLUtils.cc:108
static unsigned int instances
Definition: XMLUtils.h:61
std::unique_ptr< XercesPlatform > platform
Definition: XMLUtils.h:66
#define NULL
Definition: scimark2.h:8
void xercesInitialize()
Definition: Xerces.cc:18
STLInputStream(std::istream &in)
Definition: XMLUtils.cc:144
assert(be >=bs)
std::istream & in
Definition: XMLUtils.h:159
XERCES_CPP_NAMESPACE_QUALIFIER XMLPScanToken token
Definition: XMLUtils.h:71
static constexpr unsigned bufferSize_
Definition: XMLUtils.h:185
std::unique_ptr< XERCES_CPP_NAMESPACE_QUALIFIER SAX2XMLReader > parser
Definition: XMLUtils.h:69
std::unique_ptr< XERCES_CPP_NAMESPACE_QUALIFIER InputSource > source
Definition: XMLUtils.h:68
XMLSize_t readBytes(XMLByte *const buf, const XMLSize_t size) override
Definition: XMLUtils.cc:198
StorageWrap & in
Definition: XMLUtils.h:177
unsigned int buffLoc_
Definition: XMLUtils.h:183
XMLDocument(std::unique_ptr< std::istream > &in, Handler &handler)
Definition: XMLUtils.cc:49
unsigned int buffTotal_
Definition: XMLUtils.h:183
~StorageInputStream() override
Definition: XMLUtils.cc:196
~STLInputStream() override
Definition: XMLUtils.cc:149
~CBInputStream() override
Definition: XMLUtils.cc:110
virtual IOOffset position() const
Definition: Storage.cc:504
std::unique_ptr< Storage > storage
Definition: XMLUtils.h:36
XMLSize_t readBytes(XMLByte *const buf, const XMLSize_t size) override
Definition: XMLUtils.cc:151
std::vector< uint8_t > buffer_
Definition: XMLUtils.h:184
TPlatform const & platform()
Definition: devices.h:14
static std::string const source
Definition: EdmProvDump.cc:49
def move(src, dest)
Definition: eostools.py:511