SUMO - Simulation of Urban MObility
SUMOSAXReader.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2012-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
19 // SAX-reader encapsulation containing binary reader
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <string>
33 #include <iostream>
34 #include <xercesc/sax2/XMLReaderFactory.hpp>
35 #include <xercesc/framework/LocalFileInputSource.hpp>
36 #include <xercesc/framework/MemBufInputSource.hpp>
37 
39 #include <utils/common/ToString.h>
44 #include "GenericSAXHandler.h"
45 #include "SUMOSAXReader.h"
46 
47 
48 // ===========================================================================
49 // method definitions
50 // ===========================================================================
51 SUMOSAXReader::SUMOSAXReader(GenericSAXHandler& handler, const XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes validationScheme)
52  : myHandler(&handler), myValidationScheme(validationScheme),
53  myXMLReader(0), myBinaryInput(0) {}
54 
55 
57  delete myXMLReader;
58  delete myBinaryInput;
59 }
60 
61 
62 void
64  myHandler = &handler;
65  if (myXMLReader != 0) {
66  myXMLReader->setContentHandler(&handler);
67  myXMLReader->setErrorHandler(&handler);
68  }
69 }
70 
71 
72 void
73 SUMOSAXReader::setValidation(const XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes validationScheme) {
74  if (myXMLReader != 0 && validationScheme != myValidationScheme) {
75  if (validationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Never) {
76  myXMLReader->setEntityResolver(0);
77  myXMLReader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgWFXMLScanner);
78  } else {
79  myXMLReader->setEntityResolver(&mySchemaResolver);
80  myXMLReader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgIGXMLScanner);
81  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesSchema, true);
82  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgSAX2CoreValidation, true);
83  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesDynamic, validationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Auto);
84  }
85  }
86  myValidationScheme = validationScheme;
87 }
88 
89 
90 void
91 SUMOSAXReader::parse(std::string systemID) {
92  if (systemID.length() >= 4 && systemID.substr(systemID.length() - 4) == ".sbx") {
93  if (parseFirst(systemID)) {
94  while (parseNext());
95  }
96  } else {
97  if (myXMLReader == 0) {
99  }
100  myXMLReader->parse(systemID.c_str());
101  }
102 }
103 
104 
105 void
106 SUMOSAXReader::parseString(std::string content) {
107  if (myXMLReader == 0) {
109  }
110  XERCES_CPP_NAMESPACE::MemBufInputSource memBufIS((const XMLByte*)content.c_str(), content.size(), "registrySettings");
111  myXMLReader->parse(memBufIS);
112 }
113 
114 
115 bool
116 SUMOSAXReader::parseFirst(std::string systemID) {
117  if (systemID.substr(systemID.length() - 4) == ".sbx") {
118  myBinaryInput = new BinaryInputDevice(systemID, true, myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Always);
120  if (mySbxVersion < 1 || mySbxVersion > 2) {
121  throw ProcessError("Unknown sbx version");
122  }
123  std::string sumoVer;
124  *myBinaryInput >> sumoVer;
125  std::vector<std::string> elems;
126  *myBinaryInput >> elems;
127  // !!! check elems here
128  elems.clear();
129  *myBinaryInput >> elems;
130  // !!! check attrs here
131  elems.clear();
132  *myBinaryInput >> elems;
133  // !!! check node types here
134  elems.clear();
135  *myBinaryInput >> elems;
136  // !!! check edge types here
137  elems.clear();
138  *myBinaryInput >> elems;
139  // !!! check edges here
140  std::vector< std::vector<int> > followers;
141  *myBinaryInput >> followers;
142  // !!! check followers here
143  return parseNext();
144  } else {
145  if (myXMLReader == 0) {
147  }
148  myToken = XERCES_CPP_NAMESPACE::XMLPScanToken();
149  return myXMLReader->parseFirst(systemID.c_str(), myToken);
150  }
151 }
152 
153 
154 bool
156  if (myBinaryInput != 0) {
157  int next = myBinaryInput->peek();
158  switch (next) {
159  case EOF:
160  delete myBinaryInput;
161  myBinaryInput = 0;
162  return false;
164  int tag;
165  unsigned char tagByte;
166  *myBinaryInput >> tagByte;
167  tag = tagByte;
168  if (mySbxVersion > 1) {
170  *myBinaryInput >> tagByte;
171  tag += 256 * tagByte;
172  }
173  myXMLStack.push_back((SumoXMLTag)tag);
175  myHandler->myStartElement(tag, attrs);
176  break;
177  }
179  if (myXMLStack.empty()) {
180  throw ProcessError("Binary file is invalid, unexpected tag end.");
181  }
183  myXMLStack.pop_back();
184  myBinaryInput->read(mySbxVersion > 1 ? 1 : 2);
185  break;
186  }
187  default:
188  throw ProcessError("Binary file is invalid, expected tag start or tag end.");
189  }
190  return true;
191  } else {
192  if (myXMLReader == 0) {
193  throw ProcessError("The XML-parser was not initialized.");
194  }
195  return myXMLReader->parseNext(myToken);
196  }
197 }
198 
199 
200 XERCES_CPP_NAMESPACE::SAX2XMLReader*
202  XERCES_CPP_NAMESPACE::SAX2XMLReader* reader = XERCES_CPP_NAMESPACE::XMLReaderFactory::createXMLReader();
203  if (reader == 0) {
204  throw ProcessError("The XML-parser could not be build.");
205  }
206  // see here https://svn.apache.org/repos/asf/xerces/c/trunk/samples/src/SAX2Count/SAX2Count.cpp for the way to set features
207  if (myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Never) {
208  reader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgWFXMLScanner);
209  } else {
210  reader->setEntityResolver(&mySchemaResolver);
211  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesSchema, true);
212  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgSAX2CoreValidation, true);
213  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesDynamic, myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Auto);
214  }
215  reader->setContentHandler(myHandler);
216  reader->setErrorHandler(myHandler);
217  return reader;
218 }
219 
220 
221 XERCES_CPP_NAMESPACE::InputSource*
222 SUMOSAXReader::LocalSchemaResolver::resolveEntity(const XMLCh* const /* publicId */, const XMLCh* const systemId) {
223  const std::string url = TplConvert::_2str(systemId);
224  const std::string::size_type pos = url.rfind("/");
225  if (pos != std::string::npos) {
226  const std::string dir = url.substr(0, pos);
227  if (dir == "http://sumo.sf.net/xsd" || dir == "http://sumo-sim.org/xsd" || dir == "http://sumo-sim.org/xsd/amitran" ||
228  dir == "http://sumo.dlr.de/xsd" || dir == "http://sumo.dlr.de/xsd/amitran") {
229  const char* sumoPath = std::getenv("SUMO_HOME");
230  if (sumoPath == 0) {
231  WRITE_WARNING("Environment variable SUMO_HOME is not set, schema resolution will use slow website lookups.");
232  return 0;
233  }
234  const std::string file = sumoPath + std::string("/data/xsd") + url.substr(url.find("/xsd/") + 4);
235  if (FileHelpers::isReadable(file)) {
236  XMLCh* t = XERCES_CPP_NAMESPACE::XMLString::transcode(file.c_str());
237  XERCES_CPP_NAMESPACE::InputSource* const result = new XERCES_CPP_NAMESPACE::LocalFileInputSource(t);
238  XERCES_CPP_NAMESPACE::XMLString::release(&t);
239  return result;
240  } else {
241  WRITE_WARNING("Cannot find local schema '" + file + "', will try website lookup.");
242  }
243  }
244  }
245  return 0;
246 }
247 
248 
249 /****************************************************************************/
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:53
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:199
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:56
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.