ATLAS Offline Software
Loading...
Searching...
No Matches
XMLCoreParser.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <cstdio>
8#include <cstdlib>
9#include <sstream>
10#include <iostream>
11
12namespace{
13 class XMLCoreParserDebugger{
14 public:
15 static bool get_debug_state(){
16 return ::getenv ("XMLDEBUG") != 0;
17 }
18 static bool debug (){
19 static const bool debug_state = get_debug_state();
20 return debug_state;
21 }
22 };
23}
24
25#include "ExpatCoreParser.h"
26
27
29 if (this != &other) {
30 if (m_owns) delete m_node;
31 m_node = other.m_node;
32 m_owns = false;
33 }
34 return *this;
35}
36
38 if (this != &other) {
39 if (m_owns) delete m_node;
40 m_node = other.m_node;
41 m_owns = other.m_owns;
42 other.m_node = nullptr;
43 other.m_owns = false;
44 }
45 return *this;
46}
47
51
52
53/*
54 *
55 * XMLCoreFactory implementation
56 *
57 */
58
60 if (XMLCoreParserDebugger::debug ()){
61 std::cout << "XMLCoreFactory::~XMLCoreFactory> factory=" << this << std::endl;
62 }
63}
64
65void
67 if (XMLCoreParserDebugger::debug ()){
68 std::cout << "XMLCoreFactory::start> factory=" << this << std::endl;
69 }
70 do_start (parser, node);
71}
72
73void
75 if (XMLCoreParserDebugger::debug ()){
76 std::cout << "XMLCoreFactory::end>" << std::endl;
77 }
78 do_end (parser, node);
79}
80
81void
82XMLCoreFactory::comment (XMLCoreParser& parser, const std::string& comment) {
83 if (XMLCoreParserDebugger::debug ()){
84 std::cout << "XMLCoreFactory::comment>" << std::endl;
85 }
86 do_comment (parser,comment);
87}
88
89void
90XMLCoreFactory::do_start (XMLCoreParser& /*parser*/, const XMLCoreNode& /*node*/) {
91 if (XMLCoreParserDebugger::debug ()){
92 std::cout << "XMLCoreFactory::do_start>" << std::endl;
93 }
94}
95
96void
97XMLCoreFactory::do_end (XMLCoreParser& /*parser*/, const XMLCoreNode& /*node*/) {
98 if (XMLCoreParserDebugger::debug ()){
99 std::cout << "XMLCoreFactory::do_end>" << std::endl;
100 }
101}
102
103void
104XMLCoreFactory::do_comment (XMLCoreParser& /*parser*/, const std::string& /*comment*/) {
105 if (XMLCoreParserDebugger::debug ()){
106 std::cout << "XMLCoreFactory::do_comment>" << std::endl;
107 }
108}
109
110int
112 const CoreParser::DOMNamedNodeMap& attrs = node.get_node ().get_attributes();
113 return (attrs.size ());
114}
115
116bool
117XMLCoreFactory::has_attribute (const XMLCoreNode& node, const std::string& name) {
118 const CoreParser::DOMNamedNodeMap& attrs = node.get_node ().get_attributes();
119 CoreParser::DOMNamedNodeMap::const_iterator it = attrs.find (name);
120 if (it == attrs.end ()) return (false);
121 return (true);
122}
123
124int
125XMLCoreFactory::get_int (const XMLCoreNode& node, const std::string& name) {
126 int result = 0;
127 std::string s = get_value (node, name);
128 sscanf (s.c_str (), "%80d", &result);
129 return (result);
130}
131
132double
133XMLCoreFactory::get_double (const XMLCoreNode& node, const std::string& name) {
134 double result = 0;
135 std::string s = get_value (node, name);
136 sscanf (s.c_str (), "%80lg", &result);
137 return (result);
138}
139
140bool
141XMLCoreFactory::get_boolean (const XMLCoreNode& node, const std::string& name) {
142 bool result = false;
143 std::string s = get_token (node, name);
144 if (s == "TRUE") result = true;
145 return (result);
146}
147
148std::string XMLCoreFactory::get_ID (const XMLCoreNode& node, const std::string& name) {
149 std::string result = get_value (node, name);
150 return (result);
151}
152
153std::string
154XMLCoreFactory::get_value (const XMLCoreNode& node, const std::string& name) {
155 if (XMLCoreParserDebugger::debug ()){
156 std::cout << "XMLCoreFactory::get_value> name=" << name << std::endl;
157 }
158 const CoreParser::DOMNamedNodeMap& attrs = node.get_node ().get_attributes();
159 CoreParser::DOMNamedNodeMap::const_iterator it = attrs.find (name);
160 if (it == attrs.end ()) return ("");
161 std::string result = (*it).second;
162 if (XMLCoreParserDebugger::debug ()) {
163 std::cout << "XMLCoreFactory::get_value>2 value=" << result << std::endl;
164 }
165 return (result);
166}
167
168std::string
170 return node.get_node().get_name ();
171}
172
173int
175 return node.get_node ().sibling_number ();
176}
177
178std::string
180 const CoreParser::DOMNamedNodeMap& attrs = node.get_node ().get_attributes();
181 CoreParser::DOMNamedNodeMap::const_iterator it;
182 for (it = attrs.begin (); (index > 0) && (it != attrs.end ()); ++it){
183 --index;
184 }
185 if (it == attrs.end ()) return ("");
186 return it->first;
187}
188
189std::string
190XMLCoreFactory::get_token (const XMLCoreNode& node, const std::string& name) {
191 std::string result = get_value (node, name);
192 // trim the value
193 while ((result.length () > 0) &&
194 (result.at(0) == ' ')) result.erase (0, 1);
195
196 while ((result.length () > 0) &&
197 (result.at(result.length () - 1) == ' ')) result.erase (result.length () - 1, 1);
198 // Convert to upper case
199 for (std::string::size_type i = 0; i < result.length (); ++i){
200 result[i] = std::toupper (result[i]);
201 }
202 return (result);
203}
204
205
206bool
207XMLCoreFactory::check_int (const int n, const XMLCoreNode& node, const std::string& name) {
208 std::string checkstring = get_value (node, name);
209 int counter = 0;
210 //
211 // concatenate two times same string to
212 // check the last number of the string
213 // explicitly!
214 //
215 std::string t = checkstring + " " + checkstring;
216 std::istringstream tmpstr (t.c_str());
217 while (tmpstr.good ()) {
218 int ii;
219 counter++;
220 tmpstr >> ii;
221 }
222 if (counter/2 != n) {
223 std::cerr << "XMLCoreFactory::check_int error: no " << n
224 << " ints in \"" << checkstring << "\" for attribute " <<
225 name << ". exit." << std::endl;
226
227 std::string nodename = get_value (node, "name");
228 std::string volume = get_value (node, "volume");
229
230 if (nodename != "" ) std::cerr << "for name=" << nodename << std::endl;
231 if (volume != "" ) std::cerr << "for volume=" << volume << std::endl;
232
233 std::abort();
234 }
235 return true;
236}
237
238bool
239XMLCoreFactory::check_double (const int n, const XMLCoreNode& node, const std::string& name) {
240 std::string checkstring = get_value (node, name);
241 int counter = 0;
242 //
243 // concatenate two times same string to
244 // check the last number of the string
245 // explicitly!
246 //
247 std::string t = checkstring + " " + checkstring;
248 std::istringstream tmpstr (t.c_str());
249 while (tmpstr.good ()) {
250 double ii{};
251 counter++;
252 tmpstr >> ii;
253 }
254 if (counter/2 != n) {
255 std::cerr << "XMLCoreFactory::check_double error: (" << counter << ") no " << n
256 << " doubles in \"" << checkstring << "\" for attribute " <<
257 name << ". exit." << std::endl;
258 std::string name1 = get_value (node, "name");
259 std::string volume = get_value (node, "volume");
260 if (name1 != "" ) std::cerr << "for name=" << name << std::endl;
261 if (volume != "" ) std::cerr << "for volume=" << volume << std::endl;
262 std::abort();
263 }
264 return true;
265}
266
268};
269
270
272XMLCoreParser::parse (const std::string& file_name) {
273 m_level = 0;
274 std::unique_ptr<CoreParser::DOMNode> doc = ExpatCoreParser::parse (file_name);
275 if (XMLCoreParserDebugger::debug ()){
276 if (doc != nullptr) doc->print ("============ ALL =============");
277 }
278 if (not doc){
279 throw std::runtime_error("XMLCoreParser: no such file ["+file_name+"]");
280 }
281 return XMLCoreNode (std::move (doc));
282}
283
284void
285XMLCoreParser::visit (const std::string& file_name) {
286 if (XMLCoreParserDebugger::debug ()){
287 std::cout << "XMLCoreParser::visit file_name "
288 << file_name << std::endl;
289 }
290 XMLCoreNode n = parse (file_name);
291 if (XMLCoreParserDebugger::debug ()){
292 const CoreParser::DOMNode& node = n.get_node();
293 const CoreParser::DOMNode* nptr = &node;
294 std::cout << "XMLCoreParser::visit node=" << nptr << std::endl;
295 }
296 visit (n);
297}
298
299void
301 // Get the name and value out for convenience
302 const CoreParser::DOMNode& node = core_node.get_node ();
303 const CoreParser::DOMNode* nptr = &node;
304 const std::string& nodeName = node.get_name();
305 const std::string& nodeValue = node.get_value();
306 if (XMLCoreParserDebugger::debug ()){
307 std::cout << "XMLCoreParser::visit node(" << nptr << ") " << nodeName << std::endl;
308 }
309 XMLCoreFactory* factory = find_factory (nodeName);
310 if (XMLCoreParserDebugger::debug ()){
311 std::cout << "XMLCoreParser::visit factory " << factory << std::endl;
312 }
313
314 switch (node.get_type()) {
316 const CoreParser::DOMSiblings& siblings = node.get_siblings ();
317 for (const CoreParser::DOMNode* child : siblings) {
318 XMLCoreNode n (child);
319 visit (n);
320 }
321 break;
322 }
324 if (XMLCoreParserDebugger::debug ()){
325 std::cout << "XMLCoreParser::visit ELEMENT_NODE "
326 << " factory=" << factory
327 << std::endl;
328 }
329 if (factory != 0){
330 factory->start (*this, core_node);
331 } else {
332 std::cerr << "XMLCoreParser> Cannot find factory for element "
333 << nodeName << std::endl;
334 register_factory (nodeName, std::make_unique<DummyFactory>());
335 }
336 const CoreParser::DOMSiblings& siblings = node.get_siblings ();
337 for (const CoreParser::DOMNode* child : siblings) {
338 XMLCoreNode n (child);
339 visit (n);
340 }
341 if (factory != 0) factory->end (*this, core_node);
342 break;
343 }
345 if (factory != 0) factory->comment (*this, nodeValue);
346 break;
347 }
349 std::cout << "ENTITY_NODE " << nodeValue << std::endl;
350 break;
351 }
353 std::cout << "ENTITY_REFERENCE_NODE " << nodeValue << std::endl;
354 break;
355 }
356 default: {
357 std::cerr << "Unrecognized node type = " << (long) node.get_type() << std::endl;
358 break;
359 }
360 }
361 if (XMLCoreParserDebugger::debug ()){
362 std::cout << "XMLCoreParser::visit-2" << std::endl;
363 }
364}
365
366void
367XMLCoreParser::register_default_factory (std::unique_ptr<XMLCoreFactory> factory) {
368 m_default_factory = std::move (factory);
369}
370
371void
372XMLCoreParser::register_factory (const std::string& name,
373 std::unique_ptr<XMLCoreFactory> factory) {
374 if (XMLCoreParserDebugger::debug ()){
375 std::cout << "XMLCoreFactory::register_factory> name=" << name
376 << " factory=" << factory.get() << std::endl;
377 }
378 m_factories[name] = std::move (factory);
379}
380
381void
382XMLCoreParser::register_external_entity (const std::string& name, const std::string& file_name){
383 if (XMLCoreParserDebugger::debug ()){
384 std::cout << "XMLCoreParser::register_external_entity> name=" << name
385 << " file_name=" << file_name << std::endl;
386 }
388}
389
390void
391XMLCoreParser::register_text_entity (const std::string& name, const std::string& text){
392 if (XMLCoreParserDebugger::debug ()){
393 std::cout << "XMLCoreParser::register_text_entity> name=" << name
394 << std::endl;
395 }
397}
398
399
401XMLCoreParser::find_factory (const std::string& name) {
402 FactoryMap::iterator it = m_factories.find (name);
403 if (it != m_factories.end ()) {
404 return (*it).second.get();
405 }
406 return m_default_factory.get();
407}
408
409
410void
412 m_level += 1;
413}
414
415
416void
418 m_level -= 1;
419}
420
421
422int
424 return m_level;
425}
const bool debug
static void register_text_entity(const std::string &name, const std::string &text)
static std::unique_ptr< CoreParser::DOMNode > parse(const std::string &file_name)
static void register_external_entity(const std::string &name, const std::string &file_name)
virtual void do_comment(XMLCoreParser &parser, const std::string &comment)
virtual void do_start(XMLCoreParser &parser, const XMLCoreNode &node)
static std::string get_value(const XMLCoreNode &node, const std::string &name)
void end(XMLCoreParser &parser, const XMLCoreNode &node)
std::string get_name(const XMLCoreNode &node)
static bool has_attribute(const XMLCoreNode &node, const std::string &name)
virtual ~XMLCoreFactory()
virtual void do_end(XMLCoreParser &parser, const XMLCoreNode &node)
static int attribute_number(const XMLCoreNode &node)
static double get_double(const XMLCoreNode &node, const std::string &name)
int sibling_number(const XMLCoreNode &node)
static bool check_int(const int n, const XMLCoreNode &node, const std::string &name)
void comment(XMLCoreParser &parser, const std::string &comment)
static bool check_double(const int n, const XMLCoreNode &node, const std::string &name)
static int get_int(const XMLCoreNode &node, const std::string &name)
static std::string get_ID(const XMLCoreNode &node, const std::string &name)
void start(XMLCoreParser &parser, const XMLCoreNode &node)
static bool get_boolean(const XMLCoreNode &node, const std::string &name)
static std::string get_token(const XMLCoreNode &node, const std::string &name)
const CoreParser::DOMNode & get_node() const
const CoreParser::DOMNode * m_node
XMLCoreNode & operator=(const XMLCoreNode &other)
XMLCoreNode(const CoreParser::DOMNode *node)
std::unique_ptr< XMLCoreFactory > m_default_factory
int level() const
XMLCoreNode parse(const std::string &file_name)
FactoryMap m_factories
void visit(const std::string &file_name)
void register_factory(const std::string &name, std::unique_ptr< XMLCoreFactory > factory)
void register_text_entity(const std::string &name, const std::string &text)
void register_external_entity(const std::string &name, const std::string &file_name)
XMLCoreFactory * find_factory(const std::string &name)
void register_default_factory(std::unique_ptr< XMLCoreFactory > factory)
Definition node.h:24
std::vector< DOMNode * > DOMSiblings
Definition DOMNode.h:17
std::map< std::string, std::string > DOMNamedNodeMap
Definition DOMNode.h:16
Definition index.py:1