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_CERR.h" 00043 #include "OutputDevice_Network.h" 00044 #include "PlainXMLFormatter.h" 00045 #include <utils/common/TplConvert.h> 00046 #include <utils/common/UtilExceptions.h> 00047 #include <utils/common/FileHelpers.h> 00048 #include <utils/common/ToString.h> 00049 #include <utils/options/OptionsCont.h> 00050 00051 #ifdef CHECK_MEMORY_LEAKS 00052 #include <foreign/nvwa/debug_new.h> 00053 #endif // CHECK_MEMORY_LEAKS 00054 00055 00056 // =========================================================================== 00057 // static member definitions 00058 // =========================================================================== 00059 std::map<std::string, OutputDevice*> OutputDevice::myOutputDevices; 00060 00061 00062 // =========================================================================== 00063 // static method definitions 00064 // =========================================================================== 00065 OutputDevice& 00066 OutputDevice::getDevice(const std::string& name, 00067 const std::string& base) { 00068 std::string internalName = name; 00069 if (name == "-") { 00070 internalName = "stdout"; 00071 } 00072 // check whether the device has already been aqcuired 00073 if (myOutputDevices.find(internalName) != myOutputDevices.end()) { 00074 return *myOutputDevices[internalName]; 00075 } 00076 // build the device 00077 OutputDevice* dev = 0; 00078 // check whether the device shall print to stdout 00079 if (internalName == "stdout") { 00080 dev = OutputDevice_COUT::getDevice(); 00081 } else if (internalName == "stderr") { 00082 dev = OutputDevice_CERR::getDevice(); 00083 } else if (FileHelpers::isSocket(internalName)) { 00084 try { 00085 int port = TplConvert<char>::_2int(internalName.substr(internalName.find(":") + 1).c_str()); 00086 dev = new OutputDevice_Network(internalName.substr(0, internalName.find(":")), port); 00087 } catch (NumberFormatException&) { 00088 throw IOError("Given port number '" + internalName.substr(internalName.find(":") + 1) + "' is not numeric."); 00089 } catch (EmptyData&) { 00090 throw IOError("No port number given."); 00091 } 00092 } else { 00093 dev = new OutputDevice_File(FileHelpers::checkForRelativity(internalName, base), internalName.find(".sbx") != std::string::npos); 00094 } 00095 dev->setPrecision(); 00096 dev->getOStream() << std::setiosflags(std::ios::fixed); 00097 myOutputDevices[internalName] = dev; 00098 return *dev; 00099 } 00100 00101 00102 bool 00103 OutputDevice::createDeviceByOption(const std::string& optionName, 00104 const std::string& rootElement) { 00105 if (!OptionsCont::getOptions().isSet(optionName)) { 00106 return false; 00107 } 00108 OutputDevice& dev = OutputDevice::getDevice(OptionsCont::getOptions().getString(optionName)); 00109 if (rootElement != "") { 00110 dev.writeXMLHeader(rootElement); 00111 } 00112 return true; 00113 } 00114 00115 00116 OutputDevice& 00117 OutputDevice::getDeviceByOption(const std::string& optionName) throw(IOError, InvalidArgument) { 00118 std::string devName = OptionsCont::getOptions().getString(optionName); 00119 if (myOutputDevices.find(devName) == myOutputDevices.end()) { 00120 throw InvalidArgument("Device '" + devName + "' has not been created."); 00121 } 00122 return OutputDevice::getDevice(devName); 00123 } 00124 00125 00126 void 00127 OutputDevice::closeAll() { 00128 while (myOutputDevices.size() != 0) { 00129 myOutputDevices.begin()->second->close(); 00130 } 00131 myOutputDevices.clear(); 00132 } 00133 00134 00135 std::string 00136 OutputDevice::realString(const SUMOReal v, const int precision) { 00137 std::ostringstream oss; 00138 if (v == 0) { 00139 return "0"; 00140 } 00141 if (v < pow(10., -precision)) { 00142 oss.setf(std::ios::scientific, std::ios::floatfield); 00143 } else { 00144 oss.setf(std::ios::fixed , std::ios::floatfield); // use decimal format 00145 oss.setf(std::ios::showpoint); // print decimal point 00146 oss << std::setprecision(precision); 00147 } 00148 oss << v; 00149 return oss.str(); 00150 } 00151 00152 00153 // =========================================================================== 00154 // member method definitions 00155 // =========================================================================== 00156 OutputDevice::OutputDevice(const bool binary, const unsigned int defaultIndentation) 00157 : myAmBinary(binary) { 00158 if (binary) { 00159 myFormatter = new BinaryFormatter(); 00160 } else { 00161 myFormatter = new PlainXMLFormatter(defaultIndentation); 00162 } 00163 } 00164 00165 00166 OutputDevice::~OutputDevice() { 00167 delete myFormatter; 00168 } 00169 00170 00171 bool 00172 OutputDevice::ok() { 00173 return getOStream().good(); 00174 } 00175 00176 00177 void 00178 OutputDevice::close() { 00179 while (closeTag()) {} 00180 for (std::map<std::string, OutputDevice*>::iterator i = myOutputDevices.begin(); i != myOutputDevices.end(); ++i) { 00181 if (i->second == this) { 00182 myOutputDevices.erase(i); 00183 break; 00184 } 00185 } 00186 delete this; 00187 } 00188 00189 00190 void 00191 OutputDevice::setPrecision(unsigned int precision) { 00192 getOStream() << std::setprecision(precision); 00193 } 00194 00195 00196 bool 00197 OutputDevice::writeXMLHeader(const std::string& rootElement, const std::string xmlParams, 00198 const std::string& attrs, const std::string& comment) { 00199 return myFormatter->writeXMLHeader(getOStream(), rootElement, xmlParams, attrs, comment); 00200 } 00201 00202 00203 OutputDevice& 00204 OutputDevice::openTag(const std::string& xmlElement) { 00205 myFormatter->openTag(getOStream(), xmlElement); 00206 return *this; 00207 } 00208 00209 00210 OutputDevice& 00211 OutputDevice::openTag(const SumoXMLTag& xmlElement) { 00212 myFormatter->openTag(getOStream(), xmlElement); 00213 return *this; 00214 } 00215 00216 00217 void 00218 OutputDevice::closeOpener() { 00219 myFormatter->closeOpener(getOStream()); 00220 } 00221 00222 00223 bool 00224 OutputDevice::closeTag(bool abbreviated) { 00225 if (myFormatter->closeTag(getOStream(), abbreviated)) { 00226 postWriteHook(); 00227 return true; 00228 } 00229 return false; 00230 } 00231 00232 00233 void 00234 OutputDevice::postWriteHook() {} 00235 00236 00237 void 00238 OutputDevice::inform(const std::string& msg, const char progress) { 00239 if (progress != 0) { 00240 getOStream() << msg << progress; 00241 } else { 00242 getOStream() << msg << '\n'; 00243 } 00244 postWriteHook(); 00245 } 00246 00247 00248 OutputDevice& 00249 OutputDevice::writeAttr(std::string attr, std::string val) { 00250 myFormatter->writeAttr(getOStream(), attr, val); 00251 return *this; 00252 } 00253 00254 /****************************************************************************/ 00255