rapidyaml  0.7.1
parse and emit YAML, and do it fast
writer.hpp
Go to the documentation of this file.
1 #ifndef _C4_YML_WRITER_HPP_
2 #define _C4_YML_WRITER_HPP_
3 
4 #ifndef _C4_YML_COMMON_HPP_
5 #include "./common.hpp"
6 #endif
7 
8 #include <c4/substr.hpp>
9 #include <stdio.h> // fwrite(), fputc()
10 #include <string.h> // memcpy()
11 
12 
13 namespace c4 {
14 namespace yml {
15 
16 /** @addtogroup doc_emit
17  * @{
18  */
19 
20 /** @defgroup doc_writers Writer objects to use with an Emitter
21  * @see Emitter
22  * @{
23  */
24 
25 
26 //-----------------------------------------------------------------------------
27 //-----------------------------------------------------------------------------
28 //-----------------------------------------------------------------------------
29 /** A writer that outputs to a file. Defaults to stdout. */
30 struct WriterFile
31 {
32  FILE * m_file;
33  size_t m_pos;
34 
35  WriterFile(FILE *f = nullptr) : m_file(f ? f : stdout), m_pos(0) {}
36 
37  inline substr _get(bool /*error_on_excess*/)
38  {
39  substr sp;
40  sp.str = nullptr;
41  sp.len = m_pos;
42  return sp;
43  }
44 
45  template<size_t N>
46  inline void _do_write(const char (&a)[N])
47  {
48  fwrite(a, sizeof(char), N - 1, m_file);
49  m_pos += N - 1;
50  }
51 
52  inline void _do_write(csubstr sp)
53  {
54  #if defined(__clang__)
55  # pragma clang diagnostic push
56  # pragma GCC diagnostic ignored "-Wsign-conversion"
57  #elif defined(__GNUC__)
58  # pragma GCC diagnostic push
59  # pragma GCC diagnostic ignored "-Wsign-conversion"
60  #endif
61  if(sp.empty()) return;
62  fwrite(sp.str, sizeof(csubstr::char_type), sp.len, m_file);
63  m_pos += sp.len;
64  #if defined(__clang__)
65  # pragma clang diagnostic pop
66  #elif defined(__GNUC__)
67  # pragma GCC diagnostic pop
68  #endif
69  }
70 
71  inline void _do_write(const char c)
72  {
73  fputc(c, m_file);
74  ++m_pos;
75  }
76 
77  inline void _do_write(const char c, size_t num_times)
78  {
79  for(size_t i = 0; i < num_times; ++i)
80  fputc(c, m_file);
81  m_pos += num_times;
82  }
83 };
84 
85 
86 //-----------------------------------------------------------------------------
87 //-----------------------------------------------------------------------------
88 //-----------------------------------------------------------------------------
89 /** A writer that outputs to an STL-like ostream. */
90 template<class OStream>
92 {
93  OStream& m_stream;
94  size_t m_pos;
95 
96  WriterOStream(OStream &s) : m_stream(s), m_pos(0) {}
97 
98  inline substr _get(bool /*error_on_excess*/)
99  {
100  substr sp;
101  sp.str = nullptr;
102  sp.len = m_pos;
103  return sp;
104  }
105 
106  template<size_t N>
107  inline void _do_write(const char (&a)[N])
108  {
109  m_stream.write(a, N - 1);
110  m_pos += N - 1;
111  }
112 
113  inline void _do_write(csubstr sp)
114  {
115  #if defined(__clang__)
116  # pragma clang diagnostic push
117  # pragma GCC diagnostic ignored "-Wsign-conversion"
118  #elif defined(__GNUC__)
119  # pragma GCC diagnostic push
120  # pragma GCC diagnostic ignored "-Wsign-conversion"
121  #endif
122  if(sp.empty()) return;
123  m_stream.write(sp.str, sp.len);
124  m_pos += sp.len;
125  #if defined(__clang__)
126  # pragma clang diagnostic pop
127  #elif defined(__GNUC__)
128  # pragma GCC diagnostic pop
129  #endif
130  }
131 
132  inline void _do_write(const char c)
133  {
134  m_stream.put(c);
135  ++m_pos;
136  }
137 
138  inline void _do_write(const char c, size_t num_times)
139  {
140  for(size_t i = 0; i < num_times; ++i)
141  m_stream.put(c);
142  m_pos += num_times;
143  }
144 };
145 
146 
147 //-----------------------------------------------------------------------------
148 //-----------------------------------------------------------------------------
149 //-----------------------------------------------------------------------------
150 /** a writer to a substr */
151 struct WriterBuf
152 {
153  substr m_buf;
154  size_t m_pos;
155 
156  WriterBuf(substr sp) : m_buf(sp), m_pos(0) {}
157 
158  inline substr _get(bool error_on_excess)
159  {
160  if(m_pos <= m_buf.len)
161  {
162  return m_buf.first(m_pos);
163  }
164  if(error_on_excess)
165  {
166  c4::yml::error("not enough space in the given buffer");
167  }
168  substr sp;
169  sp.str = nullptr;
170  sp.len = m_pos;
171  return sp;
172  }
173 
174  template<size_t N>
175  inline void _do_write(const char (&a)[N])
176  {
177  RYML_ASSERT( ! m_buf.overlaps(a));
178  if(m_pos + N-1 <= m_buf.len)
179  {
180  memcpy(&(m_buf[m_pos]), a, N-1);
181  }
182  m_pos += N-1;
183  }
184 
185  inline void _do_write(csubstr sp)
186  {
187  if(sp.empty()) return;
188  RYML_ASSERT( ! sp.overlaps(m_buf));
189  if(m_pos + sp.len <= m_buf.len)
190  {
191  memcpy(&(m_buf[m_pos]), sp.str, sp.len);
192  }
193  m_pos += sp.len;
194  }
195 
196  inline void _do_write(const char c)
197  {
198  if(m_pos + 1 <= m_buf.len)
199  m_buf[m_pos] = c;
200  ++m_pos;
201  }
202 
203  inline void _do_write(const char c, size_t num_times)
204  {
205  if(m_pos + num_times <= m_buf.len)
206  for(size_t i = 0; i < num_times; ++i)
207  m_buf[m_pos + i] = c;
208  m_pos += num_times;
209  }
210 };
211 
212 /** @ } */
213 
214 /** @ } */
215 
216 
217 } // namespace yml
218 } // namespace c4
219 
220 #endif /* _C4_YML_WRITER_HPP_ */
Common utilities and infrastructure used by ryml.
void _do_write(csubstr sp)
Definition: writer.hpp:113
WriterOStream(OStream &s)
Definition: writer.hpp:96
OStream & m_stream
Definition: writer.hpp:93
void _do_write(const char(&a)[N])
Definition: writer.hpp:46
void _do_write(const char c)
Definition: writer.hpp:71
WriterFile(FILE *f=nullptr)
Definition: writer.hpp:35
void _do_write(csubstr sp)
Definition: writer.hpp:185
substr _get(bool)
Definition: writer.hpp:37
void _do_write(const char c, size_t num_times)
Definition: writer.hpp:138
void _do_write(const char c, size_t num_times)
Definition: writer.hpp:203
void _do_write(const char(&a)[N])
Definition: writer.hpp:175
WriterBuf(substr sp)
Definition: writer.hpp:156
void _do_write(const char c)
Definition: writer.hpp:132
substr _get(bool)
Definition: writer.hpp:98
void _do_write(const char(&a)[N])
Definition: writer.hpp:107
void _do_write(csubstr sp)
Definition: writer.hpp:52
void _do_write(const char c, size_t num_times)
Definition: writer.hpp:77
substr _get(bool error_on_excess)
Definition: writer.hpp:158
void _do_write(const char c)
Definition: writer.hpp:196
void error(Callbacks const &cb, const char *msg, size_t msg_len, Location loc)
Definition: common.cpp:130
Definition: common.cpp:12
a writer to a substr
Definition: writer.hpp:152
A writer that outputs to a file.
Definition: writer.hpp:31
A writer that outputs to an STL-like ostream.
Definition: writer.hpp:92
read+write string views