Ariles
writer.cpp
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4 
5  @copyright 2018-2020 Alexander Sherikov, Licensed under the Apache License, Version 2.0.
6  (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7 
8  @brief
9 */
10 
12 #include <yaml-cpp/yaml.h>
13 
14 
15 namespace ariles
16 {
17  namespace ns_yaml_cpp
18  {
19  namespace impl
20  {
22  {
23  public:
24  typedef ARILES_SHARED_PTR<YAML::Emitter> EmitterPtr;
25 
26 
27  public:
28  /// output file stream
29  std::ofstream config_ofs_;
30 
31  /// output stream
32  std::ostream *output_stream_;
33 
34  /// instance of YAML emitter, is destroyed and reinitialized by flush()
36 
37  std::size_t map_depth_;
39 
40 
41  public:
42  void initEmitter()
43  {
45  emitter_ = EmitterPtr(new YAML::Emitter);
46  emitter_->SetDoublePrecision(std::numeric_limits<double>::digits10);
47  if (output_stream_->tellp() != 0)
48  {
49  *emitter_ << YAML::Newline;
50  }
51  *emitter_ << YAML::BeginMap;
52  map_depth_ = 0;
53  skip_root_map_ = false;
54  }
55 
56 
58  {
60  *emitter_ << YAML::EndMap;
61  *output_stream_ << emitter_->c_str();
62  emitter_.reset();
63  }
64 
65  public:
66  explicit Writer(const std::string &file_name)
67  {
68  ariles::write::Visitor::openFile(config_ofs_, file_name);
69  output_stream_ = &config_ofs_;
70  initEmitter();
71  }
72 
73 
74  explicit Writer(std::ostream &output_stream)
75  {
76  output_stream_ = &output_stream;
77  initEmitter();
78  }
79 
80 
81  void flush()
82  {
83  destroyEmitter();
84  *output_stream_ << "\n";
85  output_stream_->flush();
86  initEmitter();
87  }
88  };
89  } // namespace impl
90  } // namespace ns_yaml_cpp
91 } // namespace ariles
92 
93 
94 namespace ariles
95 {
96  namespace ns_yaml_cpp
97  {
98  Writer::Writer(const std::string &file_name)
99  {
100  impl_ = ImplPtr(new Impl(file_name));
101  }
102 
103 
104  Writer::Writer(std::ostream &output_stream)
105  {
106  impl_ = ImplPtr(new Impl(output_stream));
107  }
108 
109 
110 
111  void Writer::descend(const std::string &map_name)
112  {
114  ARILES_TRACE_ENTRY(map_name);
115  *impl_->emitter_ << YAML::Key << map_name;
116  *impl_->emitter_ << YAML::Value;
117  }
118 
119 
120  void Writer::startMap(const std::size_t /*num_entries*/)
121  {
123  if (impl_->map_depth_ > 0 or false == impl_->skip_root_map_)
124  {
125  *impl_->emitter_ << YAML::BeginMap;
126  }
127  ++impl_->map_depth_;
128  }
129 
130 
132  {
134  ARILES_ASSERT(impl_->map_depth_ > 0, "Internal logic error.");
135  --impl_->map_depth_;
136  if (impl_->map_depth_ > 0 or false == impl_->skip_root_map_)
137  {
138  *impl_->emitter_ << YAML::EndMap;
139  }
140  }
141 
142 
144  {
146  impl_->flush();
147  }
148 
149 
150 
151  void Writer::startArray(const std::size_t /*size*/, const bool compact)
152  {
154  if (true == compact)
155  {
156  *impl_->emitter_ << YAML::Flow;
157  }
158  *impl_->emitter_ << YAML::BeginSeq;
159  }
160 
161 
163  {
165  *impl_->emitter_ << YAML::EndSeq;
166  }
167 
168 
169  void Writer::startRoot(const std::string &name)
170  {
172  ARILES_TRACE_ENTRY(name);
173  if (true == name.empty())
174  {
175  impl_->skip_root_map_ = true;
176  }
177  else
178  {
179  descend(name);
180  }
181  }
182 
183  void Writer::endRoot(const std::string &name)
184  {
186  if (false == name.empty())
187  {
188  ascend();
189  }
190  impl_->skip_root_map_ = false;
191  }
192 
193 
194 #define ARILES_BASIC_TYPE(type) \
195  void Writer::writeElement(const type &element) \
196  { \
197  *impl_->emitter_ << element; \
198  }
199 
201 
202 #undef ARILES_BASIC_TYPE
203 
204 
205 #define ARILES_BASIC_TYPE(type) \
206  void Writer::writeElement(const type &element) \
207  { \
208  if (true == ariles::isNaN(element)) \
209  { \
210  *impl_->emitter_ << ".nan"; \
211  } \
212  else \
213  { \
214  if (true == ariles::isInfinity(element)) \
215  { \
216  if (element < 0.0) \
217  { \
218  *impl_->emitter_ << "-.inf"; \
219  } \
220  else \
221  { \
222  *impl_->emitter_ << ".inf"; \
223  } \
224  } \
225  else \
226  { \
227  *impl_->emitter_ << element; \
228  } \
229  } \
230  }
231 
233 
234 #undef ARILES_BASIC_TYPE
235 
236 
237 
238  void Writer::writeElement(const std::string &element)
239  {
240  *impl_->emitter_ << element;
241  }
242 
243  void Writer::writeElement(const bool &element)
244  {
245  *impl_->emitter_ << element;
246  }
247  } // namespace ns_yaml_cpp
248 } // namespace ariles
#define ARILES_BASIC_INTEGER_TYPES_LIST
Definition: helpers.h:92
#define ARILES_TRACE_FUNCTION
Definition: trace.h:118
void flush()
Flush the configuration to the output.
Definition: writer.cpp:143
ARILES_SHARED_PTR< YAML::Emitter > EmitterPtr
Definition: writer.cpp:24
ARILES_MACRO_SUBSTITUTE(ARILES_BASIC_INTEGER_TYPES_LIST) ARILES_MACRO_SUBSTITUTE(ARILES_BASIC_REAL_TYPES_LIST) void Writer
Definition: writer.cpp:200
virtual void ascend()
Definition: write.h:58
void startRoot(const std::string &name)
Definition: writer.cpp:169
EmitterPtr emitter_
instance of YAML emitter, is destroyed and reinitialized by flush()
Definition: writer.cpp:35
Writer(const std::string &file_name)
Definition: writer.cpp:98
void startMap(const std::size_t)
Starts a nested map in the configuration file.
Definition: writer.cpp:120
std::ofstream config_ofs_
output file stream
Definition: writer.cpp:29
std::ostream * output_stream_
output stream
Definition: writer.cpp:32
static void openFile(std::ofstream &config_ofs, const std::string &file_name)
open configuration file
Definition: write.h:33
#define ARILES_BASIC_REAL_TYPES_LIST
Definition: helpers.h:96
void startArray(const std::size_t, const bool compact=false)
Definition: writer.cpp:151
void endMap()
Ends a nested map in the configuration file.
Definition: writer.cpp:131
Writer(const std::string &file_name)
Definition: writer.cpp:66
void endRoot(const std::string &name)
Definition: writer.cpp:183
#define ARILES_VISIBILITY_ATTRIBUTE
Definition: helpers.h:69
Writer(std::ostream &output_stream)
Definition: writer.cpp:74
#define ARILES_TRACE_ENTRY(entry_name)
Definition: trace.h:119
Definition: basic.h:17
void descend(const std::string &map_name)
Starts a nested map in the configuration file.
Definition: writer.cpp:111