aboutsummaryrefslogtreecommitdiff
path: root/bpkg/manifest-serializer.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-09-29 22:02:28 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-09-29 22:02:28 +0300
commitf4a338ee1a5eb993fb7f9688588b77b12ad944c2 (patch)
treeda7bea25e838d376eddb1263a839aca50571c4a4 /bpkg/manifest-serializer.cxx
parent4dc2c7b9fbbe7bec57524d71fd5330e2d1782c52 (diff)
Move manifest_parser and manifest_serializer to libbutl
Diffstat (limited to 'bpkg/manifest-serializer.cxx')
-rw-r--r--bpkg/manifest-serializer.cxx238
1 files changed, 0 insertions, 238 deletions
diff --git a/bpkg/manifest-serializer.cxx b/bpkg/manifest-serializer.cxx
deleted file mode 100644
index 07b7db9..0000000
--- a/bpkg/manifest-serializer.cxx
+++ /dev/null
@@ -1,238 +0,0 @@
-// file : bpkg/manifest-serializer.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <bpkg/manifest-serializer>
-
-#include <ostream>
-#include <cassert>
-
-using namespace std;
-
-namespace bpkg
-{
- using serialization = manifest_serialization;
-
- void manifest_serializer::
- next (const string& n, const string& v)
- {
- switch (s_)
- {
- case start:
- {
- if (!n.empty ())
- throw serialization (name_, "format version pair expected");
-
- if (v.empty ())
- {
- // End of manifests.
- //
- os_.flush ();
- s_ = end;
- break;
- }
-
- if (v != "1")
- throw serialization (name_, "unsupported format version " + v);
-
- os_ << ':';
-
- if (v != version_)
- {
- os_ << ' ' << v;
- version_ = v;
- }
-
- os_ << endl;
- s_ = body;
- break;
- }
- case body:
- {
- if (n.empty ())
- {
- if (!v.empty ())
- throw serialization (name_, "non-empty value in end pair");
-
- s_ = start;
- break;
- }
-
- check_name (n);
-
- os_ << n << ':';
-
- if (!v.empty ())
- {
- os_ << ' ';
-
- // Use the multi-line mode in any of the following cases:
- //
- // - name is too long (say longer than 37 (78/2 - 2) characters;
- // we cannot start on the next line since that would start the
- // multi-line mode)
- // - value contains newlines
- // - value contains leading/trailing whitespaces
- //
- if (n.size () > 37 ||
- v.find ('\n') != string::npos ||
- v.front () == ' ' || v.front () == '\t' ||
- v.back () == ' ' || v.back () == '\t')
- {
- os_ << "\\" << endl; // Multi-line mode introductor.
-
- // Chunk the value into fragments separated by newlines.
- //
- for (size_t i (0), p (v.find ('\n')); ; p = v.find ('\n', i))
- {
- if (p == string::npos)
- {
- // Last chunk.
- //
- write_value (0, v.c_str () + i, v.size () - i);
- break;
- }
-
- write_value (0, v.c_str () + i, p - i);
- os_ << endl;
- i = p + 1;
- }
-
- os_ << endl << "\\"; // Multi-line mode terminator.
- }
- else
- write_value (n.size () + 2, v.c_str (), v.size ());
- }
-
- os_ << endl;
- break;
- }
- case end:
- {
- throw serialization (name_, "serialization after eos");
- }
- }
- }
-
- void manifest_serializer::
- comment (const string& t)
- {
- if (s_ == end)
- throw serialization (name_, "serialization after eos");
-
- os_ << '#';
-
- if (!t.empty ())
- os_ << ' ' << t;
-
- os_ << endl;
- }
-
- void manifest_serializer::
- check_name (const string& n)
- {
- if (n[0] == '#')
- throw serialization (name_, "name starts with '#'");
-
- for (char c: n)
- {
- switch (c)
- {
- case ' ':
- case '\t':
- case '\n': throw serialization (name_, "name contains whitespace");
- case ':': throw serialization (name_, "name contains ':'");
- default: break;
- }
- }
- }
-
- void manifest_serializer::
- write_value (size_t cl, const char* s, size_t n)
- {
- char c ('\0');
-
- // The idea is to break on the 77th character (i.e., write it
- // on the next line) which means we have written 76 characters
- // on this line plus 2 for '\' and '\n', which gives us 78.
- //
- for (const char* e (s + n); s != e; s++, cl++)
- {
- c = *s;
- bool br (false); // Break the line.
-
- // If this is a whitespace, see if it's a good place to break the
- // line.
- //
- if (c == ' ' || c == '\t')
- {
- // Find the next whitespace (or the end) and see if it is a better
- // place.
- //
- for (const char* w (s + 1); ; w++)
- {
- if (w == e || *w == ' ' || *w == '\t')
- {
- // Is this whitespace past where we need to break? Also see
- // below the "hard" break case for why we use 78 at the end.
- //
- if (cl + static_cast<size_t> (w - s) > (w != e ? 77 : 78))
- {
- // Only break if this whitespace is close enough to
- // the end of the line.
- //
- br = (cl > 57);
- }
-
- break;
- }
- }
- }
-
- // Do we have to do a "hard" break (i.e., without a whitespace)?
- // If there is just one character left, then instead of writing
- // '\' and then the character on the next line, we might as well
- // write it on this line.
- //
- if (cl == (s + 1 != e ? 77 : 78))
- br = true;
-
- if (br)
- {
- os_ << '\\' << endl;
- cl = 0;
- }
-
- os_ << c;
- }
-
- // What comes next is always a newline. I the last character that
- // we have written is a backslash, escape it.
- //
- if (c == '\\')
- os_ << '\\';
- }
-
- // manifest_serialization
- //
-
- static string
- format (const string& n, const string& d)
- {
- string r;
- if (!n.empty ())
- {
- r += n;
- r += ": ";
- }
- r += "error: ";
- r += d;
- return r;
- }
-
- manifest_serialization::
- manifest_serialization (const string& n, const string& d)
- : runtime_error (format (n, d)), name (n), description (d)
- {
- }
-}