Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2002-2024 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 158628 : GenericSAXHandler::GenericSAXHandler(
40 : SequentialStringBijection::Entry* tags, int terminatorTag,
41 : SequentialStringBijection::Entry* attrs, int terminatorAttr,
42 158628 : const std::string& file, const std::string& expectedRoot)
43 158628 : : myParentHandler(nullptr), myParentIndicator(SUMO_TAG_NOTHING), myFileName(file),
44 475884 : myExpectedRoot(expectedRoot), myNextSectionStart(-1, nullptr) {
45 : int i = 0;
46 90388910 : while (tags[i].key != terminatorTag) {
47 90230282 : myTagMap.insert(TagMap::value_type(tags[i].str, tags[i].key));
48 90230282 : i++;
49 : }
50 : i = 0;
51 111321560 : while (attrs[i].key != terminatorAttr) {
52 : int key = attrs[i].key;
53 : assert(key >= 0);
54 223753092 : while (key >= (int)myPredefinedTags.size()) {
55 112590160 : myPredefinedTags.push_back(nullptr);
56 225180320 : myPredefinedTagsMML.push_back("");
57 : }
58 111162932 : myPredefinedTags[key] = convert(attrs[i].str);
59 111162932 : myPredefinedTagsMML[key] = attrs[i].str;
60 111162932 : i++;
61 : }
62 158628 : }
63 :
64 :
65 155850 : GenericSAXHandler::~GenericSAXHandler() {
66 110773630 : for (AttrMap::iterator i1 = myPredefinedTags.begin(); i1 != myPredefinedTags.end(); i1++) {
67 110617780 : delete[](*i1);
68 : }
69 155850 : delete myNextSectionStart.second;
70 311700 : }
71 :
72 :
73 : void
74 303876 : GenericSAXHandler::setFileName(const std::string& name) {
75 303876 : myFileName = name;
76 303876 : }
77 :
78 :
79 : const std::string&
80 960030 : GenericSAXHandler::getFileName() const {
81 960030 : return myFileName;
82 : }
83 :
84 :
85 : XMLCh*
86 111162932 : GenericSAXHandler::convert(const std::string& name) const {
87 111162932 : int len = (int)name.length();
88 111162932 : XMLCh* ret = new XMLCh[len + 1];
89 : int i = 0;
90 1306193886 : for (; i < len; i++) {
91 1195030954 : ret[i] = (XMLCh) name[i];
92 : }
93 111162932 : ret[i] = 0;
94 111162932 : return ret;
95 : }
96 :
97 :
98 : void
99 16695135 : GenericSAXHandler::startElement(const XMLCh* const /*uri*/,
100 : const XMLCh* const /*localname*/,
101 : const XMLCh* const qname,
102 : const XERCES_CPP_NAMESPACE::Attributes& attrs) {
103 16695135 : std::string name = StringUtils::transcode(qname);
104 16695135 : if (!myRootSeen && myExpectedRoot != "" && name != myExpectedRoot) {
105 1172 : WRITE_WARNINGF(TL("Found root element '%' in file '%' (expected '%')."), name, getFileName(), myExpectedRoot);
106 : }
107 16695135 : myRootSeen = true;
108 : myCharactersVector.clear();
109 16695135 : const int element = convertTag(name);
110 16695135 : if (mySectionSeen && !mySectionOpen && element != mySection) {
111 288 : mySectionEnded = true;
112 288 : myNextSectionStart.first = element;
113 288 : myNextSectionStart.second = new SUMOSAXAttributesImpl_Xerces(attrs, myPredefinedTags, myPredefinedTagsMML, name);
114 : return;
115 : }
116 16694847 : if (element == mySection) {
117 365308 : mySectionSeen = true;
118 365308 : mySectionOpen = true;
119 : }
120 16694847 : SUMOSAXAttributesImpl_Xerces na(attrs, myPredefinedTags, myPredefinedTagsMML, name);
121 16694847 : if (element == SUMO_TAG_INCLUDE) {
122 152 : std::string file = na.getString(SUMO_ATTR_HREF);
123 152 : if (!FileHelpers::isAbsolute(file)) {
124 304 : file = FileHelpers::getConfigurationRelative(getFileName(), file);
125 : }
126 152 : XMLSubSys::runParser(*this, file);
127 : } else {
128 16694695 : myStartElement(element, na);
129 : }
130 16694847 : }
131 :
132 :
133 : void
134 16686550 : GenericSAXHandler::endElement(const XMLCh* const /*uri*/,
135 : const XMLCh* const /*localname*/,
136 : const XMLCh* const qname) {
137 16686550 : std::string name = StringUtils::transcode(qname);
138 16686550 : int element = convertTag(name);
139 : // collect characters
140 16686550 : if (myCharactersVector.size() != 0) {
141 : int len = 0;
142 8081 : for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
143 4704 : len += (int)myCharactersVector[i].length();
144 : }
145 3377 : char* buf = new char[len + 1];
146 : int pos = 0;
147 8081 : for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
148 4704 : memcpy((unsigned char*) buf + pos, (unsigned char*) myCharactersVector[i].c_str(),
149 4704 : sizeof(char)*myCharactersVector[i].length());
150 4704 : pos += (int)myCharactersVector[i].length();
151 : }
152 3377 : buf[pos] = 0;
153 :
154 : // call user handler
155 : try {
156 3377 : myCharacters(element, buf);
157 0 : } catch (std::runtime_error&) {
158 0 : delete[] buf;
159 0 : throw;
160 0 : }
161 3377 : delete[] buf;
162 : }
163 16686550 : if (element == mySection) {
164 365594 : mySectionOpen = false;
165 : }
166 16686550 : if (element != SUMO_TAG_INCLUDE) {
167 16686398 : myEndElement(element);
168 16685220 : if (myParentHandler && myParentIndicator == element) {
169 4500 : XMLSubSys::setHandler(*myParentHandler);
170 4500 : myParentIndicator = SUMO_TAG_NOTHING;
171 4500 : myParentHandler = nullptr;
172 : }
173 : }
174 16685372 : }
175 :
176 :
177 : void
178 4506 : GenericSAXHandler::registerParent(const int tag, GenericSAXHandler* handler) {
179 4506 : myParentHandler = handler;
180 4506 : myParentIndicator = tag;
181 4506 : XMLSubSys::setHandler(*this);
182 4506 : }
183 :
184 :
185 : void
186 18924463 : GenericSAXHandler::characters(const XMLCh* const chars,
187 : const XERCES3_SIZE_t length) {
188 18924463 : if (myCollectCharacterData) {
189 18838 : myCharactersVector.push_back(StringUtils::transcode(chars, (int)length));
190 : }
191 18924463 : }
192 :
193 :
194 : int
195 33381685 : GenericSAXHandler::convertTag(const std::string& tag) const {
196 : TagMap::const_iterator i = myTagMap.find(tag);
197 33381685 : if (i == myTagMap.end()) {
198 : return SUMO_TAG_NOTHING;
199 : }
200 33185406 : return (*i).second;
201 : }
202 :
203 :
204 : std::string
205 3432 : GenericSAXHandler::buildErrorMessage(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
206 3432 : std::ostringstream buf;
207 3432 : char* pMsg = XERCES_CPP_NAMESPACE::XMLString::transcode(exception.getMessage());
208 3432 : buf << pMsg << std::endl;
209 3432 : buf << TL(" In file '") << getFileName() << "'" << std::endl;
210 3432 : buf << TL(" At line/column ") << exception.getLineNumber() + 1
211 3432 : << '/' << exception.getColumnNumber() << "." << std::endl;
212 3432 : XERCES_CPP_NAMESPACE::XMLString::release(&pMsg);
213 3432 : return buf.str();
214 3432 : }
215 :
216 :
217 : void
218 0 : GenericSAXHandler::warning(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
219 0 : WRITE_WARNING(buildErrorMessage(exception));
220 0 : }
221 :
222 :
223 : void
224 3363 : GenericSAXHandler::error(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
225 6726 : throw ProcessError(buildErrorMessage(exception));
226 : }
227 :
228 :
229 : void
230 69 : GenericSAXHandler::fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
231 138 : throw ProcessError(buildErrorMessage(exception));
232 : }
233 :
234 :
235 : void
236 0 : GenericSAXHandler::myStartElement(int, const SUMOSAXAttributes&) {}
237 :
238 :
239 : void
240 0 : GenericSAXHandler::myCharacters(int, const std::string&) {}
241 :
242 :
243 : void
244 64425 : GenericSAXHandler::myEndElement(int) {}
245 :
246 : void
247 862 : GenericSAXHandler::callParentEnd(int element) {
248 862 : if (myParentHandler) {
249 820 : myParentHandler->myEndElement(element);
250 : }
251 862 : }
252 :
253 : /****************************************************************************/
|