Coverage Report

Created: 2026-10-17 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libprotobuf-mutator/examples/xml/xml_writer.cc
Line
Count
Source
1
// Copyright 2017 Google Inc. All rights reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include "examples/xml/xml_writer.h"
16
17
#include <algorithm>
18
#include <sstream>
19
20
#include "examples/xml/xml.pb.h"
21
22
namespace protobuf_mutator {
23
namespace xml {
24
25
namespace {
26
27
class XmlWriter {
28
 public:
29
  XmlWriter();
30
  std::string ToXml(const Document& doc);
31
32
 private:
33
  void ToXml(const std::string& name, const std::string& value);
34
  void ToXml(const Element& element);
35
  void ToXml(const Content& content);
36
  void ToXml(const Misk& misk);
37
  void ToXml(const DoctypeDecl& doctype);
38
39
  std::ostringstream out_;
40
};
41
42
34.7k
XmlWriter::XmlWriter() {}
43
44
15.0k
void XmlWriter::ToXml(const std::string& name, const std::string& value) {
45
15.0k
  char quote = (name.size() % 2) ? '"' : '\'';
46
15.0k
  out_ << " " << name << "=" << quote << value << quote;
47
15.0k
}
48
49
1.73k
void XmlWriter::ToXml(const Misk& misk) {
50
1.73k
  if (misk.has_pi()) {
51
443
    out_ << "<?" << misk.pi().target() << misk.pi().data() << "?>";
52
443
  }
53
54
1.73k
  if (misk.has_comment()) {
55
1.26k
    out_ << "<!--" << misk.comment() << "-->";
56
1.26k
  }
57
1.73k
}
58
59
17.6k
void XmlWriter::ToXml(const DoctypeDecl& doctype) {
60
17.6k
  out_ << "<!DOCTYPE " << doctype.name();
61
17.6k
  if (doctype.has_external_id()) out_ << " " << doctype.external_id();
62
17.6k
  if (doctype.has_int_subset()) out_ << " [" << doctype.int_subset() << "]";
63
17.9k
  for (int i = 0; i < doctype.misk_size(); ++i) ToXml(doctype.misk(i));
64
17.6k
  out_ << ">";
65
17.6k
}
66
67
6.88k
void XmlWriter::ToXml(const Content& content) {
68
6.88k
  if (content.has_char_data()) out_ << content.char_data();
69
6.88k
  if (content.has_element()) ToXml(content.element());
70
6.88k
  if (content.has_reference()) {
71
21
    out_ << (content.reference().entry() ? '&' : '%')
72
21
         << content.reference().name() << ';';
73
21
  }
74
6.88k
  if (content.has_cdsect()) out_ << "<![CDATA[" << content.cdsect() << "]]>";
75
76
6.88k
  if (content.has_misk()) ToXml(content.misk());
77
6.88k
}
78
79
35.1k
void XmlWriter::ToXml(const Element& element) {
80
35.1k
  std::string tag;
81
35.1k
  std::string name;
82
35.1k
  tag += element.tag().name();
83
35.1k
  out_ << "<" << tag;
84
85
35.8k
  for (int i = 0; i < element.tag().attribute_size(); ++i) {
86
724
    ToXml(element.tag().attribute(i).name(),
87
724
          element.tag().attribute(i).value());
88
724
  }
89
90
35.1k
  if (element.content_size() == 0) {
91
28.6k
    out_ << "/>";
92
28.6k
  } else {
93
6.53k
    out_ << ">";
94
13.4k
    for (int i = 0; i < element.content_size(); ++i) ToXml(element.content(i));
95
6.53k
    out_ << "</" << tag << ">";
96
6.53k
  }
97
35.1k
}
98
99
34.7k
std::string XmlWriter::ToXml(const Document& doc) {
100
34.7k
  out_.str("");
101
102
34.7k
  if (doc.has_version() || doc.has_encoding() || doc.has_standalone()) {
103
13.4k
    out_ << "<?xml";
104
13.4k
    if (doc.has_version())
105
9.85k
      ToXml("version", (doc.version().size() == 7) ? "1.0" : doc.version());
106
13.4k
    if (doc.has_encoding()) ToXml("encoding", doc.encoding());
107
13.4k
    if (doc.has_standalone())
108
62
      ToXml("encoding", doc.standalone() ? "yes" : "no");
109
13.4k
    out_ << "?>";
110
13.4k
  }
111
112
35.1k
  for (int i = 0; i < doc.misk1_size(); ++i) ToXml(doc.misk1(i));
113
34.7k
  if (doc.has_doctype()) ToXml(doc.doctype());
114
34.7k
  ToXml(doc.element());
115
35.7k
  for (int i = 0; i < doc.misk2_size(); ++i) ToXml(doc.misk2(i));
116
117
34.7k
  return out_.str();
118
34.7k
}
119
120
}  // namespace
121
122
34.7k
std::string MessageToXml(const Document& document) {
123
34.7k
  XmlWriter writer;
124
34.7k
  return writer.ToXml(document);
125
34.7k
}
126
127
}  // namespace xml
128
}  // namespace protobuf_mutator