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 
49 // ===========================================================================
50 // method definitions
51 // ===========================================================================
52 SUMOSAXReader::SUMOSAXReader(GenericSAXHandler& handler, const XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes validationScheme)
53  : myHandler(&handler), myValidationScheme(validationScheme),
54  myXMLReader(0), myBinaryInput(0) {}
55 
56 
58  delete myXMLReader;
59  delete myBinaryInput;
60 }
61 
62 
63 void
65  myHandler = &handler;
66  if (myXMLReader != 0) {
67  myXMLReader->setContentHandler(&handler);
68  myXMLReader->setErrorHandler(&handler);
69  }
70 }
71 
72 
73 void
74 SUMOSAXReader::setValidation(const XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes validationScheme) {
75  if (myXMLReader != 0 && validationScheme != myValidationScheme) {
76  if (validationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Never) {
77  myXMLReader->setEntityResolver(0);
78  myXMLReader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgWFXMLScanner);
79  } else {
80  myXMLReader->setEntityResolver(&mySchemaResolver);
81  myXMLReader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgIGXMLScanner);
82  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesSchema, true);
83  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgSAX2CoreValidation, true);
84  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesDynamic, validationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Auto);
85  }
86  }
87  myValidationScheme = validationScheme;
88 }
89 
90 
91 void
92 SUMOSAXReader::parse(std::string systemID) {
93  if (systemID.length() >= 4 && systemID.substr(systemID.length() - 4) == ".sbx") {
94  if (parseFirst(systemID)) {
95  while (parseNext());
96  }
97  } else {
98  if (myXMLReader == 0) {
100  }
101  myXMLReader->parse(systemID.c_str());
102  }
103 }
104 
105 
106 void
107 SUMOSAXReader::parseString(std::string content) {
108  if (myXMLReader == 0) {
110  }
111  XERCES_CPP_NAMESPACE::MemBufInputSource memBufIS((const XMLByte*)content.c_str(), content.size(), "registrySettings");
112  myXMLReader->parse(memBufIS);
113 }
114 
115 
116 bool
117 SUMOSAXReader::parseFirst(std::string systemID) {
118  if (systemID.substr(systemID.length() - 4) == ".sbx") {
119  myBinaryInput = new BinaryInputDevice(systemID, true, myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Always);
121  if (mySbxVersion < 1 || mySbxVersion > 2) {
122  throw ProcessError("Unknown sbx version");
123  }
124  std::string sumoVer;
125  *myBinaryInput >> sumoVer;
126  std::vector<std::string> elems;
127  *myBinaryInput >> elems;
128  // !!! check elems here
129  elems.clear();
130  *myBinaryInput >> elems;
131  // !!! check attrs here
132  elems.clear();
133  *myBinaryInput >> elems;
134  // !!! check node types here
135  elems.clear();
136  *myBinaryInput >> elems;
137  // !!! check edge types here
138  elems.clear();
139  *myBinaryInput >> elems;
140  // !!! check edges here
141  std::vector< std::vector<int> > followers;
142  *myBinaryInput >> followers;
143  // !!! check followers here
144  return parseNext();
145  } else {
146  if (myXMLReader == 0) {
148  }
149  myToken = XERCES_CPP_NAMESPACE::XMLPScanToken();
150  return myXMLReader->parseFirst(systemID.c_str(), myToken);
151  }
152 }
153 
154 
155 bool
157  if (myBinaryInput != 0) {
158  int next = myBinaryInput->peek();
159  switch (next) {
160  case EOF:
161  delete myBinaryInput;
162  myBinaryInput = 0;
163  return false;
165  int tag;
166  unsigned char tagByte;
167  *myBinaryInput >> tagByte;
168  tag = tagByte;
169  if (mySbxVersion > 1) {
171  *myBinaryInput >> tagByte;
172  tag += 256 * tagByte;
173  }
174  myXMLStack.push_back((SumoXMLTag)tag);
176  myHandler->myStartElement(tag, attrs);
177  break;
178  }
180  if (myXMLStack.empty()) {
181  throw ProcessError("Binary file is invalid, unexpected tag end.");
182  }
184  myXMLStack.pop_back();
185  myBinaryInput->read(mySbxVersion > 1 ? 1 : 2);
186  break;
187  }
188  default:
189  throw ProcessError("Binary file is invalid, expected tag start or tag end.");
190  }
191  return true;
192  } else {
193  if (myXMLReader == 0) {
194  throw ProcessError("The XML-parser was not initialized.");
195  }
196  return myXMLReader->parseNext(myToken);
197  }
198 }
199 
200 
201 XERCES_CPP_NAMESPACE::SAX2XMLReader*
203  XERCES_CPP_NAMESPACE::SAX2XMLReader* reader = XERCES_CPP_NAMESPACE::XMLReaderFactory::createXMLReader();
204  if (reader == 0) {
205  throw ProcessError("The XML-parser could not be build.");
206  }
207  // see here https://svn.apache.org/repos/asf/xerces/c/trunk/samples/src/SAX2Count/SAX2Count.cpp for the way to set features
208  if (myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Never) {
209  reader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgWFXMLScanner);
210  } else {
211  reader->setEntityResolver(&mySchemaResolver);
212  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesSchema, true);
213  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgSAX2CoreValidation, true);
214  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesDynamic, myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Auto);
215  }
216  reader->setContentHandler(myHandler);
217  reader->setErrorHandler(myHandler);
218  return reader;
219 }
220 
221 
222 XERCES_CPP_NAMESPACE::InputSource*
223 SUMOSAXReader::LocalSchemaResolver::resolveEntity(const XMLCh* const /* publicId */, const XMLCh* const systemId) {
224  const std::string url = TplConvert::_2str(systemId);
225  const std::string::size_type pos = url.rfind("/");
226  if (pos != std::string::npos) {
227  const std::string dir = url.substr(0, pos);
228  if (dir == "http://sumo.sf.net/xsd" || dir == "http://sumo-sim.org/xsd" || dir == "http://sumo-sim.org/xsd/amitran" ||
229  dir == "http://sumo.dlr.de/xsd" || dir == "http://sumo.dlr.de/xsd/amitran") {
230  const char* sumoPath = std::getenv("SUMO_HOME");
231  if (sumoPath == 0) {
232  WRITE_WARNING("Environment variable SUMO_HOME is not set, schema resolution will use slow website lookups.");
233  return 0;
234  }
235  const std::string file = sumoPath + std::string("/data/xsd") + url.substr(url.find("/xsd/") + 4);
236  if (FileHelpers::isReadable(file)) {
237  XMLCh* t = XERCES_CPP_NAMESPACE::XMLString::transcode(file.c_str());
238  XERCES_CPP_NAMESPACE::InputSource* const result = new XERCES_CPP_NAMESPACE::LocalFileInputSource(t);
239  XERCES_CPP_NAMESPACE::XMLString::release(&t);
240  return result;
241  } else {
242  WRITE_WARNING("Cannot find local schema '" + file + "', will try website lookup.");
243  }
244  }
245  }
246  return 0;
247 }
248 
249 
250 /****************************************************************************/
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:54
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:56
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.