daemon: Support SHA-512 hashes.
[jackhill/guix/guix.git] / nix / libutil / xml-writer.cc
1 #include <assert.h>
2
3 #include "xml-writer.hh"
4
5
6 namespace nix {
7
8
9 XMLWriter::XMLWriter(bool indent, std::ostream & output)
10 : output(output), indent(indent)
11 {
12 output << "<?xml version='1.0' encoding='utf-8'?>" << std::endl;
13 closed = false;
14 }
15
16
17 XMLWriter::~XMLWriter()
18 {
19 close();
20 }
21
22
23 void XMLWriter::close()
24 {
25 if (closed) return;
26 while (!pendingElems.empty()) closeElement();
27 closed = true;
28 }
29
30
31 void XMLWriter::indent_(unsigned int depth)
32 {
33 if (!indent) return;
34 output << string(depth * 2, ' ');
35 }
36
37
38 void XMLWriter::openElement(const string & name,
39 const XMLAttrs & attrs)
40 {
41 assert(!closed);
42 indent_(pendingElems.size());
43 output << "<" << name;
44 writeAttrs(attrs);
45 output << ">";
46 if (indent) output << std::endl;
47 pendingElems.push_back(name);
48 }
49
50
51 void XMLWriter::closeElement()
52 {
53 assert(!pendingElems.empty());
54 indent_(pendingElems.size() - 1);
55 output << "</" << pendingElems.back() << ">";
56 if (indent) output << std::endl;
57 pendingElems.pop_back();
58 if (pendingElems.empty()) closed = true;
59 }
60
61
62 void XMLWriter::writeEmptyElement(const string & name,
63 const XMLAttrs & attrs)
64 {
65 assert(!closed);
66 indent_(pendingElems.size());
67 output << "<" << name;
68 writeAttrs(attrs);
69 output << " />";
70 if (indent) output << std::endl;
71 }
72
73
74 void XMLWriter::writeAttrs(const XMLAttrs & attrs)
75 {
76 for (XMLAttrs::const_iterator i = attrs.begin(); i != attrs.end(); ++i) {
77 output << " " << i->first << "=\"";
78 for (unsigned int j = 0; j < i->second.size(); ++j) {
79 char c = i->second[j];
80 if (c == '"') output << "&quot;";
81 else if (c == '<') output << "&lt;";
82 else if (c == '>') output << "&gt;";
83 else if (c == '&') output << "&amp;";
84 /* Escape newlines to prevent attribute normalisation (see
85 XML spec, section 3.3.3. */
86 else if (c == '\n') output << "&#xA;";
87 else output << c;
88 }
89 output << "\"";
90 }
91 }
92
93
94 }