SUMO - Simulation of Urban MObility

OutputDevice.cpp

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines