ObjFW  Check-in [f19cde3a14]

Overview
Comment:Move a few URL methods from OFString to OFURL
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: f19cde3a14c295f7e1e930f68e61a359436f102ff7fb59ec04d15406786b1cc6
User & Date: js on 2019-02-03 19:19:52
Other Links: manifest | tags
Context
2019-02-07
00:46
Make style consistent between ObjFW and ObjFW_RT check-in: ef6d69931e user: js tags: trunk
2019-02-03
19:19
Move a few URL methods from OFString to OFURL check-in: f19cde3a14 user: js tags: trunk
17:52
OFURL: Do not normalize in init with relative URL check-in: 2b13f285c5 user: js tags: trunk
Changes

Modified src/OFConstantString.m from [6574951a62] to [e40123b4c3].

431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
- (OFString *)stringByAppendingPathComponent: (OFString *)component
{
	[self finishInitialization];

	return [self stringByAppendingPathComponent: component];
}

- (OFString *)stringByAppendingURLPathComponent: (OFString *)component
{
	[self finishInitialization];

	return [self stringByAppendingURLPathComponent: component];
}

- (OFString *)stringByPrependingString: (OFString *)string
{
	[self finishInitialization];

	return [self stringByPrependingString: string];
}








<
<
<
<
<
<
<







431
432
433
434
435
436
437







438
439
440
441
442
443
444
- (OFString *)stringByAppendingPathComponent: (OFString *)component
{
	[self finishInitialization];

	return [self stringByAppendingPathComponent: component];
}








- (OFString *)stringByPrependingString: (OFString *)string
{
	[self finishInitialization];

	return [self stringByPrependingString: string];
}

Modified src/OFString.h from [83d6b83c23] to [054ec39bed].

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
 * @brief The double value of the string as a double.
 *
 * If the string contains any non-number characters, an
 * OFInvalidEncodingException is thrown.
 */
@property (readonly, nonatomic) double doubleValue;

/*!
 * @brief The string interpreted as a URL path with relative sub paths resolved.
 *
 * This works similar to @ref stringByStandardizingPath, but is intended for
 * standardization of paths that are part of a URL.
 */
@property (readonly, nonatomic) OFString *stringByStandardizingURLPath;

/*!
 * @brief The string as an array of Unicode characters.
 *
 * The result is valid until the autorelease pool is released. If you want to
 * use the result outside the scope of the current autorelease pool, you have to
 * copy it.
 */







<
<
<
<
<
<
<
<







211
212
213
214
215
216
217








218
219
220
221
222
223
224
 * @brief The double value of the string as a double.
 *
 * If the string contains any non-number characters, an
 * OFInvalidEncodingException is thrown.
 */
@property (readonly, nonatomic) double doubleValue;









/*!
 * @brief The string as an array of Unicode characters.
 *
 * The result is valid until the autorelease pool is released. If you want to
 * use the result outside the scope of the current autorelease pool, you have to
 * copy it.
 */
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
 * @param format A format string which generates the string to append
 * @param arguments The arguments used in the format string
 * @return A new, autoreleased OFString with the specified format appended
 */
- (OFString *)stringByAppendingFormat: (OFConstantString *)format
			    arguments: (va_list)arguments;

/*!
 * @brief Creates a new string by appending a URL path component.
 *
 * @param component The URL path component to append
 * @return A new, autoreleased OFString with the URL path component appended
 */
- (OFString *)stringByAppendingURLPathComponent: (OFString *)component;

/*!
 * @brief Creates a new string by prepending another string.
 *
 * @param string The string to prepend
 * @return A new autoreleased OFString with the specified string prepended
 */
- (OFString *)stringByPrependingString: (OFString *)string;







<
<
<
<
<
<
<
<







1029
1030
1031
1032
1033
1034
1035








1036
1037
1038
1039
1040
1041
1042
 * @param format A format string which generates the string to append
 * @param arguments The arguments used in the format string
 * @return A new, autoreleased OFString with the specified format appended
 */
- (OFString *)stringByAppendingFormat: (OFConstantString *)format
			    arguments: (va_list)arguments;









/*!
 * @brief Creates a new string by prepending another string.
 *
 * @param string The string to prepend
 * @return A new autoreleased OFString with the specified string prepended
 */
- (OFString *)stringByPrependingString: (OFString *)string;

Modified src/OFString.m from [ac5117fe19] to [b076cd8540].

2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
		arguments: arguments];

	[new makeImmutable];

	return new;
}

- (OFString *)stringByAppendingURLPathComponent: (OFString *)component
{
	if ([self hasSuffix: @"/"])
		return [self stringByAppendingString: component];
	else {
		OFMutableString *ret = [[self mutableCopy] autorelease];

		[ret appendString: @"/"];
		[ret appendString: component];

		[ret makeImmutable];

		return ret;
	}
}

