ObjFW  Diff

Differences From Artifact [2d59404d46]:

To Artifact [76e87b40ed]:


166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
static OFString*
standardize_path(OFArray *components, OFString *currentDirectory,
    OFString *parentDirectory, OFString *joinString)
{
	void *pool = objc_autoreleasePoolPush();
	OFMutableArray *array;
	OFString *ret;
	BOOL done = NO;

	array = [[components mutableCopy] autorelease];

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

		done = YES;

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

			if ([object isEqual: currentDirectory]) {
				[array removeObjectAtIndex: i];
				done = NO;

				break;
			}

			if ([object isEqual: parentDirectory]) {
				[array removeObjectAtIndex: i];

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

				done = NO;

				break;
			}
		}
	}

	ret = [[array componentsJoinedByString: joinString] retain];







|






|






|










|







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
static OFString*
standardize_path(OFArray *components, OFString *currentDirectory,
    OFString *parentDirectory, OFString *joinString)
{
	void *pool = objc_autoreleasePoolPush();
	OFMutableArray *array;
	OFString *ret;
	bool done = false;

	array = [[components mutableCopy] autorelease];

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

		done = true;

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

			if ([object isEqual: currentDirectory]) {
				[array removeObjectAtIndex: i];
				done = false;

				break;
			}

			if ([object isEqual: parentDirectory]) {
				[array removeObjectAtIndex: i];

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

				done = false;

				break;
			}
		}
	}

	ret = [[array componentsJoinedByString: joinString] retain];
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

	return (id)[string OF_initWithUTF8String: UTF8String
					  length: UTF8StringLength
					 storage: storage];
}

- initWithUTF8StringNoCopy: (char*)UTF8String
	      freeWhenDone: (BOOL)freeWhenDone
{
	return (id)[[OFString_UTF8 alloc]
	    initWithUTF8StringNoCopy: UTF8String
			freeWhenDone: freeWhenDone];
}

- initWithCString: (const char*)cString







|







248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

	return (id)[string OF_initWithUTF8String: UTF8String
					  length: UTF8StringLength
					 storage: storage];
}

- initWithUTF8StringNoCopy: (char*)UTF8String
	      freeWhenDone: (bool)freeWhenDone
{
	return (id)[[OFString_UTF8 alloc]
	    initWithUTF8StringNoCopy: UTF8String
			freeWhenDone: freeWhenDone];
}

- initWithCString: (const char*)cString
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
{
	return [[[self alloc]
	    initWithUTF8String: UTF8String
			length: UTF8StringLength] autorelease];
}

+ (instancetype)stringWithUTF8StringNoCopy: (char*)UTF8String
			      freeWhenDone: (BOOL)freeWhenDone
{
	return [[[self alloc]
	    initWithUTF8StringNoCopy: UTF8String
			freeWhenDone: freeWhenDone] autorelease];
}

+ (instancetype)stringWithCString: (const char*)cString







|







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
{
	return [[[self alloc]
	    initWithUTF8String: UTF8String
			length: UTF8StringLength] autorelease];
}

+ (instancetype)stringWithUTF8StringNoCopy: (char*)UTF8String
			      freeWhenDone: (bool)freeWhenDone
{
	return [[[self alloc]
	    initWithUTF8StringNoCopy: UTF8String
			freeWhenDone: freeWhenDone] autorelease];
}

+ (instancetype)stringWithCString: (const char*)cString
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
{
	return [self initWithCString: UTF8String
			    encoding: OF_STRING_ENCODING_UTF_8
			      length: UTF8StringLength];
}

- initWithUTF8StringNoCopy: (char*)UTF8String
	      freeWhenDone: (BOOL)freeWhenDone
{
	return [self initWithUTF8String: UTF8String];
}

