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-2016 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);
124  char sbxVer;
125  *myBinaryInput >> sbxVer;
126  if (sbxVer != 1) {
127  throw ProcessError("Unknown sbx version");
128  }
129  std::string sumoVer;
130  *myBinaryInput >> sumoVer;
131  std::vector<std::string> elems;
132  *myBinaryInput >> elems;
133  // !!! check elems here
134  elems.clear();
135  *myBinaryInput >> elems;
136  // !!! check attrs here
137  elems.clear();
138  *myBinaryInput >> elems;
139  // !!! check node types here
140  elems.clear();
141  *myBinaryInput >> elems;
142  // !!! check edge types here
143  elems.clear();
144  *myBinaryInput >> elems;
145  // !!! check edges here
146  std::vector< std::vector<int> > followers;
147  *myBinaryInput >> followers;
148  // !!! check followers here
149  return parseNext();
150  } else {
151  if (myXMLReader == 0) {
153  }
154  myToken = XERCES_CPP_NAMESPACE::XMLPScanToken();
155  return myXMLReader->parseFirst(systemID.c_str(), myToken);
156  }
157 }
158 
159 
160 bool
162  if (myBinaryInput != 0) {
163  int next = myBinaryInput->peek();
164  switch (next) {
165  case EOF:
166  delete myBinaryInput;
167  myBinaryInput = 0;
168  return false;
170  char t;
171  *myBinaryInput >> t;
173  myHandler->myStartElement(t, attrs);
174  break;
175  }
177  char t;
178  *myBinaryInput >> t;
180  break;
181  }
182  default:
183  throw ProcessError("Invalid binary file");
184  }
185  return true;
186  } else {
187  if (myXMLReader == 0) {
188  throw ProcessError("The XML-parser was not initialized.");
189  }
190  return myXMLReader->parseNext(myToken);
191  }
192 }
193 
194 
195 XERCES_CPP_NAMESPACE::SAX2XMLReader*
197  XERCES_CPP_NAMESPACE::SAX2XMLReader* reader = XERCES_CPP_NAMESPACE::XMLReaderFactory::createXMLReader();
198  if (reader == 0) {
199  throw ProcessError("The XML-parser could not be build.");
200  }
201  // see here https://svn.apache.org/repos/asf/xerces/c/trunk/samples/src/SAX2Count/SAX2Count.cpp for the way to set features
202  if (myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Never) {
203  reader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgWFXMLScanner);
204  } else {
205  reader->setEntityResolver(&mySchemaResolver);
206  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesSchema, true);
207  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgSAX2CoreValidation, true);
208  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesDynamic, myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Auto);
209  }
210  reader->setContentHandler(myHandler);
211  reader->setErrorHandler(myHandler);
212  return reader;
213 }
214 
215 
216 XERCES_CPP_NAMESPACE::InputSource*
217 SUMOSAXReader::LocalSchemaResolver::resolveEntity(const XMLCh* const /* publicId */, const XMLCh* const systemId) {
218  const std::string url = TplConvert::_2str(systemId);
219  const std::string::size_type pos = url.rfind("/");
220  if (pos != std::string::npos) {
221  const std::string dir = url.substr(0, pos);
222  if (dir == "http://sumo.sf.net/xsd" || dir == "http://sumo-sim.org/xsd" || dir == "http://sumo-sim.org/xsd/amitran" ||
223  dir == "http://sumo.dlr.de/xsd" || dir == "http://sumo.dlr.de/xsd/amitran") {
224  const char* sumoPath = std::getenv("SUMO_HOME");
225  if (sumoPath == 0) {
226  WRITE_WARNING("Environment variable SUMO_HOME is not set, schema resolution will use slow website lookups.");
227  return 0;
228  }
229  const std::string file = sumoPath + std::string("/data/xsd") + url.substr(url.find("/xsd/") + 4);
230  if (FileHelpers::isReadable(file)) {
231  XMLCh* t = XERCES_CPP_NAMESPACE::XMLString::transcode(file.c_str());
232  XERCES_CPP_NAMESPACE::InputSource* const result = new XERCES_CPP_NAMESPACE::LocalFileInputSource(t);
233  XERCES_CPP_NAMESPACE::XMLString::release(&t);
234  return result;
235  } else {
236  WRITE_WARNING("Cannot find local schema '" + file + "', will try website lookup.");
237  }
238  }
239  }
240  return 0;
241 }
242 
243 
244 /****************************************************************************/
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
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.
void parse(std::string systemID)
XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes myValidationScheme
Information whether built reader/parser shall validate XML-documents against schemata.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
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
virtual void myEndElement(int element)
Callback method for a closing tag to implement by derived classes.