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

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

Issue 2443903004: Add xmllite and xmpp sources to third_party/ (Closed)
Patch Set: Restored includes in jingle/ as well Created 3 years, 12 months 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/xmlnsstack.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
14 namespace buzz {
15
16 XmlnsStack::XmlnsStack() :
17 pxmlnsStack_(new std::vector<std::string>),
18 pxmlnsDepthStack_(new std::vector<size_t>) {
19 }
20
21 XmlnsStack::~XmlnsStack() {}
22
23 void XmlnsStack::PushFrame() {
24 pxmlnsDepthStack_->push_back(pxmlnsStack_->size());
25 }
26
27 void XmlnsStack::PopFrame() {
28 size_t prev_size = pxmlnsDepthStack_->back();
29 pxmlnsDepthStack_->pop_back();
30 if (prev_size < pxmlnsStack_->size()) {
31 pxmlnsStack_->erase(pxmlnsStack_->begin() + prev_size,
32 pxmlnsStack_->end());
33 }
34 }
35
36 std::pair<std::string, bool> XmlnsStack::NsForPrefix(
37 const std::string& prefix) {
38 if (prefix.length() >= 3 &&
39 (prefix[0] == 'x' || prefix[0] == 'X') &&
40 (prefix[1] == 'm' || prefix[1] == 'M') &&
41 (prefix[2] == 'l' || prefix[2] == 'L')) {
42 if (prefix == "xml")
43 return std::make_pair(NS_XML, true);
44 if (prefix == "xmlns")
45 return std::make_pair(NS_XMLNS, true);
46 // Other names with xml prefix are illegal.
47 return std::make_pair(STR_EMPTY, false);
48 }
49
50 std::vector<std::string>::iterator pos;
51 for (pos = pxmlnsStack_->end(); pos > pxmlnsStack_->begin(); ) {
52 pos -= 2;
53 if (*pos == prefix)
54 return std::make_pair(*(pos + 1), true);
55 }
56
57 if (prefix == STR_EMPTY)
58 return std::make_pair(STR_EMPTY, true); // default namespace
59
60 return std::make_pair(STR_EMPTY, false); // none found
61 }
62
63 bool XmlnsStack::PrefixMatchesNs(const std::string& prefix,
64 const std::string& ns) {
65 const std::pair<std::string, bool> match = NsForPrefix(prefix);
66 return match.second && (match.first == ns);
67 }
68
69 std::pair<std::string, bool> XmlnsStack::PrefixForNs(const std::string& ns,
70 bool isattr) {
71 if (ns == NS_XML)
72 return std::make_pair(std::string("xml"), true);
73 if (ns == NS_XMLNS)
74 return std::make_pair(std::string("xmlns"), true);
75 if (isattr ? ns == STR_EMPTY : PrefixMatchesNs(STR_EMPTY, ns))
76 return std::make_pair(STR_EMPTY, true);
77
78 std::vector<std::string>::iterator pos;
79 for (pos = pxmlnsStack_->end(); pos > pxmlnsStack_->begin(); ) {
80 pos -= 2;
81 if (*(pos + 1) == ns &&
82 (!isattr || !pos->empty()) && PrefixMatchesNs(*pos, ns))
83 return std::make_pair(*pos, true);
84 }
85
86 return std::make_pair(STR_EMPTY, false); // none found
87 }
88
89 std::string XmlnsStack::FormatQName(const QName& name, bool isAttr) {
90 std::string prefix(PrefixForNs(name.Namespace(), isAttr).first);
91 if (prefix == STR_EMPTY)
92 return name.LocalPart();
93 else
94 return prefix + ':' + name.LocalPart();
95 }
96
97 void XmlnsStack::AddXmlns(const std::string & prefix, const std::string & ns) {
98 pxmlnsStack_->push_back(prefix);
99 pxmlnsStack_->push_back(ns);
100 }
101
102 void XmlnsStack::RemoveXmlns() {
103 pxmlnsStack_->pop_back();
104 pxmlnsStack_->pop_back();
105 }
106
107 static bool IsAsciiLetter(char ch) {
108 return ((ch >= 'a' && ch <= 'z') ||
109 (ch >= 'A' && ch <= 'Z'));
110 }
111
112 static std::string AsciiLower(const std::string & s) {
113 std::string result(s);
114 size_t i;
115 for (i = 0; i < result.length(); i++) {
116 if (result[i] >= 'A' && result[i] <= 'Z')
117 result[i] += 'a' - 'A';
118 }
119 return result;
120 }
121
122 static std::string SuggestPrefix(const std::string & ns) {
123 size_t len = ns.length();
124 size_t i = ns.find_last_of('.');
125 if (i != std::string::npos && len - i <= 4 + 1)
126 len = i; // chop off ".html" or ".xsd" or ".?{0,4}"
127 size_t last = len;
128 while (last > 0) {
129 last -= 1;
130 if (IsAsciiLetter(ns[last])) {
131 size_t first = last;
132 last += 1;
133 while (first > 0) {
134 if (!IsAsciiLetter(ns[first - 1]))
135 break;
136 first -= 1;
137 }
138 if (last - first > 4)
139 last = first + 3;
140 std::string candidate(AsciiLower(ns.substr(first, last - first)));
141 if (candidate.find("xml") != 0)
142 return candidate;
143 break;
144 }
145 }
146 return "ns";
147 }
148
149 std::pair<std::string, bool> XmlnsStack::AddNewPrefix(const std::string& ns,
150 bool isAttr) {
151 if (PrefixForNs(ns, isAttr).second)
152 return std::make_pair(STR_EMPTY, false);
153
154 std::string base(SuggestPrefix(ns));
155 std::string result(base);
156 int i = 2;
157 while (NsForPrefix(result).second) {
158 std::stringstream ss;
159 ss << base;
160 ss << (i++);
161 ss >> result;
162 }
163 AddXmlns(result, ns);
164 return std::make_pair(result, true);
165 }
166
167 void XmlnsStack::Reset() {
168 pxmlnsStack_->clear();
169 pxmlnsDepthStack_->clear();
170 }
171
172 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698