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 
11 
13 
14 #include "common.h"
15 
16 #include <rapidjson/writer.h>
17 #include <rapidjson/prettywriter.h>
18 #include <rapidjson/stringbuffer.h>
19 
20 
21 namespace ariles2
22 {
23  namespace ns_rapidjson
24  {
25  namespace impl
26  {
27  class Writer : public ariles2::ns_rapidjson::ImplBase<::rapidjson::Value>,
29  {
30  public:
31  template <class... t_Args>
32  explicit Writer(t_Args &&...args) : FileVisitorImplementation(std::forward<t_Args>(args)...)
33  {
34  document_.SetObject();
35  }
36  };
37  } // namespace impl
38  } // namespace ns_rapidjson
39 } // namespace ariles2
40 
41 
42 namespace ariles2
43 {
44  namespace ns_rapidjson
45  {
46  Writer::Writer(const std::string &file_name)
47  {
48  impl_ = ImplPtr(new impl::Writer(file_name));
49  }
50 
51 
52  Writer::Writer(std::ostream &output_stream)
53  {
54  impl_ = ImplPtr(new impl::Writer(output_stream));
55  }
56 
57 
59  {
60  ::rapidjson::StringBuffer buffer;
61  ::rapidjson::PrettyWriter<::rapidjson::StringBuffer> writer(buffer);
62  impl_->document_.Accept(writer);
63  *impl_->output_stream_ << buffer.GetString() << std::endl;
64  impl_->output_stream_->flush();
65  }
66 
67 
68  void Writer::startMap(const Parameters &, const std::size_t /*num_entries*/)
69  {
70  impl_->getRawNode().SetObject();
71  // not provided in older versions
72  // impl_->getRawNode().MemberReserve(num_entries, impl_->document_.GetAllocator());
73  }
74 
75  void Writer::startMapEntry(const std::string &map_name)
76  {
77  ::rapidjson::Value key(map_name.c_str(), impl_->document_.GetAllocator());
78  ::rapidjson::Value value;
79  impl_->getRawNode().AddMember(key, value, impl_->document_.GetAllocator());
80 
81  // hack, we assume that the last added
82  // child is the last in the list
83  const ::rapidjson::Value::MemberIterator child = --(impl_->getRawNode().MemberEnd());
84  impl_->emplace(&(child->value));
85  }
86 
88  {
89  impl_->pop();
90  }
91 
92 
93  void Writer::startArray(const std::size_t size, const bool /*compact*/)
94  {
96  impl_->getRawNode().SetArray();
97  impl_->getRawNode().Reserve(size, impl_->document_.GetAllocator());
98  for (std::size_t i = 0; i < size; ++i)
99  {
100  ::rapidjson::Value value;
101  impl_->getRawNode().PushBack(value, impl_->document_.GetAllocator());
102  }
103  impl_->emplace(0, size);
104  }
105 
107  {
109  CPPUT_ASSERT(
110  impl_->back().index_ < impl_->back().size_,
111  "Internal error: array has more elements than expected.");
112  }
113 
115  {
117  impl_->shiftArray();
118  }
119 
121  {
123  impl_->pop();
124  }
125 
126 
127  /**
128  * @brief Write a configuration entry
129  *
130  * @param[in] element data
131  */
132  void Writer::writeElement(const std::string &element, const Parameters &)
133  {
134  impl_->getRawNode().SetString(element.c_str(), impl_->document_.GetAllocator());
135  }
136 
137  void Writer::writeElement(const bool &element, const Parameters &)
138  {
139  impl_->getRawNode().SetBool(element);
140  }
141 
142 
143  void Writer::writeElement(const float &element, const Parameters &param)
144  {
145  if (param.fallback_to_string_floats_)
146  {
147  impl_->getRawNode().SetString(
148  boost::lexical_cast<std::string>(element).c_str(), impl_->document_.GetAllocator());
149  }
150  else
151  {
152  impl_->getRawNode().SetDouble(element); // old API compatibility
153  // impl_->getRawNode().SetFloat(element);
154  }
155  }
156 
157 
158  void Writer::writeElement(const double &element, const Parameters &param)
159  {
160  if (param.fallback_to_string_floats_)
161  {
162  impl_->getRawNode().SetString(
163  boost::lexical_cast<std::string>(element).c_str(), impl_->document_.GetAllocator());
164  }
165  else
166  {
167  impl_->getRawNode().SetDouble(element);
168  }
169  }
170 
171 
172 
173 #define ARILES2_BASIC_TYPE(type) \
174  void Writer::writeElement(const type &element, const Parameters &) \
175  { \
176  impl_->getRawNode().SetInt64(element); \
177  }
178 
180 
181 #undef ARILES2_BASIC_TYPE
182 
183 
184 #define ARILES2_BASIC_TYPE(type) \
185  void Writer::writeElement(const type &element, const Parameters &) \
186  { \
187  impl_->getRawNode().SetUint64(element); \
188  }
189 
191 
192 #undef ARILES2_BASIC_TYPE
193  } // namespace ns_rapidjson
194 } // namespace ariles2
::rapidjson::Document document_
instance of the parser
Definition: common.h:40
void startMap(const Parameters &, const std::size_t)
Starts a nested map in the configuration file.
Definition: writer.cpp:68
void startArray(const std::size_t size, const bool=false)
Definition: writer.cpp:93
void flush()
Flush the configuration to the output.
Definition: writer.cpp:58
void startMapEntry(const std::string &map_name)
Starts a nested map in the configuration file.
Definition: writer.cpp:75
Writer(const std::string &file_name)
Definition: writer.cpp:46
FileVisitorImplementation(const std::string &file_name)
Definition: write.h:384
void writeElement(const std::complex< t_Scalar > &entry, const Parameters &param)
Definition: write.h:264
#define CPPUT_ASSERT(condition,...)
Definition: exception.h:32
#define ARILES2_BASIC_UNSIGNED_INTEGER_TYPES_LIST
Definition: helpers.h:50
#define ARILES2_BASIC_SIGNED_INTEGER_TYPES_LIST
Definition: helpers.h:37
#define CPPUT_MACRO_SUBSTITUTE(macro)
Definition: misc.h:21
visitor::Parameters Parameters
Definition: count.h:26
Definition: basic.h:17
#define CPPUT_TRACE_FUNCTION
Definition: trace.h:126