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-sim.org/
12 // Copyright (C) 2004-2014 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 "OutputDevice.h"
39 #include "OutputDevice_File.h"
40 #include "OutputDevice_COUT.h"
41 #include "OutputDevice_CERR.h"
42 #include "OutputDevice_Network.h"
43 #include "PlainXMLFormatter.h"
47 #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  // check whether the device has already been aqcuired
68  if (myOutputDevices.find(name) != myOutputDevices.end()) {
69  return *myOutputDevices[name];
70  }
71  // build the device
72  OutputDevice* dev = 0;
73  // check whether the device shall print to stdout
74  if (name == "stdout") {
76  } else if (name == "stderr") {
78  } else if (FileHelpers::isSocket(name)) {
79  try {
80  int port = TplConvert::_2int(name.substr(name.find(":") + 1).c_str());
81  dev = new OutputDevice_Network(name.substr(0, name.find(":")), port);
82  } catch (NumberFormatException&) {
83  throw IOError("Given port number '" + name.substr(name.find(":") + 1) + "' is not numeric.");
84  } catch (EmptyData&) {
85  throw IOError("No port number given.");
86  }
87  } else {
88  const size_t len = name.length();
89  dev = new OutputDevice_File(name, len > 4 && name.substr(len - 4) == ".sbx");
90  }
91  dev->setPrecision();
92  dev->getOStream() << std::setiosflags(std::ios::fixed);
93  myOutputDevices[name] = dev;
94  return *dev;
95 }
96 
97 
98 bool
99 OutputDevice::createDeviceByOption(const std::string& optionName,
100  const std::string& rootElement,
101  const std::string& schemaFile) {
102  if (!OptionsCont::getOptions().isSet(optionName)) {
103  return false;
104  }
105  OutputDevice& dev = OutputDevice::getDevice(OptionsCont::getOptions().getString(optionName));
106  if (rootElement != "") {
107  if (schemaFile != "") {
108  dev.writeXMLHeader(rootElement, "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/" + schemaFile + "\"");
109  } else {
110  dev.writeXMLHeader(rootElement);
111  }
112  }
113  return true;
114 }
115 
116 
118 OutputDevice::getDeviceByOption(const std::string& optionName) {
119  std::string devName = OptionsCont::getOptions().getString(optionName);
120  if (myOutputDevices.find(devName) == myOutputDevices.end()) {
121  throw InvalidArgument("Device '" + devName + "' has not been created.");
122  }
123  return OutputDevice::getDevice(devName);
124 }
125 
126 
127 void
129  std::vector<OutputDevice*> errorDevices;
130  std::vector<OutputDevice*> nonErrorDevices;
131  for (std::map<std::string, OutputDevice*>::iterator i = myOutputDevices.begin(); i != myOutputDevices.end(); ++i) {
132  if (MsgHandler::getErrorInstance()->isRetriever(i->second)) {
133  errorDevices.push_back(i->second);
134  } else {
135  nonErrorDevices.push_back(i->second);
136  }
137  }
138  for (std::vector<OutputDevice*>::iterator i = nonErrorDevices.begin(); i != nonErrorDevices.end(); ++i) {
139  try {
140  (*i)->close();
141  } catch (const IOError& e) {
142  WRITE_ERROR("Error on closing output devices.");
143  WRITE_ERROR(e.what());
144  }
145  }
146  for (std::vector<OutputDevice*>::iterator i = errorDevices.begin(); i != errorDevices.end(); ++i) {
147  try {
148  (*i)->close();
149  } catch (const IOError& e) {
150  std::cerr << "Error on closing error output devices." << std::endl;
151  std::cerr << e.what() << std::endl;
152  }
153  }
154 }
155 
156 
157 std::string
158 OutputDevice::realString(const SUMOReal v, const int precision) {
159  std::ostringstream oss;
160  if (v == 0) {
161  return "0";
162  }
163  if (v < pow(10., -precision)) {
164  oss.setf(std::ios::scientific, std::ios::floatfield);
165  } else {
166  oss.setf(std::ios::fixed , std::ios::floatfield); // use decimal format
167  oss.setf(std::ios::showpoint); // print decimal point
168  oss << std::setprecision(precision);
169  }
170  oss << v;
171  return oss.str();
172 }
173 
174 
175 // ===========================================================================
176 // member method definitions
177 // ===========================================================================
178 OutputDevice::OutputDevice(const bool binary, const unsigned int defaultIndentation)
179  : myAmBinary(binary) {
180  if (binary) {
182  } else {
183  myFormatter = new PlainXMLFormatter(defaultIndentation);
184  }
185 }
186 
187 
189  delete myFormatter;
190 }
191 
192 
193 bool
195  return getOStream().good();
196 }
197 
198 
199 void
201  while (closeTag()) {}
202  for (std::map<std::string, OutputDevice*>::iterator i = myOutputDevices.begin(); i != myOutputDevices.end(); ++i) {
203  if (i->second == this) {
204  myOutputDevices.erase(i);
205  break;
206  }
207  }
208  delete this;
209 }
210 
211 
212 void
213 OutputDevice::setPrecision(unsigned int precision) {
214  getOStream() << std::setprecision(precision);
215 }
216 
217 
218 bool
219 OutputDevice::writeXMLHeader(const std::string& rootElement,
220  const std::string& attrs, const std::string& comment) {
221  return myFormatter->writeXMLHeader(getOStream(), rootElement, attrs, comment);
222 }
223 
224 
226 OutputDevice::openTag(const std::string& xmlElement) {
227  myFormatter->openTag(getOStream(), xmlElement);
228  return *this;
229 }
230 
231 
233 OutputDevice::openTag(const SumoXMLTag& xmlElement) {
234  myFormatter->openTag(getOStream(), xmlElement);
235  return *this;
236 }
237 
238 
239 bool
241  if (myFormatter->closeTag(getOStream())) {
242  postWriteHook();
243  return true;
244  }
245  return false;
246 }
247 
248 
249 void
251 
252 
253 void
254 OutputDevice::inform(const std::string& msg, const char progress) {
255  if (progress != 0) {
256  getOStream() << msg << progress;
257  } else {
258  getOStream() << msg << '\n';
259  }
260  postWriteHook();
261 }
262 
263 
264 /****************************************************************************/
265