Coverage Report

Created: 2026-03-01 07:02

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
32.3k
XmlWriter::XmlWriter() {}
43
44
17.6k
void XmlWriter::ToXml(const std::string& name, const std::string& value) {
45
17.6k
  char quote = (name.size() % 2) ? '"' : '\'';
46
17.6k
  out_ << " " << name << "=" << quote << value << quote;
47
17.6k
}
48
49
1.74k
void XmlWriter::ToXml(const Misk& misk) {
50
1.74k
  if (misk.has_pi()) {
51
465
    out_ << "<?" << misk.pi().target() << misk.pi().data() << "?>";
52
465
  }
53
54
1.74k
  if (misk.has_comment()) {
55
1.25k
    out_ << "<!--" << misk.comment() << "-->";
56
1.25k
  }
57
1.74k
}
58
59
13.8k
void XmlWriter::ToXml(const DoctypeDecl& doctype) {
60
13.8k
  out_ << "<!DOCTYPE " << doctype.name();
61
13.8k
  if (doctype.has_external_id()) out_ << " " << doctype.external_id();
62
13.8k
  if (doctype.has_int_subset()) out_ << " [" << doctype.int_subset() << "]";
63
14.1k
  for (int i = 0; i < doctype.misk_size(); ++i) ToXml(doctype.misk(i));
64
13.8k
  out_ << ">";
65
13.8k
}
66
67
6.64k
void XmlWriter::ToXml(const Content& content) {
68
6.64k
  if (content.has_char_data()) out_ << content.char_data();
69
6.64k
  if (content.has_element()) ToXml(content.element());
70
6.64k
  if (content.has_reference()) {
71
31
    out_ << (content.reference().entry() ? '&' : '%')
72
31
         << content.reference().name() << ';';
73
31
  }
74
6.64k
  if (content.has_cdsect()) out_ << "<![CDATA[" << content.cdsect() << "]]>";
75
76
6.64k
  if (content.has_misk()) ToXml(content.misk());
77
6.64k
}
78
79
32.9k
void XmlWriter::ToXml(const Element& element) {
80
32.9k
  std::string tag;
81
32.9k
  std::string name;
82
32.9k
  tag += element.tag().name();
83
32.9k
  out_ << "<" << tag;
84
85
33.7k
  for (int i = 0; i < element.tag().attribute_size(); ++i) {
86
804
    ToXml(element.tag().attribute(i).name(),
87
804
          element.tag().attribute(i).value());
88
804
  }
89
90
32.9k
  if (element.content_size() == 0) {
91
26.7k
    out_ << "/>";
92
26.7k
  } else {
93
6.25k
    out_ << ">";
94
12.9k
    for (int i = 0; i < element.content_size(); ++i) ToXml(element.content(i));
95
6.25k
    out_ << "</" << tag << ">";
96
6.25k
  }
97
32.9k
}
98
99
32.3k
std::string XmlWriter::ToXml(const Document& doc) {
100
32.3k
  out_.str("");
101
102
32.3k
  if (doc.has_version() || doc.has_encoding() || doc.has_standalone()) {
103
15.5k
    out_ << "<?xml";
104
15.5k
    if (doc.has_version())
105
12.3k
      ToXml("version", (doc.version().size() == 7) ? "1.0" : doc.version());
106
15.5k
    if (doc.has_encoding()) ToXml("encoding", doc.encoding());
107
15.5k
    if (doc.has_standalone())
108
138
      ToXml("encoding", doc.standalone() ? "yes" : "no");
109
15.5k
    out_ << "?>";
110
15.5k
  }
111
112
32.7k
  for (int i = 0; i < doc.misk1_size(); ++i) ToXml(doc.misk1(i));
113
32.3k
  if (doc.has_doctype()) ToXml(doc.doctype());
114
32.3k
  ToXml(doc.element());
115
33.3k
  for (int i = 0; i < doc.misk2_size(); ++i) ToXml(doc.misk2(i));
116
117
32.3k
  return out_.str();
118
32.3k
}
119
120
}  // namespace
121
122
32.3k
std::string MessageToXml(const Document& document) {
123
32.3k
  XmlWriter writer;
124
32.3k
  return writer.ToXml(document);
125
32.3k
}
126
127
}  // namespace xml
128
}  // namespace protobuf_mutator