SUMO - Simulation of Urban MObility
SUMOSAXReader.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // SAX-reader encapsulation containing binary reader
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2012-2017 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <string>
34 #include <iostream>
35 #include <xercesc/sax2/XMLReaderFactory.hpp>
36 #include <xercesc/framework/LocalFileInputSource.hpp>
37 #include <xercesc/framework/MemBufInputSource.hpp>
38 
40 #include <utils/common/ToString.h>
45 #include "GenericSAXHandler.h"
46 #include "SUMOSAXReader.h"
47 
48 #ifdef CHECK_MEMORY_LEAKS
49 #include <foreign/nvwa/debug_new.h>
50 #endif // CHECK_MEMORY_LEAKS
51 
52 
53 // ===========================================================================
54 // method definitions
55 // ===========================================================================
56 SUMOSAXReader::SUMOSAXReader(GenericSAXHandler& handler, const XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes validationScheme)
57  : myHandler(&handler), myValidationScheme(validationScheme),
58  myXMLReader(0), myBinaryInput(0) {}
59 
60 
62  delete myXMLReader;
63  delete myBinaryInput;
64 }
65 
66 
67 void
69  myHandler = &handler;
70  if (myXMLReader != 0) {
71  myXMLReader->setContentHandler(&handler);
72  myXMLReader->setErrorHandler(&handler);
73  }
74 }
75 
76 
77 void
78 SUMOSAXReader::setValidation(const XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes validationScheme) {
79  if (myXMLReader != 0 && validationScheme != myValidationScheme) {
80  if (validationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Never) {
81  myXMLReader->setEntityResolver(0);
82  myXMLReader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgWFXMLScanner);
83  } else {
84  myXMLReader->setEntityResolver(&mySchemaResolver);
85  myXMLReader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgIGXMLScanner);
86  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesSchema, true);
87  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgSAX2CoreValidation, true);
88  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesDynamic, validationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Auto);
89  }
90  }
91  myValidationScheme = validationScheme;
92 }
93 
94 
95 void
96 SUMOSAXReader::parse(std::string systemID) {
97  if (systemID.length() >= 4 && systemID.substr(systemID.length() - 4) == ".sbx") {
98  if (parseFirst(systemID)) {
99  while (parseNext());
100  }
101  } else {
102  if (myXMLReader == 0) {
104  }
105  myXMLReader->parse(systemID.c_str());
106  }
107 }
108 
109 
110 void
111 SUMOSAXReader::parseString(std::string content) {
112  if (myXMLReader == 0) {
114  }
115  XERCES_CPP_NAMESPACE::MemBufInputSource memBufIS((const XMLByte*)content.c_str(), content.size(), "registrySettings");
116  myXMLReader->parse(memBufIS);
117 }
118 
119 
120 bool
121 SUMOSAXReader::parseFirst(std::string systemID) {
122  if (systemID.substr(systemID.length() - 4) == ".sbx") {
123  myBinaryInput = new BinaryInputDevice(systemID, true, myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Always);
125  if (mySbxVersion < 1 || mySbxVersion > 2) {
126  throw ProcessError("Unknown sbx version");
127  }
128  std::string sumoVer;
129  *myBinaryInput >> sumoVer;
130  std::vector<std::string> elems;
131  *myBinaryInput >> elems;
132  // !!! check elems here
133  elems.clear();
134  *myBinaryInput >> elems;
135  // !!! check attrs here
136  elems.clear();
137  *myBinaryInput >> elems;
138  // !!! check node types here
139  elems.clear();
140  *myBinaryInput >> elems;
141  // !!! check edge types here
142  elems.clear();
143  *myBinaryInput >> elems;
144  // !!! check edges here
145  std::vector< std::vector<int> > followers;
146  *myBinaryInput >> followers;
147  // !!! check followers here
148  return parseNext();
149  } else {
150  if (myXMLReader == 0) {
152  }
153  myToken = XERCES_CPP_NAMESPACE::XMLPScanToken();
154  return myXMLReader->parseFirst(systemID.c_str(), myToken);
155  }
156 }
157 
158 
159 bool
161  if (myBinaryInput != 0) {
162  int next = myBinaryInput->peek();
163  switch (next) {
164  case EOF:
165  delete myBinaryInput;
166  myBinaryInput = 0;
167  return false;
169  int tag;
170  unsigned char tagByte;
171  *myBinaryInput >> tagByte;
172  tag = tagByte;
173  if (mySbxVersion > 1) {
175  *myBinaryInput >> tagByte;
176  tag += 256 * tagByte;
177  }
178  myXMLStack.push_back((SumoXMLTag)tag);
180  myHandler->myStartElement(tag, attrs);
181  break;
182  }
184  if (myXMLStack.empty()) {
185  throw ProcessError("Binary file is invalid, unexpected tag end.");
186  }
188  myXMLStack.pop_back();
189  myBinaryInput->read(mySbxVersion > 1 ? 1 : 2);
190  break;
191  }
192  default:
193  throw ProcessError("Binary file is invalid, expected tag start or tag end.");
194  }
195  return true;
196  } else {
197  if (myXMLReader == 0) {
198  throw ProcessError("The XML-parser was not initialized.");
199  }
200  return myXMLReader->parseNext(myToken);
201  }
202 }
203 
204 
205 XERCES_CPP_NAMESPACE::SAX2XMLReader*
207  XERCES_CPP_NAMESPACE::SAX2XMLReader* reader = XERCES_CPP_NAMESPACE::XMLReaderFactory::createXMLReader();
208  if (reader == 0) {
209  throw ProcessError("The XML-parser could not be build.");
210  }
211  // see here https://svn.apache.org/repos/asf/xerces/c/trunk/samples/src/SAX2Count/SAX2Count.cpp for the way to set features
212  if (myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Never) {
213  reader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgWFXMLScanner);
214  } else {
215  reader->setEntityResolver(&mySchemaResolver);
216  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesSchema, true);
217  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgSAX2CoreValidation, true);
218  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesDynamic, myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Auto);
219  }
220  reader->setContentHandler(myHandler);
221  reader->setErrorHandler(myHandler);
222  return reader;
223 }
224 
225 
226 XERCES_CPP_NAMESPACE::InputSource*
227 SUMOSAXReader::LocalSchemaResolver::resolveEntity(const XMLCh* const /* publicId */, const XMLCh* const systemId) {
228  const std::string url = TplConvert::_2str(systemId);
229  const std::string::size_type pos = url.rfind("/");
230  if (pos != std::string::npos) {
231  const std::string dir = url.substr(0, pos);
232  if (dir == "http://sumo.sf.net/xsd" || dir == "http://sumo-sim.org/xsd" || dir == "http://sumo-sim.org/xsd/amitran" ||
233  dir == "http://sumo.dlr.de/xsd" || dir == "http://sumo.dlr.de/xsd/amitran") {
234  const char* sumoPath = std::getenv("SUMO_HOME");
235  if (sumoPath == 0) {
236  WRITE_WARNING("Environment variable SUMO_HOME is not set, schema resolution will use slow website lookups.");
237  return 0;
238  }
239  const std::string file = sumoPath + std::string("/data/xsd") + url.substr(url.find("/xsd/") + 4);
240  if (FileHelpers::isReadable(file)) {
241  XMLCh* t = XERCES_CPP_NAMESPACE::XMLString::transcode(file.c_str());
242  XERCES_CPP_NAMESPACE::InputSource* const result = new XERCES_CPP_NAMESPACE::LocalFileInputSource(t);
243  XERCES_CPP_NAMESPACE::XMLString::release(&t);
244  return result;
245  } else {
246  WRITE_WARNING("Cannot find local schema '" + file + "', will try website lookup.");
247  }
248  }
249  }
250  return 0;
251 }
252 
253 
254 /****************************************************************************/
std::vector< SumoXMLTag > myXMLStack
The stack of begun xml elements.
int peek()
Returns the next character to be read by an actual parse.
SumoXMLTag
Numbers representing SUMO-XML - element names.
SUMOSAXReader(GenericSAXHandler &handler, const XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes validationScheme)
Constructor.
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:58
void putback(char c)
Pushes a character back into the stream to be read by the next actual parse.
XERCES_CPP_NAMESPACE::SAX2XMLReader * getSAXReader()
Builds a reader.
void setValidation(const XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes validationScheme)
XERCES_CPP_NAMESPACE::XMLPScanToken myToken
void parseString(std::string content)
BinaryInputDevice * myBinaryInput
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
A handler which converts occuring elements and attributes into enums.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
void parse(std::string systemID)
XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes myValidationScheme
Information whether built reader/parser shall validate XML-documents against schemata.
bool parseFirst(std::string systemID)
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Callback method for an opening tag to implement by derived classes.
Encapsulated Xerces-SAX-attributes.
XERCES_CPP_NAMESPACE::SAX2XMLReader * myXMLReader
void setHandler(GenericSAXHandler &handler)
Sets the given handler as content and error handler for the reader.
LocalSchemaResolver mySchemaResolver
std::map< int, std::string > myPredefinedTagsMML
the map from ids to their string representation
XERCES_CPP_NAMESPACE::InputSource * resolveEntity(const XMLCh *const publicId, const XMLCh *const systemId)
~SUMOSAXReader()
Destructor.
static std::string _2str(const int var)
convert int to string
Definition: TplConvert.h:57
Encapsulates binary reading operations on a file.
GenericSAXHandler * myHandler
std::string read(int numBytes)
Reads the defined number of bytes and returns them as a string.
virtual void myEndElement(int element)
Callback method for a closing tag to implement by derived classes.