SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OutputDevice.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Static storage of an output device and its base (abstract) implementation
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
12 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <map>
34 #include <fstream>
35 #include <sstream>
36 #include <string>
37 #include <iomanip>
38 #include <cassert>
39 #include "OutputDevice.h"
40 #include "OutputDevice_File.h"
41 #include "OutputDevice_COUT.h"
42 #include "OutputDevice_CERR.h"
43 #include "OutputDevice_Network.h"
44 #include "PlainXMLFormatter.h"
48 #include <utils/common/ToString.h>
50 
51 #ifdef CHECK_MEMORY_LEAKS
52 #include <foreign/nvwa/debug_new.h>
53 #endif // CHECK_MEMORY_LEAKS
54 
55 
56 // ===========================================================================
57 // static member definitions
58 // ===========================================================================
59 std::map<std::string, OutputDevice*> OutputDevice::myOutputDevices;
60 
61 
62 // ===========================================================================
63 // static method definitions
64 // ===========================================================================
66 OutputDevice::getDevice(const std::string& name,
67  const std::string& base) {
68  std::string internalName = name;
69  if (name == "-") {
70  internalName = "stdout";
71  }
72  // check whether the device has already been aqcuired
73  if (myOutputDevices.find(internalName) != myOutputDevices.end()) {
74  return *myOutputDevices[internalName];
75  }
76  // build the device
77  OutputDevice* dev = 0;
78  // check whether the device shall print to stdout
79  if (internalName == "stdout") {
81  } else if (internalName == "stderr") {
83  } else if (FileHelpers::isSocket(internalName)) {
84  try {
85  int port = TplConvert<char>::_2int(internalName.substr(internalName.find(":") + 1).c_str());
86  dev = new OutputDevice_Network(internalName.substr(0, internalName.find(":")), port);
87  } catch (NumberFormatException&) {
88  throw IOError("Given port number '" + internalName.substr(internalName.find(":") + 1) + "' is not numeric.");
89  } catch (EmptyData&) {
90  throw IOError("No port number given.");
91  }
92  } else {
93  dev = new OutputDevice_File(FileHelpers::checkForRelativity(internalName, base), internalName.find(".sbx") != std::string::npos);
94  }
95  dev->setPrecision();
96  dev->getOStream() << std::setiosflags(std::ios::fixed);
97  myOutputDevices[internalName] = dev;
98  return *dev;
99 }
100 
101 
102 bool
103 OutputDevice::createDeviceByOption(const std::string& optionName,
104  const std::string& rootElement) {
105  if (!OptionsCont::getOptions().isSet(optionName)) {
106  return false;
107  }
108  OutputDevice& dev = OutputDevice::getDevice(OptionsCont::getOptions().getString(optionName));
109  if (rootElement != "") {
110  dev.writeXMLHeader(rootElement);
111  }
112  return true;
113 }
114 
115 
117 OutputDevice::getDeviceByOption(const std::string& optionName) throw(IOError, InvalidArgument) {
118  std::string devName = OptionsCont::getOptions().getString(optionName);
119  if (myOutputDevices.find(devName) == myOutputDevices.end()) {
120  throw InvalidArgument("Device '" + devName + "' has not been created.");
121  }
122  return OutputDevice::getDevice(devName);
123 }
124 
125 
126 void
128  while (myOutputDevices.size() != 0) {
129  myOutputDevices.begin()->second->close();
130  }
131  myOutputDevices.clear();
132 }
133 
134 
135 std::string
136 OutputDevice::realString(const SUMOReal v, const int precision) {
137  std::ostringstream oss;
138  if (v == 0) {
139  return "0";
140  }
141  if (v < pow(10., -precision)) {
142  oss.setf(std::ios::scientific, std::ios::floatfield);
143  } else {
144  oss.setf(std::ios::fixed , std::ios::floatfield); // use decimal format
145  oss.setf(std::ios::showpoint); // print decimal point
146  oss << std::setprecision(precision);
147  }
148  oss << v;
149  return oss.str();
150 }
151 
152 
153 // ===========================================================================
154 // member method definitions
155 // ===========================================================================
156 OutputDevice::OutputDevice(const bool binary, const unsigned int defaultIndentation)
157  : myAmBinary(binary) {
158  if (binary) {
160  } else {
161  myFormatter = new PlainXMLFormatter(defaultIndentation);
162  }
163 }
164 
165 
167  delete myFormatter;
168 }
169 
170 
171 bool
173  return getOStream().good();
174 }
175 
176 
177 void
179  while (closeTag()) {}
180  for (std::map<std::string, OutputDevice*>::iterator i = myOutputDevices.begin(); i != myOutputDevices.end(); ++i) {
181  if (i->second == this) {
182  myOutputDevices.erase(i);
183  break;
184  }
185  }
186  delete this;
187 }
188 
189 
190 void
191 OutputDevice::setPrecision(unsigned int precision) {
192  getOStream() << std::setprecision(precision);
193 }
194 
195 
196 bool
197 OutputDevice::writeXMLHeader(const std::string& rootElement, const std::string xmlParams,
198  const std::string& attrs, const std::string& comment) {
199  return myFormatter->writeXMLHeader(getOStream(), rootElement, xmlParams, attrs, comment);
200 }
201 
202 
204 OutputDevice::openTag(const std::string& xmlElement) {
205  myFormatter->openTag(getOStream(), xmlElement);
206  return *this;
207 }
208 
209 
211 OutputDevice::openTag(const SumoXMLTag& xmlElement) {
212  myFormatter->openTag(getOStream(), xmlElement);
213  return *this;
214 }
215 
216 
217 void
220 }
221 
222 
223 bool
224 OutputDevice::closeTag(bool abbreviated) {
225  if (myFormatter->closeTag(getOStream(), abbreviated)) {
226  postWriteHook();
227  return true;
228  }
229  return false;
230 }
231 
232 
233 void
235 
236 
237 void
238 OutputDevice::inform(const std::string& msg, const char progress) {
239  if (progress != 0) {
240  getOStream() << msg << progress;
241  } else {
242  getOStream() << msg << '\n';
243  }
244  postWriteHook();
245 }
246 
247 
248 OutputDevice&
249 OutputDevice::writeAttr(std::string attr, std::string val) {
250  myFormatter->writeAttr(getOStream(), attr, val);
251  return *this;
252 }
253 
254 /****************************************************************************/
255