- (OFString *)stringByPrependingString: (OFString *)string
{
	OFMutableString *new = [[string mutableCopy] autorelease];

	[new appendString: self];

	[new makeImmutable];







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2038
2039
2040
2041
2042
2043
2044
















2045
2046
2047
2048
2049
2050
2051
		arguments: arguments];

	[new makeImmutable];

	return new;
}

















- (OFString *)stringByPrependingString: (OFString *)string
{
	OFMutableString *new = [[string mutableCopy] autorelease];

	[new appendString: self];

	[new makeImmutable];
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
	[array makeImmutable];

	objc_autoreleasePoolPop(pool);

	return array;
}

- (OFString *)stringByStandardizingURLPath
{
	void *pool = objc_autoreleasePoolPush();
	OFArray OF_GENERIC(OFString *) *components =
	    [self componentsSeparatedByString: @"/"];
	OFMutableArray OF_GENERIC(OFString *) *array;
	OFString *ret;
	bool done = false, startsWithEmpty, endsWithEmpty;

	array = [[components mutableCopy] autorelease];

	if ((startsWithEmpty = [[array firstObject] isEqual: @""]))
		[array removeObjectAtIndex: 0];
	endsWithEmpty = [[array lastObject] isEqual: @""];

	while (!done) {
		size_t length = [array count];

		done = true;

		for (size_t i = 0; i < length; i++) {
			id object = [array objectAtIndex: i];
			id parent;

			if (i > 0)
				parent = [array objectAtIndex: i - 1];
			else
				parent = nil;

			if ([object isEqual: @"."] ||
			   [object length] == 0) {
				[array removeObjectAtIndex: i];

				done = false;
				break;
			}

			if ([object isEqual: @".."] && parent != nil &&
			    ![parent isEqual: @".."]) {
				[array removeObjectsInRange:
				    of_range(i - 1, 2)];

				done = false;
				break;
			}
		}
	}

	if (startsWithEmpty)
		[array insertObject: @""
			    atIndex: 0];
	if (endsWithEmpty)
		[array addObject: @""];

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

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

- (intmax_t)decimalValue
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];
	size_t i = 0, length = [self length];
	intmax_t value = 0;
	bool expectWhitespace = false;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2311
2312
2313
2314
2315
2316
2317





























































2318
2319
2320
2321
2322
2323
2324
	[array makeImmutable];

	objc_autoreleasePoolPop(pool);

	return array;
}






























































- (intmax_t)decimalValue
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];
	size_t i = 0, length = [self length];
	intmax_t value = 0;
	bool expectWhitespace = false;

Modified src/OFURL.h from [e32aace5ab] to [b537389466].

138
139
140
141
142
143
144





145
146
147
148
149
150
151
    OFString *URLEncodedFragment;

/*!
 * @brief The URL as a string.
 */
@property (readonly, nonatomic) OFString *string;






#ifdef OF_HAVE_FILES
/*!
 * @brief The local file system representation for a file URL.
 *
 * @note This only exists for URLs with the file scheme and throws an exception
 *	 otherwise.
 *







>
>
>
>
>







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    OFString *URLEncodedFragment;

/*!
 * @brief The URL as a string.
 */
@property (readonly, nonatomic) OFString *string;

/*!
 * @brief The URL with relative sub paths resolved.
 */
@property (readonly, nonatomic) OFURL *URLByStandardizingPath;

