tue_config
write.cpp
Go to the documentation of this file.
1 #include "tue/config/write.h"
2 
3 #include "tue/config/data.h"
4 #include "tue/config/node.h"
5 #include "tue/config/map.h"
6 #include "tue/config/sequence.h"
7 
8 #include <fstream>
9 
10 namespace tue
11 {
12 
13 namespace config
14 {
15 
16 // ----------------------------------------------------------------------------------------------------
17 
18 struct WriterImpl
19 {
20 
21  WriterImpl(std::ostream& out_, const tue::config::Data& cfg_) : out(out_), cfg(cfg_) {}
22 
23  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
24 
31 
32  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
33 
34  void setIndentSize(int n)
35  {
36  tab.clear();
37 
38  if (n <= 0)
39  {
40  newline.clear();
41  return;
42  }
43 
44  newline = "\n";
45 
46  for(int i = 0; i < n; ++i)
47  tab += " ";
48 
49  for(int i = 0; i < n - 2; ++i)
50  yaml_array_tab += " ";
51  }
52 
53  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
54 
55  void writeJSON(const NodePtr& n, const std::string& indent)
56  {
57  out << "{" << newline;
58 
59  Map* map = static_cast<Map*>(n.get());
60 
61  bool first = true;
62  std::string new_indent = indent + tab;
63 
64  const std::map<Label, Variant>& values = map->values;
65  for(std::map<Label, Variant>::const_iterator it = values.begin(); it != values.end(); ++it)
66  {
67  if (!first)
68  out << "," << newline;
69  else
70  first = false;
71 
72  out << new_indent << "\"" << cfg.getName(it->first) << "\"" << delimiter;
73 
74  const Variant& v = it->second;
75  if (v.isString())
76  out << "\"" << v << "\"";
77  else
78  out << v;
79  }
80 
81  const std::map<Label, NodeIdx>& children = map->map_;
82  for(std::map<Label, NodeIdx>::const_iterator it = children.begin(); it != children.end(); ++it)
83  {
84  if (!first)
85  out << "," << newline;
86  else
87  first = false;
88 
89  out << new_indent << "\"" << cfg.getName(it->first) << "\"" << delimiter;
90 
91  const NodePtr& m = cfg.nodes[it->second];
92 
93  if (m->type() == ARRAY)
94  {
95  out << "[" << newline;
96 
97  Sequence* array = static_cast<Sequence*>(m.get());
98  const std::vector<NodeIdx>& children = array->children_;
99  for(std::vector<NodeIdx>::const_iterator it = children.begin(); it != children.end(); ++it)
100  {
101  if (it != children.begin())
102  out << "," << newline;
103 
104  out << new_indent << tab;
105 
106  writeJSON(cfg.nodes[*it], new_indent + tab);
107  }
108 
109  out << newline << new_indent << "]";
110  }
111  else
112  {
113  writeJSON(cfg.nodes[it->second], new_indent);
114  }
115  }
116 
117  out << newline << indent << "}";
118  }
119 
120  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
121 
122  void writeYAML(const NodePtr& n, const std::string& indent, bool array_item_start)
123  {
124  Map* map = static_cast<Map*>(n.get());
125 
126  const std::map<Label, Variant>& values = map->values;
127  for(std::map<Label, Variant>::const_iterator it = values.begin(); it != values.end(); ++it)
128  {
129  if (array_item_start)
130  array_item_start = false;
131  else
132  out << indent;
133 
134  out << cfg.getName(it->first) << delimiter << " " << it->second << std::endl;
135  }
136 
137  const std::map<Label, NodeIdx>& children = map->map_;
138  for(std::map<Label, NodeIdx>::const_iterator it = children.begin(); it != children.end(); ++it)
139  {
140  if (array_item_start)
141  array_item_start = false;
142  else
143  out << indent;
144 
145  out << cfg.getName(it->first) << delimiter << std::endl;
146 
147  const NodePtr& m = cfg.nodes[it->second];
148 
149  if (m->type() == ARRAY)
150  {
151  Sequence* array = static_cast<Sequence*>(m.get());
152  const std::vector<NodeIdx>& children = array->children_;
153  for(std::vector<NodeIdx>::const_iterator it = children.begin(); it != children.end(); ++it)
154  {
155  out << indent << yaml_array_tab << "- ";
156  writeYAML(cfg.nodes[*it], indent + tab, true);
157  }
158  }
159  else
160  {
161  writeYAML(cfg.nodes[it->second], indent + tab, false);
162  }
163  }
164  }
165 };
166 
167 // ----------------------------------------------------------------------------------------------------
168 
169 void toStream(std::ostream& s, const DataConstPointer& data, WriteType write_type, int indent_size)
170 {
171  if (!data.data)
172  return;
173 
174  WriterImpl writer(s, *data.data);
175 
176  if (write_type == XML)
177  {
178  throw std::logic_error("Writing XML is not yet implemented");
179  }
180  else if (write_type == YAML)
181  {
182  writer.delimiter = ":";
183  writer.setIndentSize(std::max<int>(indent_size, 2));
184  writer.writeYAML(data.data->nodes[data.idx], "", false);
185  }
186  else // JSON
187  {
188  if (indent_size > 0)
189  writer.delimiter = ": ";
190  else
191  writer.delimiter = ":";
192 
193  writer.setIndentSize(indent_size);
194  writer.writeJSON(data.data->nodes[data.idx], "");
195  }
196 }
197 
198 // ----------------------------------------------------------------------------------------------------
199 
200 bool toFile(const std::string& filename, const DataConstPointer& data, WriteType write_type, int indent_size)
201 {
202  return toFile(filename.c_str(), data, write_type, indent_size);
203 }
204 
205 // ----------------------------------------------------------------------------------------------------
206 
207 bool toFile(const char* filename, const DataConstPointer& data, WriteType write_type, int indent_size)
208 {
209  std::ofstream out;
210  out.open(filename);
211  if (!out.is_open())
212  return false;
213 
214  toStream(out, data, write_type, indent_size);
215  return true;
216 }
217 
218 // ----------------------------------------------------------------------------------------------------
219 
220 }
221 }
tue::config::Data::getName
const std::string & getName(const Label &label) const
Definition: data.h:55
fstream
std::string
tue::config::WriterImpl::yaml_array_tab
std::string yaml_array_tab
Definition: write.cpp:28
tue::config::toFile
bool toFile(const std::string &filename, const DataConstPointer &data, WriteType write_type, int indent_size=0)
Definition: write.cpp:200
tue::config::XML
@ XML
Definition: write.h:14
tue::config::WriterImpl::WriterImpl
WriterImpl(std::ostream &out_, const tue::config::Data &cfg_)
Definition: write.cpp:21
std::vector< NodeIdx >
tue::config::WriterImpl::out
std::ostream & out
Definition: write.cpp:25
tue::config::WriteType
WriteType
Definition: write.h:12
tue::config::toStream
void toStream(std::ostream &s, const DataConstPointer &data, WriteType write_type, int indent_size=0)
Definition: write.cpp:169
tue::config::WriterImpl::setIndentSize
void setIndentSize(int n)
Definition: write.cpp:34
tue::config::Sequence::children_
std::vector< NodeIdx > children_
Definition: sequence.h:40
tue::config::WriterImpl::cfg
const tue::config::Data & cfg
Definition: write.cpp:26
tue::config::Map::map_
std::map< Label, NodeIdx > map_
Definition: map.h:62
sequence.h
std::string::clear
T clear(T... args)
tue::config::Map
Definition: map.h:12
tue::config::Data::nodes
std::vector< NodePtr > nodes
Definition: data.h:77
tue::config::WriterImpl
Definition: write.cpp:18
tue::config::WriterImpl::delimiter
std::string delimiter
Definition: write.cpp:30
tue::config::YAML
@ YAML
Definition: write.h:15
node.h
std::ostream
std::ofstream
std::string::c_str
T c_str(T... args)
std::ofstream::open
T open(T... args)
std::logic_error
tue::config::Variant::isString
bool isString() const
Definition: variant.h:140
map.h
tue::config::WriterImpl::tab
std::string tab
Definition: write.cpp:27
std::map
tue::config::WriterImpl::writeJSON
void writeJSON(const NodePtr &n, const std::string &indent)
Definition: write.cpp:55
tue::config::ARRAY
@ ARRAY
Definition: node_type.h:13
tue::config::Data
Definition: data.h:17
tue::config::WriterImpl::writeYAML
void writeYAML(const NodePtr &n, const std::string &indent, bool array_item_start)
Definition: write.cpp:122
tue::config::WriterImpl::newline
std::string newline
Definition: write.cpp:29
std::endl
T endl(T... args)
std::map::begin
T begin(T... args)
data.h
tue::config::NodePtr
boost::shared_ptr< Node > NodePtr
Definition: types.h:21
tue::config::DataConstPointer
Definition: data_pointer.h:35
std::map::end
T end(T... args)
tue::config::Map::values
std::map< Label, Variant > values
Definition: map.h:64
write.h
std::ofstream::is_open
T is_open(T... args)
tue
tue::config::Variant
Definition: variant.h:111
tue::config::Sequence
Definition: sequence.h:14
config
tue::config::ReaderWriter config
Definition: sdf_gtest.cpp:9