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 160252 : GenericSAXHandler::GenericSAXHandler(
40 : SequentialStringBijection::Entry* tags, int terminatorTag,
41 : SequentialStringBijection::Entry* attrs, int terminatorAttr,
42 160252 : const std::string& file, const std::string& expectedRoot)
43 160252 : : myParentHandler(nullptr), myParentIndicator(SUMO_TAG_NOTHING), myFileName(file),
44 480756 : myExpectedRoot(expectedRoot), myNextSectionStart(-1, nullptr) {
45 : int i = 0;
46 91314590 : while (tags[i].key != terminatorTag) {
47 91154338 : myTagMap.insert(TagMap::value_type(tags[i].str, tags[i].key));
48 91154338 : i++;
49 : }
50 : i = 0;
51 113422802 : while (attrs[i].key != terminatorAttr) {
52 : int key = attrs[i].key;
53 : assert(key >= 0);
54 227966944 : while (key >= (int)myPredefinedTags.size()) {
55 114704394 : myPredefinedTags.push_back(nullptr);
56 229408788 : myPredefinedTagsMML.push_back("");
57 : }
58 113262550 : myPredefinedTags[key] = convert(attrs[i].str);
59 113262550 : myPredefinedTagsMML[key] = attrs[i].str;
60 113262550 : i++;
61 : }
62 160252 : }
63 :
64 :
65 157303 : GenericSAXHandler::~GenericSAXHandler() {
66 112750213 : for (AttrMap::iterator i1 = myPredefinedTags.begin(); i1 != myPredefinedTags.end(); i1++) {
67 112592910 : delete[](*i1);
68 : }
69 157303 : delete myNextSectionStart.second;
70 314606 : }
71 :
72 :
73 : void
74 337449 : GenericSAXHandler::setFileName(const std::string& name) {
75 337449 : myFileName = name;
76 337449 : }
77 :
78 :
79 : const std::string&
80 999551 : GenericSAXHandler::getFileName() const {
81 999551 : return myFileName;
82 : }
83 :
84 :
85 : XMLCh*
86 113262550 : GenericSAXHandler::convert(const std::string& name) const {
87 113262550 : int len = (int)name.length();
88 113262550 : XMLCh* ret = new XMLCh[len + 1];
89 : int i = 0;
90 1332707092 : for (; i < len; i++) {
91 1219444542 : ret[i] = (XMLCh) name[i];
92 : }
93 113262550 : ret[i] = 0;
94 113262550 : return ret;
95 : }
96 :
97 :
98 : void
99 16865385 : GenericSAXHandler::startElement(const XMLCh* const /*uri*/,
100 : const XMLCh* const /*localname*/,
101 : const XMLCh* const qname,
102 : const XERCES_CPP_NAMESPACE::Attributes& attrs) {
103 16865385 : std::string name = StringUtils::transcode(qname);
104 16865385 : if (!myRootSeen && myExpectedRoot != "" && name != myExpectedRoot) {
105 1179 : WRITE_WARNINGF(TL("Found root element '%' in file '%' (expected '%')."), name, getFileName(), myExpectedRoot);
106 : }
107 16865385 : myRootSeen = true;
108 : myCharactersVector.clear();
109 16865385 : const int element = convertTag(name);
110 16865385 : 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 16865097 : if (element == mySection) {
117 365308 : mySectionSeen = true;
118 365308 : mySectionOpen = true;
119 : }
120 16865097 : SUMOSAXAttributesImpl_Xerces na(attrs, myPredefinedTags, myPredefinedTagsMML, name);
121 16865097 : 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 16864945 : myStartElement(element, na);
129 : }
130 16865097 : }
131 :
132 :
133 : void
134 16856617 : GenericSAXHandler::endElement(const XMLCh* const /*uri*/,
135 : const XMLCh* const /*localname*/,
136 : const XMLCh* const qname) {
137 16856617 : std::string name = StringUtils::transcode(qname);
138 16856617 : int element = convertTag(name);
139 : // collect characters
140 16856617 : 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 16856617 : if (element == mySection) {
164 365594 : mySectionOpen = false;
165 : }
166 16856617 : if (element != SUMO_TAG_INCLUDE) {
167 16856465 : myEndElement(element);
168 16855273 : if (myParentHandler && myParentIndicator == element) {
169 4661 : XMLSubSys::setHandler(*myParentHandler);
170 4661 : myParentIndicator = SUMO_TAG_NOTHING;
171 4661 : myParentHandler = nullptr;
172 : }
173 : }
174 16855425 : }
175 :
176 :
177 : void
178 4667 : GenericSAXHandler::registerParent(const int tag, GenericSAXHandler* handler) {
179 4667 : myParentHandler = handler;
180 4667 : myParentIndicator = tag;
181 4667 : XMLSubSys::setHandler(*this);
182 4667 : }
183 :
184 :
185 : void
186 19069389 : GenericSAXHandler::characters(const XMLCh* const chars,
187 : const XERCES3_SIZE_t length) {
188 19069389 : if (myCollectCharacterData) {
189 18838 : myCharactersVector.push_back(StringUtils::transcode(chars, (int)length));
190 : }
191 19069389 : }
192 :
193 :
194 : int
195 33722002 : GenericSAXHandler::convertTag(const std::string& tag) const {
196 : TagMap::const_iterator i = myTagMap.find(tag);
197 33722002 : if (i == myTagMap.end()) {
198 : return SUMO_TAG_NOTHING;
199 : }
200 33493364 : return (*i).second;
201 : }
202 :
203 :
204 : std::string
205 3594 : GenericSAXHandler::buildErrorMessage(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
206 3594 : std::ostringstream buf;
207 3594 : char* pMsg = XERCES_CPP_NAMESPACE::XMLString::transcode(exception.getMessage());
208 3594 : buf << pMsg << std::endl;
209 3594 : buf << TL(" In file '") << getFileName() << "'" << std::endl;
210 3594 : buf << TL(" At line/column ") << exception.getLineNumber() + 1
211 3594 : << '/' << exception.getColumnNumber() << "." << std::endl;
212 3594 : XERCES_CPP_NAMESPACE::XMLString::release(&pMsg);
213 3594 : return buf.str();
214 3594 : }
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 3524 : GenericSAXHandler::error(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
225 7048 : throw ProcessError(buildErrorMessage(exception));
226 : }
227 :
228 :
229 : void
230 70 : GenericSAXHandler::fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
231 140 : 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 65887 : GenericSAXHandler::myEndElement(int) {}
245 :
246 : void
247 952 : GenericSAXHandler::callParentEnd(int element) {
248 952 : if (myParentHandler) {
249 910 : myParentHandler->myEndElement(element);
250 : }
251 952 : }
252 :
253 : /****************************************************************************/
|