Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GenericSAXHandler.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/****************************************************************************/
21// A handler which converts occurring elements and attributes into enums
22/****************************************************************************/
23#include <config.h>
24
25#include <cassert>
26#include "GenericSAXHandler.h"
33#include "XMLSubSys.h"
34
35
36// ===========================================================================
37// class definitions
38// ===========================================================================
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
66 for (AttrMap::iterator i1 = myPredefinedTags.begin(); i1 != myPredefinedTags.end(); i1++) {
67 delete[](*i1);
68 }
69 delete myNextSectionStart.second;
70}
71
72
73void
74GenericSAXHandler::setFileName(const std::string& name) {
75 myFileName = name;
76}
77
78
79const std::string&
83
84
85XMLCh*
86GenericSAXHandler::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
98void
99GenericSAXHandler::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;
114 return;
115 }
116 if (element == mySection) {
117 mySectionSeen = true;
118 mySectionOpen = true;
119 }
121 if (element == SUMO_TAG_INCLUDE) {
122 std::string file = na.getString(SUMO_ATTR_HREF);
123 if (!FileHelpers::isAbsolute(file)) {
125 }
126 XMLSubSys::runParser(*this, file);
127 } else {
128 myStartElement(element, na);
129 }
130}
131
132
133void
134GenericSAXHandler::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) {
171 myParentHandler = nullptr;
172 }
173 }
174}
175
176
177void
179 myParentHandler = handler;
180 myParentIndicator = tag;
182}
183
184
185void
186GenericSAXHandler::characters(const XMLCh* const chars,
187 const XERCES3_SIZE_t length) {
189 myCharactersVector.push_back(StringUtils::transcode(chars, (int)length));
190 }
191}
192
193
194int
195GenericSAXHandler::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
204std::string
205GenericSAXHandler::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
217void
218GenericSAXHandler::warning(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
220}
221
222
223void
224GenericSAXHandler::error(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
225 throw ProcessError(buildErrorMessage(exception));
226}
227
228
229void
230GenericSAXHandler::fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
231 throw ProcessError(buildErrorMessage(exception));
232}
233
234
235void
237
238
239void
240GenericSAXHandler::myCharacters(int, const std::string&) {}
241
242
243void
245
246void
248 if (myParentHandler) {
250 }
251}
252
253/****************************************************************************/
#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 registerParent(const int tag, GenericSAXHandler *handler)
Assigning a parent handler which is enabled when the specified tag is closed.
virtual void myCharacters(int element, const std::string &chars)
Callback method for characters to implement by derived classes.
std::string buildErrorMessage(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Builds an error message.
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
GenericSAXHandler(SequentialStringBijection::Entry *tags, int terminatorTag, SequentialStringBijection::Entry *attrs, int terminatorAttr, const std::string &file, const std::string &expectedRoot="")
Constructor.
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.
bool mySectionEnded
whether the reader has already seen the end of the section
std::string myFileName
The name of the currently parsed file.
bool mySectionOpen
whether an element of the current section is open
void error(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-errors.
bool mySectionSeen
whether the reader has already seen the begin of the section
GenericSAXHandler * myParentHandler
The handler to give control back to.
int mySection
The tag indicating the current section to parse.
void setFileName(const std::string &name)
Sets the current file name.
int myParentIndicator
The tag indicating that control should be given back.
void characters(const XMLCh *const chars, const XERCES3_SIZE_t length)
The inherited method called when characters occurred.
virtual ~GenericSAXHandler()
Destructor.
virtual void myEndElement(int element)
Callback method for a closing tag to implement by derived classes.
void warning(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-warnings.
std::string myExpectedRoot
The root element to expect, empty string disables the check.
std::pair< int, SUMOSAXAttributes * > myNextSectionStart
void callParentEnd(int element)
signal endElement to the parent handler (special case for MSCalibrator)
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Callback method for an opening tag to implement by derived classes.
std::vector< std::string > myCharactersVector
A list of character strings obtained so far to build the complete characters string at the end.
void fatalError(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-errors.
bool myRootSeen
whether the reader has already seen the root element
bool myCollectCharacterData
whether the reader should collect character data
const std::string & getFileName() const
returns the current file name
std::vector< std::string > myPredefinedTagsMML
the map from ids to their string representation
void endElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname)
The inherited method called when a tag is being closed.
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
static void setHandler(GenericSAXHandler &handler)
Sets the given handler for the default reader.
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false, const bool isExternal=false, const bool catchExceptions=true)
Runs the given handler on the given file; returns if everything's ok.
int key
const char * str