- initWithCString: (const char*)cString
	 encoding: (of_string_encoding_t)encoding
{







|







665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
{
	return [self initWithCString: UTF8String
			    encoding: OF_STRING_ENCODING_UTF_8
			      length: UTF8StringLength];
}

- initWithUTF8StringNoCopy: (char*)UTF8String
	      freeWhenDone: (bool)freeWhenDone
{
	return [self initWithUTF8String: UTF8String];
}

- initWithCString: (const char*)cString
	 encoding: (of_string_encoding_t)encoding
{
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
{
	size_t i;

	for (i = 0; i < range.length; i++)
		buffer[i] = [self characterAtIndex: range.location + i];
}

- (BOOL)isEqual: (id)object
{
	void *pool;
	OFString *otherString;
	const of_unichar_t *characters, *otherCharacters;
	size_t length;

	if (object == self)
		return YES;

	if (![object isKindOfClass: [OFString class]])
		return NO;

	otherString = object;
	length = [self length];

	if ([otherString length] != length)
		return NO;

	pool = objc_autoreleasePoolPush();

	characters = [self characters];
	otherCharacters = [otherString characters];

	if (memcmp(characters, otherCharacters,
	    length * sizeof(of_unichar_t))) {
		objc_autoreleasePoolPop(pool);
		return NO;
	}

	objc_autoreleasePoolPop(pool);

	return YES;
}

- copy
{
	return [self retain];
}








|







|


|





|









|




|







1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
{
	size_t i;

	for (i = 0; i < range.length; i++)
		buffer[i] = [self characterAtIndex: range.location + i];
}

- (bool)isEqual: (id)object
{
	void *pool;
	OFString *otherString;
	const of_unichar_t *characters, *otherCharacters;
	size_t length;

	if (object == self)
		return true;

	if (![object isKindOfClass: [OFString class]])
		return false;

	otherString = object;
	length = [self length];

	if ([otherString length] != length)
		return false;

	pool = objc_autoreleasePoolPush();

	characters = [self characters];
	otherCharacters = [otherString characters];

	if (memcmp(characters, otherCharacters,
	    length * sizeof(of_unichar_t))) {
		objc_autoreleasePoolPop(pool);
		return false;
	}

	objc_autoreleasePoolPop(pool);

	return true;
}

- copy
{
	return [self retain];
}

1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
	}

	objc_autoreleasePoolPop(pool);

	return of_range(OF_NOT_FOUND, 0);
}

- (BOOL)containsString: (OFString*)string
{
	void *pool;
	const of_unichar_t *characters, *searchCharacters;
	size_t i, length, searchLength;

	if ((searchLength = [string length]) == 0)
		return YES;

	if (searchLength > (length = [self length]))
		return NO;

	pool = objc_autoreleasePoolPush();

	characters = [self characters];
	searchCharacters = [string characters];

	for (i = 0; i <= length - searchLength; i++) {
		if (!memcmp(characters + i, searchCharacters,
		    searchLength * sizeof(of_unichar_t))) {
			objc_autoreleasePoolPop(pool);
			return YES;
		}
	}

	objc_autoreleasePoolPop(pool);

	return NO;
}

- (OFString*)substringWithRange: (of_range_t)range
{
	void *pool;
	OFString *ret;








|






|


|










|





|







1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
	}

	objc_autoreleasePoolPop(pool);

	return of_range(OF_NOT_FOUND, 0);
}

- (bool)containsString: (OFString*)string
{
	void *pool;
	const of_unichar_t *characters, *searchCharacters;
	size_t i, length, searchLength;

	if ((searchLength = [string length]) == 0)
		return true;

	if (searchLength > (length = [self length]))
		return false;

	pool = objc_autoreleasePoolPush();

	characters = [self characters];
	searchCharacters = [string characters];

	for (i = 0; i <= length - searchLength; i++) {
		if (!memcmp(characters + i, searchCharacters,
		    searchLength * sizeof(of_unichar_t))) {
			objc_autoreleasePoolPop(pool);
			return true;
		}
	}

	objc_autoreleasePoolPop(pool);

	return false;
}

- (OFString*)substringWithRange: (of_range_t)range
{
	void *pool;
	OFString *ret;

1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
	[new deleteEnclosingWhitespaces];

	[new makeImmutable];

	return new;
}

