Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GenericHandler.cpp
Go to the documentation of this file.
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/****************************************************************************/
18// A handler which converts occurring elements and attributes into strings
19/****************************************************************************/
20#include <config.h>
21
22#include <cassert>
28
29#include "GenericHandler.h"
31#include "XMLSubSys.h"
32
33
34// ===========================================================================
35// class definitions
36// ===========================================================================
37
38GenericHandler::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
49
50
51void
52GenericHandler::setFileName(const std::string& name) {
53 myFileName = name;
54}
55
56
57const std::string&
59 return myFileName;
60}
61
62
63XMLCh*
64GenericHandler::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
76void
77GenericHandler::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)) {
103 }
104 //XMLSubSys::runParser(*this, file);
105 } else {
106 myStartElement(element, na);
107 }
108}
109
110
111void
112GenericHandler::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);
149 myParentHandler = nullptr;
150 }
151 }
152}
153
154
155void
157 myParentHandler = handler;
158 myParentIndicator = tag;
159 //XMLSubSys::setHandler(*this);
160}
161
162
163void
164GenericHandler::characters(const XMLCh* const chars, const XERCES3_SIZE_t length) {
166 myCharactersVector.push_back(StringUtils::transcode(chars, (int)length));
167 }
168}
169
170
171int
172GenericHandler::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
181std::string
182GenericHandler::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
194void
195GenericHandler::warning(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
197}
198
199
200void
201GenericHandler::error(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
202 throw ProcessError(buildErrorMessage(exception));
203}
204
205
206void
207GenericHandler::fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
208 throw ProcessError(buildErrorMessage(exception));
209}
210
211
212void
214
215
216void
217GenericHandler::myCharacters(int, const std::string&) {}
218
219
220void
222
223void
225 if (myParentHandler) {
227 }
228}
229
230/****************************************************************************/
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:296
#define WRITE_WARNING(msg)
Definition MsgHandler.h:295
#define TL(string)
Definition MsgHandler.h:315
@ SUMO_TAG_INCLUDE
@ SUMO_TAG_NOTHING
invalid tag, must be the last one
@ SUMO_ATTR_HREF
static bool isAbsolute(const std::string &path)
Returns the information whether the given path is absolute.
static std::string getConfigurationRelative(const std::string &configPath, const std::string &path)
Returns the second path as a relative path to the first file.
A handler which converts occurring elements and attributes into enums.
void endElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname)
The inherited method called when a tag is being closed.
bool myCollectCharacterData
whether the reader should collect character data
bool mySectionEnded
whether the reader has already seen the end of the section
void fatalError(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-errors.
bool mySectionOpen
whether an element of the current section is open
void registerParent(const int tag, GenericHandler *handler)
Assigning a parent handler which is enabled when the specified tag is closed.
virtual ~GenericHandler()
Destructor.
bool myRootSeen
whether the reader has already seen the root element
virtual void myCharacters(int element, const std::string &chars)
Callback method for characters to implement by derived classes.
void callParentEnd(int element)
signal endElement to the parent handler (special case for MSCalibrator)
GenericHandler(const std::string &file, const std::string &expectedRoot="")
Constructor.
std::string myFileName
The name of the currently parsed file.
int mySection
The tag indicating the current section to parse.
const std::string & getFileName() const
returns the current file name
std::vector< std::string > myCharactersVector
A list of character strings obtained so far to build the complete characters string at the end.
int myParentIndicator
The tag indicating that control should be given back.
virtual void myEndElement(int element)
Callback method for a closing tag to implement by derived classes.
std::string buildErrorMessage(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Builds an error message.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Callback method for an opening tag to implement by derived classes.
std::pair< int, SUMOSAXAttributes * > myNextSectionStart
void error(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-errors.
int convertTag(const std::string &tag) const
Converts a tag from its string into its numerical representation.
XMLCh * convert(const std::string &name) const
converts from c++-string into unicode
void warning(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-warnings.
GenericHandler * myParentHandler
The handler to give control back to.
bool mySectionSeen
whether the reader has already seen the begin of the section
void setFileName(const std::string &name)
Sets the current file name.
std::string myExpectedRoot
The root element to expect, empty string disables the check.
void characters(const XMLCh *const chars, const XERCES3_SIZE_t length)
The inherited method called when characters occurred.
void startElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname, const XERCES_CPP_NAMESPACE::Attributes &attrs)
The inherited method called when a new tag opens.
Encapsulated SAX-Attributes.
Encapsulated Xerces-SAX-attributes.
std::string getString(int id, bool *isPresent=nullptr) const
Returns the string-value of the named (by its enum-value) attribute.
static std::string transcode(const XMLCh *const data)
converts a 0-terminated XMLCh* array (usually UTF-16, stemming from Xerces) into std::string in UTF-8