Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/xml/GenericSAXHandler.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 GenericSAXHandler.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @author Laura Bieker
19
/// @date Sept 2002
20
///
21
// A handler which converts occurring elements and attributes into enums
22
/****************************************************************************/
23
#include <config.h>
24
25
#include <cassert>
26
#include "GenericSAXHandler.h"
27
#include <utils/common/StringUtils.h>
28
#include <utils/common/StringUtils.h>
29
#include <utils/common/FileHelpers.h>
30
#include <utils/common/MsgHandler.h>
31
#include <utils/common/ToString.h>
32
#include "SUMOSAXAttributesImpl_Xerces.h"
33
#include "XMLSubSys.h"
34
35
36
// ===========================================================================
37
// class definitions
38
// ===========================================================================
39
GenericSAXHandler::GenericSAXHandler(
40
SequentialStringBijection::Entry* tags, int terminatorTag,
41
SequentialStringBijection::Entry* attrs, int terminatorAttr,
42
const std::string& file, const std::string& expectedRoot)
43
: myParentHandler(nullptr), myParentIndicator(SUMO_TAG_NOTHING), myFileName(file),
44
myExpectedRoot(expectedRoot), myNextSectionStart(-1, nullptr) {
45
int i = 0;
46
while (tags[i].key != terminatorTag) {
47
myTagMap.insert(TagMap::value_type(tags[i].str, tags[i].key));
48
i++;
49
}
50
i = 0;
51
while (attrs[i].key != terminatorAttr) {
52
int key = attrs[i].key;
53
assert(key >= 0);
54
while (key >= (int)myPredefinedTags.size()) {
55
myPredefinedTags.push_back(nullptr);
56
myPredefinedTagsMML.push_back("");
57
}
58
myPredefinedTags[key] = convert(attrs[i].str);
59
myPredefinedTagsMML[key] = attrs[i].str;
60
i++;
61
}
62
}
63
64
65
GenericSAXHandler::~GenericSAXHandler() {
66
for (AttrMap::iterator i1 = myPredefinedTags.begin(); i1 != myPredefinedTags.end(); i1++) {
67
delete[](*i1);
68
}
69
delete myNextSectionStart.second;
70
}
71
72
73
void
74
GenericSAXHandler::setFileName(const std::string& name) {
75
myFileName = name;
76
}
77
78
79
const std::string&
80
GenericSAXHandler::getFileName() const {
81
return myFileName;
82
}
83
84
85
XMLCh*
86
GenericSAXHandler::convert(const std::string& name) const {
87
int len = (int)name.length();
88
XMLCh* ret = new XMLCh[len + 1];
89
int i = 0;
90
for (; i < len; i++) {
91
ret[i] = (XMLCh) name[i];
92
}
93
ret[i] = 0;
94
return ret;
95
}
96
97
98
void
99
GenericSAXHandler::startElement(const XMLCh* const /*uri*/,
100
const XMLCh* const /*localname*/,
101
const XMLCh* const qname,
102
const XERCES_CPP_NAMESPACE::Attributes& attrs) {
103
std::string name = StringUtils::transcode(qname);
104
if (!myRootSeen && myExpectedRoot != "" && name != myExpectedRoot) {
105
WRITE_WARNINGF(TL("Found root element '%' in file '%' (expected '%')."), name, getFileName(), myExpectedRoot);
106
}
107
myRootSeen = true;
108
myCharactersVector.clear();
109
const int element = convertTag(name);
110
if (mySectionSeen && !mySectionOpen && element != mySection) {
111
mySectionEnded = true;
112
myNextSectionStart.first = element;
113
myNextSectionStart.second = new SUMOSAXAttributesImpl_Xerces(attrs, myPredefinedTags, myPredefinedTagsMML, name);
114
return;
115
}
116
if (element == mySection) {
117
mySectionSeen = true;
118
mySectionOpen = true;
119
}
120
SUMOSAXAttributesImpl_Xerces na(attrs, myPredefinedTags, myPredefinedTagsMML, name);
121
if (element == SUMO_TAG_INCLUDE) {
122
std::string file = na.getString(SUMO_ATTR_HREF);
123
if (!FileHelpers::isAbsolute(file)) {
124
file = FileHelpers::getConfigurationRelative(getFileName(), file);
125
}
126
XMLSubSys::runParser(*this, file);
127
} else {
128
myStartElement(element, na);
129
}
130
}
131
132
133
void
134
GenericSAXHandler::endElement(const XMLCh* const /*uri*/,
135
const XMLCh* const /*localname*/,
136
const XMLCh* const qname) {
137
std::string name = StringUtils::transcode(qname);
138
int element = convertTag(name);
139
// collect characters
140
if (myCharactersVector.size() != 0) {
141
int len = 0;
142
for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
143
len += (int)myCharactersVector[i].length();
144
}
145
char* buf = new char[len + 1];
146
int pos = 0;
147
for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
148
memcpy((unsigned char*) buf + pos, (unsigned char*) myCharactersVector[i].c_str(),
149
sizeof(char)*myCharactersVector[i].length());
150
pos += (int)myCharactersVector[i].length();
151
}
152
buf[pos] = 0;
153
154
// call user handler
155
try {
156
myCharacters(element, buf);
157
} catch (std::runtime_error&) {
158
delete[] buf;
159
throw;
160
}
161
delete[] buf;
162
}
163
if (element == mySection) {
164
mySectionOpen = false;
165
}
166
if (element != SUMO_TAG_INCLUDE) {
167
myEndElement(element);
168
if (myParentHandler && myParentIndicator == element) {
169
XMLSubSys::setHandler(*myParentHandler);
170
myParentIndicator = SUMO_TAG_NOTHING;
171
myParentHandler = nullptr;
172
}
173
}
174
}
175
176
177
void
178
GenericSAXHandler::registerParent(const int tag, GenericSAXHandler* handler) {
179
myParentHandler = handler;
180
myParentIndicator = tag;
181
XMLSubSys::setHandler(*this);
182
}
183
184
185
void
186
GenericSAXHandler::characters(const XMLCh* const chars,
187
const XERCES3_SIZE_t length) {
188
if (myCollectCharacterData) {
189
myCharactersVector.push_back(StringUtils::transcode(chars, (int)length));
190
}
191
}
192
193
194
int
195
GenericSAXHandler::convertTag(const std::string& tag) const {
196
TagMap::const_iterator i = myTagMap.find(tag);
197
if (i == myTagMap.end()) {
198
return SUMO_TAG_NOTHING;
199
}
200
return (*i).second;
201
}
202
203
204
std::string
205
GenericSAXHandler::buildErrorMessage(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
206
std::ostringstream buf;
207
char* pMsg = XERCES_CPP_NAMESPACE::XMLString::transcode(exception.getMessage());
208
buf << pMsg << std::endl;
209
buf << TL(" In file '") << getFileName() << "'" << std::endl;
210
buf << TL(" At line/column ") << exception.getLineNumber() + 1
211
<< '/' << exception.getColumnNumber() << "." << std::endl;
212
XERCES_CPP_NAMESPACE::XMLString::release(&pMsg);
213
return buf.str();
214
}
215
216
217
void
218
GenericSAXHandler::warning(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
219
WRITE_WARNING(buildErrorMessage(exception));
220
}
221
222
223
void
224
GenericSAXHandler::error(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
225
throw ProcessError(buildErrorMessage(exception));
226
}
227
228
229
void
230
GenericSAXHandler::fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
231
throw ProcessError(buildErrorMessage(exception));
232
}
233
234
235
void
236
GenericSAXHandler::myStartElement(int, const SUMOSAXAttributes&) {}
237
238
239
void
240
GenericSAXHandler::myCharacters(int, const std::string&) {}
241
242
243
void
244
GenericSAXHandler::myEndElement(int) {}
245
246
void
247
GenericSAXHandler::callParentEnd(int element) {
248
if (myParentHandler) {
249
myParentHandler->myEndElement(element);
250
}
251
}
252
253
/****************************************************************************/
254
255