- (BOOL)hasPrefix: (OFString*)prefix
{
	of_unichar_t *tmp;
	const of_unichar_t *prefixCharacters;
	size_t prefixLength;
	int compare;

	if ((prefixLength = [prefix length]) > [self length])
		return NO;

	tmp = [self allocMemoryWithSize: sizeof(of_unichar_t)
				  count: prefixLength];
	@try {
		void *pool = objc_autoreleasePoolPush();

		[self getCharacters: tmp







|







|







1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
	[new deleteEnclosingWhitespaces];

	[new makeImmutable];

	return new;
}

- (bool)hasPrefix: (OFString*)prefix
{
	of_unichar_t *tmp;
	const of_unichar_t *prefixCharacters;
	size_t prefixLength;
	int compare;

	if ((prefixLength = [prefix length]) > [self length])
		return false;

	tmp = [self allocMemoryWithSize: sizeof(of_unichar_t)
				  count: prefixLength];
	@try {
		void *pool = objc_autoreleasePoolPush();

		[self getCharacters: tmp
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
	} @finally {
		[self freeMemory: tmp];
	}

	return !compare;
}

- (BOOL)hasSuffix: (OFString*)suffix
{
	of_unichar_t *tmp;
	const of_unichar_t *suffixCharacters;
	size_t length, suffixLength;
	int compare;

	if ((suffixLength = [suffix length]) > [self length])
		return NO;

	length = [self length];

	tmp = [self allocMemoryWithSize: sizeof(of_unichar_t)
				  count: suffixLength];
	@try {
		void *pool = objc_autoreleasePoolPush();







|







|







1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
	} @finally {
		[self freeMemory: tmp];
	}

	return !compare;
}

- (bool)hasSuffix: (OFString*)suffix
{
	of_unichar_t *tmp;
	const of_unichar_t *suffixCharacters;
	size_t length, suffixLength;
	int compare;

	if ((suffixLength = [suffix length]) > [self length])
		return false;

	length = [self length];

	tmp = [self allocMemoryWithSize: sizeof(of_unichar_t)
				  count: suffixLength];
	@try {
		void *pool = objc_autoreleasePoolPush();
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
				options: (int)options
{
	void *pool;
	OFMutableArray *array = [OFMutableArray array];
	const of_unichar_t *characters, *delimiterCharacters;
	BOOL skipEmpty = (options & OF_STRING_SKIP_EMPTY);
	size_t length = [self length];
	size_t delimiterLength = [delimiter length];
	size_t i, last;
	OFString *component;

	pool = objc_autoreleasePoolPush();








|







1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
				options: (int)options
{
	void *pool;
	OFMutableArray *array = [OFMutableArray array];
	const of_unichar_t *characters, *delimiterCharacters;
	bool skipEmpty = (options & OF_STRING_SKIP_EMPTY);
	size_t length = [self length];
	size_t delimiterLength = [delimiter length];
	size_t i, last;
	OFString *component;

	pool = objc_autoreleasePoolPush();

2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
- (intmax_t)decimalValue
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];
	size_t length = [self length];
	int i = 0;
	intmax_t value = 0;
	BOOL expectWhitespace = NO;

	while (length > 0 && (*characters == ' ' || *characters == '\t' ||
	    *characters == '\n' || *characters == '\r' ||
	    *characters == '\f')) {
		characters++;
		length--;
	}







|







2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
- (intmax_t)decimalValue
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];
	size_t length = [self length];
	int i = 0;
	intmax_t value = 0;
	bool expectWhitespace = false;

	while (length > 0 && (*characters == ' ' || *characters == '\t' ||
	    *characters == '\n' || *characters == '\r' ||
	    *characters == '\f')) {
		characters++;
		length--;
	}
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
				@throw [OFOutOfRangeException
				    exceptionWithClass: [self class]];

			value = (value * 10) + (characters[i] - '0');
		} else if (characters[i] == ' ' || characters[i] == '\t' ||
		    characters[i] == '\n' || characters[i] == '\r' ||
		    characters[i] == '\f')
			expectWhitespace = YES;
		else
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];
	}

	if (characters[0] == '-')
		value *= -1;

	objc_autoreleasePoolPop(pool);

	return value;
}

- (uintmax_t)hexadecimalValue
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];
	size_t length = [self length];
	int i = 0;
	uintmax_t value = 0;
	BOOL expectWhitespace = NO, foundValue = NO;

	while (length > 0 && (*characters == ' ' || *characters == '\t' ||
	    *characters == '\n' || *characters == '\r' ||
	    *characters == '\f')) {
		characters++;
		length--;
	}







|




















|







