ATLAS Offline Software
Loading...
Searching...
No Matches
XMLCoreParser.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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
28/*
29 *
30 * XMLCoreFactory implementation
31 *
32 */
33
35 if (XMLCoreParserDebugger::debug ()){
36 std::cout << "XMLCoreFactory::~XMLCoreFactory> factory=" << this << std::endl;
37 }
38}
39
40void
42 if (XMLCoreParserDebugger::debug ()){
43 std::cout << "XMLCoreFactory::start> factory=" << this << std::endl;
44 }
45 do_start (parser, node);
46}
47
48void
50 if (XMLCoreParserDebugger::debug ()){
51 std::cout << "XMLCoreFactory::end>" << std::endl;
52 }
53 do_end (parser, node);
54}
55
56void
57XMLCoreFactory::comment (XMLCoreParser& parser, const std::string& comment) {
58 if (XMLCoreParserDebugger::debug ()){
59 std::cout << "XMLCoreFactory::comment>" << std::endl;
60 }
61 do_comment (parser,comment);
62}
63
64void
65XMLCoreFactory::do_start (XMLCoreParser& /*parser*/, const XMLCoreNode& /*node*/) {
66 if (XMLCoreParserDebugger::debug ()){
67 std::cout << "XMLCoreFactory::do_start>" << std::endl;
68 }
69}
70
71void
72XMLCoreFactory::do_end (XMLCoreParser& /*parser*/, const XMLCoreNode& /*node*/) {
73 if (XMLCoreParserDebugger::debug ()){
74 std::cout << "XMLCoreFactory::do_end>" << std::endl;
75 }
76}
77
78void
79XMLCoreFactory::do_comment (XMLCoreParser& /*parser*/, const std::string& /*comment*/) {
80 if (XMLCoreParserDebugger::debug ()){
81 std::cout << "XMLCoreFactory::do_comment>" << std::endl;
82 }
83}
84
85bool
86XMLCoreFactory::has_attribute (const XMLCoreNode& node, const std::string& name) {
87 return node.has_attrib (name);
88}
89
90int
91XMLCoreFactory::get_int (const XMLCoreNode& node, const std::string& name) {
92 int result = 0;
93 std::string s = get_value (node, name);
94 sscanf (s.c_str (), "%80d", &result);
95 return (result);
96}
97
98double
99XMLCoreFactory::get_double (const XMLCoreNode& node, const std::string& name) {
100 double result = 0;
101 std::string s = get_value (node, name);
102 sscanf (s.c_str (), "%80lg", &result);
103 return (result);
104}
105
106bool
107XMLCoreFactory::get_boolean (const XMLCoreNode& node, const std::string& name) {
108 bool result = false;
109 std::string s = get_token (node, name);
110 if (s == "TRUE") result = true;
111 return (result);
112}
113
114std::string XMLCoreFactory::get_ID (const XMLCoreNode& node, const std::string& name) {
115 std::string result = get_value (node, name);
116 return (result);
117}
118
119std::string
120XMLCoreFactory::get_value (const XMLCoreNode& node, const std::string& name) {
121 if (XMLCoreParserDebugger::debug ()){
122 std::cout << "XMLCoreFactory::get_value> name=" << name << std::endl;
123 }
124 std::string result;
125 if (node.has_attrib (name))
126 result = node.get_attrib (name);
127 if (XMLCoreParserDebugger::debug ()) {
128 std::cout << "XMLCoreFactory::get_value>2 value=" << result << std::endl;
129 }
130 return (result);
131}
132
133std::string
134XMLCoreFactory::get_token (const XMLCoreNode& node, const std::string& name) {
135 std::string result = get_value (node, name);
136 // trim the value
137 while ((result.length () > 0) &&
138 (result.at(0) == ' ')) result.erase (0, 1);
139
140 while ((result.length () > 0) &&
141 (result.at(result.length () - 1) == ' ')) result.erase (result.length () - 1, 1);
142 // Convert to upper case
143 for (std::string::size_type i = 0; i < result.length (); ++i){
144 result[i] = std::toupper (result[i]);
145 }
146 return (result);
147}
148
149
150bool
151XMLCoreFactory::check_int (const int n, const XMLCoreNode& node, const std::string& name) {
152 std::string checkstring = get_value (node, name);
153 int counter = 0;
154 //
155 // concatenate two times same string to
156 // check the last number of the string
157 // explicitly!
158 //
159 std::string t = checkstring + " " + checkstring;
160 std::istringstream tmpstr (t.c_str());
161 while (tmpstr.good ()) {
162 int ii;
163 counter++;
164 tmpstr >> ii;
165 }
166 if (counter/2 != n) {
167 std::cerr << "XMLCoreFactory::check_int error: no " << n
168 << " ints in \"" << checkstring << "\" for attribute " <<
169 name << ". exit." << std::endl;
170
171 std::string nodename = get_value (node, "name");
172 std::string volume = get_value (node, "volume");
173
174 if (nodename != "" ) std::cerr << "for name=" << nodename << std::endl;
175 if (volume != "" ) std::cerr << "for volume=" << volume << std::endl;
176
177 std::abort();
178 }
179 return true;
180}
181
182bool
183XMLCoreFactory::check_double (const int n, const XMLCoreNode& node, const std::string& name) {
184 std::string checkstring = get_value (node, name);
185 int counter = 0;
186 //
187 // concatenate two times same string to
188 // check the last number of the string
189 // explicitly!
190 //
191 std::string t = checkstring + " " + checkstring;
192 std::istringstream tmpstr (t.c_str());
193 while (tmpstr.good ()) {
194 double ii{};
195 counter++;
196 tmpstr >> ii;
197 }
198 if (counter/2 != n) {
199 std::cerr << "XMLCoreFactory::check_double error: (" << counter << ") no " << n
200 << " doubles in \"" << checkstring << "\" for attribute " <<
201 name << ". exit." << std::endl;
202 std::string name1 = get_value (node, "name");
203 std::string volume = get_value (node, "volume");
204 if (name1 != "" ) std::cerr << "for name=" << name << std::endl;
205 if (volume != "" ) std::cerr << "for volume=" << volume << std::endl;
206 std::abort();
207 }
208 return true;
209}
210
212};
213
214
215std::unique_ptr<XMLCoreNode>
216XMLCoreParser::parse (const std::string& file_name) {
217 m_level = 0;
218 std::unique_ptr<XMLCoreNode> doc = ExpatCoreParser::parse (file_name);
219 if (XMLCoreParserDebugger::debug ()){
220 if (doc != nullptr) doc->print ("============ ALL =============");
221 }
222 if (not doc){
223 throw std::runtime_error("XMLCoreParser: no such file ["+file_name+"]");
224 }
225 return doc;
226}
227
228std::unique_ptr<XMLCoreNode>
229XMLCoreParser::parse_string (const std::string& text) {
230 m_level = 0;
231 std::unique_ptr<XMLCoreNode> doc = ExpatCoreParser::parse_string (text);
232 if (XMLCoreParserDebugger::debug ()){
233 if (doc != nullptr) doc->print ("============ ALL =============");
234 }
235 if (not doc){
236 throw std::runtime_error("XMLCoreParser: cannot parse string");
237 }
238 return doc;
239}
240
241void
242XMLCoreParser::visit (const std::string& file_name) {
243 if (XMLCoreParserDebugger::debug ()){
244 std::cout << "XMLCoreParser::visit file_name "
245 << file_name << std::endl;
246 }
247 std::unique_ptr<XMLCoreNode> n = parse (file_name);
248 if (XMLCoreParserDebugger::debug ()){
249 std::cout << "XMLCoreParser::visit node=" << n.get() << std::endl;
250 }
251 visit (*n);
252}
253
254void
256 // Get the name and value out for convenience
257 const std::string& nodeName = node.get_name();
258 const std::string& nodeValue = node.get_value();
259 if (XMLCoreParserDebugger::debug ()){
260 std::cout << "XMLCoreParser::visit node(" << &node << ") " << nodeName << std::endl;
261 }
262 XMLCoreFactory* factory = find_factory (nodeName);
263 if (XMLCoreParserDebugger::debug ()){
264 std::cout << "XMLCoreParser::visit factory " << factory << std::endl;
265 }
266
267 switch (node.get_type()) {
269 std::vector<const XMLCoreNode*> children = node.get_children();
270 for (const XMLCoreNode* child : children) {
271 visit (*child);
272 }
273 break;
274 }
276 if (XMLCoreParserDebugger::debug ()){
277 std::cout << "XMLCoreParser::visit ELEMENT_NODE "
278 << " factory=" << factory
279 << std::endl;
280 }
281 if (factory != 0){
282 factory->start (*this, node);
283 } else {
284 std::cerr << "XMLCoreParser> Cannot find factory for element "
285 << nodeName << std::endl;
286 register_factory (nodeName, std::make_unique<DummyFactory>());
287 }
288 std::vector<const XMLCoreNode*> children = node.get_children();
289 for (const XMLCoreNode* child : children) {
290 visit (*child);
291 }
292 if (factory != 0) factory->end (*this, node);
293 break;
294 }
296 if (factory != 0) factory->comment (*this, nodeValue);
297 break;
298 }
300 std::cout << "ENTITY_NODE " << nodeValue << std::endl;
301 break;
302 }
304 std::cout << "ENTITY_REFERENCE_NODE " << nodeValue << std::endl;
305 break;
306 }
308 break;
309 default:
310 std::cerr << "Unrecognized node type = " << (long) node.get_type() << std::endl;
311 break;
312 }
313 if (XMLCoreParserDebugger::debug ()){
314 std::cout << "XMLCoreParser::visit-2" << std::endl;
315 }
316}
317
318void
319XMLCoreParser::register_default_factory (std::unique_ptr<XMLCoreFactory> factory) {
320 m_default_factory = std::move (factory);
321}
322
323void
324XMLCoreParser::register_factory (const std::string& name,
325 std::unique_ptr<XMLCoreFactory> factory) {
326 if (XMLCoreParserDebugger::debug ()){
327 std::cout << "XMLCoreFactory::register_factory> name=" << name
328 << " factory=" << factory.get() << std::endl;
329 }
330 m_factories[name] = std::move (factory);
331}
332
333void
334XMLCoreParser::register_external_entity (const std::string& name, const std::string& file_name){
335 if (XMLCoreParserDebugger::debug ()){
336 std::cout << "XMLCoreParser::register_external_entity> name=" << name
337 << " file_name=" << file_name << std::endl;
338 }
340}
341
342void
343XMLCoreParser::register_text_entity (const std::string& name, const std::string& text){
344 if (XMLCoreParserDebugger::debug ()){
345 std::cout << "XMLCoreParser::register_text_entity> name=" << name
346 << std::endl;
347 }
349}
350
351
353XMLCoreParser::find_factory (const std::string& name) {
354 FactoryMap::iterator it = m_factories.find (name);
355 if (it != m_factories.end ()) {
356 return (*it).second.get();
357 }
358 return m_default_factory.get();
359}
360
361
362void
364 m_level += 1;
365}
366
367
368void
370 m_level -= 1;
371}
372
373
374int
376 return m_level;
377}
const bool debug
static void register_text_entity(const std::string &name, const std::string &text)
static std::unique_ptr< XMLCoreNode > parse(const std::string &file_name)
static std::unique_ptr< XMLCoreNode > parse_string(const std::string &text)
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)
static bool has_attribute(const XMLCoreNode &node, const std::string &name)
virtual ~XMLCoreFactory()
virtual void do_end(XMLCoreParser &parser, const XMLCoreNode &node)
static double get_double(const XMLCoreNode &node, const std::string &name)
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)
Simple DOM-like node structure to hold the result of XML parsing.
Definition XMLCoreNode.h:45
@ ENTITY_REFERENCE_NODE
Definition XMLCoreNode.h:57
std::unique_ptr< XMLCoreFactory > m_default_factory
int level() const
std::unique_ptr< 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)
std::unique_ptr< XMLCoreNode > parse_string(const std::string &text)
void register_default_factory(std::unique_ptr< XMLCoreFactory > factory)
Definition node.h:24