Merge pull request #2796 from jimklimov/fix-docs-markup
[networkupstools.git] / include / nutwriter.hpp
blob6d88ca6c093eab3f96197e74398d0bf03188db46
1 /*
2 nutwriter.hpp - NUT writer
4 Copyright (C)
5 2012 Vaclav Krpec <VaclavKrpec@Eaton.com>
6 2024 Jim Klimov <jimklimov+nut@gmail.com>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #ifndef nut_nutwriter_h
24 #define nut_nutwriter_h
26 #ifdef __cplusplus
28 #include "nutstream.hpp"
29 #include "nutconf.hpp"
31 #include <stdexcept>
34 namespace nut
37 /**
38 * \brief NUT stream writer
40 class NutWriter {
41 public:
43 /** NUT writer status */
44 typedef enum {
45 NUTW_OK = 0, /** Writing successful */
46 NUTW_ERROR, /** Writing failed */
47 } status_t; // end of typedef enum */
49 protected:
51 /** EoL separator */
52 static const std::string & eol;
54 /** Output stream (by reference) */
55 NutStream & m_output_stream;
57 public:
59 /**
60 * \brief Constructor
62 * Creates the writer.
63 * The \c ostream parameter provides the writer reference
64 * to an existing output stream; note that the stream
65 * must exist throughout whole the writer's life.
67 * TBD:
68 * The stream might actually be passed either by value
69 * (\c NutStream implementations would have to support
70 * copying, though, which is not implemented at the moment)
71 * or using reference counting mechanism (smart pointers etc).
72 * The latter is perhaps a better choice (if the stream existence
73 * dependency is a considerable issue).
75 * \param ostream Output stream
77 NutWriter(NutStream & ostream): m_output_stream(ostream) {}
79 /**
80 * \brief Write to output stream
82 * The method writes the provided string to the output stream.
84 * \retval NUTW_OK on success
85 * \retval NUTW_ERROR otherwise
87 inline status_t write(const std::string & str) {
88 NutStream::status_t status = m_output_stream.putString(str);
90 return NutStream::NUTS_OK == status ? NUTW_OK : NUTW_ERROR;
93 /**
94 * \brief Write to output stream
96 * The method writes the provided string to the output stream.
97 * An exception is thrown on error.
99 inline void writex(const std::string & str) {
100 NutStream::status_t status = m_output_stream.putString(str);
102 if (NutStream::NUTS_OK != status) {
103 std::stringstream e;
104 e << "Failed to write to output stream: " << status;
106 throw std::runtime_error(e.str());
110 protected:
113 * \brief Write (prefixed) lines
115 * The method splits string to lines (by EoL) and prefix them
116 * with specified string upon writing.
118 * \param str String (multi-line)
119 * \param pref Prefix
121 * \retval NUTW_OK on success
122 * \retval NUTW_ERROR otherwise
124 status_t writeEachLine(const std::string & str, const std::string & pref);
126 }; // end of class NutWriter
130 * \brief NUT configuration writer interface (generic)
132 class NutConfigWriter: public NutWriter {
133 protected:
135 /** Formal constructor */
136 NutConfigWriter(NutStream & ostream): NutWriter(ostream) {}
138 public:
141 * \brief Write comment
143 * \param str Comment string
145 * \retval NUTW_OK on success
146 * \retval NUTW_ERROR otherwise
148 virtual status_t writeComment(const std::string & str) = 0;
151 * \brief Write section name
153 * \param name Section name
155 * \retval NUTW_OK on success
156 * \retval NUTW_ERROR otherwise
158 virtual status_t writeSectionName(const std::string & name) = 0;
161 * \brief Write directive
163 * \param str Directive string
165 * \retval NUTW_OK on success
166 * \retval NUTW_ERROR otherwise
168 virtual status_t writeDirective(const std::string & str) = 0;
170 /** Virtual destructor */
171 virtual ~NutConfigWriter();
173 }; // end of class NutConfigWriter
177 * \brief NUT section-less configuration writer specialization
179 * Partial implementation of \ref NutConfigWriter for section-less
180 * configuration files.
182 class SectionlessConfigWriter: public NutConfigWriter {
183 protected:
186 * \brief Constructor
188 * \param ostream Output stream
190 SectionlessConfigWriter(NutStream & ostream): NutConfigWriter(ostream) {}
192 public:
194 // Partial \ref NutConfigWriter interface implementation
195 status_t writeDirective(const std::string & str) override;
196 status_t writeComment(const std::string & str) override;
198 private:
200 // Section name writing is forbidden (no sections)
201 status_t writeSectionName(const std::string & name) override;
203 }; // end of class SectionlessConfigWriter
207 * \brief \c nut.conf configuration file serializer
209 class NutConfConfigWriter: public SectionlessConfigWriter {
210 public:
213 * \brief Constructor
215 * \param ostream Output stream
217 NutConfConfigWriter(NutStream & ostream): SectionlessConfigWriter(ostream) {}
220 * \brief Serialize configuration container
222 * \param config Configuration
224 * \retval NUTW_OK on success
225 * \retval NUTW_ERROR otherwise
227 status_t writeConfig(const NutConfiguration & config);
229 /* Ensure an out-of-line method to avoid "weak-vtables" warning */
230 virtual ~NutConfConfigWriter() override;
231 }; // end of class NutConfConfigWriter
235 * \brief \c upsmon.conf configuration file serializer
237 class UpsmonConfigWriter: public SectionlessConfigWriter {
238 public:
241 * \brief Constructor
243 * \param ostream Output stream
245 UpsmonConfigWriter(NutStream & ostream): SectionlessConfigWriter(ostream) {}
248 * \brief Serialize configuration container
250 * \param config Configuration
252 * \retval NUTW_OK on success
253 * \retval NUTW_ERROR otherwise
255 status_t writeConfig(const UpsmonConfiguration & config);
257 /* Ensure an out-of-line method to avoid "weak-vtables" warning */
258 virtual ~UpsmonConfigWriter() override;
259 }; // end of class UpsmonConfigWriter
263 * \brief \c upsd.conf configuration file serializer
265 class UpsdConfigWriter: public SectionlessConfigWriter {
266 public:
269 * \brief Constructor
271 * \param ostream Output stream
273 UpsdConfigWriter(NutStream & ostream): SectionlessConfigWriter(ostream) {}
276 * \brief Serialize configuration container
278 * \param config Configuration
280 * \retval NUTW_OK on success
281 * \retval NUTW_ERROR otherwise
283 status_t writeConfig(const UpsdConfiguration & config);
285 /* Ensure an out-of-line method to avoid "weak-vtables" warning */
286 virtual ~UpsdConfigWriter() override;
287 }; // end of class UpsdConfigWriter
291 * \brief NUT default configuration writer ancestor
293 * Implements the \ref NutConfigWriter interface
294 * and adds \c writeSection prototype to be implemented
295 * by descendants.
297 class DefaultConfigWriter: public NutConfigWriter {
298 protected:
301 * \brief Constructor
303 * \param ostream Output stream
305 DefaultConfigWriter(NutStream & ostream): NutConfigWriter(ostream) {}
307 public:
309 // \ref NutConfigWriter interface implementation
310 status_t writeComment(const std::string & str) override;
311 status_t writeSectionName(const std::string & name) override;
312 status_t writeDirective(const std::string & str) override;
315 * \brief Write configuration section
317 * Serialize generic configuration section.
319 * \param section Configuration section
321 * \retval NUTW_OK on success
322 * \retval NUTW_ERROR otherwise
324 virtual status_t writeSection(const GenericConfigSection & section) = 0;
326 }; // end of class DefaultConfigWriter
330 * \brief NUT generic configuration writer
332 * Base configuration file serializer.
333 * Implements the \ref DefaultConfigWriter \c writeSection method
334 * and adds \c writeConfig routine for configuration file serialization.
336 class GenericConfigWriter: public DefaultConfigWriter {
337 protected:
339 /** Default indentation of the key/value pair in section entry */
340 static const std::string s_default_section_entry_indent;
342 /** Default separator of the key/value pair in section entry */
343 static const std::string s_default_section_entry_separator;
346 * \brief Section entry serializer
348 * \param entry Section entry
349 * \param indent Indentation
350 * \param kv_sep Key/value separator
352 * \retval NUTW_OK on success
353 * \retval NUTW_ERROR otherwise
355 status_t writeSectionEntry(
356 const GenericConfigSectionEntry & entry,
357 const std::string & indent = s_default_section_entry_indent,
358 const std::string & kv_sep = s_default_section_entry_separator);
360 public:
363 * \brief Constructor
365 * \param ostream Output stream
367 GenericConfigWriter(NutStream & ostream): DefaultConfigWriter(ostream) {}
369 // Section serializer implementation
370 status_t writeSection(const GenericConfigSection & section) override;
373 * \brief Base configuration serializer
375 * \param config Base configuration
377 * \retval NUTW_OK on success
378 * \retval NUTW_ERROR otherwise
380 status_t writeConfig(const GenericConfiguration & config);
382 }; // end of class GenericConfigWriter
386 * \brief NUT upsd.users configuration file writer
388 * upsd.users configuration file serializer.
389 * Overloads the generic section serializer because of the upsmon section,
390 * which contains an anomalous upsmon (master|slave) directive.
392 class UpsdUsersConfigWriter: public GenericConfigWriter {
393 public:
396 * \brief Constructor
398 * \param ostream Output stream
400 UpsdUsersConfigWriter(NutStream & ostream): GenericConfigWriter(ostream) {}
402 // Section serializer overload
403 status_t writeSection(const GenericConfigSection & section) override;
405 }; // end of class UpsdUsersConfigWriter
407 } // end of namespace nut
409 #endif /* __cplusplus */
411 #endif /* end of #ifndef nut_nutwriter_h */