DCL 3.7.4
Loading...
Searching...
No Matches
URI.cpp
Go to the documentation of this file.
1
2#include <ctype.h>
3#include <string.h>
4
5#include <dcl/Object.h>
6
7#if __DCL_HAVE_ALLOC_DEBUG
8#undef __DCL_ALLOC_LEVEL
9#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
10#endif
11
12#include <dcl/Regex.h>
13#include <dcl/Numeric.h>
14#include <dcl/Charset.h>
15
16#include <dcl/URI.h>
17
18#if __DCL_HAVE_THIS_FILE__
19#undef __THIS_FILE__
20static const char_t* __THIS_FILE__ = __T("dcl/URI.cpp");
21#endif
22
23__DCL_BEGIN_NAMESPACE
24
25static int hextoi(const char* _s)
26{
27 __DCL_ASSERT(_s != NULL);
28
29 __DCL_ASSERT(_s[0] != '\0');
30 int c = _s[0];
31 if (isupper(c))
32 c = tolower(c);
33
34 int r = (('0' <= c && c <= '9') ? c - '0' : c - 'a' + 10) * 16;
35
36 __DCL_ASSERT(_s[1] != '\0');
37 c = _s[1];
38 if (isupper(c))
39 c = tolower(c);
40
41 r += ('0' <= c && c <= '9') ? c - '0' : c - 'a' + 10;
42
43 return r;
44}
45
46ByteString URLDecoder::decode(const char* _begin, const char* _end)
47{
48 ByteStringBuilder r;
49 while (_begin < _end) {
50 if (*_begin == '+')
51 r += ' ';
52 else if (
53 *_begin == '%'
54 && (_begin + 2) < _end
55 && isxdigit(*(_begin +1))
56 && isxdigit(*(_begin + 2))
57 ) {
58 r += (char)hextoi(_begin + 1);
59 _begin += 2;
60 }
61 else
62 r += *_begin;
63 _begin++;
64 }
65 return r;
66}
67
68ByteString URLDecoder::decode(const ByteString& _str)
69{
70 return URLDecoder::decode(_str, _str.data() + _str.length());
71}
72
73String URLDecoder::decode(const String& _str)
74{
75 return UTF8Decoder::decode(
77 UTF8Encoder::encode(_str)
78 )
79 );
80}
81
82ByteString URLEncoder::encode(const ByteString& _str)
83{
84 static unsigned char hexchars[] = "0123456789ABCDEF";
85
86 ByteStringBuilder r;
87
88 const char* psz = _str.data();
89 for (; *psz; psz++) {
90 unsigned char c = (unsigned char)*psz;
91 if (c == ' ')
92 r += '+';
93 else if ((c < '0' && c != '-' && c != '.')
94 || (c < 'A' && c > '9')
95 || (c > 'Z' && c < 'a' && c != '_')
96 || (c > 'z')
97 ) {
98 r += '%';
99 r += (char)hexchars[c >> 4];
100 r += (char)hexchars[c & 15];
101 }
102 else
103 r += (char)c;
104 }
105 return r;
106}
107
108String URLEncoder::encode(const String& _str)
109{
112 UTF8Encoder::encode(_str)
113 )
114 );
115}
116
118
119URI::URI(const wchar_t* _uri)
121{
122 __port = -1;
123 parse(_uri);
124}
125
126URI::URI(const wchar_t* _scheme,
127 const wchar_t* _schemeSpecificPart,
128 const wchar_t* _fragment
130{
131 __port = -1;
132 assign(
133 _scheme,
134 _schemeSpecificPart,
135 NULL,
136 -1,
137 NULL,
138 NULL,
139 _fragment
140 );
141}
142
143URI::URI(const wchar_t* _scheme,
144 const wchar_t* _userInfo,
145 const wchar_t* _host,
146 int _port,
147 const wchar_t* _path,
148 const wchar_t* _query,
149 const wchar_t* _fragment
151{
152 __port = -1;
153 assign(
154 _scheme,
155 _userInfo,
156 _host,
157 _port,
158 _path,
159 _query,
160 _fragment
161 );
162}
163
164URI::URI(const wchar_t* _scheme,
165 const wchar_t* _host,
166 const wchar_t* _path,
167 const wchar_t* _fragment
169{
170 __port = -1;
171 assign(
172 _scheme,
173 NULL,
174 _host,
175 -1,
176 _path,
177 NULL,
178 _fragment
179 );
180}
181
182URI::URI(const wchar_t* _scheme,
183 const wchar_t* _authority,
184 const wchar_t* _path,
185 const wchar_t* _query,
186 const wchar_t* _fragment
188{
189 __port = -1;
190 assign(
191 _scheme,
192 _authority,
193 NULL,
194 -1,
195 _path,
196 _query,
197 _fragment
198 );
199}
200
202 const wchar_t* _scheme,
203 const wchar_t* _userInfo,
204 const wchar_t* _host,
205 int _port,
206 const wchar_t* _path,
207 const wchar_t* _query,
208 const wchar_t* _fragment
210{
211 StringBuilder r;
212 if (_scheme) {
213 r = _scheme;
214 r += __T(":");
215 }
216
217 if (_userInfo || _host || _port > -1)
218 r += __T("//");
219
220 if (_userInfo) {
221 r += _userInfo;
222 r += __T("@");
223 }
224
225 if (_host)
226 r += _host;
227
228 if (_port > -1) {
229 r +=__T( ":");
230 r += Integer::toString(_port);
231 }
232
233 if (_path)
234 r += _path;
235
236 if (_query) {
237 r += __T("?");
238 r += _query;
239 }
240
241 if (_fragment) {
242 r += __T("#");
243 r += _fragment;
244 }
245
246 parse(r);
247}
248
249static const wchar_t* const __REGEXP_URI =
250 __T("^(([^:/?#]+):)?((//([^/?#]*))?([^?#]*)(\\?([^#]*))?)?(#(.*))?");
251
252static const wchar_t* const __REGEXP_AUTHORITY =
253 __T("^(([^?#]*)@)?([^?#:]*)(:([^?#]*))?");
254
255#define SCHEME_GROUP 2
256#define SCHEME_SPEC_PART_GROUP 3
257#define AUTHORITY_GROUP 5
258#define PATH_GROUP 6
259#define QUERY_GROUP 8
260#define FRAGMENT_GROUP 10
261
262#define AUTHORITY_USERINFO_GROUP 2
263#define AUTHORITY_HOST_GROUP 3
264#define AUTHORITY_PORT_GROUP 5
265
266void URI::parse(const wchar_t* _uri)
268{
269 __DCL_ASSERT(_uri && *_uri);
270
271 Regex re(__REGEXP_URI);
272 {
273 Regex::MatchResults m; // aMatch[11];
274 if (!re.match(_uri, m)) {
275 throw new URISyntaxException(
276 __T("doesn't match URI regular expression"),
277 _uri
278 );
279 }
280
281#define __MATCH_STR(m, index) m[index].first, m[index].second
282
286 __path.assign(__MATCH_STR(m, PATH_GROUP));
287 __query.assign(__MATCH_STR(m, QUERY_GROUP));
289 }
290
291 if (__authority.isEmpty())
292 return;
293
294 re.compile(__REGEXP_AUTHORITY);
295 {
297 if (re.match(__authority, m)) {
300 String port(__MATCH_STR(m, AUTHORITY_PORT_GROUP));
301 __port = Integer::parse(port, 10, __port);
302 }
303 }
304 __uri = _uri;
305}
306
308
309URISyntaxException::URISyntaxException(
310 const String& _reason,
311 const String& _source
312) : Exception(NULL)
313{
314 __message = _reason + __T(": ") + _source;
315}
316
317String URISyntaxException::toString() const
318{
319 return __message;
320}
321
322__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
wchar_t char_t
Definition Config.h:247
#define __DCL_THROWS1(e)
Definition Config.h:152
IOException *size_t r
Definition MediaInfo.cpp:82
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
#define QUERY_GROUP
Definition URI.cpp:259
#define AUTHORITY_USERINFO_GROUP
Definition URI.cpp:262
#define FRAGMENT_GROUP
Definition URI.cpp:260
#define SCHEME_SPEC_PART_GROUP
Definition URI.cpp:256
#define SCHEME_GROUP
Definition URI.cpp:255
#define AUTHORITY_GROUP
Definition URI.cpp:257
#define AUTHORITY_HOST_GROUP
Definition URI.cpp:263
#define AUTHORITY_PORT_GROUP
Definition URI.cpp:264
#define PATH_GROUP
Definition URI.cpp:258
#define __MATCH_STR(m, index)
static String decode(const char *_mbs, size_t _mbslen=(size_t) -1)
virtual String toString() const
Definition Exception.cpp:40
String toString(unsigned _base=10) const
Definition Numeric.inl:21
static int parse(const wchar_t *_number, unsigned _base=10) __DCL_THROWS1(NumericConvertException *)
Definition Numeric.inl:36
Definition Regex.h:32
bool match(const wchar_t *_begin, const wchar_t *_end, unsigned int _flags) __DCL_THROWS1(RegexException *)
Definition Regex.cpp:160
void compile(const wchar_t *_pattern, size_t _n, unsigned int _flags=0) __DCL_THROWS1(RegexException *)
Definition Regex.cpp:103
Definition URI.h:36
int __port
Definition URI.h:89
String __uri
Definition URI.h:94
String __authority
Definition URI.h:86
String __userInfo
Definition URI.h:87
String __fragment
Definition URI.h:92
String __query
Definition URI.h:91
void parse(const wchar_t *_uri) __DCL_THROWS1(URISyntaxException *)
Definition URI.cpp:266
String __scheme
Definition URI.h:84
void assign(const wchar_t *_scheme, const wchar_t *_userInfo, const wchar_t *_host, int _port, const wchar_t *_path, const wchar_t *_query, const wchar_t *_fragment) __DCL_THROWS1(URISyntaxException *)
Definition URI.cpp:201
String __schemeSpecificPart
Definition URI.h:85
String __host
Definition URI.h:88
String __path
Definition URI.h:90
String __message
Definition URI.h:118
static ByteString decode(const char *_begin, const char *_end)
Definition URI.cpp:46
static ByteString encode(const ByteString &_str)
Definition URI.cpp:82