Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(464)

Side by Side Diff: third_party/xmllite/xmlprinter.cc

Issue 2443903004: Add xmllite and xmpp sources to third_party/ (Closed)
Patch Set: Restored includes in jingle/ as well Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2004 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/xmllite/xmlprinter.h"
6
7 #include <sstream>
8 #include <string>
9 #include <vector>
10
11 #include "third_party/xmllite/xmlconstants.h"
12 #include "third_party/xmllite/xmlelement.h"
13 #include "third_party/xmllite/xmlnsstack.h"
14
15 namespace buzz {
16
17 class XmlPrinterImpl {
18 public:
19 XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack);
20 void PrintElement(const XmlElement* element);
21 void PrintQuotedValue(const std::string& text);
22 void PrintBodyText(const std::string& text);
23 void PrintCDATAText(const std::string& text);
24
25 private:
26 std::ostream *pout_;
27 XmlnsStack* ns_stack_;
28 };
29
30 void XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element) {
31 XmlnsStack ns_stack;
32 PrintXml(pout, element, &ns_stack);
33 }
34
35 void XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element,
36 XmlnsStack* ns_stack) {
37 XmlPrinterImpl printer(pout, ns_stack);
38 printer.PrintElement(element);
39 }
40
41 XmlPrinterImpl::XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack)
42 : pout_(pout),
43 ns_stack_(ns_stack) {
44 }
45
46 void XmlPrinterImpl::PrintElement(const XmlElement* element) {
47 ns_stack_->PushFrame();
48
49 // first go through attrs of pel to add xmlns definitions
50 const XmlAttr* attr;
51 for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
52 if (attr->Name() == QN_XMLNS) {
53 ns_stack_->AddXmlns(STR_EMPTY, attr->Value());
54 } else if (attr->Name().Namespace() == NS_XMLNS) {
55 ns_stack_->AddXmlns(attr->Name().LocalPart(),
56 attr->Value());
57 }
58 }
59
60 // then go through qnames to make sure needed xmlns definitons are added
61 std::vector<std::string> new_ns;
62 std::pair<std::string, bool> prefix;
63 prefix = ns_stack_->AddNewPrefix(element->Name().Namespace(), false);
64 if (prefix.second) {
65 new_ns.push_back(prefix.first);
66 new_ns.push_back(element->Name().Namespace());
67 }
68
69 for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
70 prefix = ns_stack_->AddNewPrefix(attr->Name().Namespace(), true);
71 if (prefix.second) {
72 new_ns.push_back(prefix.first);
73 new_ns.push_back(attr->Name().Namespace());
74 }
75 }
76
77 // print the element name
78 *pout_ << '<' << ns_stack_->FormatQName(element->Name(), false);
79
80 // and the attributes
81 for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
82 *pout_ << ' ' << ns_stack_->FormatQName(attr->Name(), true) << "=\"";
83 PrintQuotedValue(attr->Value());
84 *pout_ << '"';
85 }
86
87 // and the extra xmlns declarations
88 std::vector<std::string>::iterator i(new_ns.begin());
89 while (i < new_ns.end()) {
90 if (*i == STR_EMPTY) {
91 *pout_ << " xmlns=\"" << *(i + 1) << '"';
92 } else {
93 *pout_ << " xmlns:" << *i << "=\"" << *(i + 1) << '"';
94 }
95 i += 2;
96 }
97
98 // now the children
99 const XmlChild* child = element->FirstChild();
100
101 if (child == NULL)
102 *pout_ << "/>";
103 else {
104 *pout_ << '>';
105 while (child) {
106 if (child->IsText()) {
107 if (element->IsCDATA()) {
108 PrintCDATAText(child->AsText()->Text());
109 } else {
110 PrintBodyText(child->AsText()->Text());
111 }
112 } else {
113 PrintElement(child->AsElement());
114 }
115 child = child->NextChild();
116 }
117 *pout_ << "</" << ns_stack_->FormatQName(element->Name(), false) << '>';
118 }
119
120 ns_stack_->PopFrame();
121 }
122
123 void XmlPrinterImpl::PrintQuotedValue(const std::string& text) {
124 size_t safe = 0;
125 for (;;) {
126 size_t unsafe = text.find_first_of("<>&\"", safe);
127 if (unsafe == std::string::npos)
128 unsafe = text.length();
129 *pout_ << text.substr(safe, unsafe - safe);
130 if (unsafe == text.length())
131 return;
132 switch (text[unsafe]) {
133 case '<': *pout_ << "&lt;"; break;
134 case '>': *pout_ << "&gt;"; break;
135 case '&': *pout_ << "&amp;"; break;
136 case '"': *pout_ << "&quot;"; break;
137 }
138 safe = unsafe + 1;
139 if (safe == text.length())
140 return;
141 }
142 }
143
144 void XmlPrinterImpl::PrintBodyText(const std::string& text) {
145 size_t safe = 0;
146 for (;;) {
147 size_t unsafe = text.find_first_of("<>&", safe);
148 if (unsafe == std::string::npos)
149 unsafe = text.length();
150 *pout_ << text.substr(safe, unsafe - safe);
151 if (unsafe == text.length())
152 return;
153 switch (text[unsafe]) {
154 case '<': *pout_ << "&lt;"; break;
155 case '>': *pout_ << "&gt;"; break;
156 case '&': *pout_ << "&amp;"; break;
157 }
158 safe = unsafe + 1;
159 if (safe == text.length())
160 return;
161 }
162 }
163
164 void XmlPrinterImpl::PrintCDATAText(const std::string& text) {
165 *pout_ << "<![CDATA[" << text << "]]>";
166 }
167
168 } // namespace buzz
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698