SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SUMOSAXReader.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // SAX-reader encapsulation containing binary reader
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
10 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <string>
32 #include <iostream>
33 #include <xercesc/sax2/XMLReaderFactory.hpp>
34 #include <xercesc/framework/LocalFileInputSource.hpp>
35 #include <xercesc/framework/MemBufInputSource.hpp>
36 
38 #include <utils/common/ToString.h>
43 #include "GenericSAXHandler.h"
44 #include "SUMOSAXReader.h"
45 
46 #ifdef CHECK_MEMORY_LEAKS
47 #include <foreign/nvwa/debug_new.h>
48 #endif // CHECK_MEMORY_LEAKS
49 
50 
51 // ===========================================================================
52 // method definitions
53 // ===========================================================================
54 SUMOSAXReader::SUMOSAXReader(GenericSAXHandler& handler, const XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes validationScheme)
55  : myHandler(&handler), myValidationScheme(validationScheme),
56  myXMLReader(0), myBinaryInput(0) {}
57 
58 
60  delete myXMLReader;
61  delete myBinaryInput;
62 }
63 
64 
65 void
67  myHandler = &handler;
68  if (myXMLReader != 0) {
69  myXMLReader->setContentHandler(&handler);
70  myXMLReader->setErrorHandler(&handler);
71  }
72 }
73 
74 
75 void
76 SUMOSAXReader::setValidation(const XERCES_CPP_NAMESPACE::SAX2XMLReader::ValSchemes validationScheme) {
77  if (myXMLReader != 0 && validationScheme != myValidationScheme) {
78  if (validationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Never) {
79  myXMLReader->setEntityResolver(0);
80  myXMLReader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgWFXMLScanner);
81  } else {
82  myXMLReader->setEntityResolver(&mySchemaResolver);
83  myXMLReader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgIGXMLScanner);
84  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesSchema, true);
85  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgSAX2CoreValidation, true);
86  myXMLReader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesDynamic, validationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Auto);
87  }
88  }
89  myValidationScheme = validationScheme;
90 }
91 
92 
93 void
94 SUMOSAXReader::parse(std::string systemID) {
95  if (systemID.length() >= 4 && systemID.substr(systemID.length() - 4) == ".sbx") {
96  if (parseFirst(systemID)) {
97  while (parseNext());
98  }
99  } else {
100  if (myXMLReader == 0) {
102  }
103  myXMLReader->parse(systemID.c_str());
104  }
105 }
106 
107 
108 void
109 SUMOSAXReader::parseString(std::string content) {
110  if (myXMLReader == 0) {
112  }
113  XERCES_CPP_NAMESPACE::MemBufInputSource memBufIS((const XMLByte*)content.c_str(), content.size(), "registrySettings");
114  myXMLReader->parse(memBufIS);
115 }
116 
117 
118 bool
119 SUMOSAXReader::parseFirst(std::string systemID) {
120  if (systemID.substr(systemID.length() - 4) == ".sbx") {
121  myBinaryInput = new BinaryInputDevice(systemID, true, myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Always);
122  char sbxVer;
123  *myBinaryInput >> sbxVer;
124  if (sbxVer != 1) {
125  throw ProcessError("Unknown sbx version");
126  }
127  std::string sumoVer;
128  *myBinaryInput >> sumoVer;
129  std::vector<std::string> elems;
130  *myBinaryInput >> elems;
131  // !!! check elems here
132  elems.clear();
133  *myBinaryInput >> elems;
134  // !!! check attrs here
135  elems.clear();
136  *myBinaryInput >> elems;
137  // !!! check node types here
138  elems.clear();
139  *myBinaryInput >> elems;
140  // !!! check edge types here
141  elems.clear();
142  *myBinaryInput >> elems;
143  // !!! check edges here
144  std::vector< std::vector<unsigned int> > followers;
145  *myBinaryInput >> followers;
146  // !!! check followers here
147  return parseNext();
148  } else {
149  if (myXMLReader == 0) {
151  }
152  myToken = XERCES_CPP_NAMESPACE::XMLPScanToken();
153  return myXMLReader->parseFirst(systemID.c_str(), myToken);
154  }
155 }
156 
157 
158 bool
160  if (myBinaryInput != 0) {
161  int next = myBinaryInput->peek();
162  switch (next) {
163  case EOF:
164  delete myBinaryInput;
165  myBinaryInput = 0;
166  return false;
168  char t;
169  *myBinaryInput >> t;
171  myHandler->myStartElement(t, attrs);
172  break;
173  }
175  char t;
176  *myBinaryInput >> t;
178  break;
179  }
180  default:
181  throw ProcessError("Invalid binary file");
182  }
183  return true;
184  } else {
185  if (myXMLReader == 0) {
186  throw ProcessError("The XML-parser was not initialized.");
187  }
188  return myXMLReader->parseNext(myToken);
189  }
190 }
191 
192 
193 XERCES_CPP_NAMESPACE::SAX2XMLReader*
195  XERCES_CPP_NAMESPACE::SAX2XMLReader* reader = XERCES_CPP_NAMESPACE::XMLReaderFactory::createXMLReader();
196  if (reader == 0) {
197  throw ProcessError("The XML-parser could not be build.");
198  }
199  // see here https://svn.apache.org/repos/asf/xerces/c/trunk/samples/src/SAX2Count/SAX2Count.cpp for the way to set features
200  if (myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Never) {
201  reader->setProperty(XERCES_CPP_NAMESPACE::XMLUni::fgXercesScannerName, (void*)XERCES_CPP_NAMESPACE::XMLUni::fgWFXMLScanner);
202  } else {
203  reader->setEntityResolver(&mySchemaResolver);
204  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesSchema, true);
205  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgSAX2CoreValidation, true);
206  reader->setFeature(XERCES_CPP_NAMESPACE::XMLUni::fgXercesDynamic, myValidationScheme == XERCES_CPP_NAMESPACE::SAX2XMLReader::Val_Auto);
207  }
208  reader->setContentHandler(myHandler);
209  reader->setErrorHandler(myHandler);
210  return reader;
211 }
212 
213 
214 XERCES_CPP_NAMESPACE::InputSource*
215 SUMOSAXReader::LocalSchemaResolver::resolveEntity(const XMLCh* const /* publicId */, const XMLCh* const systemId) {
216  const std::string url = TplConvert::_2str(systemId);
217  const std::string::size_type pos = url.rfind("/");
218  if (pos != std::string::npos) {
219  const std::string dir = url.substr(0, pos);
220  if (dir == "http://sumo-sim.org/xsd" || dir == "http://sumo.sf.net/xsd") {
221  const char* sumoPath = std::getenv("SUMO_HOME");
222  if (sumoPath == 0) {
223  WRITE_WARNING("Environment variable SUMO_HOME is not set, schema resolution will use slow website lookups.");
224  return 0;
225  }
226  const std::string file = sumoPath + std::string("/data/xsd") + url.substr(pos);
227  if (FileHelpers::exists(file)) {
228  XMLCh* t = XERCES_CPP_NAMESPACE::XMLString::transcode(file.c_str());
229  XERCES_CPP_NAMESPACE::InputSource* const result = new XERCES_CPP_NAMESPACE::LocalFileInputSource(t);
230  XERCES_CPP_NAMESPACE::XMLString::release(&t);
231  return result;
232  } else {
233  WRITE_WARNING("Cannot find local schema '" + file + "', will try website lookup.");
234  }
235  }
236  }
237  return 0;
238 }
239 
240 
241 /****************************************************************************/
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.
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:196
A handler which converts occuring elements and attributes into enums.
void parse(std::string systemID)
static std::string _2str(const E *const data)
Definition: TplConvert.h:56
static bool exists(std::string path)
Checks whether the given file exists.
Definition: FileHelpers.cpp:57
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:52
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.
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.