|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00009 // Static storage of an output device and its base (abstract) implementation 00010 /****************************************************************************/ 00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00013 /****************************************************************************/ 00014 // 00015 // This file is part of SUMO. 00016 // SUMO is free software: you can redistribute it and/or modify 00017 // it under the terms of the GNU General Public License as published by 00018 // the Free Software Foundation, either version 3 of the License, or 00019 // (at your option) any later version. 00020 // 00021 /****************************************************************************/ 00022 00023 00024 // =========================================================================== 00025 // included modules 00026 // =========================================================================== 00027 #ifdef _MSC_VER 00028 #include <windows_config.h> 00029 #else 00030 #include <config.h> 00031 #endif 00032 00033 #include <map> 00034 #include <fstream> 00035 #include <sstream> 00036 #include <string> 00037 #include <iomanip> 00038 #include <cassert> 00039 #include "OutputDevice.h" 00040 #include "OutputDevice_File.h" 00041 #include "OutputDevice_COUT.h" 00042 #include "OutputDevice_Network.h" 00043 #include <utils/common/TplConvert.h> 00044 #include <utils/common/UtilExceptions.h> 00045 #include <utils/common/FileHelpers.h> 00046 #include <utils/common/ToString.h> 00047 #include <utils/options/OptionsCont.h> 00048 00049 #ifdef CHECK_MEMORY_LEAKS 00050 #include <foreign/nvwa/debug_new.h> 00051 #endif // CHECK_MEMORY_LEAKS 00052 00053 00054 // =========================================================================== 00055 // static member definitions 00056 // =========================================================================== 00057 OutputDevice::DeviceMap OutputDevice::myOutputDevices; 00058 00059 00060 // =========================================================================== 00061 // static method definitions 00062 // =========================================================================== 00063 OutputDevice& 00064 OutputDevice::getDevice(const std::string& name, 00065 const std::string& base) { 00066 // check whether the device has already been aqcuired 00067 if (myOutputDevices.find(name) != myOutputDevices.end()) { 00068 return *myOutputDevices[name]; 00069 } 00070 // build the device 00071 OutputDevice* dev = 0; 00072 // check whether the device shall print to stdout 00073 if (name == "stdout" || name == "-") { 00074 dev = new OutputDevice_COUT(); 00075 } else if (FileHelpers::isSocket(name)) { 00076 try { 00077 int port = TplConvert<char>::_2int(name.substr(name.find(":") + 1).c_str()); 00078 dev = new OutputDevice_Network(name.substr(0, name.find(":")), port); 00079 } catch (NumberFormatException&) { 00080 throw IOError("Given port number '" + name.substr(name.find(":") + 1) + "' is not numeric."); 00081 } catch (EmptyData&) { 00082 throw IOError("No port number given."); 00083 } 00084 } else { 00085 dev = new OutputDevice_File(FileHelpers::checkForRelativity(name, base)); 00086 } 00087 dev->setPrecision(); 00088 dev->getOStream() << std::setiosflags(std::ios::fixed); 00089 myOutputDevices[name] = dev; 00090 return *dev; 00091 } 00092 00093 00094 bool 00095 OutputDevice::createDeviceByOption(const std::string& optionName, 00096 const std::string& rootElement) { 00097 if (!OptionsCont::getOptions().isSet(optionName)) { 00098 return false; 00099 } 00100 OutputDevice& dev = OutputDevice::getDevice(OptionsCont::getOptions().getString(optionName)); 00101 if (rootElement != "") { 00102 dev.writeXMLHeader(rootElement); 00103 } 00104 return true; 00105 } 00106 00107 00108 OutputDevice& 00109 OutputDevice::getDeviceByOption(const std::string& optionName) throw(IOError, InvalidArgument) { 00110 std::string devName = OptionsCont::getOptions().getString(optionName); 00111 if (myOutputDevices.find(devName) == myOutputDevices.end()) { 00112 throw InvalidArgument("Device '" + devName + "' has not been created."); 00113 } 00114 return OutputDevice::getDevice(devName); 00115 } 00116 00117 00118 void 00119 OutputDevice::closeAll() { 00120 while (myOutputDevices.size() != 0) { 00121 myOutputDevices.begin()->second->close(); 00122 } 00123 myOutputDevices.clear(); 00124 } 00125 00126 00127 std::string 00128 OutputDevice::realString(const SUMOReal v, const int precision) { 00129 std::ostringstream oss; 00130 if (v == 0) { 00131 return "0"; 00132 } 00133 if (v < pow(10., -precision)) { 00134 oss.setf(std::ios::scientific, std::ios::floatfield); 00135 } else { 00136 oss.setf(std::ios::fixed , std::ios::floatfield); // use decimal format 00137 oss.setf(std::ios::showpoint); // print decimal point 00138 oss << std::setprecision(precision); 00139 } 00140 oss << v; 00141 return oss.str(); 00142 } 00143 00144 00145 // =========================================================================== 00146 // member method definitions 00147 // =========================================================================== 00148 OutputDevice::OutputDevice(const unsigned int defaultIndentation) 00149 : myDefaultIndentation(defaultIndentation) { 00150 } 00151 00152 00153 bool 00154 OutputDevice::ok() { 00155 return getOStream().good(); 00156 } 00157 00158 00159 void 00160 OutputDevice::close() { 00161 while (closeTag()) {} 00162 for (DeviceMap::iterator i = myOutputDevices.begin(); i != myOutputDevices.end(); ++i) { 00163 if (i->second == this) { 00164 myOutputDevices.erase(i); 00165 break; 00166 } 00167 } 00168 delete this; 00169 } 00170 00171 00172 void 00173 OutputDevice::setPrecision(unsigned int precision) { 00174 getOStream() << std::setprecision(precision); 00175 } 00176 00177 00178 bool 00179 OutputDevice::writeXMLHeader(const std::string& rootElement, const std::string xmlParams, 00180 const std::string& attrs, const std::string& comment) { 00181 if (myXMLStack.empty()) { 00182 OptionsCont::getOptions().writeXMLHeader(getOStream(), xmlParams); 00183 if (comment != "") { 00184 getOStream() << comment << "\n"; 00185 } 00186 openTag(rootElement); 00187 if (attrs != "") { 00188 getOStream() << " " << attrs; 00189 } 00190 getOStream() << ">\n"; 00191 return true; 00192 } 00193 return false; 00194 } 00195 00196 00197 OutputDevice& 00198 OutputDevice::indent() { 00199 getOStream() << std::string(4 * (myXMLStack.size() + myDefaultIndentation), ' '); 00200 postWriteHook(); 00201 return *this; 00202 } 00203 00204 00205 OutputDevice& 00206 OutputDevice::openTag(const std::string& xmlElement) { 00207 getOStream() << std::string(4 * (myXMLStack.size() + myDefaultIndentation), ' ') << "<" << xmlElement; 00208 postWriteHook(); 00209 myXMLStack.push_back(xmlElement); 00210 return *this; 00211 } 00212 00213 00214 OutputDevice& 00215 OutputDevice::openTag(const SumoXMLTag& xmlElement) { 00216 return openTag(toString(xmlElement)); 00217 } 00218 00219 00220 bool 00221 OutputDevice::closeTag(bool abbreviated) { 00222 if (!myXMLStack.empty()) { 00223 if (abbreviated) { 00224 getOStream() << "/>" << std::endl; 00225 } else { 00226 std::string indent(4 * (myXMLStack.size() + myDefaultIndentation - 1), ' '); 00227 getOStream() << indent << "</" << myXMLStack.back() << ">" << std::endl; 00228 } 00229 myXMLStack.pop_back(); 00230 postWriteHook(); 00231 return true; 00232 } 00233 return false; 00234 } 00235 00236 00237 void 00238 OutputDevice::postWriteHook() {} 00239 00240 00241 void 00242 OutputDevice::inform(const std::string& msg) { 00243 getOStream() << msg << '\n'; 00244 postWriteHook(); 00245 } 00246 00247 00248 OutputDevice& 00249 OutputDevice::writeAttr(std::string attr, std::string val) { 00250 getOStream() << " " << attr << "=\"" << val << "\""; 00251 return *this; 00252 } 00253 00254 /****************************************************************************/ 00255