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 2001-2010 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/options/OptionsCont.h>
00044 
00045 #ifdef CHECK_MEMORY_LEAKS
00046 #include <foreign/nvwa/debug_new.h>
00047 #endif // CHECK_MEMORY_LEAKS
00048 
00049 
00050 // ===========================================================================
00051 // static member definitions
00052 // ===========================================================================
00053 OutputDevice::DeviceMap OutputDevice::myOutputDevices;
00054 
00055 
00056 // ===========================================================================
00057 // static method definitions
00058 // ===========================================================================
00059 OutputDevice&
00060 OutputDevice::getDevice(const std::string &name,
00061                         const std::string &base) throw(IOError) {
00062     // check whether the device has already been aqcuired
00063     if (myOutputDevices.find(name)!=myOutputDevices.end()) {
00064         return *myOutputDevices[name];
00065     }
00066     // build the device
00067     OutputDevice *dev = 0;
00068     // check whether the device shall print to stdout
00069     if (name=="stdout" || name=="-") {
00070         dev = new OutputDevice_COUT();
00071     } else if (FileHelpers::isSocket(name)) {
00072         try {
00073             int port = TplConvert<char>::_2int(name.substr(name.find(":")+1).c_str());
00074             dev = new OutputDevice_Network(name.substr(0, name.find(":")), port);
00075         } catch (NumberFormatException &) {
00076             throw IOError("Given port number '" + name.substr(name.find(":")+1) + "' is not numeric.");
00077         } catch (EmptyData &) {
00078             throw IOError("No port number given.");
00079         }
00080     } else {
00081         dev = new OutputDevice_File(FileHelpers::checkForRelativity(name, base));
00082     }
00083     dev->setPrecision();
00084     dev->getOStream() << std::setiosflags(std::ios::fixed);
00085     myOutputDevices[name] = dev;
00086     return *dev;
00087 }
00088 
00089 
00090 bool
00091 OutputDevice::createDeviceByOption(const std::string &optionName,
00092                                    const std::string &rootElement) throw(IOError) {
00093     if (!OptionsCont::getOptions().isSet(optionName)) {
00094         return false;
00095     }
00096     OutputDevice& dev = OutputDevice::getDevice(OptionsCont::getOptions().getString(optionName));
00097     if (rootElement != "") {
00098         dev.writeXMLHeader(rootElement);
00099     }
00100     return true;
00101 }
00102 
00103 
00104 OutputDevice&
00105 OutputDevice::getDeviceByOption(const std::string &optionName) throw(IOError, InvalidArgument) {
00106     std::string devName = OptionsCont::getOptions().getString(optionName);
00107     if (myOutputDevices.find(devName)==myOutputDevices.end()) {
00108         throw InvalidArgument("Device '" + devName + "' has not been created.");
00109     }
00110     return OutputDevice::getDevice(devName);
00111 }
00112 
00113 
00114 void
00115 OutputDevice::closeAll() throw() {
00116     while (myOutputDevices.size()!=0) {
00117         myOutputDevices.begin()->second->close();
00118     }
00119     myOutputDevices.clear();
00120 }
00121 
00122 
00123 
00124 // ===========================================================================
00125 // member method definitions
00126 // ===========================================================================
00127 bool
00128 OutputDevice::ok() throw() {
00129     return getOStream().good();
00130 }
00131 
00132 void
00133 OutputDevice::close() throw() {
00134     while (closeTag());
00135     for (DeviceMap::iterator i=myOutputDevices.begin(); i!=myOutputDevices.end(); ++i) {
00136         if (i->second == this) {
00137             myOutputDevices.erase(i);
00138             break;
00139         }
00140     }
00141     delete this;
00142 }
00143 
00144 
00145 void
00146 OutputDevice::setPrecision(unsigned int precision) throw() {
00147     getOStream() << std::setprecision(precision);
00148 }
00149 
00150 
00151 bool
00152 OutputDevice::writeXMLHeader(const std::string &rootElement, const bool writeConfig,
00153                              const std::string &attrs, const std::string &comment) throw() {
00154     if (myXMLStack.empty()) {
00155         OptionsCont::getOptions().writeXMLHeader(getOStream(), writeConfig);
00156         if (comment != "") {
00157             getOStream() << comment << "\n";
00158         }
00159         openTag(rootElement);
00160         if (attrs != "") {
00161             getOStream() << " " << attrs;
00162         }
00163         getOStream() << ">\n";
00164         return true;
00165     }
00166     return false;
00167 }
00168 
00169 
00170 OutputDevice&
00171 OutputDevice::indent() throw() {
00172     getOStream() << std::string(4*myXMLStack.size(), ' ');
00173     postWriteHook();
00174     return *this;
00175 }
00176 
00177 
00178 OutputDevice&
00179 OutputDevice::openTag(const std::string &xmlElement) throw() {
00180     getOStream() << std::string(4*myXMLStack.size(), ' ') << "<" << xmlElement;
00181     postWriteHook();
00182     myXMLStack.push_back(xmlElement);
00183     return *this;
00184 }
00185 
00186 
00187 bool
00188 OutputDevice::closeTag(bool abbreviated) throw() {
00189     if (!myXMLStack.empty()) {
00190         if (abbreviated) {
00191             getOStream() << "/>" << std::endl;
00192         } else {
00193             std::string indent(4*(myXMLStack.size()-1), ' ');
00194             getOStream() << indent << "</" << myXMLStack.back() << ">" << std::endl;
00195         }
00196         myXMLStack.pop_back();
00197         postWriteHook();
00198         return true;
00199     }
00200     return false;
00201 }
00202 
00203 
00204 void
00205 OutputDevice::postWriteHook() throw() {}
00206 
00207 
00208 void
00209 OutputDevice::inform(const std::string &msg) {
00210     getOStream() << msg << '\n';
00211     postWriteHook();
00212 }
00213 
00214 
00215 /****************************************************************************/
00216 

Generated on Wed May 5 00:06:35 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6