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

Side by Side Diff: third_party/xmpp/jid.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/xmpp/jid.h"
6
7 #include <ctype.h>
8
9 #include <algorithm>
10 #include <string>
11
12 #include "third_party/xmpp/constants.h"
13 #include "webrtc/base/common.h"
14 #include "webrtc/base/logging.h"
15
16 namespace buzz {
17
18 Jid::Jid() {
19 }
20
21 Jid::Jid(const std::string& jid_string) {
22 if (jid_string.empty())
23 return;
24
25 // First find the slash and slice off that part
26 size_t slash = jid_string.find('/');
27 resource_name_ = (slash == std::string::npos ? STR_EMPTY :
28 jid_string.substr(slash + 1));
29
30 // Now look for the node
31 size_t at = jid_string.find('@');
32 size_t domain_begin;
33 if (at < slash && at != std::string::npos) {
34 node_name_ = jid_string.substr(0, at);
35 domain_begin = at + 1;
36 } else {
37 domain_begin = 0;
38 }
39
40 // Now take what is left as the domain
41 size_t domain_length = (slash == std::string::npos) ?
42 (jid_string.length() - domain_begin) : (slash - domain_begin);
43 domain_name_ = jid_string.substr(domain_begin, domain_length);
44
45 ValidateOrReset();
46 }
47
48 Jid::Jid(const std::string& node_name,
49 const std::string& domain_name,
50 const std::string& resource_name)
51 : node_name_(node_name),
52 domain_name_(domain_name),
53 resource_name_(resource_name) {
54 ValidateOrReset();
55 }
56
57 void Jid::ValidateOrReset() {
58 bool valid_node;
59 bool valid_domain;
60 bool valid_resource;
61
62 node_name_ = PrepNode(node_name_, &valid_node);
63 domain_name_ = PrepDomain(domain_name_, &valid_domain);
64 resource_name_ = PrepResource(resource_name_, &valid_resource);
65
66 if (!valid_node || !valid_domain || !valid_resource) {
67 node_name_.clear();
68 domain_name_.clear();
69 resource_name_.clear();
70 }
71 }
72
73 std::string Jid::Str() const {
74 if (!IsValid())
75 return STR_EMPTY;
76
77 std::string ret;
78
79 if (!node_name_.empty())
80 ret = node_name_ + "@";
81
82 ASSERT(domain_name_ != STR_EMPTY);
83 ret += domain_name_;
84
85 if (!resource_name_.empty())
86 ret += "/" + resource_name_;
87
88 return ret;
89 }
90
91 Jid::~Jid() {
92 }
93
94 bool Jid::IsEmpty() const {
95 return (node_name_.empty() && domain_name_.empty() &&
96 resource_name_.empty());
97 }
98
99 bool Jid::IsValid() const {
100 return !domain_name_.empty();
101 }
102
103 bool Jid::IsBare() const {
104 if (IsEmpty()) {
105 LOG(LS_VERBOSE) << "Warning: Calling IsBare() on the empty jid.";
106 return true;
107 }
108 return IsValid() && resource_name_.empty();
109 }
110
111 bool Jid::IsFull() const {
112 return IsValid() && !resource_name_.empty();
113 }
114
115 Jid Jid::BareJid() const {
116 if (!IsValid())
117 return Jid();
118 if (!IsFull())
119 return *this;
120 return Jid(node_name_, domain_name_, STR_EMPTY);
121 }
122
123 bool Jid::BareEquals(const Jid& other) const {
124 return other.node_name_ == node_name_ &&
125 other.domain_name_ == domain_name_;
126 }
127
128 void Jid::CopyFrom(const Jid& jid) {
129 this->node_name_ = jid.node_name_;
130 this->domain_name_ = jid.domain_name_;
131 this->resource_name_ = jid.resource_name_;
132 }
133
134 bool Jid::operator==(const Jid& other) const {
135 return other.node_name_ == node_name_ &&
136 other.domain_name_ == domain_name_ &&
137 other.resource_name_ == resource_name_;
138 }
139
140 int Jid::Compare(const Jid& other) const {
141 int compare_result;
142 compare_result = node_name_.compare(other.node_name_);
143 if (0 != compare_result)
144 return compare_result;
145 compare_result = domain_name_.compare(other.domain_name_);
146 if (0 != compare_result)
147 return compare_result;
148 compare_result = resource_name_.compare(other.resource_name_);
149 return compare_result;
150 }
151
152 // --- JID parsing code: ---
153
154 // Checks and normalizes the node part of a JID.
155 std::string Jid::PrepNode(const std::string& node, bool* valid) {
156 *valid = false;
157 std::string result;
158
159 for (std::string::const_iterator i = node.begin(); i < node.end(); ++i) {
160 bool char_valid = true;
161 unsigned char ch = *i;
162 if (ch <= 0x7F) {
163 result += PrepNodeAscii(ch, &char_valid);
164 }
165 else {
166 // TODO: implement the correct stringprep protocol for these
167 result += tolower(ch);
168 }
169 if (!char_valid) {
170 return STR_EMPTY;
171 }
172 }
173
174 if (result.length() > 1023) {
175 return STR_EMPTY;
176 }
177 *valid = true;
178 return result;
179 }
180
181
182 // Returns the appropriate mapping for an ASCII character in a node.
183 char Jid::PrepNodeAscii(char ch, bool* valid) {
184 *valid = true;
185 switch (ch) {
186 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
187 case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
188 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
189 case 'V': case 'W': case 'X': case 'Y': case 'Z':
190 return (char)(ch + ('a' - 'A'));
191
192 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
193 case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
194 case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
195 case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
196 case ' ': case '&': case '/': case ':': case '<': case '>': case '@':
197 case '\"': case '\'':
198 case 0x7F:
199 *valid = false;
200 return 0;
201
202 default:
203 return ch;
204 }
205 }
206
207
208 // Checks and normalizes the resource part of a JID.
209 std::string Jid::PrepResource(const std::string& resource, bool* valid) {
210 *valid = false;
211 std::string result;
212
213 for (std::string::const_iterator i = resource.begin();
214 i < resource.end(); ++i) {
215 bool char_valid = true;
216 unsigned char ch = *i;
217 if (ch <= 0x7F) {
218 result += PrepResourceAscii(ch, &char_valid);
219 }
220 else {
221 // TODO: implement the correct stringprep protocol for these
222 result += ch;
223 }
224 }
225
226 if (result.length() > 1023) {
227 return STR_EMPTY;
228 }
229 *valid = true;
230 return result;
231 }
232
233 // Returns the appropriate mapping for an ASCII character in a resource.
234 char Jid::PrepResourceAscii(char ch, bool* valid) {
235 *valid = true;
236 switch (ch) {
237 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
238 case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
239 case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
240 case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
241 case 0x7F:
242 *valid = false;
243 return 0;
244
245 default:
246 return ch;
247 }
248 }
249
250 // Checks and normalizes the domain part of a JID.
251 std::string Jid::PrepDomain(const std::string& domain, bool* valid) {
252 *valid = false;
253 std::string result;
254
255 // TODO: if the domain contains a ':', then we should parse it
256 // as an IPv6 address rather than giving an error about illegal domain.
257 PrepDomain(domain, &result, valid);
258 if (!*valid) {
259 return STR_EMPTY;
260 }
261
262 if (result.length() > 1023) {
263 return STR_EMPTY;
264 }
265 *valid = true;
266 return result;
267 }
268
269
270 // Checks and normalizes an IDNA domain.
271 void Jid::PrepDomain(const std::string& domain, std::string* buf, bool* valid) {
272 *valid = false;
273 std::string::const_iterator last = domain.begin();
274 for (std::string::const_iterator i = domain.begin(); i < domain.end(); ++i) {
275 bool label_valid = true;
276 char ch = *i;
277 switch (ch) {
278 case 0x002E:
279 #if 0 // FIX: This isn't UTF-8-aware.
280 case 0x3002:
281 case 0xFF0E:
282 case 0xFF61:
283 #endif
284 PrepDomainLabel(last, i, buf, &label_valid);
285 *buf += '.';
286 last = i + 1;
287 break;
288 }
289 if (!label_valid) {
290 return;
291 }
292 }
293 PrepDomainLabel(last, domain.end(), buf, valid);
294 }
295
296 // Checks and normalizes a domain label.
297 void Jid::PrepDomainLabel(
298 std::string::const_iterator start, std::string::const_iterator end,
299 std::string* buf, bool* valid) {
300 *valid = false;
301
302 int start_len = static_cast<int>(buf->length());
303 for (std::string::const_iterator i = start; i < end; ++i) {
304 bool char_valid = true;
305 unsigned char ch = *i;
306 if (ch <= 0x7F) {
307 *buf += PrepDomainLabelAscii(ch, &char_valid);
308 }
309 else {
310 // TODO: implement ToASCII for these
311 *buf += ch;
312 }
313 if (!char_valid) {
314 return;
315 }
316 }
317
318 int count = static_cast<int>(buf->length() - start_len);
319 if (count == 0) {
320 return;
321 }
322 else if (count > 63) {
323 return;
324 }
325
326 // Is this check needed? See comment in PrepDomainLabelAscii.
327 if ((*buf)[start_len] == '-') {
328 return;
329 }
330 if ((*buf)[buf->length() - 1] == '-') {
331 return;
332 }
333 *valid = true;
334 }
335
336
337 // Returns the appropriate mapping for an ASCII character in a domain label.
338 char Jid::PrepDomainLabelAscii(char ch, bool* valid) {
339 *valid = true;
340 // TODO: A literal reading of the spec seems to say that we do
341 // not need to check for these illegal characters (an "internationalized
342 // domain label" runs ToASCII with UseSTD3... set to false). But that
343 // can't be right. We should at least be checking that there are no '/'
344 // or '@' characters in the domain. Perhaps we should see what others
345 // do in this case.
346
347 switch (ch) {
348 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
349 case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
350 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
351 case 'V': case 'W': case 'X': case 'Y': case 'Z':
352 return (char)(ch + ('a' - 'A'));
353
354 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
355 case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
356 case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
357 case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
358 case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D:
359 case 0x1E: case 0x1F: case 0x20: case 0x21: case 0x22: case 0x23:
360 case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29:
361 case 0x2A: case 0x2B: case 0x2C: case 0x2E: case 0x2F: case 0x3A:
362 case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F: case 0x40:
363 case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F: case 0x60:
364 case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F:
365 *valid = false;
366 return 0;
367
368 default:
369 return ch;
370 }
371 }
372
373 } // namespace buzz
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698