diff options
author | Mike Buland <eichlan@xagasoft.com> | 2009-02-08 00:44:10 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2009-02-08 00:44:10 +0000 |
commit | 366a8063730aa7ae696bcb9cf56eafd13d43dfc0 (patch) | |
tree | 42e3597edfde0c183506ad0d452f045cb7726137 /src/url.cpp | |
parent | 4f59dec6bad120b72f1bc075715d79bfbe881f7e (diff) | |
download | libbu++-366a8063730aa7ae696bcb9cf56eafd13d43dfc0.tar.gz libbu++-366a8063730aa7ae696bcb9cf56eafd13d43dfc0.tar.bz2 libbu++-366a8063730aa7ae696bcb9cf56eafd13d43dfc0.tar.xz libbu++-366a8063730aa7ae696bcb9cf56eafd13d43dfc0.zip |
So many updates. I recommend using the new FString iterators instead of direct
indexing. It is now many times faster, and requires less overhead. Also,
more stuff iterator related in every class. More on that later.
Diffstat (limited to '')
-rw-r--r-- | src/url.cpp | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/src/url.cpp b/src/url.cpp new file mode 100644 index 0000000..7cc4263 --- /dev/null +++ b/src/url.cpp | |||
@@ -0,0 +1,237 @@ | |||
1 | #include "bu/url.h" | ||
2 | #ifndef WIN32 | ||
3 | # include <netdb.h> | ||
4 | # include <netinet/in.h> | ||
5 | #endif | ||
6 | #include <stdlib.h> | ||
7 | |||
8 | char Bu::Url::hexcode[] = { | ||
9 | '0', '1', '2', '3', '4', '5', '6', '7', | ||
10 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' | ||
11 | }; | ||
12 | |||
13 | Bu::Url::Url() | ||
14 | { | ||
15 | } | ||
16 | |||
17 | Bu::Url::Url( const Bu::FString &sUrl ) | ||
18 | { | ||
19 | parseUrl( sUrl ); | ||
20 | } | ||
21 | |||
22 | Bu::Url::~Url() | ||
23 | { | ||
24 | } | ||
25 | |||
26 | void Bu::Url::parseUrl( const Bu::FString &sUrl ) | ||
27 | { | ||
28 | clear(); | ||
29 | |||
30 | Bu::FString::const_iterator i = sUrl.begin(); | ||
31 | parseProtocol( i ); | ||
32 | parseUserPass( i ); | ||
33 | parseHost( i ); | ||
34 | parsePath( i ); | ||
35 | } | ||
36 | |||
37 | Bu::FString Bu::Url::decode( const Bu::FString &sStr ) | ||
38 | { | ||
39 | Bu::FString sRet; | ||
40 | char buf[3] = {0, 0, 0}; | ||
41 | for( Bu::FString::const_iterator i = sStr.begin(); i; i++ ) | ||
42 | { | ||
43 | if( *i == '+' ) | ||
44 | { | ||
45 | sRet += ' '; | ||
46 | } | ||
47 | else if( *i == '%' ) | ||
48 | { | ||
49 | i++; | ||
50 | buf[0] = *i; | ||
51 | i++; | ||
52 | buf[1] = *i; | ||
53 | sRet += (char)((unsigned char)strtol( buf, NULL, 16 )); | ||
54 | } | ||
55 | else | ||
56 | { | ||
57 | sRet += *i; | ||
58 | } | ||
59 | } | ||
60 | return sRet; | ||
61 | } | ||
62 | |||
63 | Bu::FString Bu::Url::encode( const Bu::FString &sStr ) | ||
64 | { | ||
65 | Bu::FString sRet; | ||
66 | for( Bu::FString::const_iterator i = sStr.begin(); i; i++ ) | ||
67 | { | ||
68 | if( *i == ' ' ) | ||
69 | { | ||
70 | sRet += '+'; | ||
71 | } | ||
72 | else if( | ||
73 | (*i >= 'A' && *i <= 'Z') || | ||
74 | (*i >= 'a' && *i <= 'z') || | ||
75 | (*i >= '0' && *i <= '9') || | ||
76 | (*i == '-' || *i == '_' || *i == '.' || *i == '~') | ||
77 | ) | ||
78 | { | ||
79 | sRet += *i; | ||
80 | } | ||
81 | else | ||
82 | { | ||
83 | unsigned char b = *i; | ||
84 | sRet += '%'; | ||
85 | sRet += hexcode[(b>>4)&0xF]; | ||
86 | sRet += hexcode[b&0xF]; | ||
87 | } | ||
88 | } | ||
89 | return sRet; | ||
90 | } | ||
91 | |||
92 | void Bu::Url::parseProtocol( Bu::FString::const_iterator &i ) | ||
93 | { | ||
94 | Bu::FString::const_iterator s = i.find("://", 3); | ||
95 | if( !s ) | ||
96 | throw Bu::ExceptionBase("No :// in url"); | ||
97 | Bu::FString sTmp( i, s ); | ||
98 | setProtocol( sTmp ); | ||
99 | i = s + 3; | ||
100 | } | ||
101 | |||
102 | void Bu::Url::setProtocol( const Bu::FString &sNewProto, bool bAutoSetPort ) | ||
103 | { | ||
104 | sProtocol = sNewProto; | ||
105 | #ifndef WIN32 | ||
106 | if( bAutoSetPort ) | ||
107 | { | ||
108 | struct servent *se = getservbyname( sProtocol.getStr(), "tcp" ); | ||
109 | if( se ) | ||
110 | { | ||
111 | iPort = ntohs( se->s_port ); | ||
112 | } | ||
113 | } | ||
114 | #endif | ||
115 | } | ||
116 | |||
117 | void Bu::Url::parseUserPass( Bu::FString::const_iterator &i ) | ||
118 | { | ||
119 | Bu::FString::const_iterator s = i.find('@'); | ||
120 | if( !s ) | ||
121 | return; | ||
122 | |||
123 | Bu::FString::const_iterator p = i.find(':'); | ||
124 | if( p ) | ||
125 | { | ||
126 | sUser.set( i, p ); | ||
127 | sPass.set( p+1, s ); | ||
128 | } | ||
129 | else | ||
130 | { | ||
131 | sUser.set( i, s ); | ||
132 | } | ||
133 | |||
134 | i = s + 1; | ||
135 | } | ||
136 | |||
137 | void Bu::Url::parseHost( Bu::FString::const_iterator &i ) | ||
138 | { | ||
139 | Bu::FString::const_iterator s = i; | ||
140 | for( ; s && *s != '/'; s++ ) | ||
141 | { | ||
142 | if( *s == ':' ) | ||
143 | { | ||
144 | sHost.set( i, s ); | ||
145 | i = s + 1; | ||
146 | s = i.find('/'); | ||
147 | Bu::FString sPort( i, s ); | ||
148 | iPort = strtol( sPort.getStr(), NULL, 10 ); | ||
149 | i = s; | ||
150 | return; | ||
151 | } | ||
152 | } | ||
153 | sHost.set( i, s ); | ||
154 | i = s; | ||
155 | } | ||
156 | |||
157 | void Bu::Url::parsePath( Bu::FString::const_iterator &i ) | ||
158 | { | ||
159 | if( i ) | ||
160 | { | ||
161 | Bu::FString::const_iterator s = i.find('?'); | ||
162 | sPath.set( i, s ); | ||
163 | i = s + 1; | ||
164 | if( s ) | ||
165 | { | ||
166 | parseParams( i ); | ||
167 | } | ||
168 | } | ||
169 | else | ||
170 | { | ||
171 | sPath = "/"; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | void Bu::Url::parseParams( Bu::FString::const_iterator &i ) | ||
176 | { | ||
177 | bool bName = true; | ||
178 | Bu::FString sName, sValue; | ||
179 | for( Bu::FString::const_iterator s = i; s; s++ ) | ||
180 | { | ||
181 | if( bName ) | ||
182 | { | ||
183 | if( *s == '&' ) | ||
184 | { | ||
185 | sName.set( i, s ); | ||
186 | sValue.clear(); | ||
187 | i = s + 1; | ||
188 | addParam( decode( sName ), decode( sValue ) ); | ||
189 | } | ||
190 | else if( *s == '=' ) | ||
191 | { | ||
192 | sName.set( i, s ); | ||
193 | i = s + 1; | ||
194 | bName = false; | ||
195 | } | ||
196 | } | ||
197 | else | ||
198 | { | ||
199 | if( *s == '&' ) | ||
200 | { | ||
201 | sValue.set( i, s ); | ||
202 | i = s + 1; | ||
203 | bName = true; | ||
204 | addParam( decode( sName ), decode( sValue ) ); | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | if( i ) | ||
209 | { | ||
210 | if( bName ) | ||
211 | { | ||
212 | sName.set( i ); | ||
213 | sValue.clear(); | ||
214 | } | ||
215 | else | ||
216 | { | ||
217 | sValue.set( i ); | ||
218 | } | ||
219 | addParam( decode( sName ), decode( sValue ) ); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | void Bu::Url::addParam( const Bu::FString &n, const Bu::FString &v ) | ||
224 | { | ||
225 | lParam.append( Param( n, v ) ); | ||
226 | } | ||
227 | |||
228 | void Bu::Url::clear() | ||
229 | { | ||
230 | sProtocol.clear(); | ||
231 | sUser.clear(); | ||
232 | sPass.clear(); | ||
233 | sHost.clear(); | ||
234 | sPath.clear(); | ||
235 | iPort.clear(); | ||
236 | } | ||
237 | |||