Eclipse SUMO - Simulation of Urban MObility
GenericSAXHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2002-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // A handler which converts occuring elements and attributes into enums
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <cassert>
27 #include "GenericSAXHandler.h"
32 #include <utils/common/ToString.h>
34 #include "XMLSubSys.h"
35 
36 
37 // ===========================================================================
38 // class definitions
39 // ===========================================================================
41  StringBijection<int>::Entry* tags, int terminatorTag,
42  StringBijection<int>::Entry* attrs, int terminatorAttr,
43  const std::string& file, const std::string& expectedRoot)
44  : myParentHandler(nullptr), myParentIndicator(SUMO_TAG_NOTHING), myFileName(file), myExpectedRoot(expectedRoot), mySchemaSeen(false) {
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  assert(myPredefinedTags.find(attrs[i].key) == myPredefinedTags.end());
53  myPredefinedTags[attrs[i].key] = convert(attrs[i].str);
54  myPredefinedTagsMML[attrs[i].key] = attrs[i].str;
55  i++;
56  }
57 }
58 
59 
61  for (AttrMap::iterator i1 = myPredefinedTags.begin(); i1 != myPredefinedTags.end(); i1++) {
62  delete[](*i1).second;
63  }
64 }
65 
66 
67 void
68 GenericSAXHandler::setFileName(const std::string& name) {
69  myFileName = name;
70 }
71 
72 
73 const std::string&
75  return myFileName;
76 }
77 
78 
79 XMLCh*
80 GenericSAXHandler::convert(const std::string& name) const {
81  int len = (int)name.length();
82  XMLCh* ret = new XMLCh[len + 1];
83  int i = 0;
84  for (; i < len; i++) {
85  ret[i] = (XMLCh) name[i];
86  }
87  ret[i] = 0;
88  return ret;
89 }
90 
91 
92 void
93 GenericSAXHandler::startElement(const XMLCh* const /*uri*/,
94  const XMLCh* const /*localname*/,
95  const XMLCh* const qname,
96  const XERCES_CPP_NAMESPACE::Attributes& attrs) {
97  std::string name = StringUtils::transcode(qname);
98  if (mySchemaSeen && myExpectedRoot != "") {
99  if (name != myExpectedRoot) {
100  throw ProcessError("Found root element '" + name + "' in file '" + getFileName() + "' (expected '" + myExpectedRoot + "').");
101  }
102  mySchemaSeen = false;
103  }
104  int element = convertTag(name);
105  myCharactersVector.clear();
107  if (element == SUMO_TAG_INCLUDE) {
108  std::string file = na.getString(SUMO_ATTR_HREF);
109  if (!FileHelpers::isAbsolute(file)) {
111  }
112  XMLSubSys::runParser(*this, file);
113  } else {
114  myStartElement(element, na);
115  }
116 }
117 
118 
119 void
120 GenericSAXHandler::endElement(const XMLCh* const /*uri*/,
121  const XMLCh* const /*localname*/,
122  const XMLCh* const qname) {
123  std::string name = StringUtils::transcode(qname);
124  int element = convertTag(name);
125  // collect characters
126  if (myCharactersVector.size() != 0) {
127  int len = 0;
128  for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
129  len += (int)myCharactersVector[i].length();
130  }
131  char* buf = new char[len + 1];
132  int pos = 0;
133  for (int i = 0; i < (int)myCharactersVector.size(); ++i) {
134  memcpy((unsigned char*) buf + pos, (unsigned char*) myCharactersVector[i].c_str(),
135  sizeof(char)*myCharactersVector[i].length());
136  pos += (int)myCharactersVector[i].length();
137  }
138  buf[pos] = 0;
139 
140  // call user handler
141  try {
142  myCharacters(element, buf);
143  } catch (std::runtime_error&) {
144  delete[] buf;
145  throw;
146  }
147  delete[] buf;
148  }
149  if (element != SUMO_TAG_INCLUDE) {
150  myEndElement(element);
151  if (myParentHandler && myParentIndicator == element) {
154  myParentHandler = nullptr;
155  }
156  }
157 }
158 
159 
160 void
162  myParentHandler = handler;
163  myParentIndicator = tag;
164  XMLSubSys::setHandler(*this);
165 }
166 
167 
168 void
169 GenericSAXHandler::characters(const XMLCh* const chars,
170  const XERCES3_SIZE_t length) {
171  myCharactersVector.push_back(StringUtils::transcode(chars, (int)length));
172 }
173 
174 
175 int
176 GenericSAXHandler::convertTag(const std::string& tag) const {
177  TagMap::const_iterator i = myTagMap.find(tag);
178  if (i == myTagMap.end()) {
179  return SUMO_TAG_NOTHING;
180  }
181  return (*i).second;
182 }
183 
184 
185 std::string
186 GenericSAXHandler::buildErrorMessage(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
187  std::ostringstream buf;
188  char* pMsg = XERCES_CPP_NAMESPACE::XMLString::transcode(exception.getMessage());
189  buf << pMsg << std::endl;
190  buf << " In file '" << getFileName() << "'" << std::endl;
191  buf << " At line/column " << exception.getLineNumber() + 1
192  << '/' << exception.getColumnNumber() << "." << std::endl;
193  XERCES_CPP_NAMESPACE::XMLString::release(&pMsg);
194  return buf.str();
195 }
196 
197 
198 void
199 GenericSAXHandler::warning(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
200  WRITE_WARNING(buildErrorMessage(exception));
201 }
202 
203 
204 void
205 GenericSAXHandler::error(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
206  throw ProcessError(buildErrorMessage(exception));
207 }
208 
209 
210 void
211 GenericSAXHandler::fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception) {
212  throw ProcessError(buildErrorMessage(exception));
213 }
214 
215 
216 void
218 
219 
220 void
221 GenericSAXHandler::myCharacters(int, const std::string&) {}
222 
223 
224 void
226 
227 
228 /****************************************************************************/
229 
GenericSAXHandler.h
GenericSAXHandler::registerParent
void registerParent(const int tag, GenericSAXHandler *handler)
Assigning a parent handler which is enabled when the specified tag is closed.
Definition: GenericSAXHandler.cpp:161
ToString.h
XMLSubSys::runParser
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:112
GenericSAXHandler::warning
void warning(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-warnings.
Definition: GenericSAXHandler.cpp:199
WRITE_WARNING
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:275
GenericSAXHandler::myCharacters
virtual void myCharacters(int element, const std::string &chars)
Callback method for characters to implement by derived classes.
Definition: GenericSAXHandler.cpp:221
GenericSAXHandler::fatalError
void fatalError(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-errors.
Definition: GenericSAXHandler.cpp:211
MsgHandler.h
FileHelpers::getConfigurationRelative
static std::string getConfigurationRelative(const std::string &configPath, const std::string &path)
Returns the second path as a relative path to the first file.
Definition: FileHelpers.cpp:115
SUMOSAXAttributesImpl_Xerces
Encapsulated Xerces-SAX-attributes.
Definition: SUMOSAXAttributesImpl_Xerces.h:45
FileHelpers.h
XERCES3_SIZE_t
#define XERCES3_SIZE_t
Definition: config.h:216
XMLSubSys::setHandler
static void setHandler(GenericSAXHandler &handler)
Sets the given handler for the default reader.
Definition: XMLSubSys.cpp:106
GenericSAXHandler::myStartElement
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Callback method for an opening tag to implement by derived classes.
Definition: GenericSAXHandler.cpp:217
SUMOSAXAttributesImpl_Xerces.h
SUMO_TAG_NOTHING
@ SUMO_TAG_NOTHING
invalid tag
Definition: SUMOXMLDefinitions.h:43
GenericSAXHandler::mySchemaSeen
bool mySchemaSeen
whether the reader has already seen a schema
Definition: GenericSAXHandler.h:321
GenericSAXHandler::myPredefinedTagsMML
std::map< int, std::string > myPredefinedTagsMML
the map from ids to their string representation
Definition: GenericSAXHandler.h:291
GenericSAXHandler::myTagMap
TagMap myTagMap
Definition: GenericSAXHandler.h:302
GenericSAXHandler::myParentIndicator
int myParentIndicator
The tag indicating that control should be given back.
Definition: GenericSAXHandler.h:312
GenericSAXHandler::GenericSAXHandler
GenericSAXHandler(StringBijection< int >::Entry *tags, int terminatorTag, StringBijection< int >::Entry *attrs, int terminatorAttr, const std::string &file, const std::string &expectedRoot="")
Constructor.
Definition: GenericSAXHandler.cpp:40
GenericSAXHandler::startElement
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.
Definition: GenericSAXHandler.cpp:93
StringBijection
Definition: StringBijection.h:43
GenericSAXHandler::endElement
void endElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname)
The inherited method called when a tag is being closed.
Definition: GenericSAXHandler.cpp:120
ProcessError
Definition: UtilExceptions.h:39
SUMO_TAG_INCLUDE
@ SUMO_TAG_INCLUDE
Definition: SUMOXMLDefinitions.h:257
GenericSAXHandler::myEndElement
virtual void myEndElement(int element)
Callback method for a closing tag to implement by derived classes.
Definition: GenericSAXHandler.cpp:225
SUMO_ATTR_HREF
@ SUMO_ATTR_HREF
Definition: SUMOXMLDefinitions.h:822
GenericSAXHandler::myPredefinedTags
AttrMap myPredefinedTags
Definition: GenericSAXHandler.h:288
GenericSAXHandler::buildErrorMessage
std::string buildErrorMessage(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Builds an error message.
Definition: GenericSAXHandler.cpp:186
StringUtils.h
StringUtils::transcode
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
Definition: StringUtils.h:136
GenericSAXHandler::convertTag
int convertTag(const std::string &tag) const
Converts a tag from its string into its numerical representation.
Definition: GenericSAXHandler.cpp:176
transcode
std::string transcode(const XMLCh *const qname)
Definition: VehicleEngineHandler.cpp:37
GenericSAXHandler::getFileName
const std::string & getFileName() const
returns the current file name
Definition: GenericSAXHandler.cpp:74
GenericSAXHandler::myFileName
std::string myFileName
The name of the currently parsed file.
Definition: GenericSAXHandler.h:315
GenericSAXHandler::myCharactersVector
std::vector< std::string > myCharactersVector
A list of character strings obtained so far to build the complete characters string at the end.
Definition: GenericSAXHandler.h:306
FileHelpers::isAbsolute
static bool isAbsolute(const std::string &path)
Returns the information whether the given path is absolute.
Definition: FileHelpers.cpp:129
GenericSAXHandler::error
void error(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-errors.
Definition: GenericSAXHandler.cpp:205
config.h
GenericSAXHandler::myExpectedRoot
std::string myExpectedRoot
The root element to expect, empty string disables the check.
Definition: GenericSAXHandler.h:318
GenericSAXHandler::~GenericSAXHandler
virtual ~GenericSAXHandler()
Destructor.
Definition: GenericSAXHandler.cpp:60
GenericSAXHandler
A handler which converts occuring elements and attributes into enums.
Definition: GenericSAXHandler.h:67
SUMOSAXAttributesImpl_Xerces::getString
std::string getString(int id) const
Returns the string-value of the named (by its enum-value) attribute.
Definition: SUMOSAXAttributesImpl_Xerces.cpp:85
SUMOSAXAttributes
Encapsulated SAX-Attributes.
Definition: SUMOSAXAttributes.h:56
GenericSAXHandler::characters
void characters(const XMLCh *const chars, const XERCES3_SIZE_t length)
The inherited method called when characters occurred.
Definition: GenericSAXHandler.cpp:169
GenericSAXHandler::convert
XMLCh * convert(const std::string &name) const
converts from c++-string into unicode
Definition: GenericSAXHandler.cpp:80
GenericSAXHandler::setFileName
void setFileName(const std::string &name)
Sets the current file name.
Definition: GenericSAXHandler.cpp:68
XMLSubSys.h
GenericSAXHandler::myParentHandler
GenericSAXHandler * myParentHandler
The handler to give control back to.
Definition: GenericSAXHandler.h:309