#ifdef OF_HAVE_FILES
/*!
 * @brief The local file system representation for a file URL.
 *
 * @note This only exists for URLs with the file scheme and throws an exception
 *	 otherwise.
 *

Modified src/OFURL.m from [684f4e251d] to [4bf97fa647].

1134
1135
1136
1137
1138
1139
1140



































































1141
1142
1143
1144
1145
1146
1147
		objc_autoreleasePoolPop(pool);
	}

	[ret makeImmutable];

	return ret;
}




































































- (OFString *)description
{
	return [OFString stringWithFormat: @"<%@: %@>",
					   [self class], [self string]];
}








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







1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
		objc_autoreleasePoolPop(pool);
	}

	[ret makeImmutable];

	return ret;
}

- (OFURL *)URLByStandardizingPath
{
	void *pool;
	OFMutableArray OF_GENERIC(OFString *) *array;
	bool done = false, endsWithEmpty;
	OFString *path;
	OFMutableURL *URL;

	if (_URLEncodedPath == nil)
		return self;

	pool = objc_autoreleasePoolPush();

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

	if ([[array firstObject] length] != 0)
		@throw [OFInvalidFormatException exception];

	endsWithEmpty = ([[array lastObject] length] == 0);

	while (!done) {
		size_t length = [array count];

		done = true;

		for (size_t i = 0; i < length; i++) {
			id object = [array objectAtIndex: i];
			id parent =
			    (i > 0 ? [array objectAtIndex: i - 1] : nil);

			if ([object isEqual: @"."] || [object length] == 0) {
				[array removeObjectAtIndex: i];

				done = false;
				break;
			}

			if ([object isEqual: @".."] && parent != nil &&
			    ![parent isEqual: @".."]) {
				[array removeObjectsInRange:
				    of_range(i - 1, 2)];

				done = false;
				break;
			}
		}
	}

	[array insertObject: @""
		    atIndex: 0];
	if (endsWithEmpty)
		[array addObject: @""];

	path = [array componentsJoinedByString: @"/"];
	if ([path length] == 0)
		path = @"/";

	URL = [[self mutableCopy] autorelease];
	[URL setURLEncodedPath: path];
	[URL makeImmutable];

	[URL retain];
	objc_autoreleasePoolPop(pool);
	return [URL autorelease];
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<%@: %@>",
					   [self class], [self string]];
}

Modified tests/OFStringTests.m from [ec27cf1f39] to [f95cef297c].

587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
	is = [stringClass stringWithString: s[1]];
	[s[1] appendString: @"baz"];
	TEST(@"-[stringByAppendingPathComponent:]",
	    [[s[0] stringByAppendingPathComponent: @"baz"] isEqual: s[1]] &&
	    [[is stringByAppendingPathComponent: @"baz"] isEqual: s[1]])
#endif

	s[0] = [mutableStringClass stringWithString: @"foo"];
	[s[0] appendString: @"/"];
	[s[0] appendString: @"bar"];
	s[1] = [mutableStringClass stringWithString: s[0]];
	[s[1] appendString: @"/"];
	is = [stringClass stringWithString: s[1]];
	[s[1] appendString: @"baz"];
	TEST(@"-[stringByAppendingURLPathComponent:]",
	    [[s[0] stringByAppendingURLPathComponent: @"baz"] isEqual: s[1]] &&
	    [[is stringByAppendingURLPathComponent: @"baz"] isEqual: s[1]])

	TEST(@"-[hasPrefix:]", [C(@"foobar") hasPrefix: @"foo"] &&
	    ![C(@"foobar") hasPrefix: @"foobar0"])

	TEST(@"-[hasSuffix:]", [C(@"foobar") hasSuffix: @"bar"] &&
	    ![C(@"foobar") hasSuffix: @"foobar0"])

	i = 0;







<
<
<
<
<
<
<
<
<
<
<







587
588
589
590
591
592
593











594
595
596
597
598
599
600
	is = [stringClass stringWithString: s[1]];
	[s[1] appendString: @"baz"];
	TEST(@"-[stringByAppendingPathComponent:]",
	    [[s[0] stringByAppendingPathComponent: @"baz"] isEqual: s[1]] &&
	    [[is stringByAppendingPathComponent: @"baz"] isEqual: s[1]])
#endif












	TEST(@"-[hasPrefix:]", [C(@"foobar") hasPrefix: @"foo"] &&
	    ![C(@"foobar") hasPrefix: @"foobar0"])

	TEST(@"-[hasSuffix:]", [C(@"foobar") hasSuffix: @"bar"] &&
	    ![C(@"foobar") hasSuffix: @"foobar0"])

	i = 0;

Modified tests/OFURLTests.m from [2aa332308d] to [65b67dad50].

272
273
274
275
276
277
278














279
280
281
			    isDirectory: false] isEqual:
	    [OFURL URLWithString: @"file:///qu%3Fx"]] &&
	    [[[OFURL URLWithString: @"file:///foo/bar/"]
	    URLByAppendingPathComponent: @"/qu?x"
			    isDirectory: true] isEqual:
	    [OFURL URLWithString: @"file:///qu%3Fx/"]])















	[pool drain];
}
@end







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



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
			    isDirectory: false] isEqual:
	    [OFURL URLWithString: @"file:///qu%3Fx"]] &&
	    [[[OFURL URLWithString: @"file:///foo/bar/"]
	    URLByAppendingPathComponent: @"/qu?x"
			    isDirectory: true] isEqual:
	    [OFURL URLWithString: @"file:///qu%3Fx/"]])

	TEST(@"-[URLByStandardizingPath]",
	    [[[OFURL URLWithString: @"http://foo/bar/.."]
	    URLByStandardizingPath] isEqual:
	    [OFURL URLWithString: @"http://foo/"]] &&
	    [[[OFURL URLWithString: @"http://foo/bar/%2E%2E/../qux/"]
	    URLByStandardizingPath] isEqual:
	    [OFURL URLWithString: @"http://foo/bar/qux/"]] &&
	    [[[OFURL URLWithString: @"http://foo/bar/./././qux/./"]
	    URLByStandardizingPath] isEqual:
	    [OFURL URLWithString: @"http://foo/bar/qux/"]] &&
	    [[[OFURL URLWithString: @"http://foo/bar/../../qux"]
	    URLByStandardizingPath] isEqual:
	    [OFURL URLWithString: @"http://foo/../qux"]])

	[pool drain];
}
@end