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