File indexing completed on 2024-04-06 12:13:51
0001 #ifndef GeneratorInterface_LHEInterface_XMLUtils_h
0002 #define GeneratorInterface_LHEInterface_XMLUtils_h
0003
0004 #include <iostream>
0005 #include <string>
0006 #include <memory>
0007 #include <vector>
0008
0009 #include <xercesc/util/XMLString.hpp>
0010 #include <xercesc/util/XMLUni.hpp>
0011 #include <xercesc/util/XMLChar.hpp>
0012 #include <xercesc/util/BinInputStream.hpp>
0013 #include <xercesc/framework/XMLPScanToken.hpp>
0014 #include <xercesc/sax/InputSource.hpp>
0015 #include <xercesc/sax2/DefaultHandler.hpp>
0016 #include <xercesc/sax2/SAX2XMLReader.hpp>
0017 #include <lzma.h>
0018
0019 namespace edm::storage {
0020 class Storage;
0021 }
0022
0023 namespace lhef {
0024
0025 class StorageWrap {
0026 public:
0027 using Storage = edm::storage::Storage;
0028
0029 StorageWrap(std::unique_ptr<Storage> storage);
0030 ~StorageWrap();
0031
0032 Storage *operator->() { return storage.get(); }
0033 const Storage *operator->() const { return storage.get(); }
0034
0035 private:
0036 std::unique_ptr<Storage> storage;
0037 };
0038
0039 class XMLDocument {
0040 public:
0041 class Handler : public XERCES_CPP_NAMESPACE_QUALIFIER DefaultHandler {};
0042
0043 XMLDocument(std::unique_ptr<std::istream> &in, Handler &handler);
0044 XMLDocument(std::unique_ptr<StorageWrap> &in, Handler &handler);
0045 virtual ~XMLDocument();
0046
0047 bool parse();
0048
0049 static std::shared_ptr<void> platformHandle() { return std::make_shared<XercesPlatform>(); }
0050
0051 private:
0052 class XercesPlatform {
0053 public:
0054 XercesPlatform();
0055
0056 XercesPlatform(const XercesPlatform &orig) = delete;
0057 XercesPlatform &operator=(const XercesPlatform &orig) = delete;
0058 ~XercesPlatform();
0059
0060 private:
0061 static unsigned int instances;
0062 };
0063
0064 void init(Handler &handler);
0065
0066 std::unique_ptr<XercesPlatform> platform;
0067
0068 std::unique_ptr<XERCES_CPP_NAMESPACE_QUALIFIER InputSource> source;
0069 std::unique_ptr<XERCES_CPP_NAMESPACE_QUALIFIER SAX2XMLReader> parser;
0070
0071 XERCES_CPP_NAMESPACE_QUALIFIER XMLPScanToken token;
0072
0073 bool done;
0074 };
0075
0076 class XMLSimpleStr {
0077 public:
0078 XMLSimpleStr(const XMLCh *str) : string(XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(str)) {}
0079
0080 ~XMLSimpleStr() { XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&string); }
0081
0082 inline operator const char *() const { return string; }
0083
0084 inline static bool isAllSpaces(const XMLCh *str, unsigned int length) {
0085 return XERCES_CPP_NAMESPACE_QUALIFIER XMLChar1_0::isAllSpaces(str, length);
0086 }
0087
0088 inline static bool isSpace(XMLCh ch) { return XERCES_CPP_NAMESPACE_QUALIFIER XMLChar1_0::isWhitespace(ch); }
0089
0090 private:
0091 char *string;
0092 };
0093
0094 class XMLUniStr {
0095 public:
0096 XMLUniStr(const char *str) : unicode(XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(str)) {}
0097
0098 ~XMLUniStr() { XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&unicode); }
0099
0100 operator const XMLCh *() const { return unicode; }
0101
0102 private:
0103 XMLCh *unicode;
0104 };
0105
0106 template <typename T>
0107 class XMLInputSourceWrapper : public XERCES_CPP_NAMESPACE_QUALIFIER InputSource {
0108 public:
0109 typedef typename T::Stream_t Stream_t;
0110
0111 XMLInputSourceWrapper(std::unique_ptr<Stream_t> &obj) : obj(std::move(obj)) {}
0112 ~XMLInputSourceWrapper() override {}
0113
0114 XERCES_CPP_NAMESPACE_QUALIFIER BinInputStream *makeStream() const override { return new T(*obj); }
0115
0116 private:
0117 std::unique_ptr<Stream_t> obj;
0118 };
0119
0120 class CBInputStream : public XERCES_CPP_NAMESPACE_QUALIFIER BinInputStream {
0121 public:
0122 class Reader {
0123 public:
0124 virtual ~Reader();
0125 virtual const std::string &data() = 0;
0126 };
0127
0128 typedef Reader Stream_t;
0129
0130 CBInputStream(Reader &in);
0131 ~CBInputStream() override;
0132
0133 XMLFilePos curPos() const override { return pos; }
0134
0135 XMLSize_t readBytes(XMLByte *const buf, const XMLSize_t size) override;
0136
0137 const XMLCh *getContentType() const override { return nullptr; }
0138
0139 private:
0140 Reader &reader;
0141 std::string buffer;
0142 unsigned int pos;
0143 };
0144
0145 class STLInputStream : public XERCES_CPP_NAMESPACE_QUALIFIER BinInputStream {
0146 public:
0147 typedef std::istream Stream_t;
0148
0149 STLInputStream(std::istream &in);
0150 ~STLInputStream() override;
0151
0152 XMLFilePos curPos() const override { return pos; }
0153
0154 XMLSize_t readBytes(XMLByte *const buf, const XMLSize_t size) override;
0155
0156 const XMLCh *getContentType() const override { return nullptr; }
0157
0158 private:
0159 std::istream ∈
0160 unsigned int pos;
0161 };
0162
0163 class StorageInputStream : public XERCES_CPP_NAMESPACE_QUALIFIER BinInputStream {
0164 public:
0165 typedef StorageWrap Stream_t;
0166
0167 StorageInputStream(StorageWrap &in);
0168 ~StorageInputStream() override;
0169
0170 XMLFilePos curPos() const override { return pos; }
0171
0172 XMLSize_t readBytes(XMLByte *const buf, const XMLSize_t size) override;
0173
0174 const XMLCh *getContentType() const override { return nullptr; }
0175
0176 private:
0177 StorageWrap ∈
0178 unsigned int pos;
0179 lzma_stream lstr;
0180 bool compression_;
0181 unsigned int lasttotal_;
0182
0183 unsigned int buffLoc_ = 0, buffTotal_ = 0;
0184 std::vector<uint8_t> buffer_;
0185 static constexpr unsigned bufferSize_ = 16 * 1024 * 1024;
0186 };
0187
0188 typedef XMLInputSourceWrapper<CBInputStream> CBInputSource;
0189 typedef XMLInputSourceWrapper<STLInputStream> STLInputSource;
0190 typedef XMLInputSourceWrapper<StorageInputStream> StorageInputSource;
0191
0192 }
0193
0194 #endif