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-2013 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>
49 
50 #ifdef CHECK_MEMORY_LEAKS
51 #include <foreign/nvwa/debug_new.h>
52 #endif // CHECK_MEMORY_LEAKS
53 
54 
55 // ===========================================================================
56 // static member definitions
57 // ===========================================================================
58 std::map<std::string, OutputDevice*> OutputDevice::myOutputDevices;
59 
60 
61 // ===========================================================================
62 // static method definitions
63 // ===========================================================================
65 OutputDevice::getDevice(const std::string& name,
66  const std::string& base) {
67  std::string internalName = name;
68  if (name == "-") {
69  internalName = "stdout";
70  }
71  // check whether the device has already been aqcuired
72  if (myOutputDevices.find(internalName) != myOutputDevices.end()) {
73  return *myOutputDevices[internalName];
74  }
75  // build the device
76  OutputDevice* dev = 0;
77  // check whether the device shall print to stdout
78  if (internalName == "stdout") {
80  } else if (internalName == "stderr") {
82  } else if (FileHelpers::isSocket(internalName)) {
83  try {
84  int port = TplConvert::_2int(internalName.substr(internalName.find(":") + 1).c_str());
85  dev = new OutputDevice_Network(internalName.substr(0, internalName.find(":")), port);
86  } catch (NumberFormatException&) {
87  throw IOError("Given port number '" + internalName.substr(internalName.find(":") + 1) + "' is not numeric.");
88  } catch (EmptyData&) {
89  throw IOError("No port number given.");
90  }
91  } else {
92  const size_t len = internalName.length();
93  dev = new OutputDevice_File(FileHelpers::checkForRelativity(internalName, base),
94  len > 4 && internalName.substr(len - 4) == ".sbx");
95  }
96  dev->setPrecision();
97  dev->getOStream() << std::setiosflags(std::ios::fixed);
98  myOutputDevices[internalName] = dev;
99  return *dev;
100 }
101 
102 
103 bool
104 OutputDevice::createDeviceByOption(const std::string& optionName,
105  const std::string& rootElement) {
106  if (!OptionsCont::getOptions().isSet(optionName)) {
107  return false;
108  }
109  OutputDevice& dev = OutputDevice::getDevice(OptionsCont::getOptions().getString(optionName));
110  if (rootElement != "") {
111  if (rootElement == "routes" || rootElement == "netstate") {
112  dev.writeXMLHeader(rootElement, "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/" + rootElement + "_file.xsd\"");
113  } else {
114  dev.writeXMLHeader(rootElement);
115  }
116  }
117  return true;
118 }
119 
120 
122 OutputDevice::getDeviceByOption(const std::string& optionName) throw(IOError, InvalidArgument) {
123  std::string devName = OptionsCont::getOptions().getString(optionName);
124  if (myOutputDevices.find(devName) == myOutputDevices.end()) {
125  throw InvalidArgument("Device '" + devName + "' has not been created.");
126  }
127  return OutputDevice::getDevice(devName);
128 }
129 
130 
131 void
133  while (myOutputDevices.size() != 0) {
134  myOutputDevices.begin()->second->close();
135  }
136  myOutputDevices.clear();
137 }
138 
139 
140 std::string
141 OutputDevice::realString(const SUMOReal v, const int precision) {
142  std::ostringstream oss;
143  if (v == 0) {
144  return "0";
145  }
146  if (v < pow(10., -precision)) {
147  oss.setf(std::ios::scientific, std::ios::floatfield);
148  } else {
149  oss.setf(std::ios::fixed , std::ios::floatfield); // use decimal format
150  oss.setf(std::ios::showpoint); // print decimal point
151  oss << std::setprecision(precision);
152  }
153  oss << v;
154  return oss.str();
155 }
156 
157 
158 // ===========================================================================
159 // member method definitions
160 // ===========================================================================
161 OutputDevice::OutputDevice(const bool binary, const unsigned int defaultIndentation)
162  : myAmBinary(binary) {
163  if (binary) {
165  } else {
166  myFormatter = new PlainXMLFormatter(defaultIndentation);
167  }
168 }
169 
170 
172  delete myFormatter;
173 }
174 
175 
176 bool
178  return getOStream().good();
179 }
180 
181 
182 void
184  while (closeTag()) {}
185  for (std::map<std::string, OutputDevice*>::iterator i = myOutputDevices.begin(); i != myOutputDevices.end(); ++i) {
186  if (i->second == this) {
187  myOutputDevices.erase(i);
188  break;
189  }
190  }
191  delete this;
192 }
193 
194 
195 void
196 OutputDevice::setPrecision(unsigned int precision) {
197  getOStream() << std::setprecision(precision);
198 }
199 
200 
201 bool
202 OutputDevice::writeXMLHeader(const std::string& rootElement,
203  const std::string& attrs, const std::string& comment) {
204  return myFormatter->writeXMLHeader(getOStream(), rootElement, attrs, comment);
205 }
206 
207 
209 OutputDevice::openTag(const std::string& xmlElement) {
210  myFormatter->openTag(getOStream(), xmlElement);
211  return *this;
212 }
213 
214 
216 OutputDevice::openTag(const SumoXMLTag& xmlElement) {
217  myFormatter->openTag(getOStream(), xmlElement);
218  return *this;
219 }
220 
221 
222 bool
224  if (myFormatter->closeTag(getOStream())) {
225  postWriteHook();
226  return true;
227  }
228  return false;
229 }
230 
231 
232 void
234 
235 
236 void
237 OutputDevice::inform(const std::string& msg, const char progress) {
238  if (progress != 0) {
239  getOStream() << msg << progress;
240  } else {
241  getOStream() << msg << '\n';
242  }
243  postWriteHook();
244 }
245 
246 
248 OutputDevice::writeAttr(std::string attr, std::string val) {
249  myFormatter->writeAttr(getOStream(), attr, val);
250  return *this;
251 }
252 
253 /****************************************************************************/
254