ObjFW  Check-in [ddd3a6683f]

Overview
Comment:Add support for relative URLs to OFURL.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ddd3a6683f58441021149c112b5add3945cceba9f47fbc690809dffd3021bc02
User & Date: js on 2011-02-09 12:33:32
Other Links: manifest | tags
Context
2011-02-09
16:16
Add OFHTTPRequest class. check-in: 3beecbace3 user: js tags: trunk
12:33
Add support for relative URLs to OFURL. check-in: ddd3a6683f user: js tags: trunk
09:37
Add -[containsString:] to OFString. check-in: a6c5af136b user: js tags: trunk
Changes

Modified src/OFURL.h from [a030f72131] to [dd0072857c].

43
44
45
46
47
48
49
50
51
52
53
54








55
56
57
58
59
60
61
62










63
64
65
66
67
68
69
@property (copy) OFString *path;
@property (copy) OFString *parameters;
@property (copy) OFString *query;
@property (copy) OFString *fragment;
#endif

/**
 * \param str A string describing an URL
 * \return A new, autoreleased OFURL
 */
+ URLWithString: (OFString*)str;









/**
 * Initializes an already allocated OFURL.
 *
 * \param str A string describing an URL
 * \return An initialized OFURL
 */
- initWithString: (OFString*)str;











/**
 * \return The scheme part of the URL
 */
- (OFString*)scheme;

/**
 * Set the scheme part of the URL.







|




>
>
>
>
>
>
>
>



|




>
>
>
>
>
>
>
>
>
>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
@property (copy) OFString *path;
@property (copy) OFString *parameters;
@property (copy) OFString *query;
@property (copy) OFString *fragment;
#endif

/**
 * \param str A string describing a URL
 * \return A new, autoreleased OFURL
 */
+ URLWithString: (OFString*)str;

/**
 * \param str A string describing a URL
 * \param url An URL to which the string is relative
 * \return A new, autoreleased OFURL
 */
+ URLWithString: (OFString*)str
  relativeToURL: (OFURL*)url;

/**
 * Initializes an already allocated OFURL.
 *
 * \param str A string describing a URL
 * \return An initialized OFURL
 */
- initWithString: (OFString*)str;

/**
 * Initializes an already allocated OFURL.
 *
 * \param str A string describing a URL
 * \param url A URL to which the string is relative
 * \return An initialized OFURL
 */
- initWithString: (OFString*)str
   relativeToURL: (OFURL*)url;

/**
 * \return The scheme part of the URL
 */
- (OFString*)scheme;

