diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2016-09-29 21:54:14 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2016-09-29 23:28:03 +0300 |
commit | 25a9484378ddaae9602ec54532cdc03b1f1924ef (patch) | |
tree | 7aafb613337eb6c6aee4fef78b8345405c4d7f70 /butl/manifest-parser | |
parent | f4f6d906733027a7bd802e035b3e9852db7be967 (diff) |
Add manifest_parser and manifest_serializer
Diffstat (limited to 'butl/manifest-parser')
-rw-r--r-- | butl/manifest-parser | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/butl/manifest-parser b/butl/manifest-parser new file mode 100644 index 0000000..a005b34 --- /dev/null +++ b/butl/manifest-parser @@ -0,0 +1,94 @@ +// file : butl/manifest-parser -*- C++ -*- +// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BUTL_MANIFEST_PARSER +#define BUTL_MANIFEST_PARSER + +#include <string> +#include <iosfwd> +#include <cstdint> // uint64_t +#include <stdexcept> // runtime_error + +#include <butl/export> + +#include <butl/char-scanner> + +namespace butl +{ + class LIBBUTL_EXPORT manifest_parsing: public std::runtime_error + { + public: + manifest_parsing (const std::string& name, + std::uint64_t line, + std::uint64_t column, + const std::string& description); + + std::string name; + std::uint64_t line; + std::uint64_t column; + std::string description; + }; + + class manifest_name_value + { + public: + std::string name; + std::string value; + + std::uint64_t name_line; + std::uint64_t name_column; + + std::uint64_t value_line; + std::uint64_t value_column; + + bool + empty () const {return name.empty () && value.empty ();} + }; + + class LIBBUTL_EXPORT manifest_parser: protected butl::char_scanner + { + public: + manifest_parser (std::istream& is, const std::string& name) + : char_scanner (is), name_ (name) {} + + const std::string& + name () const {return name_;} + + // The first returned pair is special "start-of-manifest" with + // empty name and value being the format version: {"", "<ver>"}. + // 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 get 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 (aka EOF). To put it another way, the parse sequence + // always has the following form: + // + // ({"", "<ver>"} {"<name>", "<value>"}* {"", ""})* {"", ""} + // + manifest_name_value + next (); + + private: + void + parse_name (manifest_name_value&); + + void + parse_value (manifest_name_value&); + + // Skip spaces and return the first peeked non-space character. + // + xchar + skip_spaces (); + + private: + const std::string name_; + + enum {start, body, end} s_ = start; + std::string version_; // Current format version. + }; +} + +#endif // BUTL_MANIFEST_PARSER |