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