/**
 * Set the scheme part of the URL.

Modified src/OFURL.m from [8d89f1d113] to [2d664c10f0].

18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35













































36
37
38
39
40







41
42
43
44
45
46
47

#include <stdlib.h>
#include <string.h>
#include <assert.h>

#import "OFURL.h"
#import "OFString.h"

#import "OFAutoreleasePool.h"
#import "OFExceptions.h"
#import "macros.h"

#define ADD_STR_HASH(str)			\
	h = [str hash];				\
	OF_HASH_ADD(hash, h >> 24);		\
	OF_HASH_ADD(hash, (h >> 16) & 0xFF);	\
	OF_HASH_ADD(hash, (h >> 8) & 0xFF);	\
	OF_HASH_ADD(hash, h & 0xFF);














































@implementation OFURL
+ URLWithString: (OFString*)str
{
	return [[[self alloc] initWithString: str] autorelease];
}








- initWithString: (OFString*)str
{
	char *str_c, *str_c2 = NULL;

	self = [super init];








>











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

#include <stdlib.h>
#include <string.h>
#include <assert.h>

#import "OFURL.h"
#import "OFString.h"
#import "OFArray.h"
#import "OFAutoreleasePool.h"
#import "OFExceptions.h"
#import "macros.h"

#define ADD_STR_HASH(str)			\
	h = [str hash];				\
	OF_HASH_ADD(hash, h >> 24);		\
	OF_HASH_ADD(hash, (h >> 16) & 0xFF);	\
	OF_HASH_ADD(hash, (h >> 8) & 0xFF);	\
	OF_HASH_ADD(hash, h & 0xFF);

static OF_INLINE OFString*
resolve_relative_path(OFString *path)
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMutableArray *array;
	OFString *ret;
	BOOL done = NO;

	array = [[[path componentsSeparatedByString: @"/"] mutableCopy]
	    autorelease];

	while (!done) {
		id *array_c = [array cArray];
		size_t i, array_len = [array count];

		done = YES;

		for (i = 0; i < array_len; i++) {
			if ([array_c[i] isEqual: @"."]) {
				[array removeObjectAtIndex: i];
				done = NO;

				break;
			}

			if ([array_c[i] isEqual: @".."]) {
				[array removeObjectAtIndex: i];

				if (i > 0)
					[array removeObjectAtIndex: i - 1];

				done = NO;

				break;
			}
		}
	}

	ret = [[array componentsJoinedByString: @"/"] retain];

	[pool release];

	return [ret autorelease];
}

@implementation OFURL
+ URLWithString: (OFString*)str
{
	return [[[self alloc] initWithString: str] autorelease];
}

+ URLWithString: (OFString*)str
  relativeToURL: (OFURL*)url
{
	return [[[self alloc] initWithString: str
			       relativeToURL: url] autorelease];
}

- initWithString: (OFString*)str
{
	char *str_c, *str_c2 = NULL;

	self = [super init];

139
140
141
142
143
144
145










































































146
147
148
149
150
151
152
				*tmp = '\0';

				parameters = [[OFString alloc]
				    initWithCString: tmp + 1];
			}

			path = [[OFString alloc] initWithCString: str_c];










































































		}
	} @catch (id e) {
		[self release];
		@throw e;
	} @finally {
		if (str_c2 != NULL)
			free(str_c2);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
				*tmp = '\0';

				parameters = [[OFString alloc]
				    initWithCString: tmp + 1];
			}

			path = [[OFString alloc] initWithCString: str_c];
		}
	} @catch (id e) {
		[self release];
		@throw e;
	} @finally {
		if (str_c2 != NULL)
			free(str_c2);
	}

	return self;
}

- initWithString: (OFString*)str
   relativeToURL: (OFURL*)url
{
	char *str_c, *str_c2 = NULL;

	if ([str containsString: @"://"])
		return [self initWithString: str];

	self = [super init];

	@try {
		char *tmp;

		scheme = [url->scheme copy];
		host = [url->host copy];
		port = url->port;
		user = [url->user copy];
		password = [url->password copy];

		if ((str_c2 = strdup([str cString])) == NULL)
			@throw [OFOutOfMemoryException
			     newWithClass: isa
			    requestedSize: [str cStringLength]];

		str_c = str_c2;

		if ((tmp = strchr(str_c, '#')) != NULL) {
			*tmp = '\0';
			fragment = [[OFString alloc] initWithCString: tmp + 1];
		}

		if ((tmp = strchr(str_c, '?')) != NULL) {
			*tmp = '\0';
			query = [[OFString alloc] initWithCString: tmp + 1];
		}

		if ((tmp = strchr(str_c, ';')) != NULL) {
			*tmp = '\0';
			parameters = [[OFString alloc]
			    initWithCString: tmp + 1];
		}

		if (*str_c == '/')
			path = [[OFString alloc] initWithCString: str_c + 1];
		else {
			OFAutoreleasePool *pool;
			OFString *s;

			pool = [[OFAutoreleasePool alloc] init];

			if ([url->path hasSuffix: @"/"])
				s = [OFString stringWithFormat: @"%@%s",
								url->path,
								str_c];
			else
				s = [OFString stringWithFormat: @"%@/../%s",
								url->path,
								str_c];

			path = [resolve_relative_path(s) copy];

			[pool release];
		}
	} @catch (id e) {
		[self release];
		@throw e;
	} @finally {
		if (str_c2 != NULL)
			free(str_c2);

Modified tests/OFURLTests.m from [7ab756aa3f] to [7e19b927ee].

33
34
35
36
37
38
39













40
41
42
43
44
45
46
	OFURL *u1, *u2, *u3, *u4;

	TEST(@"+[URLWithString:]",
	    R(u1 = [OFURL URLWithString: url_str]) &&
	    R(u2 = [OFURL URLWithString: @"http://foo:80"]) &&
	    R(u3 = [OFURL URLWithString: @"http://bar/"]))














	TEST(@"-[description]",
	    [[u1 description] isEqual: url_str] &&
	    [[u2 description] isEqual: @"http://foo"] &&
	    [[u3 description] isEqual: @"http://bar/"])

	TEST(@"-[scheme]", [[u1 scheme] isEqual: @"http"])
	TEST(@"-[user]", [[u1 user] isEqual: @"u"])







>
>
>
>
>
>
>
>
>
>
>
>
>







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
	OFURL *u1, *u2, *u3, *u4;

	TEST(@"+[URLWithString:]",
	    R(u1 = [OFURL URLWithString: url_str]) &&
	    R(u2 = [OFURL URLWithString: @"http://foo:80"]) &&
	    R(u3 = [OFURL URLWithString: @"http://bar/"]))

	TEST(@"+[URLWithString:relativeToURL:]",
	    [[[OFURL URLWithString: @"/foo"
		     relativeToURL: u1] description] isEqual:
	    @"http://u:p@h:1234/foo"] &&
	    [[[OFURL URLWithString: @"foo/bar?q"
		     relativeToURL: [OFURL URLWithString: @"http://h/qux/quux"]]
	    description] isEqual: @"http://h/qux/foo/bar?q"] &&
	    [[[OFURL URLWithString: @"foo/bar"
		     relativeToURL: [OFURL URLWithString: @"http://h/qux/?x"]]
	    description] isEqual: @"http://h/qux/foo/bar"] &&
	    [[[OFURL URLWithString: @"http://foo/?q"
		     relativeToURL: u1] description] isEqual: @"http://foo/?q"])

	TEST(@"-[description]",
	    [[u1 description] isEqual: url_str] &&
	    [[u2 description] isEqual: @"http://foo"] &&
	    [[u3 description] isEqual: @"http://bar/"])

	TEST(@"-[scheme]", [[u1 scheme] isEqual: @"http"])
	TEST(@"-[user]", [[u1 user] isEqual: @"u"])