aboutsummaryrefslogtreecommitdiff
path: root/bpkg/manifest-serializer
blob: 2c5a09b5139923994d1e8c318ec0b0a5a649205f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// file      : bpkg/manifest-serializer -*- C++ -*-
// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
// license   : MIT; see accompanying LICENSE file

#ifndef BPKG_MANIFEST_SERIALIZER
#define BPKG_MANIFEST_SERIALIZER

#include <string>
#include <iosfwd>
#include <cstddef>   // size_t
#include <stdexcept> // runtime_error

namespace bpkg
{
  class manifest_serialization: public std::runtime_error
  {
  public:
    manifest_serialization (const std::string& name,
                            const std::string& description);

    std::string name;
    std::string description;
  };

  class 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&);

  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_;
  };
}

#endif // BPKG_MANIFEST_SERIALIZER