aboutsummaryrefslogtreecommitdiff
path: root/xml/serializer
blob: 6c55d51f157a55342555494a1e1d56010ea2f86b (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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// file      : xml/serializer -*- C++ -*-
// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC
// license   : MIT; see accompanying LICENSE file

#ifndef XML_SERIALIZER
#define XML_SERIALIZER

#include <xml/details/pre.hxx>

#include <string>
#include <ostream>
#include <cstddef> // std::size_t

#include <xml/details/genx/genx.h>

#include <xml/forward>
#include <xml/qname>
#include <xml/exception>

#include <xml/details/export.hxx>

namespace xml
{
  class serializer;

  struct LIBSTUDXML_EXPORT serialization: exception
  {
    virtual
    ~serialization () throw ();

    serialization (const std::string& name,
                   const std::string& description);

    serialization (const serializer&, const std::string& description);

    const std::string&
    name () const {return name_;}

    const std::string&
    description () const {return description_;}

    virtual const char*
    what () const throw ();

  private:
    void
    init ();

  private:
    std::string name_;
    std::string description_;
    std::string what_;
  };

  class LIBSTUDXML_EXPORT serializer
  {
  public:
    typedef xml::qname qname_type;

    // Serialize to std::ostream. Output name is used in diagnostics to
    // identify the document being serialized. The indentation argument
    // specifies the number of indentation spaces that should be used for
    // pretty-printing. If 0 is passed, no pretty-printing is performed.
    //
    // If stream exceptions are enabled then std::ios_base::failure
    // exception is used to report io errors (badbit and failbit).
    // Otherwise, those are reported as the serialization exception.
    //
    serializer (std::ostream&,
                const std::string& output_name,
                unsigned short indentation = 2);

    const std::string&
    output_name () const {return oname_;}

    ~serializer ();

  private:
    serializer (const serializer&);
    serializer& operator= (const serializer&);

    // Serialization functions.
    //
  public:

    // Elements.
    //
    void
    start_element (const qname_type& qname);

    void
    start_element (const std::string& name);

    void
    start_element (const std::string& ns, const std::string& name);

    void
    end_element ();

    // Helpers for serializing elements with simple content. The first two
    // functions assume that start_element() has already been called. The
    // other two serialize the complete element, from start to end.
    //
    void
    element (const std::string& value);

    template <typename T>
    void
    element (const T& value);

    void
    element (const std::string& name, const std::string& value);

    template <typename T>
    void
    element (const std::string& name, const T& value);

    void
    element (const qname_type& qname, const std::string& value);

    template <typename T>
    void
    element (const qname_type& qname, const T& value);

    void
    element (const std::string& namespace_,
             const std::string& name,
             const std::string& value);

    template <typename T>
    void
    element (const std::string& namespace_,
             const std::string& name,
             const T& value);

    // Attributes.
    //
    void
    start_attribute (const qname_type& qname);

    void
    start_attribute (const std::string& name);

    void
    start_attribute (const std::string& ns, const std::string& name);

    void
    end_attribute ();

    void
    attribute (const qname_type& qname, const std::string& value);

    template <typename T>
    void
    attribute (const qname_type& qname, const T& value);

    void
    attribute (const std::string& name, const std::string& value);

    template <typename T>
    void
    attribute (const std::string& name, const T& value);

    void
    attribute (const std::string& ns,
               const std::string& name,
               const std::string& value);

    template <typename T>
    void
    attribute (const std::string& ns,
               const std::string& name,
               const T& value);

    // Characters.
    //
    void
    characters (const std::string& value);

    template <typename T>
    void
    characters (const T& value);

    // Namespaces declaration. If prefix is empty, then the default
    // namespace is declared. If both prefix and namespace are empty,
    // then the default namespace declaration is cleared (xmlns="").
    //
    void
    namespace_decl (const std::string& ns, const std::string& prefix);

    // XML declaration. If encoding or standalone are not specified,
    // then these attributes are omitted from the output.
    //
    void
    xml_decl (const std::string& version = "1.0",
              const std::string& encoding = "UTF-8",
              const std::string& standalone = "");

    // Utility functions.
    //
  public:
    // Return true if there is a mapping. In this case, prefix contains
    // the mapped prefix.
    //
    bool
    lookup_namespace_prefix (const std::string& ns, std::string& prefix);

  private:
    void
    handle_error (genxStatus);

  private:
    std::ostream& os_;
    std::ostream::iostate os_state_; // Original exception state.
    const std::string oname_;

    genxWriter s_;
    genxSender sender_;
    std::size_t depth_;
  };
}

#include <xml/serializer.ixx>

#include <xml/details/post.hxx>

#endif // XML_SERIALIZER