summaryrefslogtreecommitdiff
path: root/chromium/tools/gn/xml_element_writer.cc
blob: fcf34b283cce6ad473f29f6a745be78ff4062e38 (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
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "tools/gn/xml_element_writer.h"

#include "base/memory/ptr_util.h"

XmlAttributes::XmlAttributes() {}

XmlAttributes::XmlAttributes(const base::StringPiece& attr_key,
                             const base::StringPiece& attr_value) {
  add(attr_key, attr_value);
}

XmlAttributes& XmlAttributes::add(const base::StringPiece& attr_key,
                                  const base::StringPiece& attr_value) {
  push_back(std::make_pair(attr_key, attr_value));
  return *this;
}

XmlElementWriter::XmlElementWriter(std::ostream& out,
                                   const std::string& tag,
                                   const XmlAttributes& attributes)
    : XmlElementWriter(out, tag, attributes, 0) {}

XmlElementWriter::XmlElementWriter(std::ostream& out,
                                   const std::string& tag,
                                   const XmlAttributes& attributes,
                                   int indent)
    : out_(out),
      tag_(tag),
      indent_(indent),
      opening_tag_finished_(false),
      one_line_(true) {
  out << std::string(indent, ' ') << '<' << tag;
  for (auto attribute : attributes)
    out << ' ' << attribute.first << "=\"" << attribute.second << '"';
}

XmlElementWriter::~XmlElementWriter() {
  if (!opening_tag_finished_) {
    // The XML spec does not require a space before the closing slash. However,
    // Eclipse is unable to parse XML settings files if there is no space.
    out_ << " />" << std::endl;
  } else {
    if (!one_line_)
      out_ << std::string(indent_, ' ');
    out_ << "</" << tag_ << '>' << std::endl;
  }
}

void XmlElementWriter::Text(const base::StringPiece& content) {
  StartContent(false);
  out_ << content;
}

std::unique_ptr<XmlElementWriter> XmlElementWriter::SubElement(
    const std::string& tag) {
  return SubElement(tag, XmlAttributes());
}

std::unique_ptr<XmlElementWriter> XmlElementWriter::SubElement(
    const std::string& tag,
    const XmlAttributes& attributes) {
  StartContent(true);
  return base::WrapUnique(
      new XmlElementWriter(out_, tag, attributes, indent_ + 2));
}

std::ostream& XmlElementWriter::StartContent(bool start_new_line) {
  if (!opening_tag_finished_) {
    out_ << '>';
    opening_tag_finished_ = true;

    if (start_new_line && one_line_) {
      out_ << std::endl;
      one_line_ = false;
    }
  }

  return out_;
}