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 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 0 : GenericHandler::GenericHandler(const std::string& file, const std::string& expectedRoot) :
39 0 : myParentHandler(nullptr),
40 0 : myParentIndicator(SUMO_TAG_NOTHING),
41 0 : myFileName(file),
42 0 : myExpectedRoot(expectedRoot), myNextSectionStart(-1, nullptr) {
43 0 : }
44 :
45 :
46 0 : GenericHandler::~GenericHandler() {
47 0 : delete myNextSectionStart.second;
48 0 : }
49 :
50 :
51 : void
52 0 : GenericHandler::setFileName(const std::string& name) {
53 0 : myFileName = name;
54 0 : }
55 :
56 :
57 : const std::string&
58 0 : GenericHandler::getFileName() const {
59 0 : return myFileName;
60 : }
61 :
62 :
63 : XMLCh*
64 0 : GenericHandler::convert(const std::string& name) const {
65 0 : int len = (int)name.length();
66 0 : XMLCh* ret = new XMLCh[len + 1];
67 : int i = 0;
68 0 : for (; i < len; i++) {
69 0 : ret[i] = (XMLCh) name[i];
70 : }
71 0 : ret[i] = 0;
72 0 : return ret;
73 : }
74 :
75 :
76 : void
77 0 : GenericHandler::startElement(const XMLCh* const /*uri*/,
78 : const XMLCh* const /*localname*/,
79 : const XMLCh* const qname,
80 : const XERCES_CPP_NAMESPACE::Attributes& attrs) {
81 0 : std::string name = StringUtils::transcode(qname);
82 0 : if (!myRootSeen && myExpectedRoot != "" && name != myExpectedRoot) {
83 0 : WRITE_WARNINGF(TL("Found root element '%' in file '%' (expected '%')."), name, getFileName(), myExpectedRoot);
84 : }
85 0 : myRootSeen = true;
86 : myCharactersVector.clear();
87 0 : const int element = convertTag(name);
88 0 : if (mySectionSeen && !mySectionOpen && element != mySection) {
89 0 : mySectionEnded = true;
90 0 : myNextSectionStart.first = element;
91 0 : myNextSectionStart.second = new SUMOSAXAttributesImpl_Xerces(attrs, {}, {}, name);
92 : return;
93 : }
94 0 : if (element == mySection) {
95 0 : mySectionSeen = true;
96 0 : mySectionOpen = true;
97 : }
98 0 : SUMOSAXAttributesImpl_Xerces na(attrs, {}, {}, name);
99 0 : if (element == SUMO_TAG_INCLUDE) {
100 0 : std::string file = na.getString(SUMO_ATTR_HREF);
101 0 : if (!FileHelpers::isAbsolute(file)) {
102 0 : file = FileHelpers::getConfigurationRelative(getFileName(), file);
103 : }
104 : //XMLSubSys::runParser(*this, file);
105 : } else {
106 0 : myStartElement(element, na);
107 : }
108 0 : }
109 :
110 :
111 : void
112 0 : GenericHandler::endElement(const XMLCh* const /*uri*/,
113 : const XMLCh* const /*localname*/,
114 : const XMLCh* const qname) {
115 0 : std::string name = StringUtils::transcode(qname);
116 0 : int element = convertTag(name);
117 : // collect characters
118 0 : if (myCharactersVector.size() != 0) {
119 : int len = 0;
120 0 : for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
121 0 : len += (int)myCharactersVector[i].length();
122 : }
123 0 : char* buf = new char[len + 1];
124 : int pos = 0;
125 0 : for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
126 0 : memcpy((unsigned char*) buf + pos, (unsigned char*) myCharactersVector[i].c_str(),
127 0 : sizeof(char)*myCharactersVector[i].length());
128 0 : pos += (int)myCharactersVector[i].length();
129 : }
130 0 : buf[pos] = 0;
131 :
132 : // call user handler
133 : try {
134 0 : myCharacters(element, buf);
135 0 : } catch (std::runtime_error&) {
136 0 : delete[] buf;
137 0 : throw;
138 0 : }
139 0 : delete[] buf;
140 : }
141 0 : if (element == mySection) {
142 0 : mySectionOpen = false;
143 : }
144 0 : if (element != SUMO_TAG_INCLUDE) {
145 0 : myEndElement(element);
146 0 : if (myParentHandler && myParentIndicator == element) {
147 : //XMLSubSys::setHandler(*myParentHandler);
148 0 : myParentIndicator = SUMO_TAG_NOTHING;
149 0 : myParentHandler = nullptr;
150 : }
151 : }
152 0 : }
153 :
154 :
155 : void
156 0 : GenericHandler::registerParent(const int tag, GenericHandler* handler) {
157 0 : myParentHandler = handler;
158 0 : myParentIndicator = tag;
159 : //XMLSubSys::setHandler(*this);
160 0 : }
161 :
162 :
163 : void
164 0 : GenericHandler::characters(const XMLCh* const chars, const XERCES3_SIZE_t length) {
165 0 : if (myCollectCharacterData) {
166 0 : myCharactersVector.push_back(StringUtils::transcode(chars, (int)length));
167 : }
168 0 : }
169 :
170 :
171 : int
172 0 : GenericHandler::convertTag(const std::string& tag) const {
173 : TagMap::const_iterator i = myTagMap.find(tag);
174 0 : if (i == myTagMap.end()) {
175 : return SUMO_TAG_NOTHING;
176 : }
177 0 : return (*i).second;
178 : }
179 :
180 :
181 : std::string
182 0 : GenericHandler::buildErrorMessage(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
183 0 : std::ostringstream buf;
184 0 : char* pMsg = XERCES_CPP_NAMESPACE::XMLString::transcode(exception.getMessage());
185 0 : buf << pMsg << std::endl;
186 0 : buf << " In file '" << getFileName() << "'" << std::endl;
187 0 : buf << " At line/column " << exception.getLineNumber() + 1
188 0 : << '/' << exception.getColumnNumber() << "." << std::endl;
189 0 : XERCES_CPP_NAMESPACE::XMLString::release(&pMsg);
190 0 : return buf.str();
191 0 : }
192 :
193 :
194 : void
195 0 : GenericHandler::warning(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
196 0 : WRITE_WARNING(buildErrorMessage(exception));
197 0 : }
198 :
199 :
200 : void
201 0 : GenericHandler::error(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
202 0 : throw ProcessError(buildErrorMessage(exception));
203 : }
204 :
205 :
206 : void
207 0 : GenericHandler::fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
208 0 : throw ProcessError(buildErrorMessage(exception));
209 : }
210 :
211 :
212 : void
213 0 : GenericHandler::myStartElement(int, const SUMOSAXAttributes&) {}
214 :
215 :
216 : void
217 0 : GenericHandler::myCharacters(int, const std::string&) {}
218 :
219 :
220 : void
221 0 : GenericHandler::myEndElement(int) {}
222 :
223 : void
224 0 : GenericHandler::callParentEnd(int element) {
225 0 : if (myParentHandler) {
226 0 : myParentHandler->myEndElement(element);
227 : }
228 0 : }
229 :
230 : /****************************************************************************/
|