aboutsummaryrefslogtreecommitdiff
path: root/libbutl/manifest-serializer.mxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbutl/manifest-serializer.mxx')
-rw-r--r--libbutl/manifest-serializer.mxx95
1 files changed, 95 insertions, 0 deletions
diff --git a/libbutl/manifest-serializer.mxx b/libbutl/manifest-serializer.mxx
new file mode 100644
index 0000000..e468786
--- /dev/null
+++ b/libbutl/manifest-serializer.mxx
@@ -0,0 +1,95 @@
+// file : libbutl/manifest-serializer.mxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef __cpp_modules
+#pragma once
+#endif
+
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <iosfwd>
+#include <cstddef> // size_t
+#include <stdexcept> // runtime_error
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.manifest_serializer;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
+
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
+{
+ class LIBBUTL_SYMEXPORT manifest_serialization: public std::runtime_error
+ {
+ public:
+ manifest_serialization (const std::string& name,
+ const std::string& description);
+
+ std::string name;
+ std::string description;
+ };
+
+ class LIBBUTL_SYMEXPORT manifest_serializer
+ {
+ public:
+ manifest_serializer (std::ostream& os, const std::string& name)
+ : os_ (os), name_ (name) {}
+
+ const std::string&
+ name () const {return name_;}
+
+ // The first name-value pair should be the special "start-of-manifest"
+ // with empty name and value being the format version. After that we
+ // have a sequence of ordinary pairs which are the manifest. At the
+ // end of the manifest we have the special "end-of-manifest" pair
+ // with empty name and value. After that we can either have another
+ // start-of-manifest pair (in which case the whole sequence repeats
+ // from the beginning) or we get another end-of-manifest pair which
+ // signals the end of stream.
+ //
+ void
+ next (const std::string& name, const std::string& value);
+
+ // Write a comment. The supplied text is prefixed with "# " and
+ // terminated with a newline.
+ //
+ void
+ comment (const std::string&);
+
+ // Merge the manifest value and a comment into the single string, having
+ // the '<value>; <comment>' form. Escape ';' characters in the value with
+ // the backslash.
+ //
+ static std::string
+ merge_comment (const std::string& value, const std::string& comment);
+
+ private:
+ void
+ check_name (const std::string&);
+
+ // Write 'n' characters from 's' (assuming there are no newlines)
+ // split into multiple lines at or near the 78 characters
+ // boundary. The first line starts at the 'column' offset.
+ //
+ void
+ write_value (std::size_t column, const char* s, std::size_t n);
+
+ private:
+ enum {start, body, end} s_ = start;
+ std::string version_; // Current format version.
+
+ private:
+ std::ostream& os_;
+ const std::string name_;
+ };
+}