Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/src/uri.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 115 - (show annotations) (download) (as text)
Fri Dec 7 07:17:41 2012 UTC (11 years, 5 months ago) by z0rac
File MIME type: text/x-c++src
File size: 3479 byte(s)


1 /*
2 * Copyright (C) 2010-2012 TSUBAKIMOTO Hiroya <z0rac@users.sourceforge.jp>
3 *
4 * This software comes with ABSOLUTELY NO WARRANTY; for details of
5 * the license terms, see the LICENSE.txt file included with the program.
6 */
7 #include "mailbox.h"
8 #include "win32.h"
9 #include <cassert>
10 #include <cstdlib>
11 #include <cstring>
12
13 #ifdef _DEBUG
14 #include <iostream>
15 #define DBG(s) s
16 #define LOG(s) (cout << s)
17 #else
18 #define DBG(s)
19 #define LOG(s)
20 #endif
21
22 /*
23 * Functions of the class uri
24 */
25 namespace {
26 string::size_type find(const string& s,
27 string::value_type c, string::size_type i = 0)
28 {
29 while (i < s.size()) {
30 if (s[i] == c) return i;
31 i += (i + 1 < s.size() && IsDBCSLeadByte(BYTE(s[i]))) + 1;
32 }
33 return string::npos;
34 }
35
36 string decode(const string& s)
37 {
38 string result;
39 string::size_type i = 0;
40 while (i < s.size()) {
41 string::size_type n = find(s, '%', i);
42 if (n == string::npos || s.size() - n < 3) break;
43 result.append(s, i, n - i);
44 char hex[3] = { s[n + 1], s[n + 2] };
45 char* e;
46 char c = char(strtoul(hex, &e, 16));
47 i = n + (*e ? (c = '%', 1) : 3);
48 result.push_back(c);
49 }
50 if (i < s.size()) result.append(s.c_str() + i);
51 return result;
52 }
53
54 string encode(const string& s, const char* chs)
55 {
56 string result;
57 string::size_type i = 0;
58 while (i < s.size()) {
59 const char* const t = s.c_str();
60 const char* p = t + i;
61 while (BYTE(*p) > 32) {
62 string::size_type n =
63 IsDBCSLeadByte(BYTE(*p)) ? (p[1] != 0) * 2 : !strchr(chs, *p);
64 p += n;
65 if (n == 0) break;
66 }
67 if (!*p) break;
68 string::size_type n = p - t;
69 result.append(s, i, n - i);
70 char hex[4] = { '%' };
71 _ltoa(s[n] & 255, hex + 1, 16);
72 result.append(hex);
73 i = n + 1;
74 }
75 if (i < s.size()) result.append(s.c_str() + i);
76 return result;
77 }
78 }
79
80 uri::uri(const string& uri)
81 {
82 string::size_type i = find(uri, '#');
83 if (i != string::npos) _part[fragment] = decode(uri.substr(i + 1));
84
85 string t(uri, 0, min(find(uri, '?'), i));
86 i = find(t, ':');
87 for (; i != string::npos; i = find(t, ':', i)) {
88 if (++i == t.size() || t[i] != '/') continue;
89 if (++i == t.size() || t[i] != '/') continue;
90 _part[scheme] = decode(t.substr(0, i - 2));
91 t.erase(0, i + 1);
92 break;
93 }
94 i = find(t, '/');
95 if (i != string::npos) {
96 _part[path] = decode(t.substr(i + 1));
97 t.erase(i);
98 }
99 i = find(t, '@');
100 if (i != string::npos) {
101 _part[user] = decode(t.substr(0, min(find(t, ';'), i)));
102 t.erase(0, i + 1);
103 }
104 i = find(t, ':');
105 for (; i != string::npos; i = find(t, ':', i)) {
106 string::size_type n = i;
107 while (++i < t.size() && strchr("0123456789", t[i])) continue;
108 if (i < t.size()) continue;
109 _part[port] = t.substr(n + 1);
110 t.erase(n);
111 }
112 _part[host] = decode(t);
113 }
114
115 uri::operator string() const
116 {
117 string uri = encode(_part[scheme], "#%") + "://";
118 if (!_part[host].empty()) {
119 if (!_part[user].empty()) uri += encode(_part[user], "@/#%") + '@';
120 const string& h = _part[host];
121 uri += encode(h, *h.begin() == '[' && *h.rbegin() == ']' ? "/#%" : ":/#%");
122 if (!_part[port].empty()) uri += ':' + _part[port];
123 }
124 uri += '/' + encode(_part[path], "#%");
125 if (!_part[fragment].empty()) uri += '#' + encode(_part[fragment], "%");
126 return uri;
127 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26