2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
				@throw [OFOutOfRangeException
				    exceptionWithClass: [self class]];

			value = (value * 10) + (characters[i] - '0');
		} else if (characters[i] == ' ' || characters[i] == '\t' ||
		    characters[i] == '\n' || characters[i] == '\r' ||
		    characters[i] == '\f')
			expectWhitespace = true;
		else
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];
	}

	if (characters[0] == '-')
		value *= -1;

	objc_autoreleasePoolPop(pool);

	return value;
}

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

	while (length > 0 && (*characters == ' ' || *characters == '\t' ||
	    *characters == '\n' || *characters == '\r' ||
	    *characters == '\f')) {
		characters++;
		length--;
	}
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
				@throw [OFInvalidFormatException
				    exceptionWithClass: [self class]];
			continue;
		}

		if (characters[i] >= '0' && characters[i] <= '9') {
			newValue = (value << 4) | (characters[i] - '0');
			foundValue = YES;
		} else if (characters[i] >= 'A' && characters[i] <= 'F') {
			newValue = (value << 4) | (characters[i] - 'A' + 10);
			foundValue = YES;
		} else if (characters[i] >= 'a' && characters[i] <= 'f') {
			newValue = (value << 4) | (characters[i] - 'a' + 10);
			foundValue = YES;
		} else if (characters[i] == 'h' || characters[i] == ' ' ||
		    characters[i] == '\t' || characters[i] == '\n' ||
		    characters[i] == '\r' || characters[i] == '\f') {
			expectWhitespace = YES;
			continue;
		} else
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];

		if (newValue < value)
			@throw [OFOutOfRangeException







|


|


|



|







2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
				@throw [OFInvalidFormatException
				    exceptionWithClass: [self class]];
			continue;
		}

		if (characters[i] >= '0' && characters[i] <= '9') {
			newValue = (value << 4) | (characters[i] - '0');
			foundValue = true;
		} else if (characters[i] >= 'A' && characters[i] <= 'F') {
			newValue = (value << 4) | (characters[i] - 'A' + 10);
			foundValue = true;
		} else if (characters[i] >= 'a' && characters[i] <= 'f') {
			newValue = (value << 4) | (characters[i] - 'a' + 10);
			foundValue = true;
		} else if (characters[i] == 'h' || characters[i] == ' ' ||
		    characters[i] == '\t' || characters[i] == '\n' ||
		    characters[i] == '\r' || characters[i] == '\f') {
			expectWhitespace = true;
			continue;
		} else
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];

		if (newValue < value)
			@throw [OFOutOfRangeException
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];
	size_t length = [self length];
	of_char16_t *ret;
	size_t i, j;
	BOOL swap = (byteOrder != OF_BYTE_ORDER_NATIVE);

	/* Allocate memory for the worst case */
	ret = [object allocMemoryWithSize: sizeof(of_char16_t)
				    count: (length + 1) * 2];

	j = 0;








|







2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];
	size_t length = [self length];
	of_char16_t *ret;
	size_t i, j;
	bool swap = (byteOrder != OF_BYTE_ORDER_NATIVE);

	/* Allocate memory for the worst case */
	ret = [object allocMemoryWithSize: sizeof(of_char16_t)
				    count: (length + 1) * 2];

	j = 0;

2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528

#ifdef OF_HAVE_BLOCKS
- (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];
	size_t i, last = 0, length = [self length];
	BOOL stop = NO, lastCarriageReturn = NO;

	for (i = 0; i < length && !stop; i++) {
		if (lastCarriageReturn && characters[i] == '\n') {
			lastCarriageReturn = NO;
			last++;

			continue;
		}

		if (characters[i] == '\n' || characters[i] == '\r') {
			void *pool2 = objc_autoreleasePoolPush();







|



|







2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528

#ifdef OF_HAVE_BLOCKS
- (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];
	size_t i, last = 0, length = [self length];
	bool stop = false, lastCarriageReturn = false;

	for (i = 0; i < length && !stop; i++) {
		if (lastCarriageReturn && characters[i] == '\n') {
			lastCarriageReturn = false;
			last++;

			continue;
		}

		if (characters[i] == '\n' || characters[i] == '\r') {
			void *pool2 = objc_autoreleasePoolPush();