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#include <format>
12
13namespace{
14 class XMLCoreParserDebugger{
15 public:
16 static bool get_debug_state(){
17 return ::getenv ("XMLDEBUG") != 0;
18 }
19 static bool debug (){
20 static const bool debug_state = get_debug_state();
21 return debug_state;
22 }
23 };
24}
25
26#include "ExpatCoreParser.h"
27
28
29/*
30 *
31 * XMLCoreFactory implementation
32 *
33 */
34
36 if (XMLCoreParserDebugger::debug ()){
37 std::cout << "XMLCoreFactory::~XMLCoreFactory> factory=" << this << std::endl;
38 }
39}
40
41void
43 if (XMLCoreParserDebugger::debug ()){
44 std::cout << "XMLCoreFactory::start> factory=" << this << std::endl;
45 }
46 do_start (parser, node);
47}
48
49void
51 if (XMLCoreParserDebugger::debug ()){
52 std::cout << "XMLCoreFactory::end>" << std::endl;
53 }
54 do_end (parser, node);
55}
56
57void
58XMLCoreFactory::comment (XMLCoreParser& parser, const std::string& comment) {
59 if (XMLCoreParserDebugger::debug ()){
60 std::cout << "XMLCoreFactory::comment>" << std::endl;
61 }
62 do_comment (parser,comment);
63}
64
65void
66XMLCoreFactory::do_start (XMLCoreParser& /*parser*/, const XMLCoreNode& /*node*/) {
67 if (XMLCoreParserDebugger::debug ()){
68 std::cout << "XMLCoreFactory::do_start>" << std::endl;
69 }
70}
71
72void
73XMLCoreFactory::do_end (XMLCoreParser& /*parser*/, const XMLCoreNode& /*node*/) {
74 if (XMLCoreParserDebugger::debug ()){
75 std::cout << "XMLCoreFactory::do_end>" << std::endl;
76 }
77}
78
79void
80XMLCoreFactory::do_comment (XMLCoreParser& /*parser*/, const std::string& /*comment*/) {
81 if (XMLCoreParserDebugger::debug ()){
82 std::cout << "XMLCoreFactory::do_comment>" << std::endl;
83 }
84}
85
86bool
87XMLCoreFactory::has_attribute (const XMLCoreNode& node, const std::string& name) {
88 return node.has_attrib (name);
89}
90
91int
92XMLCoreFactory::get_int (const XMLCoreNode& node, const std::string& name) {
93 int result = 0;
94 std::string s = get_value (node, name);
95 sscanf (s.c_str (), "%80d", &result);
96 return (result);
97}
98
99double
100XMLCoreFactory::get_double (const XMLCoreNode& node, const std::string& name) {
101 double result = 0;
102 std::string s = get_value (node, name);
103 sscanf (s.c_str (), "%80lg", &result);
104 return (result);
105}
106
107bool
108XMLCoreFactory::get_boolean (const XMLCoreNode& node, const std::string& name) {
109 bool result = false;
110 std::string s = get_token (node, name);
111 if (s == "TRUE") result = true;
112 return (result);
113}
114
115std::string XMLCoreFactory::get_ID (const XMLCoreNode& node, const std::string& name) {
116 std::string result = get_value (node, name);
117 return (result);
118}
119
120std::string
121XMLCoreFactory::get_value (const XMLCoreNode& node, const std::string& name) {
122 if (XMLCoreParserDebugger::debug ()){
123 std::cout << "XMLCoreFactory::get_value> name=" << name << std::endl;
124 }
125 std::string result;
126 if (node.has_attrib (name))
127 result = node.get_attrib (name);
128 if (XMLCoreParserDebugger::debug ()) {
129 std::cout << "XMLCoreFactory::get_value>2 value=" << result << std::endl;
130 }
131 return (result);
132}
133
134std::string
135XMLCoreFactory::get_token (const XMLCoreNode& node, const std::string& name) {
136 std::string result = get_value (node, name);
137 // trim the value
138 while ((result.length () > 0) &&
139 (result.at(0) == ' ')) result.erase (0, 1);
140
141 while ((result.length () > 0) &&
142 (result.at(result.length () - 1) == ' ')) result.erase (result.length () - 1, 1);
143 // Convert to upper case
144 for (std::string::size_type i = 0; i < result.length (); ++i){
145 result[i] = std::toupper (result[i]);
146 }
147 return (result);
148}
149
150
151bool
152XMLCoreFactory::check_int (const int n, const XMLCoreNode& node, const std::string& name) {
153 std::string checkstring = get_value (node, name);
154 int counter = 0;
155 //
156 // concatenate two times same string to
157 // check the last number of the string
158 // explicitly!
159 //
160 std::string t = checkstring + " " + checkstring;
161 std::istringstream tmpstr (t.c_str());
162 while (tmpstr.good ()) {
163 int ii;
164 counter++;
165 tmpstr >> ii;
166 }
167 if (counter/2 != n) {
168 std::cerr << "XMLCoreFactory::check_int error: no " << n
169 << " ints in \"" << checkstring << "\" for attribute " <<
170 name << ". exit." << std::endl;
171
172 std::string nodename = get_value (node, "name");
173 std::string volume = get_value (node, "volume");
174
175 if (nodename != "" ) std::cerr << "for name=" << nodename << std::endl;
176 if (volume != "" ) std::cerr << "for volume=" << volume << std::endl;
177
178 std::abort();
179 }
180 return true;
181}
182
183bool
184XMLCoreFactory::check_double (const int n, const XMLCoreNode& node, const std::string& name) {
185 std::string checkstring = get_value (node, name);
186 int counter = 0;
187 //
188 // concatenate two times same string to
189 // check the last number of the string
190 // explicitly!
191 //
192 std::string t = checkstring + " " + checkstring;
193 std::istringstream tmpstr (t.c_str());
194 while (tmpstr.good ()) {
195 double ii{};
196 counter++;
197 tmpstr >> ii;
198 }
199 if (counter/2 != n) {
200 std::cerr << "XMLCoreFactory::check_double error: (" << counter << ") no " << n
201 << " doubles in \"" << checkstring << "\" for attribute " <<
202 name << ". exit." << std::endl;
203 std::string name1 = get_value (node, "name");
204 std::string volume = get_value (node, "volume");
205 if (name1 != "" ) std::cerr << "for name=" << name << std::endl;
206 if (volume != "" ) std::cerr << "for volume=" << volume << std::endl;
207 std::abort();
208 }
209 return true;
210}
211
213};
214
215
216std::unique_ptr<XMLCoreNode>
217XMLCoreParser::parse (std::string_view file_name) {
218 m_level = 0;
219 std::unique_ptr<XMLCoreNode> doc = ExpatCoreParser::parse (file_name);
220 if (XMLCoreParserDebugger::debug ()){
221 if (doc != nullptr) doc->print ("============ ALL =============");
222 }
223 if (not doc){
224 throw std::runtime_error(std::format("XMLCoreParser: no such file [{}]", file_name));
225 }
226 return doc;
227}
228
229std::unique_ptr<XMLCoreNode>
230XMLCoreParser::parse_string (const std::string& text) {
231 m_level = 0;
232 std::unique_ptr<XMLCoreNode> doc = ExpatCoreParser::parse_string (text);
233 if (XMLCoreParserDebugger::debug ()){
234 if (doc != nullptr) doc->print ("============ ALL =============");
235 }
236 if (not doc){
237 throw std::runtime_error("XMLCoreParser: cannot parse string");
238 }
239 return doc;
240}
241
242void
243XMLCoreParser::visit (std::string_view file_name) {
244 if (XMLCoreParserDebugger::debug ()){
245 std::cout << std::format("XMLCoreParser::visit file_name {}\n", file_name);
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(std::string_view 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
FactoryMap m_factories
std::unique_ptr< XMLCoreNode > parse(std::string_view file_name)
void visit(std::string_view 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