00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #include <string>
00031 #include "SUMOSAXAttributes.h"
00032 #include <utils/common/MsgHandler.h>
00033 #include <utils/common/StringTokenizer.h>
00034 #include <iostream>
00035 #include <sstream>
00036
00037 #ifdef CHECK_MEMORY_LEAKS
00038 #include <foreign/nvwa/debug_new.h>
00039 #endif // CHECK_MEMORY_LEAKS
00040
00041
00042
00043
00044
00045 bool SUMOSAXAttributes::myHaveInformedAboutDeprecatedDivider = false;
00046
00047
00048
00049
00050
00051 bool
00052 SUMOSAXAttributes::setIDFromAttributes(const char * objecttype,
00053 std::string &id, bool report) const throw() {
00054 id = "";
00055 if (hasAttribute(SUMO_ATTR_ID)) {
00056 id = getString(SUMO_ATTR_ID);
00057 }
00058 if (id=="") {
00059 if (report) {
00060 MsgHandler::getErrorInstance()->inform("Missing id of a '" + std::string(objecttype) + "'-object.");
00061 }
00062 return false;
00063 }
00064 return true;
00065 }
00066
00067
00068 int
00069 SUMOSAXAttributes::getIntReporting(SumoXMLAttr attr, const char *objecttype, const char *objectid,
00070 bool &ok, bool report) const throw() {
00071 if (!hasAttribute(attr)) {
00072 if (report) {
00073 emitUngivenError(getName(attr), objecttype, objectid);
00074 }
00075 ok = false;
00076 return -1;
00077 }
00078 try {
00079 return getInt(attr);
00080 } catch (NumberFormatException &) {
00081 if (report) {
00082 emitFormatError(getName(attr), "an int", objecttype, objectid);
00083 }
00084 } catch (EmptyData &) {
00085 if (report) {
00086 emitEmptyError(getName(attr), objecttype, objectid);
00087 }
00088 }
00089 ok = false;
00090 return -1;
00091 }
00092
00093
00094 int
00095 SUMOSAXAttributes::getOptIntReporting(SumoXMLAttr attr, const char *objecttype, const char *objectid,
00096 bool &ok, int defaultValue, bool report) const throw() {
00097 if (!hasAttribute(attr)) {
00098 return defaultValue;
00099 }
00100 try {
00101 return getInt(attr);
00102 } catch (NumberFormatException &) {
00103 if (report) {
00104 emitFormatError(getName(attr), "an int", objecttype, objectid);
00105 }
00106 } catch (EmptyData &) {
00107 if (report) {
00108 emitEmptyError(getName(attr), objecttype, objectid);
00109 }
00110 }
00111 ok = false;
00112 return -1;
00113 }
00114
00115
00116 SUMOReal
00117 SUMOSAXAttributes::getSUMORealReporting(SumoXMLAttr attr, const char *objecttype, const char *objectid,
00118 bool &ok, bool report) const throw() {
00119 if (!hasAttribute(attr)) {
00120 if (report) {
00121 emitUngivenError(getName(attr), objecttype, objectid);
00122 }
00123 ok = false;
00124 return -1;
00125 }
00126 try {
00127 return getFloat(attr);
00128 } catch (NumberFormatException &) {
00129 if (report) {
00130 emitFormatError(getName(attr), "a real number", objecttype, objectid);
00131 }
00132 } catch (EmptyData &) {
00133 if (report) {
00134 emitEmptyError(getName(attr), objecttype, objectid);
00135 }
00136 }
00137 ok = false;
00138 return (SUMOReal) -1;
00139 }
00140
00141
00142 SUMOReal
00143 SUMOSAXAttributes::getOptSUMORealReporting(SumoXMLAttr attr, const char *objecttype, const char *objectid,
00144 bool &ok, SUMOReal defaultValue, bool report) const throw() {
00145 if (!hasAttribute(attr)) {
00146 return defaultValue;
00147 }
00148 try {
00149 return getFloat(attr);
00150 } catch (NumberFormatException &) {
00151 if (report) {
00152 emitFormatError(getName(attr), "a real number", objecttype, objectid);
00153 }
00154 } catch (EmptyData &) {
00155 if (report) {
00156 emitEmptyError(getName(attr), objecttype, objectid);
00157 }
00158 }
00159 ok = false;
00160 return (SUMOReal) -1;
00161 }
00162
00163
00164 bool
00165 SUMOSAXAttributes::getBoolReporting(SumoXMLAttr attr, const char *objecttype, const char *objectid,
00166 bool &ok, bool report) const throw() {
00167 if (!hasAttribute(attr)) {
00168 if (report) {
00169 emitUngivenError(getName(attr), objecttype, objectid);
00170 }
00171 ok = false;
00172 return false;
00173 }
00174 try {
00175 return getBool(attr);
00176 } catch (BoolFormatException &) {
00177 if (report) {
00178 emitFormatError(getName(attr), "a boolean", objecttype, objectid);
00179 }
00180 } catch (EmptyData &) {
00181 if (report) {
00182 emitEmptyError(getName(attr), objecttype, objectid);
00183 }
00184 }
00185 ok = false;
00186 return false;
00187 }
00188
00189
00190 bool
00191 SUMOSAXAttributes::getOptBoolReporting(SumoXMLAttr attr, const char *objecttype, const char *objectid,
00192 bool &ok, bool defaultValue, bool report) const throw() {
00193 if (!hasAttribute(attr)) {
00194 return defaultValue;
00195 }
00196 try {
00197 return getBool(attr);
00198 } catch (BoolFormatException &) {
00199 if (report) {
00200 emitFormatError(getName(attr), "a boolean", objecttype, objectid);
00201 }
00202 } catch (EmptyData &) {
00203 if (report) {
00204 emitEmptyError(getName(attr), objecttype, objectid);
00205 }
00206 }
00207 ok = false;
00208 return false;
00209 }
00210
00211
00212 std::string
00213 SUMOSAXAttributes::getStringReporting(SumoXMLAttr attr, const char *objecttype, const char *objectid,
00214 bool &ok, bool report) const throw() {
00215 if (!hasAttribute(attr)) {
00216 if (report) {
00217 emitUngivenError(getName(attr), objecttype, objectid);
00218 }
00219 ok = false;
00220 return "";
00221 }
00222 try {
00223 std::string ret = getString(attr);
00224 if (ret=="") {
00225 throw EmptyData();
00226 }
00227 return ret;
00228 } catch (EmptyData &) {
00229 if (report) {
00230 emitEmptyError(getName(attr), objecttype, objectid);
00231 }
00232 }
00233 ok = false;
00234 return "";
00235 }
00236
00237
00238 std::string
00239 SUMOSAXAttributes::getOptStringReporting(SumoXMLAttr attr, const char *objecttype, const char *objectid,
00240 bool &ok, const std::string&defaultValue, bool report) const throw() {
00241 if (!hasAttribute(attr)) {
00242 return defaultValue;
00243 }
00244 try {
00245 return getString(attr);
00246 } catch (EmptyData &) {
00247 if (report) {
00248 emitEmptyError(getName(attr), objecttype, objectid);
00249 }
00250 }
00251 ok = false;
00252 return "";
00253 }
00254
00255
00256 SUMOTime
00257 SUMOSAXAttributes::getSUMOTimeReporting(SumoXMLAttr attr, const char *objecttype, const char *objectid,
00258 bool &ok, bool report) const throw() {
00259 #ifdef HAVE_SUBSECOND_TIMESTEPS
00260 if (!hasAttribute(attr)) {
00261 if (report) {
00262 emitUngivenError(getName(attr), objecttype, objectid);
00263 }
00264 ok = false;
00265 return -1;
00266 }
00267 try {
00268 return (SUMOTime)(getFloat(attr) * 1000.);
00269 } catch (NumberFormatException &) {
00270 if (report) {
00271 emitFormatError(getName(attr), "a time value", objecttype, objectid);
00272 }
00273 } catch (EmptyData &) {
00274 if (report) {
00275 emitEmptyError(getName(attr), objecttype, objectid);
00276 }
00277 }
00278 ok = false;
00279 return (SUMOTime) -1;
00280 #else
00281 return getIntReporting(attr, objecttype, objectid, ok, report);
00282 #endif
00283 }
00284
00285
00286 SUMOTime
00287 SUMOSAXAttributes::getOptSUMOTimeReporting(SumoXMLAttr attr, const char *objecttype, const char *objectid,
00288 bool &ok, SUMOTime defaultValue, bool report) const throw() {
00289 #ifdef HAVE_SUBSECOND_TIMESTEPS
00290 if (!hasAttribute(attr)) {
00291 return defaultValue;
00292 }
00293 try {
00294 return (SUMOTime)(getFloat(attr)*1000.);
00295 } catch (NumberFormatException &) {
00296 if (report) {
00297 emitFormatError(getName(attr), "a real number", objecttype, objectid);
00298 }
00299 } catch (EmptyData &) {
00300 if (report) {
00301 emitEmptyError(getName(attr), objecttype, objectid);
00302 }
00303 }
00304 ok = false;
00305 return (SUMOTime) -1;
00306 #else
00307 return getOptIntReporting(attr, objecttype, objectid, ok, defaultValue, report);
00308 #endif
00309 }
00310
00311
00312
00313
00314
00315 void
00316 SUMOSAXAttributes::emitUngivenError(const std::string &attrname, const char *objecttype, const char *objectid) const throw() {
00317 std::ostringstream oss;
00318 oss << "Attribute '" << attrname << "' is missing in definition of ";
00319 if (objectid==0) {
00320 oss << "a ";
00321 }
00322 if (objecttype!=0) {
00323 oss << objecttype;
00324 } else {
00325 oss << "<unknown type>";
00326 }
00327 if (objectid!=0) {
00328 oss << " '" << objectid << "'";
00329 }
00330 oss << ".";
00331 MsgHandler::getErrorInstance()->inform(oss.str());
00332 }
00333
00334
00335 void
00336 SUMOSAXAttributes::emitEmptyError(const std::string &attrname, const char *objecttype, const char *objectid) const throw() {
00337 std::ostringstream oss;
00338 oss << "Attribute '" << attrname << "' in definition of ";
00339 if (objectid==0) {
00340 oss << "a ";
00341 }
00342 if (objecttype!=0) {
00343 oss << objecttype;
00344 } else {
00345 oss << "<unknown type>";
00346 }
00347 if (objectid!=0) {
00348 oss << " '" << objectid << "'";
00349 }
00350 oss << " is empty.";
00351 MsgHandler::getErrorInstance()->inform(oss.str());
00352 }
00353
00354
00355 void
00356 SUMOSAXAttributes::emitFormatError(const std::string &attrname, const std::string &type, const char *objecttype, const char *objectid) const throw() {
00357 std::ostringstream oss;
00358 oss << "Attribute '" << attrname << "' in definition of ";
00359 if (objectid==0) {
00360 oss << "a ";
00361 }
00362 if (objecttype!=0) {
00363 oss << objecttype;
00364 } else {
00365 oss << "<unknown type>";
00366 }
00367 if (objectid!=0) {
00368 oss << " '" << objectid << "'";
00369 }
00370 oss << " is not " << type << ".";
00371 MsgHandler::getErrorInstance()->inform(oss.str());
00372 }
00373
00374
00375 void
00376 SUMOSAXAttributes::parseStringVector(const std::string &def, std::vector<std::string> &into) throw() {
00377 if (def.find(';')!=std::string::npos||def.find(',')!=std::string::npos) {
00378 if (!myHaveInformedAboutDeprecatedDivider) {
00379 MsgHandler::getWarningInstance()->inform("Please note that using ';' and ',' as XML list separators is deprecated.\n From 1.0 onwards, only ' ' will be accepted.");
00380 myHaveInformedAboutDeprecatedDivider = true;
00381 }
00382 }
00383 StringTokenizer st(def, ";, ", true);
00384 while (st.hasNext()) {
00385 into.push_back(st.next());
00386 }
00387 }
00388
00389
00390
00391