Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/xml/GenericHandler.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2002-2025 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file GenericHandler.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Dec 2022
17
///
18
// A handler which converts occurring elements and attributes into strings
19
/****************************************************************************/
20
#include <config.h>
21
22
#include <cassert>
23
#include <utils/common/StringUtils.h>
24
#include <utils/common/StringUtils.h>
25
#include <utils/common/FileHelpers.h>
26
#include <utils/common/MsgHandler.h>
27
#include <utils/common/ToString.h>
28
29
#include "GenericHandler.h"
30
#include "SUMOSAXAttributesImpl_Xerces.h"
31
#include "XMLSubSys.h"
32
33
34
// ===========================================================================
35
// class definitions
36
// ===========================================================================
37
38
GenericHandler::GenericHandler(const std::string& file, const std::string& expectedRoot) :
39
myParentHandler(nullptr),
40
myParentIndicator(SUMO_TAG_NOTHING),
41
myFileName(file),
42
myExpectedRoot(expectedRoot), myNextSectionStart(-1, nullptr) {
43
}
44
45
46
GenericHandler::~GenericHandler() {
47
delete myNextSectionStart.second;
48
}
49
50
51
void
52
GenericHandler::setFileName(const std::string& name) {
53
myFileName = name;
54
}
55
56
57
const std::string&
58
GenericHandler::getFileName() const {
59
return myFileName;
60
}
61
62
63
XMLCh*
64
GenericHandler::convert(const std::string& name) const {
65
int len = (int)name.length();
66
XMLCh* ret = new XMLCh[len + 1];
67
int i = 0;
68
for (; i < len; i++) {
69
ret[i] = (XMLCh) name[i];
70
}
71
ret[i] = 0;
72
return ret;
73
}
74
75
76
void
77
GenericHandler::startElement(const XMLCh* const /*uri*/,
78
const XMLCh* const /*localname*/,
79
const XMLCh* const qname,
80
const XERCES_CPP_NAMESPACE::Attributes& attrs) {
81
std::string name = StringUtils::transcode(qname);
82
if (!myRootSeen && myExpectedRoot != "" && name != myExpectedRoot) {
83
WRITE_WARNINGF(TL("Found root element '%' in file '%' (expected '%')."), name, getFileName(), myExpectedRoot);
84
}
85
myRootSeen = true;
86
myCharactersVector.clear();
87
const int element = convertTag(name);
88
if (mySectionSeen && !mySectionOpen && element != mySection) {
89
mySectionEnded = true;
90
myNextSectionStart.first = element;
91
myNextSectionStart.second = new SUMOSAXAttributesImpl_Xerces(attrs, {}, {}, name);
92
return;
93
}
94
if (element == mySection) {
95
mySectionSeen = true;
96
mySectionOpen = true;
97
}
98
SUMOSAXAttributesImpl_Xerces na(attrs, {}, {}, name);
99
if (element == SUMO_TAG_INCLUDE) {
100
std::string file = na.getString(SUMO_ATTR_HREF);
101
if (!FileHelpers::isAbsolute(file)) {
102
file = FileHelpers::getConfigurationRelative(getFileName(), file);
103
}
104
//XMLSubSys::runParser(*this, file);
105
} else {
106
myStartElement(element, na);
107
}
108
}
109
110
111
void
112
GenericHandler::endElement(const XMLCh* const /*uri*/,
113
const XMLCh* const /*localname*/,
114
const XMLCh* const qname) {
115
std::string name = StringUtils::transcode(qname);
116
int element = convertTag(name);
117
// collect characters
118
if (myCharactersVector.size() != 0) {
119
int len = 0;
120
for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
121
len += (int)myCharactersVector[i].length();
122
}
123
char* buf = new char[len + 1];
124
int pos = 0;
125
for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
126
memcpy((unsigned char*) buf + pos, (unsigned char*) myCharactersVector[i].c_str(),
127
sizeof(char)*myCharactersVector[i].length());
128
pos += (int)myCharactersVector[i].length();
129
}
130
buf[pos] = 0;
131
132
// call user handler
133
try {
134
myCharacters(element, buf);
135
} catch (std::runtime_error&) {
136
delete[] buf;
137
throw;
138
}
139
delete[] buf;
140
}
141
if (element == mySection) {
142
mySectionOpen = false;
143
}
144
if (element != SUMO_TAG_INCLUDE) {
145
myEndElement(element);
146
if (myParentHandler && myParentIndicator == element) {
147
//XMLSubSys::setHandler(*myParentHandler);
148
myParentIndicator = SUMO_TAG_NOTHING;
149
myParentHandler = nullptr;
150
}
151
}
152
}
153
154
155
void
156
GenericHandler::registerParent(const int tag, GenericHandler* handler) {
157
myParentHandler = handler;
158
myParentIndicator = tag;
159
//XMLSubSys::setHandler(*this);
160
}
161
162
163
void
164
GenericHandler::characters(const XMLCh* const chars, const XERCES3_SIZE_t length) {
165
if (myCollectCharacterData) {
166
myCharactersVector.push_back(StringUtils::transcode(chars, (int)length));
167
}
168
}
169
170
171
int
172
GenericHandler::convertTag(const std::string& tag) const {
173
TagMap::const_iterator i = myTagMap.find(tag);
174
if (i == myTagMap.end()) {
175
return SUMO_TAG_NOTHING;
176
}
177
return (*i).second;
178
}
179
180
181
std::string
182
GenericHandler::buildErrorMessage(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
183
std::ostringstream buf;
184
char* pMsg = XERCES_CPP_NAMESPACE::XMLString::transcode(exception.getMessage());
185
buf << pMsg << std::endl;
186
buf << " In file '" << getFileName() << "'" << std::endl;
187
buf << " At line/column " << exception.getLineNumber() + 1
188
<< '/' << exception.getColumnNumber() << "." << std::endl;
189
XERCES_CPP_NAMESPACE::XMLString::release(&pMsg);
190
return buf.str();
191
}
192
193
194
void
195
GenericHandler::warning(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
196
WRITE_WARNING(buildErrorMessage(exception));
197
}
198
199
200
void
201
GenericHandler::error(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
202
throw ProcessError(buildErrorMessage(exception));
203
}
204
205
206
void
207
GenericHandler::fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
208
throw ProcessError(buildErrorMessage(exception));
209
}
210
211
212
void
213
GenericHandler::myStartElement(int, const SUMOSAXAttributes&) {}
214
215
216
void
217
GenericHandler::myCharacters(int, const std::string&) {}
218
219
220
void
221
GenericHandler::myEndElement(int) {}
222
223
void
224
GenericHandler::callParentEnd(int element) {
225
if (myParentHandler) {
226
myParentHandler->myEndElement(element);
227
}
228
}
229
230
/****************************************************************************/
231
232