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 namespace lhef {
24 
25 StorageWrap::StorageWrap(std::unique_ptr<Storage> storage) :
26  storage(std::move(storage))
27 {
28 }
29 
31 {
32  storage->close();
33 }
34 
36 
38 {
39  if (!instances++) {
40  try {
42  } catch(const XMLException &e) {
43  throw cms::Exception("XMLDocument")
44  << "cms::concurrency::xercesInitialize failed "
45  "because of: "
46  << XMLSimpleStr(e.getMessage()) << std::endl;
47  }
48  }
49 }
50 
52 {
53  if (!--instances)
55 }
56 
57 XMLDocument::XMLDocument(std::auto_ptr<std::istream> &in, Handler &handler) :
58  platform(new XercesPlatform()),
59  source(new STLInputSource(in)),
60  parser(XMLReaderFactory::createXMLReader()),
61  done(false)
62 {
63  init(handler);
64 }
65 
66 XMLDocument::XMLDocument(std::auto_ptr<StorageWrap> &in, Handler &handler) :
67  platform(new XercesPlatform()),
68  source(new StorageInputSource(in)),
69  parser(XMLReaderFactory::createXMLReader()),
70  done(false)
71 {
72  init(handler);
73 }
74 
75 void XMLDocument::init(Handler &handler)
76 {
77  try {
78  parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
79  parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, false);
80  parser->setFeature(XMLUni::fgXercesSchema, false);
81  parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
82 
83  parser->setContentHandler(&handler);
84  parser->setLexicalHandler(&handler);
85  parser->setErrorHandler(&handler);
86 
87  if (!parser->parseFirst(*source, token))
88  throw cms::Exception("XMLParseError")
89  << "SAXParser::parseFirst failed" << std::endl;
90  } catch(const XMLException &e) {
91  throw cms::Exception("XMLDocument")
92  << "cms::concurrency::xercesInitialize failed because of "
93  << XMLSimpleStr(e.getMessage()) << std::endl;
94  } catch(const SAXException &e) {
95  throw cms::Exception("XMLDocument")
96  << "XML parser reported: "
97  << XMLSimpleStr(e.getMessage()) << "." << std::endl;
98  }
99 }
100 
102 {
103 }
104 
106 {
107  try {
108  if (done || parser->getErrorCount())
109  return false;
110 
111  done = !parser->parseNext(token);
112  } catch(const XMLException &e) {
113  throw cms::Exception("XMLDocument")
114  << "cms::concurrency::xercesInitialize failed because of "
115  << XMLSimpleStr(e.getMessage()) << std::endl;
116  } catch(const SAXException &e) {
117  throw cms::Exception("XMLDocument")
118  << "XML parser reported: "
119  << XMLSimpleStr(e.getMessage()) << "." << std::endl;
120  }
121 
122  return !done;
123 }
124 
126 {
127 }
128 
130  reader(reader)
131 {
132 }
133 
135 {
136 }
137 
138 XMLSize_t CBInputStream::readBytes(XMLByte* const buf,
139  const XMLSize_t size)
140 {
141  char *rawBuf = reinterpret_cast<char*>(buf);
142  unsigned int bytes = size * sizeof(XMLByte);
143  unsigned int read = 0;
144 
145  while(read < bytes) {
146  if (buffer.empty()) {
147  buffer = reader.data();
148  if (buffer.empty())
149  break;
150  }
151 
152  unsigned int len = buffer.length();
153  unsigned int rem = bytes - read;
154  if (rem < len) {
155  std::memcpy(rawBuf + read, buffer.c_str(), rem);
156  buffer.erase(0, rem);
157  read += rem;
158  break;
159  }
160 
161  std::memcpy(rawBuf + read, buffer.c_str(), len);
162  buffer.clear();
163  read += len;
164  }
165 
166  read /= sizeof(XMLByte);
167  pos += read;
168 
169  return read;
170 }
171 
173  in(in)
174 {
175  if (in.bad())
176  throw cms::Exception("FileStreamError")
177  << "I/O stream bad in STLInputStream::STLInputStream()"
178  << std::endl;
179 }
180 
182 {
183 }
184 
185 XMLSize_t STLInputStream::readBytes(XMLByte* const buf,
186  const XMLSize_t size)
187 {
188  char *rawBuf = reinterpret_cast<char*>(buf);
189  unsigned int bytes = size * sizeof(XMLByte);
190  in.read(rawBuf, bytes);
191  unsigned int readBytes = in.gcount();
192 
193  if (in.bad())
194  throw cms::Exception("FileStreamError")
195  << "I/O stream bad in STLInputStream::readBytes()"
196  << std::endl;
197 
198  unsigned int read = (unsigned int)(readBytes / sizeof(XMLByte));
199  unsigned int rest = (unsigned int)(readBytes % sizeof(XMLByte));
200  for(unsigned int i = 1; i <= rest; i++)
201  in.putback(rawBuf[readBytes - i]);
202 
203  pos += read;
204  return read;
205 }
206 
208  in(in),
209  lstr(LZMA_STREAM_INIT),
210  compression_(false),
211  lasttotal_(0)
212 {
213  buffer_.reserve(bufferSize_);
214  // Check the kind of file.
215  char header[6];
216  /*unsigned int s = */ in->read(header, 6);
217  in->position(0, Storage::SET);
218  // Let's use lzma to start with.
219  if (header[1] == '7'
220  && header[2] == 'z'
221  && header[3] == 'X'
222  && header[4] == 'Z')
223  {
224  compression_ = true;
225  lstr = LZMA_STREAM_INIT;
226  // We store the beginning of the outBuffer to make sure
227  // we can always update previous results.
228 
229 #if LZMA_VERSION <= UINT32_C(49990030)
230  int ret = lzma_auto_decoder(&lstr, NULL, NULL);
231 #else
232  int ret = lzma_auto_decoder(&lstr, -1, 0);
233 #endif
234 
235  if (ret != LZMA_OK)
236  {
237  lzma_end(&lstr);
238  throw cms::Exception("IO") << "Error while reading compressed LHE file";
239  }
240  }
241 }
242 
244 {
245  lzma_end(&(lstr));
246 }
247 
248 
249 XMLSize_t StorageInputStream::readBytes(XMLByte* const buf, const XMLSize_t size)
250 {
251  // Compression code is not able to handle sizeof(XMLByte) > 1.
252  assert(sizeof(XMLByte) == sizeof(unsigned char));
253 
254  if (! (buffLoc_ < buffTotal_) )
255  {
256  int rd = in->read((void*)&buffer_[0], buffer_.capacity());
257  // Storage layer is supposed to throw exceptions instead of returning errors; just-in-case
258  if (rd < 0)
259  {
261  ex << "Error while reading buffered LHE file";
262  throw ex;
263  }
264  buffLoc_=0;
265  buffTotal_=rd;
266  if (buffTotal_ == 0)
267  {
268  return 0;
269  }
270  }
271  unsigned int dataRead;
272  if (!compression_)
273  {
274  dataRead = std::min(buffTotal_-buffLoc_, static_cast<unsigned int>(size));
275  memcpy(buf, &buffer_[buffLoc_], dataRead);
276  buffLoc_ += dataRead;
277  }
278  else
279  {
280  dataRead = buffTotal_-buffLoc_;
281  lstr.next_in = &buffer_[buffLoc_];
282  lstr.avail_in = dataRead;
283  lstr.next_out = buf;
284  lstr.avail_out = size;
285  int ret = lzma_code(&lstr, LZMA_RUN);
286  if(ret != LZMA_OK && ret != LZMA_STREAM_END)
287  { /* decompression error */
288  lzma_end(&lstr);
289  throw cms::Exception("IO") << "Error while reading compressed LHE file (error code " << ret << ")";
290  }
291  dataRead -= lstr.avail_in;
292  buffLoc_ += dataRead;
293  // Decoder was unable to make progress; reset stream and try again.
294  // If this becomes problematic, we can make the buffer circular.
295  if (!dataRead)
296  {
297  // NOTE: lstr.avail_in == buffTotal-buffLoc_
298  in->position(-(IOOffset)(lstr.avail_in), Storage::CURRENT);
299  buffLoc_ = 0;
300  buffTotal_ = 0;
301  return readBytes(buf, size);
302  }
303  dataRead = (size - lstr.avail_out);
304  }
305  return dataRead;
306 }
307 
308 } // namespace lhef
size
Write out results.
virtual XMLSize_t readBytes(XMLByte *const buf, const XMLSize_t size) override
Definition: XMLUtils.cc:138
std::auto_ptr< XERCES_CPP_NAMESPACE_QUALIFIER SAX2XMLReader > parser
Definition: XMLUtils.h:64
void init(Handler &handler)
Definition: XMLUtils.cc:75
virtual IOSize read(void *into, IOSize n, IOOffset pos)
Definition: Storage.cc:17
StorageWrap(std::unique_ptr< Storage > storage)
Definition: XMLUtils.cc:25
std::auto_ptr< XERCES_CPP_NAMESPACE_QUALIFIER InputSource > source
Definition: XMLUtils.h:63
StorageInputStream(StorageWrap &in)
Definition: XMLUtils.cc:207
std::string buffer
Definition: XMLUtils.h:149
void xercesTerminate()
Definition: Xerces.cc:23
virtual ~XMLDocument()
Definition: XMLUtils.cc:101
std::auto_ptr< XercesPlatform > platform
Definition: XMLUtils.h:61
virtual const std::string & data()=0
CBInputStream(Reader &in)
Definition: XMLUtils.cc:129
#define NULL
Definition: scimark2.h:8
virtual ~StorageInputStream()
Definition: XMLUtils.cc:243
XMLDocument(std::auto_ptr< std::istream > &in, Handler &handler)
Definition: XMLUtils.cc:57
virtual ~STLInputStream()
Definition: XMLUtils.cc:181
void xercesInitialize()
Definition: Xerces.cc:18
STLInputStream(std::istream &in)
Definition: XMLUtils.cc:172
virtual XMLSize_t readBytes(XMLByte *const buf, const XMLSize_t size) override
Definition: XMLUtils.cc:185
std::istream & in
Definition: XMLUtils.h:168
XERCES_CPP_NAMESPACE_QUALIFIER XMLPScanToken token
Definition: XMLUtils.h:66
virtual IOOffset position(void) const
Definition: Storage.cc:95
static constexpr unsigned bufferSize_
Definition: XMLUtils.h:196
T min(T a, T b)
Definition: MathUtil.h:58
virtual XMLSize_t readBytes(XMLByte *const buf, const XMLSize_t size) override
Definition: XMLUtils.cc:249
StorageWrap & in
Definition: XMLUtils.h:188
unsigned int buffLoc_
Definition: XMLUtils.h:194
int64_t IOOffset
Definition: IOTypes.h:19
unsigned int buffTotal_
Definition: XMLUtils.h:194
std::unique_ptr< Storage > storage
Definition: XMLUtils.h:32
static unsigned int instances
Definition: XMLUtils.h:56
std::vector< uint8_t > buffer_
Definition: XMLUtils.h:195
virtual ~CBInputStream()
Definition: XMLUtils.cc:134
static std::string const source
Definition: EdmProvDump.cc:43
def move(src, dest)
Definition: eostools.py:510