ObjFW  Check-in [c5ef582958]

Overview
Comment:Replace BOOL with bool.

The only places where BOOL is left are those where they are required by
the ABI.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: c5ef582958cb70d27e3b5246c5bc10fcf5c44a892c36a265ed79f207d6ed785d
User & Date: js on 2013-03-04 17:20:15
Other Links: manifest | tags
Context
2013-03-04
18:32
Make old GCCs happy. check-in: 0bb3fc850a user: js tags: trunk
17:20
Replace BOOL with bool. check-in: c5ef582958 user: js tags: trunk
2013-03-01
21:19
Rethrow some exceptions to fix class. check-in: 2de15db195 user: js tags: trunk
Changes

Modified generators/Makefile from [eba8d44ad9] to [193fb354a9].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
18
19
20
21
22
23
24

25
26
27
28
29
30
31







-







	fi
	if test -f ../src/libobjfw.dll; then \
		${LN_S} ../src/libobjfw.dll libobjfw.dll; \
	fi
	if test -f ../src/libobjfw.dylib; then \
		${LN_S} ../src/libobjfw.dylib libobjfw.dylib; \
	fi
	echo "Generating tables..."
	LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \
	DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \
	LIBRARY_PATH=.$${LIBRARY_PATH+:}$$LIBRARY_PATH \
	${TEST_LAUNCHER} ./${PROG_NOINST}; EXIT=$$?; \
	rm -f libobjfw.so.${OBJFW_LIB_MAJOR}; \
	rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} libobjfw.dll \
	rm -f libobjfw.dylib; \

Modified generators/TableGenerator.m from [2bd483c89b] to [d6bc06fa8f].

176
177
178
179
180
181
182
183

184
185
186
187

188
189
190
191
192
193
194
176
177
178
179
180
181
182

183
184
185
186

187
188
189
190
191
192
193
194







-
+



-
+







	    @"#include \"config.h\"\n"
	    @"\n"
	    @"#import \"OFString.h\"\n\n"
	    @"static const of_unichar_t nop_page[0x100] = {};\n\n"];

	/* Write uppercase_page_%u */
	for (i = 0; i < 0x110000; i += 0x100) {
		BOOL isEmpty = YES;
		bool isEmpty = true;

		for (j = i; j < i + 0x100; j++) {
			if (uppercaseTable[j] != 0) {
				isEmpty = NO;
				isEmpty = false;
				uppercaseTableSize = i >> 8;
				uppercaseTableUsed[uppercaseTableSize] = YES;
				break;
			}
		}

		if (!isEmpty) {
214
215
216
217
218
219
220
221

222
223
224
225

226
227
228
229
230
231
232
214
215
216
217
218
219
220

221
222
223
224

225
226
227
228
229
230
231
232







-
+



-
+








			objc_autoreleasePoolPop(pool2);
		}
	}

	/* Write lowercase_page_%u */
	for (i = 0; i < 0x110000; i += 0x100) {
		BOOL isEmpty = YES;
		bool isEmpty = true;

		for (j = i; j < i + 0x100; j++) {
			if (lowercaseTable[j] != 0) {
				isEmpty = NO;
				isEmpty = false;
				lowercaseTableSize = i >> 8;
				lowercaseTableUsed[lowercaseTableSize] = YES;
				break;
			}
		}

		if (!isEmpty) {
252
253
254
255
256
257
258
259

260
261
262
263

264
265

266
267
268
269
270
271
272
252
253
254
255
256
257
258

259
260
261
262

263
264

265
266
267
268
269
270
271
272







-
+



-
+

-
+








			objc_autoreleasePoolPop(pool2);
		}
	}

	/* Write titlecase_page_%u if it does NOT match uppercase_page_%u */
	for (i = 0; i < 0x110000; i += 0x100) {
		BOOL isEmpty = YES;
		bool isEmpty = true;

		for (j = i; j < i + 0x100; j++) {
			if (titlecaseTable[j] != 0) {
				isEmpty = (memcmp(uppercaseTable + i,
				isEmpty = !memcmp(uppercaseTable + i,
				    titlecaseTable + i,
				    256 * sizeof(of_unichar_t)) ? NO : YES);
				    256 * sizeof(of_unichar_t));
				titlecaseTableSize = i >> 8;
				titlecaseTableUsed[titlecaseTableSize] =
				    (isEmpty ? 2 : 1);
				break;
			}
		}

293
294
295
296
297
298
299
300

301
302
303
304

305
306

307
308
309
310
311
312
313
293
294
295
296
297
298
299

300
301
302
303

304
305

306
307
308
309
310
311
312
313







-
+



-
+

-
+








			objc_autoreleasePoolPop(pool2);
		}
	}

	/* Write casefolding_page_%u if it does NOT match lowercase_page_%u */
	for (i = 0; i < 0x110000; i += 0x100) {
		BOOL isEmpty = YES;
		bool isEmpty = true;

		for (j = i; j < i + 0x100; j++) {
			if (casefoldingTable[j] != 0) {
				isEmpty = (memcmp(lowercaseTable + i,
				isEmpty = !memcmp(lowercaseTable + i,
				    casefoldingTable + i,
				    256 * sizeof(of_unichar_t)) ? NO : YES);
				    256 * sizeof(of_unichar_t));
				casefoldingTableSize = i >> 8;
				casefoldingTableUsed[casefoldingTableSize] =
				    (isEmpty ? 2 : 1);
				break;
			}
		}

Modified src/OFApplication.m from [ca5bc2d367] to [19e85a0ef2].

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
280
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
280







-
+






-
+






-
+






-
+






-
+







		 * expect.
		 */
		pool = objc_autoreleasePoolPush();

		if ((env = getenv("HOME")) != NULL) {
			OFString *home = [[[OFString alloc]
			    initWithUTF8StringNoCopy: env
					freeWhenDone: NO] autorelease];
					freeWhenDone: false] autorelease];
			[environment setObject: home
					forKey: @"HOME"];
		}
		if ((env = getenv("PATH")) != NULL) {
			OFString *path = [[[OFString alloc]
			    initWithUTF8StringNoCopy: env
					freeWhenDone: NO] autorelease];
					freeWhenDone: false] autorelease];
			[environment setObject: path
					forKey: @"PATH"];
		}
		if ((env = getenv("SHELL")) != NULL) {
			OFString *shell = [[[OFString alloc]
			    initWithUTF8StringNoCopy: env
					freeWhenDone: NO] autorelease];
					freeWhenDone: false] autorelease];
			[environment setObject: shell
					forKey: @"SHELL"];
		}
		if ((env = getenv("TMPDIR")) != NULL) {
			OFString *tmpdir = [[[OFString alloc]
			    initWithUTF8StringNoCopy: env
					freeWhenDone: NO] autorelease];
					freeWhenDone: false] autorelease];
			[environment setObject: tmpdir
					forKey: @"TMPDIR"];
		}
		if ((env = getenv("USER")) != NULL) {
			OFString *user = [[[OFString alloc]
			    initWithUTF8StringNoCopy: env
					freeWhenDone: NO] autorelease];
					freeWhenDone: false] autorelease];
			[environment setObject: user
					forKey: @"USER"];
		}

		objc_autoreleasePoolPop(pool);
#endif

354
355
356
357
358
359
360
361

362
363
364
365
366

367
368
369
370
371

372
373
374
375
376
377
378
354
355
356
357
358
359
360

361
362
363
364
365

366
367
368
369
370

371
372
373
374
375
376
377
378







-
+




-
+




-
+







{
	*argc = _argc;
	*argv = _argv;
}

- (OFString*)programName
{
	OF_GETTER(_programName, NO)
	OF_GETTER(_programName, false)
}

- (OFArray*)arguments
{
	OF_GETTER(_arguments, NO)
	OF_GETTER(_arguments, false)
}

- (OFDictionary*)environment
{
	OF_GETTER(_environment, NO)
	OF_GETTER(_environment, false)
}

- (id <OFApplicationDelegate>)delegate
{
	return _delegate;
}

Modified src/OFArray.h from [fbd6a9a1ad] to [ecde9fadf5].

34
35
36
37
38
39
40
41
42


43
44
45
46
47
48
49
34
35
36
37
38
39
40


41
42
43
44
45
46
47
48
49







-
-
+
+








enum {
	OF_SORT_OPTIONS_DESCENDING = 1
};

#ifdef OF_HAVE_BLOCKS
typedef void (^of_array_enumeration_block_t)(id object, size_t index,
    BOOL *stop);
typedef BOOL (^of_array_filter_block_t)(id odject, size_t index);
    bool *stop);
typedef bool (^of_array_filter_block_t)(id odject, size_t index);
typedef id (^of_array_map_block_t)(id object, size_t index);
typedef id (^of_array_fold_block_t)(id left, id right);
#endif

/*!
 * @brief An abstract class for storing objects in an array.
 */
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206







-
+







 * @brief Checks whether the array contains an object with the specified
 *	  address.
 *
 * @param object The object which is checked for being in the array
 * @return A boolean whether the array contains an object with the specified
 *	   address.
 */
- (BOOL)containsObjectIdenticalTo: (id)object;
- (bool)containsObjectIdenticalTo: (id)object;

/*!
 * @brief Returns the first object of the array or nil.
 *
 * @warning The returned object is *not* retained and autoreleased for
 *	    performance reasons!
 *
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341







-
+







 * @param block A block which maps an object for each object
 * @return A new, autoreleased OFArray
 */
- (OFArray*)mappedArrayUsingBlock: (of_array_map_block_t)block;

/*!
 * @brief Creates a new array, only containing the objects for which the block
 *	  returns YES.
 *	  returns true.
 *
 * @param block A block which determines if the object should be in the new
 *		array
 * @return A new, autoreleased OFArray
 */
- (OFArray*)filteredArrayUsingBlock: (of_array_filter_block_t)block;

Modified src/OFArray.m from [369534eb2f] to [65b65f023d].

335
336
337
338
339
340
341
342

343
344
345
346
347

348
349
350
351
352
353
354
335
336
337
338
339
340
341

342
343
344
345
346

347
348
349
350
351
352
353
354







-
+




-
+







	for (i = 0; i < count; i++)
		if ([self objectAtIndex: i] == object)
			return i;

	return OF_NOT_FOUND;
}

- (BOOL)containsObject: (id)object
- (bool)containsObject: (id)object
{
	return ([self indexOfObject: object] != OF_NOT_FOUND);
}

- (BOOL)containsObjectIdenticalTo: (id)object
- (bool)containsObjectIdenticalTo: (id)object
{
	return ([self indexOfObjectIdenticalTo: object] != OF_NOT_FOUND);
}

- (id)firstObject
{
	if ([self count] > 0)
443
444
445
446
447
448
449
450

451
452
453
454
455
456
457

458
459
460
461
462
463
464

465
466
467
468
469

470
471

472
473
474
475
476
477
478
443
444
445
446
447
448
449

450
451
452
453
454
455
456

457
458
459
460
461
462
463

464
465
466
467
468

469
470

471
472
473
474
475
476
477
478







-
+






-
+






-
+




-
+

-
+







	[ret makeImmutable];

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	/* FIXME: Optimize (for example, buffer of 16 for each) */
	OFArray *otherArray;
	size_t i, count;

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

	otherArray = object;

	count = [self count];

	if (count != [otherArray count])
		return NO;
		return false;

	for (i = 0; i < count; i++)
		if (![[self objectAtIndex: i] isEqual:
		    [otherArray objectAtIndex: i]])
			return NO;
			return false;

	return YES;
	return true;
}

- (uint32_t)hash
{
	id *objects = [self objects];
	size_t i, count = [self count];
	uint32_t hash;
700
701
702
703
704
705
706
707

708
709
710
711
712
713
714
700
701
702
703
704
705
706

707
708
709
710
711
712
713
714







-
+







					    mutationsPtr: NULL] autorelease];
}

#if defined(OF_HAVE_BLOCKS) && defined(OF_HAVE_FAST_ENUMERATION)
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
	size_t i = 0;
	BOOL stop = NO;
	bool stop = false;

	for (id object in self) {
		block(object, i++, &stop);

		if (stop)
			break;
	}
757
758
759
760
761
762
763
764

765
766
767
768
769
770
771
757
758
759
760
761
762
763

764
765
766
767
768
769
770
771







-
+







	OFArray *ret;
	size_t count = [self count];
	id *tmp = [self allocMemoryWithSize: sizeof(id)
				      count: count];

	@try {
		[self enumerateObjectsUsingBlock: ^ (id object, size_t index,
		    BOOL *stop) {
		    bool *stop) {
			tmp[index] = block(object, index);
		}];

		ret = [OFArray arrayWithObjects: tmp
					  count: count];
	} @finally {
		[self freeMemory: tmp];
781
782
783
784
785
786
787
788

789
790
791
792
793
794
795
781
782
783
784
785
786
787

788
789
790
791
792
793
794
795







-
+







	id *tmp = [self allocMemoryWithSize: sizeof(id)
				      count: count];

	@try {
		__block size_t i = 0;

		[self enumerateObjectsUsingBlock: ^ (id object, size_t index,
		    BOOL *stop) {
		    bool *stop) {
			if (block(object, index))
				tmp[i++] = object;
		}];

		ret = [OFArray arrayWithObjects: tmp
					  count: i];
	} @finally {
806
807
808
809
810
811
812
813

814
815
816
817
818
819
820
806
807
808
809
810
811
812

813
814
815
816
817
818
819
820







-
+








	if (count == 0)
		return nil;
	if (count == 1)
		return [[[self firstObject] retain] autorelease];

	[self enumerateObjectsUsingBlock: ^ (id object, size_t index,
	    BOOL *stop) {
	    bool *stop) {
		id new;

		if (index == 0) {
			current = [object retain];
			return;
		}

Modified src/OFArray_adjacent.m from [2158b59870] to [712ba693de].

134
135
136
137
138
139
140
141

142
143
144
145

146
147
148
149
150
151
152
134
135
136
137
138
139
140

141
142
143
144

145
146
147
148
149
150
151
152







-
+



-
+







- initWithObjects: (id const*)objects
	    count: (size_t)count
{
	self = [self init];

	@try {
		size_t i;
		BOOL ok = YES;
		bool ok = true;

		for (i = 0; i < count; i++) {
			if (objects[i] == nil)
				ok = NO;
				ok = false;

			[objects[i] retain];
		}

		if (!ok)
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]];
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326

327
328

329
330
331
332
333
334
335
296
297
298
299
300
301
302

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318

319
320
321
322
323
324
325

326
327

328
329
330
331
332
333
334
335







-
+















-
+






-
+

-
+







		    arrayWithObjects: (id*)[_array items] + range.location
			       count: range.length];

	return [OFArray_adjacentSubarray arrayWithArray: self
						  range: range];
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFArray *otherArray;
	id *objects, *otherObjects;
	size_t i, count;

	if ([object class] != [OFArray_adjacent class] &&
	    [object class] != [OFMutableArray_adjacent class] &&
	    [object class] != [OFArray_adjacentSubarray class])
		return [super isEqual: object];

	otherArray = object;

	count = [_array count];

	if (count != [otherArray count])
		return NO;
		return false;

	objects = [_array items];
	otherObjects = [otherArray objects];

	for (i = 0; i < count; i++)
		if (![objects[i] isEqual: otherObjects[i]])
			return NO;
			return false;

	return YES;
	return true;
}

- (uint32_t)hash
{
	id *objects = [_array items];
	size_t i, count = [_array count];
	uint32_t hash;
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359







-
+







}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
	id *objects = [_array items];
	size_t i, count = [_array count];
	BOOL stop = NO;
	bool stop = false;

	for (i = 0; i < count && !stop; i++)
		block(objects[i], i, &stop);
}
#endif

- (void)dealloc

Modified src/OFArray_adjacentSubarray.m from [57128f3980] to [cb0839dc3a].

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
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







-
+













-
+






-
+

-
+







-
+







@implementation OFArray_adjacentSubarray
- (id*)objects
{
	return [_array objects] + _range.location;
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFArray *otherArray;
	id *objects, *otherObjects;
	size_t i;

	if ([object class] != [OFArray_adjacent class] &&
	    [object class] != [OFMutableArray_adjacent class] &&
	    [object class] != [OFArray_adjacentSubarray class])
		return [super isEqual: object];

	otherArray = object;

	if (_range.length != [otherArray count])
		return NO;
		return false;

	objects = [self objects];
	otherObjects = [otherArray objects];

	for (i = 0; i < _range.length; i++)
		if (![objects[i] isEqual: otherObjects[i]])
			return NO;
			return false;

	return YES;
	return true;
}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
	id *objects = [self objects];
	size_t i;
	BOOL stop = NO;
	bool stop = false;

	for (i = 0; i < _range.length && !stop; i++)
		block(objects[i], i, &stop);
}
#endif
@end

Modified src/OFAutoreleasePool.h from [c4bc0a71ca] to [7b7e104b06].

23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37







-
+







 * be released when the autorelease pool is released.
 *
 * Every thread has its own stack of autorelease pools.
 */
@interface OFAutoreleasePool: OFObject
{
	void *_pool;
	BOOL _ignoreRelease;
	bool _ignoreRelease;
}

/*!
 * @brief Adds an object to the autorelease pool at the top of the
 *	  thread-specific autorelease pool stack.
 *
 * @param object The object to add to the autorelease pool

Modified src/OFAutoreleasePool.m from [933769a877] to [06405e2bb2].

92
93
94
95
96
97
98
99

100
101
102
103
104
105
106

107
108
109
110
111
112
113
92
93
94
95
96
97
98

99
100
101
102
103
104
105

106
107
108
109
110
111
112
113







-
+






-
+







	}

	return self;
}

- (void)releaseObjects
{
	_ignoreRelease = YES;
	_ignoreRelease = true;

	objc_autoreleasePoolPop(_pool);
	_pool = objc_autoreleasePoolPush();

	_objc_rootAutorelease(self);

	_ignoreRelease = NO;
	_ignoreRelease = false;
}

- (void)release
{
	[self dealloc];
}

121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156







-
+




















-
+







#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	OFAutoreleasePool **cache = of_tlskey_get(cacheKey);
#endif

	if (_ignoreRelease)
		return;

	_ignoreRelease = YES;
	_ignoreRelease = true;

	objc_autoreleasePoolPop(_pool);

	if (cache == NULL) {
		cache = calloc(sizeof(OFAutoreleasePool*), MAX_CACHE_SIZE);

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
		if (!of_tlskey_set(cacheKey, cache)) {
			free(cache);
			cache = NULL;
		}
#endif
	}

	if (cache != NULL) {
		unsigned i;

		for (i = 0; i < MAX_CACHE_SIZE; i++) {
			if (cache[i] == NULL) {
				_pool = NULL;
				_ignoreRelease = NO;
				_ignoreRelease = false;

				cache[i] = self;

				return;
			}
		}
	}

Modified src/OFCollection.h from [c9383e691e] to [00c1a07208].

34
35
36
37
38
39
40
41

42
34
35
36
37
38
39
40

41
42







-
+

/*!
 * @brief Checks whether the collection contains an object equal to the
 *	  specified object.
 *
 * @param object The object which is checked for being in the collection
 * @return A boolean whether the collection contains the specified object
 */
- (BOOL)containsObject: (id)object;
- (bool)containsObject: (id)object;
@end

Modified src/OFCondition.h from [c116d03373] to [0374131e0b].

18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32







-
+








/*!
 * @brief A class implementing a condition variable for thread synchronization.
 */
@interface OFCondition: OFMutex
{
	of_condition_t _condition;
	BOOL _conditionInitialized;
	bool _conditionInitialized;
}

/*!
 * @brief Creates a new condition.
 *
 * @return A new, autoreleased OFCondition
 */

Modified src/OFCondition.m from [7c4793cfc9] to [ece321bbec].

36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50







-
+








	if (!of_condition_new(&_condition)) {
		Class c = [self class];
		[self release];
		@throw [OFInitializationFailedException exceptionWithClass: c];
	}

	_conditionInitialized = YES;
	_conditionInitialized = true;

	return self;
}

- (void)dealloc
{
	if (_conditionInitialized)

Modified src/OFConstantString.m from [1a105f7a00] to [9960343709].

155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
155
156
157
158
159
160
161

162
163
164
165
166
167
168
169







-
+








	ivars->cString = _cString;
	ivars->cStringLength = _cStringLength;

	switch (of_string_utf8_check(ivars->cString, ivars->cStringLength,
	    &ivars->length)) {
	case 1:
		ivars->isUTF8 = YES;
		ivars->isUTF8 = true;
		break;
	case -1:
		free(ivars);
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];
	}

265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279







-
+







{
	[self finishInitialization];

	return [self compare: object];
}

/* From OFObject, but reimplemented in OFString */
- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	[self finishInitialization];

	return [self isEqual: object];
}

- (uint32_t)hash
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
383
384
385
386
387
388
389

390
391
392
393
394
395
396
397







-
+







	[self finishInitialization];

	return [self rangeOfString: string
			   options: options
			     range: range];
}

- (BOOL)containsString: (OFString*)string
- (bool)containsString: (OFString*)string
{
	[self finishInitialization];

	return [self containsString: string];
}

- (OFString*)substringWithRange: (of_range_t)range
491
492
493
494
495
496
497
498

499
500
501
502
503
504
505

506
507
508
509
510
511
512
491
492
493
494
495
496
497

498
499
500
501
502
503
504

505
506
507
508
509
510
511
512







-
+






-
+







- (OFString*)stringByDeletingEnclosingWhitespaces
{
	[self finishInitialization];

	return [self stringByDeletingEnclosingWhitespaces];
}

- (BOOL)hasPrefix: (OFString*)prefix
- (bool)hasPrefix: (OFString*)prefix
{
	[self finishInitialization];

	return [self hasPrefix: prefix];
}

- (BOOL)hasSuffix: (OFString*)suffix
- (bool)hasSuffix: (OFString*)suffix
{
	[self finishInitialization];

	return [self hasSuffix: suffix];
}

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter

Modified src/OFCountedSet.h from [c44767e63a] to [6a5aa970ef].

14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28







-
+







 * file.
 */

#import "OFSet.h"

#ifdef OF_HAVE_BLOCKS
typedef void (^of_counted_set_enumeration_block_t)(id object, size_t count,
    BOOL *stop);
    bool *stop);
#endif

/*!
 * @brief An abstract class for a mutable unordered set of objects, counting how
 *	  often it contains an object.
 */
@interface OFCountedSet: OFMutableSet

Modified src/OFCountedSet.m from [028e438698] to [d006ca7115].

232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246







-
+







	return [element autorelease];
}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsAndCountUsingBlock:
    (of_counted_set_enumeration_block_t)block
{
	[self enumerateObjectsUsingBlock: ^ (id object, BOOL *stop) {
	[self enumerateObjectsUsingBlock: ^ (id object, bool *stop) {
		block(object, [self countForObject: object], stop);
	}];
}
#endif

- (void)minusSet: (OFSet*)set
{

Modified src/OFCountedSet_hashtable.m from [9994d542a0] to [ce18d3e849].

190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204







-
+








#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsAndCountUsingBlock:
    (of_counted_set_enumeration_block_t)block
{
	@try {
		[_mapTable enumerateKeysAndValuesUsingBlock:
		    ^ (void *key, void *value, BOOL *stop) {
		    ^ (void *key, void *value, bool *stop) {
			block(key, (size_t)(uintptr_t)value, stop);
		}];
	} @catch (OFEnumerationMutationException *e) {
		@throw [OFEnumerationMutationException
		    exceptionWithClass: [self class]
				object: self];
	}

Modified src/OFDataArray+BinaryPackValue.m from [5af444f490] to [1c8792fc3a].

264
265
266
267
268
269
270
271

272
273
274
275

276
277
278
279
280
281
282
264
265
266
267
268
269
270

271
272
273
274

275
276
277
278
279
280
281
282







-
+



-
+







		return 9;
	/* nil */
	case 0xC0:
		*object = [OFNull null];
		return 1;
	/* false */
	case 0xC2:
		*object = [OFNumber numberWithBool: NO];
		*object = [OFNumber numberWithBool: false];
		return 1;
	/* true */
	case 0xC3:
		*object = [OFNumber numberWithBool: YES];
		*object = [OFNumber numberWithBool: true];
		return 1;
	/* Data */
	case 0xD5:
		if (length < 2)
			goto error;

		count = buffer[1];

Modified src/OFDataArray.m from [7955bfc3cd] to [bf3d520a45].

470
471
472
473
474
475
476
477

478
479
480
481
482

483
484
485
486
487
488

489
490

491
492

493
494
495
496
497
498
499
470
471
472
473
474
475
476

477
478
479
480
481

482
483
484
485
486
487

488
489

490
491

492
493
494
495
496
497
498
499







-
+




-
+





-
+

-
+

-
+








	[copy addItems: _items
		 count: _count];

	return copy;
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFDataArray *dataArray;

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

	dataArray = object;

	if ([dataArray count] != _count ||
	    [dataArray itemSize] != _itemSize)
		return NO;
		return false;
	if (memcmp([dataArray items], _items, _count * _itemSize))
		return NO;
		return false;

	return YES;
	return true;
}

- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	OFDataArray *dataArray;
	int comparison;
	size_t count, minCount;

Modified src/OFDate.m from [bc182cbf9d] to [ce6ad02444].

343
344
345
346
347
348
349
350

351
352
353
354
355

356
357
358
359
360

361
362

363
364
365
366
367
368
369
343
344
345
346
347
348
349

350
351
352
353
354

355
356
357
358
359

360
361

362
363
364
365
366
367
368
369







-
+




-
+




-
+

-
+







		[self release];
		@throw e;
	}

	return self;
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFDate *otherDate;

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

	otherDate = object;

	if (otherDate->_seconds != _seconds)
		return NO;
		return false;

	return YES;
	return true;
}

- (uint32_t)hash
{
	uint32_t hash;
	union {
		double d;

Modified src/OFDictionary.h from [dbe3c67ed9] to [ecacbc0808].

30
31
32
33
34
35
36
37
38


39
40
41
42
43
44
45
30
31
32
33
34
35
36


37
38
39
40
41
42
43
44
45







-
-
+
+







#import "OFJSONRepresentation.h"
#import "OFBinaryPackRepresentation.h"

@class OFArray;

#ifdef OF_HAVE_BLOCKS
typedef void (^of_dictionary_enumeration_block_t)(id key, id object,
     BOOL *stop);
typedef BOOL (^of_dictionary_filter_block_t)(id key, id object);
     bool *stop);
typedef bool (^of_dictionary_filter_block_t)(id key, id object);
typedef id (^of_dictionary_map_block_t)(id key, id object);
#endif

/*!
 * @brief An abstract class for storing objects in a dictionary.
 *
 * Keys are copied and thus must conform to the OFCopying protocol.
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
184
185
186
187
188
189
190

191
192
193
194
195
196
197
198







-
+







 * @brief Checks whether the dictionary contains an object with the specified
 *	  address.
 *
 * @param object The object which is checked for being in the dictionary
 * @return A boolean whether the dictionary contains an object with the
 *	   specified address.
 */
- (BOOL)containsObjectIdenticalTo: (id)object;
- (bool)containsObjectIdenticalTo: (id)object;

/*!
 * @brief Returns an array of all keys.
 *
 * @return An array of all keys
 */
- (OFArray*)allKeys;
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241







-
+







 * @param block A block which maps an object for each object
 * @return A new autoreleased OFDictionary
 */
- (OFDictionary*)mappedDictionaryUsingBlock: (of_dictionary_map_block_t)block;

/*!
 * @brief Creates a new dictionary, only containing the objects for which the
 *	  block returns YES.
 *	  block returns true.
 *
 * @param block A block which determines if the object should be in the new
 *		dictionary
 * @return A new autoreleased OFDictionary
 */
- (OFDictionary*)filteredDictionaryUsingBlock:
    (of_dictionary_filter_block_t)block;

Modified src/OFDictionary.m from [bd2462ab4e] to [b5ab4c9ae4].

324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339

340
341
342
343
344

345
346
347
348
349
350
351
352
353
354
355

356
357
358
359
360
361

362
363
364

365
366
367
368
369
370
371

372
373
374
375
376
377
378
379

380
381
382
383
384
385

386
387
388

389
390
391
392
393
394
395

396
397
398
399
400
401
402
403

404
405
406
407
408
409

410
411
412
413
414
415
416
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338

339
340
341
342
343

344
345
346
347
348
349
350
351
352
353
354

355
356
357
358
359
360

361
362
363

364
365
366
367
368
369
370

371
372
373
374
375
376
377
378

379
380
381
382
383
384

385
386
387

388
389
390
391
392
393
394

395
396
397
398
399
400
401
402

403
404
405
406
407
408

409
410
411
412
413
414
415
416







-
+







-
+




-
+










-
+





-
+


-
+






-
+







-
+





-
+


-
+






-
+







-
+





-
+







}

- mutableCopy
{
	return [[OFMutableDictionary alloc] initWithDictionary: self];
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFDictionary *otherDictionary;
	void *pool;
	OFEnumerator *enumerator;
	id key;

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

	otherDictionary = object;

	if ([otherDictionary count] != [self count])
		return NO;
		return false;

	pool = objc_autoreleasePoolPush();

	enumerator = [self keyEnumerator];
	while ((key = [enumerator nextObject]) != nil) {
		id object = [otherDictionary objectForKey: key];

		if (object == nil ||
		    ![object isEqual: [self objectForKey: key]]) {
			objc_autoreleasePoolPop(pool);
			return NO;
			return false;
		}
	}

	objc_autoreleasePoolPop(pool);

	return YES;
	return true;
}

- (BOOL)containsObject: (id)object
- (bool)containsObject: (id)object
{
	void *pool;
	OFEnumerator *enumerator;
	id currentObject;

	if (object == nil)
		return NO;
		return false;

	pool = objc_autoreleasePoolPush();
	enumerator = [self objectEnumerator];

	while ((currentObject = [enumerator nextObject]) != nil) {
		if ([currentObject isEqual: object]) {
			objc_autoreleasePoolPop(pool);
			return YES;
			return true;
		}
	}

	objc_autoreleasePoolPop(pool);

	return NO;
	return false;
}

- (BOOL)containsObjectIdenticalTo: (id)object
- (bool)containsObjectIdenticalTo: (id)object
{
	void *pool;
	OFEnumerator *enumerator;
	id currentObject;

	if (object == nil)
		return NO;
		return false;

	pool = objc_autoreleasePoolPush();
	enumerator = [self objectEnumerator];

	while ((currentObject = [enumerator nextObject]) != nil) {
		if (currentObject == object) {
			objc_autoreleasePoolPop(pool);
			return YES;
			return true;
		}
	}

	objc_autoreleasePoolPop(pool);

	return NO;
	return false;
}

- (OFArray*)allKeys
{
	void *pool = objc_autoreleasePoolPush();
	id *keys = [self allocMemoryWithSize: sizeof(id)
				       count: [self count]];
485
486
487
488
489
490
491
492

493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509

510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525

526
527
528
529
530
531
532
485
486
487
488
489
490
491

492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524

525
526
527
528
529
530
531
532







-
+
















-
+















-
+







	abort();
}

#if defined(OF_HAVE_BLOCKS) && defined(OF_HAVE_FAST_ENUMERATION)
- (void)enumerateKeysAndObjectsUsingBlock:
    (of_dictionary_enumeration_block_t)block
{
	BOOL stop = NO;
	bool stop = false;

	for (id key in self) {
		block(key, [self objectForKey: key], &stop);

		if (stop)
			break;
	}
}
#endif

#ifdef OF_HAVE_BLOCKS
- (OFDictionary*)mappedDictionaryUsingBlock: (of_dictionary_map_block_t)block
{
	OFMutableDictionary *new = [OFMutableDictionary dictionary];

	[self enumerateKeysAndObjectsUsingBlock: ^ (id key, id object,
	    BOOL *stop) {
	    bool *stop) {
		[new setObject: block(key, object)
			forKey: key];
	}];

	[new makeImmutable];

	return new;
}

- (OFDictionary*)filteredDictionaryUsingBlock:
    (of_dictionary_filter_block_t)block
{
	OFMutableDictionary *new = [OFMutableDictionary dictionary];

	[self enumerateKeysAndObjectsUsingBlock: ^ (id key, id object,
	    BOOL *stop) {
	    bool *stop) {
		if (block(key, object))
			[new setObject: object
				forKey: key];
	}];

	[new makeImmutable];

Modified src/OFDictionary_hashtable.m from [c66bc3b5e1] to [df272a2515].

51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65







-
+








static uint32_t
hash(void *value)
{
	return [(id)value hash];
}

static BOOL
static bool
equal(void *value1, void *value2)
{
	return [(id)value1 isEqual: (id)value2];
}

static of_map_table_functions_t keyFunctions = {
	.retain = copy,
317
318
319
320
321
322
323
324

325
326
327
328
329
330
331
332
333
334
335
336
337

338
339
340
341
342

343
344
345
346
347
348
349
317
318
319
320
321
322
323

324
325
326
327
328
329
330
331
332
333
334
335
336

337
338
339
340
341

342
343
344
345
346
347
348
349







-
+












-
+




-
+







}

- (size_t)count
{
	return [_mapTable count];
}

- (BOOL)isEqual: (id)dictionary
- (bool)isEqual: (id)dictionary
{
	OFDictionary_hashtable *dictionary_;

	if ([self class] != [OFDictionary_hashtable class] &&
	    [self class] != [OFMutableDictionary_hashtable class])
		return [super isEqual: dictionary];

	dictionary_ = (OFDictionary_hashtable*)dictionary;

	return [dictionary_->_mapTable isEqual: _mapTable];
}

- (BOOL)containsObject: (id)object
- (bool)containsObject: (id)object
{
	return [_mapTable containsValue: object];
}

- (BOOL)containsObjectIdenticalTo: (id)object
- (bool)containsObjectIdenticalTo: (id)object
{
	return [_mapTable containsValueIdenticalTo: object];
}

- (OFArray*)allKeys
{
	OFArray *ret;
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453







-
+








#ifdef OF_HAVE_BLOCKS
- (void)enumerateKeysAndObjectsUsingBlock:
    (of_dictionary_enumeration_block_t)block
{
	@try {
		[_mapTable enumerateKeysAndValuesUsingBlock:
		    ^ (void *key, void *value, BOOL *stop) {
		    ^ (void *key, void *value, bool *stop) {
			block(key, value, stop);
		}];
	} @catch (OFEnumerationMutationException *e) {
		@throw [OFEnumerationMutationException
		    exceptionWithClass: [self class]
				object: self];
	}

Modified src/OFFile.h from [d7d2855fce] to [bad7a67060].

38
39
40
41
42
43
44
45
46


47
48
49
50
51
52
53
38
39
40
41
42
43
44


45
46
47
48
49
50
51
52
53







-
-
+
+








/*!
 * @brief A class which provides functions to read, write and manipulate files.
 */
@interface OFFile: OFSeekableStream
{
	int  _fd;
	BOOL _closable;
	BOOL _atEndOfStream;
	bool _closable;
	bool _atEndOfStream;
}

/*!
 * @brief Creates a new OFFile with the specified path and mode.
 *
 * @param path The path to the file to open as a string
 * @param mode The mode in which the file should be opened.@n
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127







-
+







-
+















-
+








/*!
 * @brief Checks whether a file exists at the specified path.
 *
 * @param path The path to check
 * @return A boolean whether there is a file at the specified path
 */
+ (BOOL)fileExistsAtPath: (OFString*)path;
+ (bool)fileExistsAtPath: (OFString*)path;

/*!
 * @brief Checks whether a directory exists at the specified path.
 *
 * @param path The path to check
 * @return A boolean whether there is a directory at the specified path
 */
+ (BOOL)directoryExistsAtPath: (OFString*)path;
+ (bool)directoryExistsAtPath: (OFString*)path;

/*!
 * @brief Creates a directory at the specified path.
 *
 * @param path The path of the directory
 */
+ (void)createDirectoryAtPath: (OFString*)path;

/*!
 * @brief Creates a directory at the specified path.
 *
 * @param path The path of the directory
 * @param createParents Whether to create the parents of the directory
 */
+ (void)createDirectoryAtPath: (OFString*)path
		createParents: (BOOL)createParents;
		createParents: (bool)createParents;

/*!
 * @brief Returns an array with the files in the specified directory.
 *
 * @param path The path of the directory
 * @return An array of OFStrings with the files at the specified path
 */

Modified src/OFFile.m from [7a0b90bbf0] to [6182cd74e1].

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
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







-
+






-
+




-
+



-
+

-
+


-
+






-
+




-
+



-
+

-
+
















-
+







	} @finally {
		free(buffer);
	}

	return ret;
}

+ (BOOL)fileExistsAtPath: (OFString*)path
+ (bool)fileExistsAtPath: (OFString*)path
{
#ifndef _WIN32
	struct stat s;

	if (stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    &s) == -1)
		return NO;
		return false;
#else
	struct _stat s;

	if (_wstat([path UTF16String], &s) == -1)
		return NO;
		return false;
#endif

	if (S_ISREG(s.st_mode))
		return YES;
		return true;

	return NO;
	return false;
}

+ (BOOL)directoryExistsAtPath: (OFString*)path
+ (bool)directoryExistsAtPath: (OFString*)path
{
#ifndef _WIN32
	struct stat s;

	if (stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    &s) == -1)
		return NO;
		return false;
#else
	struct _stat s;

	if (_wstat([path UTF16String], &s) == -1)
		return NO;
		return false;
#endif

	if (S_ISDIR(s.st_mode))
		return YES;
		return true;

	return NO;
	return false;
}

+ (void)createDirectoryAtPath: (OFString*)path
{
#ifndef _WIN32
	if (mkdir([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    DIR_MODE))
#else
	if (_wmkdir([path UTF16String]))
#endif
		@throw [OFCreateDirectoryFailedException
		    exceptionWithClass: self
				  path: path];
}

+ (void)createDirectoryAtPath: (OFString*)path
		createParents: (BOOL)createParents
		createParents: (bool)createParents
{
	void *pool;
	OFArray *pathComponents;
	OFString *currentPath = nil, *component;
	OFEnumerator *enumerator;

	if (!createParents) {
509
510
511
512
513
514
515
516

517
518
519
520
521
522
523
509
510
511
512
513
514
515

516
517
518
519
520
521
522
523







-
+







}
#endif

+ (void)copyFileAtPath: (OFString*)source
		toPath: (OFString*)destination
{
	void *pool = objc_autoreleasePoolPush();
	BOOL override;
	bool override;
	OFFile *sourceFile = nil;
	OFFile *destinationFile = nil;
	char *buffer;
	size_t pageSize;

	if ([self directoryExistsAtPath: destination]) {
		OFString *filename = [source lastPathComponent];
692
693
694
695
696
697
698
699

700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717

718
719
720

721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737

738
739
740
741
742
743
744
692
693
694
695
696
697
698

699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716

717
718
719

720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736

737
738
739
740
741
742
743
744







-
+

















-
+


-
+
















-
+







		    DEFAULT_MODE)) == -1)
#endif
			@throw [OFOpenFileFailedException
			    exceptionWithClass: [self class]
					  path: path
					  mode: mode];

		_closable = YES;
		_closable = true;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithFileDescriptor: (int)fd
{
	self = [super init];

	_fd = fd;

	return self;
}

- (BOOL)lowlevelIsAtEndOfStream
- (bool)lowlevelIsAtEndOfStream
{
	if (_fd == -1)
		return YES;
		return true;

	return _atEndOfStream;
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer
			  length: (size_t)length
{
	ssize_t ret;

	if (_fd == -1 || _atEndOfStream ||
	    (ret = read(_fd, buffer, length)) < 0)
		@throw [OFReadFailedException exceptionWithClass: [self class]
							  stream: self
						 requestedLength: length];

	if (ret == 0)
		_atEndOfStream = YES;
		_atEndOfStream = true;

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
		     length: (size_t)length
{

Modified src/OFHTTPClient.h from [97e24a8655] to [157d08fbae].

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
101
102
103
104
105
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
101
102
103
104
105







-
+










-
+




-
+







 * callback will not be called.
 *
 * @param client The OFHTTPClient which wants to follow a redirect
 * @param URL The URL to which it will follow a redirect
 * @param request The request for which the OFHTTPClient wants to redirect
 * @return A boolean whether the OFHTTPClient should follow the redirect
 */
-	  (BOOL)client: (OFHTTPClient*)client
-	  (bool)client: (OFHTTPClient*)client
  shouldFollowRedirect: (OFURL*)URL
	       request: (OFHTTPRequest*)request;
@end

/*!
 * @brief A class for performing HTTP requests.
 */
@interface OFHTTPClient: OFObject
{
	id <OFHTTPClientDelegate> _delegate;
	BOOL _insecureRedirectsAllowed;
	bool _insecureRedirectsAllowed;
}

#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFHTTPClientDelegate> delegate;
@property BOOL insecureRedirectsAllowed;
@property bool insecureRedirectsAllowed;
#endif

/*!
 * @brief Creates a new OFHTTPClient.
 *
 * @return A new, autoreleased OFHTTPClient
 */
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134

135
136
137
138
139
140
141
120
121
122
123
124
125
126

127
128
129
130
131
132
133

134
135
136
137
138
139
140
141







-
+






-
+







- (id <OFHTTPClientDelegate>)delegate;

/*!
 * @brief Sets whether redirects from HTTPS to HTTP are allowed.
 *
 * @param allowed Whether redirects from HTTPS to HTTP are allowed
 */
- (void)setInsecureRedirectsAllowed: (BOOL)allowed;
- (void)setInsecureRedirectsAllowed: (bool)allowed;

/*!
 * @brief Returns whether redirects from HTTPS to HTTP will be allowed
 *
 * @return Whether redirects from HTTPS to HTTP will be allowed
 */
- (BOOL)insecureRedirectsAllowed;
- (bool)insecureRedirectsAllowed;

/*!
 * @brief Performs the specified HTTP request
 */
- (OFHTTPRequestReply*)performRequest: (OFHTTPRequest*)request;

/*!

Modified src/OFHTTPClient.m from [8b8198d6dd] to [4a71698195].

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
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







-
+



-
+






-
+







-
+







#import "autorelease.h"
#import "macros.h"

static OF_INLINE void
normalize_key(char *str_)
{
	uint8_t *str = (uint8_t*)str_;
	BOOL firstLetter = YES;
	bool firstLetter = true;

	while (*str != '\0') {
		if (!isalnum(*str)) {
			firstLetter = YES;
			firstLetter = true;
			str++;
			continue;
		}

		*str = (firstLetter ? toupper(*str) : tolower(*str));

		firstLetter = NO;
		firstLetter = false;
		str++;
	}
}

@interface OFHTTPClientReply: OFHTTPRequestReply
{
	OFTCPSocket *_socket;
	BOOL _chunked, _atEndOfStream;
	bool _chunked, _atEndOfStream;
	size_t _toRead;
}

- initWithSocket: (OFTCPSocket*)socket;
@end

@implementation OFHTTPClientReply
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164







-
+








-
+







		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidServerReplyException
			    exceptionWithClass: [self class]];
		}

		if (_toRead == 0) {
			[_socket close];
			_atEndOfStream = YES;
			_atEndOfStream = true;
		}

		objc_autoreleasePoolPop(pool);

		return 0;
	}
}

- (BOOL)lowlevelIsAtEndOfStream
- (bool)lowlevelIsAtEndOfStream
{
	if (!_chunked)
		return [_socket isAtEndOfStream];

	return _atEndOfStream;
}

191
192
193
194
195
196
197
198

199
200
201
202
203

204
205
206
207
208
209
210
191
192
193
194
195
196
197

198
199
200
201
202

203
204
205
206
207
208
209
210







-
+




-
+







}

- (id <OFHTTPClientDelegate>)delegate
{
	return _delegate;
}

- (void)setInsecureRedirectsAllowed: (BOOL)allowed
- (void)setInsecureRedirectsAllowed: (bool)allowed
{
	_insecureRedirectsAllowed = allowed;
}

- (BOOL)insecureRedirectsAllowed
- (bool)insecureRedirectsAllowed
{
	return _insecureRedirectsAllowed;
}

- (OFHTTPRequestReply*)performRequest: (OFHTTPRequest*)request
{
	return [self performRequest: request
254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268







-
+







	[socket connectToHost: [URL host]
			 port: [URL port]];

	/*
	 * Work around a bug with packet splitting in lighttpd when using
	 * HTTPS.
	 */
	[socket setWriteBufferEnabled: YES];
	[socket setWriteBufferEnabled: true];

	if (requestType == OF_HTTP_REQUEST_TYPE_GET)
		type = "GET";
	if (requestType == OF_HTTP_REQUEST_TYPE_HEAD)
		type = "HEAD";
	if (requestType == OF_HTTP_REQUEST_TYPE_POST)
		type = "POST";
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
308
309
310
311
312
313
314

315
316
317
318
319
320
321
322







-
+







		    [POSTData count] * [POSTData itemSize]];
	}

	[socket writeString: @"\r\n"];

	/* Work around a bug in lighttpd, see above */
	[socket flushWriteBuffer];
	[socket setWriteBufferEnabled: NO];
	[socket setWriteBufferEnabled: false];

	if (requestType == OF_HTTP_REQUEST_TYPE_POST)
		[socket writeBuffer: [POSTData items]
			     length: [POSTData count] * [POSTData itemSize]];

	@try {
		line = [socket readLine];
371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404
371
372
373
374
375
376
377

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396

397
398
399
400
401
402
403
404







-
+


















-
+








		memcpy(keyC, lineC, tmp - lineC);
		keyC[tmp - lineC] = '\0';
		normalize_key(keyC);

		@try {
			key = [OFString stringWithUTF8StringNoCopy: keyC
						      freeWhenDone: YES];
						      freeWhenDone: true];
		} @catch (id e) {
			free(keyC);
			@throw e;
		}

		do {
			tmp++;
		} while (*tmp == ' ');

		value = [OFString stringWithUTF8String: tmp];

		if ((redirects > 0 && (status == 301 || status == 302 ||
		    status == 303 || status == 307) &&
		    [key isEqual: @"Location"]) && (_insecureRedirectsAllowed ||
		    [scheme isEqual: @"http"] ||
		    ![value hasPrefix: @"http://"])) {
			OFURL *newURL;
			OFHTTPRequest *newRequest;
			BOOL follow = YES;
			bool follow = true;

			newURL = [OFURL URLWithString: value
					relativeToURL: URL];

			if ([_delegate respondsToSelector:
			    @selector(client:shouldFollowRedirect:request:)])
				follow = [_delegate client: self

Modified src/OFHTTPRequest.m from [67ed2116e0] to [24712e6afd].

75
76
77
78
79
80
81
82

83
84
85
86
87

88
89
90
91
92
93
94
75
76
77
78
79
80
81

82
83
84
85
86

87
88
89
90
91
92
93
94







-
+




-
+







	[_remoteAddress release];

	[super dealloc];
}

- (void)setURL: (OFURL*)URL
{
	OF_SETTER(_URL, URL, YES, 1)
	OF_SETTER(_URL, URL, true, 1)
}

- (OFURL*)URL
{
	OF_GETTER(_URL, YES)
	OF_GETTER(_URL, true)
}

- (void)setRequestType: (of_http_request_type_t)requestType
{
	_requestType = requestType;
}

143
144
145
146
147
148
149
150

151
152
153
154
155

156
157
158
159
160

161
162
163
164
165

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
143
144
145
146
147
148
149

150
151
152
153
154

155
156
157
158
159

160
161
162
163
164

165
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







-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+







{
	return [OFString stringWithFormat: @"%u.%u", _protocolVersion.major,
					   _protocolVersion.minor];
}

- (void)setHeaders: (OFDictionary*)headers
{
	OF_SETTER(_headers, headers, YES, 1)
	OF_SETTER(_headers, headers, true, 1)
}

- (OFDictionary*)headers
{
	OF_GETTER(_headers, YES)
	OF_GETTER(_headers, true)
}

- (void)setPOSTData: (OFDataArray*)POSTData
{
	OF_SETTER(_POSTData, POSTData, YES, 0)
	OF_SETTER(_POSTData, POSTData, true, 0)
}

- (OFDataArray*)POSTData
{
	OF_GETTER(_POSTData, YES)
	OF_GETTER(_POSTData, true)
}

- (void)setMIMEType: (OFString*)MIMEType
{
	OF_SETTER(_MIMEType, MIMEType, YES, 1)
	OF_SETTER(_MIMEType, MIMEType, true, 1)
}

- (OFString*)MIMEType
{
	OF_GETTER(_MIMEType, YES)
	OF_GETTER(_MIMEType, true)
}

- (void)setRemoteAddress: (OFString*)remoteAddress
{
	OF_SETTER(_remoteAddress, remoteAddress, YES, 1)
	OF_SETTER(_remoteAddress, remoteAddress, true, 1)
}

- (OFString*)remoteAddress
{
	OF_GETTER(_remoteAddress, YES)
	OF_GETTER(_remoteAddress, true)
}

- (OFString*)description
{
	void *pool = objc_autoreleasePoolPush();
	const char *requestTypeStr = NULL;
	OFString *indentedHeaders, *indentedPOSTData, *ret;

Modified src/OFHTTPRequestReply.m from [bae34e8d9b] to [6bcf634ee6].

102
103
104
105
106
107
108
109

110
111
112
113
114

115
116
117
118
119
120
121
102
103
104
105
106
107
108

109
110
111
112
113

114
115
116
117
118
119
120
121







-
+




-
+







- (void)setStatusCode: (short)statusCode
{
	_statusCode = statusCode;
}

- (OFDictionary*)headers
{
	OF_GETTER(_headers, YES)
	OF_GETTER(_headers, true)
}

- (void)setHeaders: (OFDictionary*)headers
{
	OF_SETTER(_headers, headers, YES, YES)
	OF_SETTER(_headers, headers, true, 1)
}

- (OFString*)description
{
	void *pool = objc_autoreleasePoolPush();
	OFString *indentedHeaders, *ret;

Modified src/OFHTTPServer.h from [bf775ba1f9] to [37d7fcda08].

44
45
46
47
48
49
50
51
52
53



54
55

56
57
58
59
60
61
62
44
45
46
47
48
49
50



51
52
53
54

55
56
57
58
59
60
61
62







-
-
-
+
+
+

-
+







/*!
 * @brief This method is called when the HTTP server's listening socket
 *	  encountered an exception.
 *
 * @param server The HTTP server which encountered an exception
 * @param exception The exception that occurred on the HTTP server's listening
 *		    socket
 * @return Whether to continue listening. If you return NO, existing connections
 *	   will still be handled and you can start accepting new connections
 *	   again by calling @ref OFHTTPServer::start again.
 * @return Whether to continue listening. If you return false, existing
 *	   connections will still be handled and you can start accepting new
 *	   connections again by calling @ref OFHTTPServer::start again.
 */
-			  (BOOL)server: (OFHTTPServer*)server
-			  (bool)server: (OFHTTPServer*)server
  didReceiveExceptionOnListeningSocket: (OFException*)exception;
@end

/*!
 * @brief A class for creating a simple HTTP server inside of applications.
 */
@interface OFHTTPServer: OFObject
146
147
148
149
150
151
152
153

154
155
156
157
158
159
146
147
148
149
150
151
152

153
154
155
156
157
158
159







-
+






/*!
 * @brief Stops the HTTP server, meaning it will not accept any new incoming
 *	  connections, but still handle existing connections until they are
 *	  finished or timed out.
 */
- (void)stop;

- (BOOL)OF_socket: (OFTCPSocket*)socket
- (bool)OF_socket: (OFTCPSocket*)socket
  didAcceptSocket: (OFTCPSocket*)clientSocket
	exception: (OFException*)exception;
@end

@interface OFObject (OFHTTPServerDelegate) <OFHTTPServerDelegate>
@end

Modified src/OFHTTPServer.m from [7e47217e14] to [a4708f3429].

137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160

161
162
163
164
165

166
167
168
169
170
171
172

173
174
175
176
177
178
179
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159

160
161
162
163
164

165
166
167
168
169
170
171

172
173
174
175
176
177
178
179







-
+








-
+






-
+




-
+






-
+







}

static OF_INLINE OFString*
normalized_key(OFString *key)
{
	char *cString = strdup([key UTF8String]);
	uint8_t *tmp = (uint8_t*)cString;
	BOOL firstLetter = YES;
	bool firstLetter = true;

	if (cString == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithClass: nil
			 requestedSize: strlen([key UTF8String])];

	while (*tmp != '\0') {
		if (!isalnum(*tmp)) {
			firstLetter = YES;
			firstLetter = true;
			tmp++;
			continue;
		}

		*tmp = (firstLetter ? toupper(*tmp) : tolower(*tmp));

		firstLetter = NO;
		firstLetter = false;
		tmp++;
	}

	return [OFString stringWithUTF8StringNoCopy: cString
				       freeWhenDone: YES];
				       freeWhenDone: true];
}

@interface OFHTTPServerReply: OFHTTPRequestReply
{
	OFTCPSocket *_socket;
	OFHTTPServer *_server;
	BOOL _chunked, _headersSent, _closed;
	bool _chunked, _headersSent, _closed;
}

- initWithSocket: (OFTCPSocket*)socket
	  server: (OFHTTPServer*)server;
@end

@implementation OFHTTPServerReply
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234







-
+







	while ((key = [keyEnumerator nextObject]) != nil &&
	    (value = [valueEnumerator nextObject]) != nil)
		if (![key isEqual: @"Server"] && ![key isEqual: @"Date"])
			[_socket writeFormat: @"%@: %@\r\n", key, value];

	[_socket writeString: @"\r\n"];

	_headersSent = YES;
	_headersSent = true;
	_chunked = [[_headers objectForKey: @"Transfer-Encoding"]
	    isEqual: @"chunked"];

	objc_autoreleasePoolPop(pool);
}

- (void)lowlevelWriteBuffer: (const void*)buffer
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
262
263
264
265
266
267
268

269
270
271
272
273
274
275
276







-
+








	if (_chunked)
		[_socket writeBuffer: "0\r\n\r\n"
			      length: 5];

	[_socket close];

	_closed = YES;
	_closed = true;
}

- (int)fileDescriptorForWriting
{
	return [_socket fileDescriptorForWriting];
}
@end
292
293
294
295
296
297
298
299

300
301
302
303
304



305
306
307
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
292
293
294
295
296
297
298

299
300
301



302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325

326
327
328
329
330
331
332
333







-
+


-
-
-
+
+
+



-
+

















-
+







	OFMutableDictionary *_headers;
	size_t _contentLength;
	OFDataArray *_POSTData;
}

- initWithSocket: (OFTCPSocket*)socket
	  server: (OFHTTPServer*)server;
- (BOOL)socket: (OFTCPSocket*)socket
- (bool)socket: (OFTCPSocket*)socket
   didReadLine: (OFString*)line
     exception: (OFException*)exception;
- (BOOL)parseProlog: (OFString*)line;
- (BOOL)parseHeaders: (OFString*)line;
-      (BOOL)socket: (OFTCPSocket*)socket
- (bool)parseProlog: (OFString*)line;
- (bool)parseHeaders: (OFString*)line;
-      (bool)socket: (OFTCPSocket*)socket
  didReadIntoBuffer: (const char*)buffer
	     length: (size_t)length
	  exception: (OFException*)exception;
- (BOOL)sendErrorAndClose: (short)statusCode;
- (bool)sendErrorAndClose: (short)statusCode;
- (void)createReply;
@end

@implementation OFHTTPServer_Connection
- initWithSocket: (OFTCPSocket*)socket
	  server: (OFHTTPServer*)server
{
	self = [super init];

	@try {
		_socket = [socket retain];
		_server = [server retain];
		_timer = [[OFTimer
		    scheduledTimerWithTimeInterval: 10
					    target: socket
					  selector: @selector(
							cancelAsyncRequests)
					   repeats: NO] retain];
					   repeats: false] retain];
		_state = AWAITING_PROLOG;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
345
346
347
348
349
350
351
352

353
354
355
356
357

358
359
360
361
362
363
364
365

366
367
368
369

370
371
372

373
374

375
376
377

378
379
380
381
382
383

384
385
386
387
388
389
390
345
346
347
348
349
350
351

352
353
354
355
356

357
358
359
360
361
362
363
364

365
366
367
368

369
370
371

372
373

374
375
376

377
378
379
380
381
382

383
384
385
386
387
388
389
390







-
+




-
+







-
+



-
+


-
+

-
+


-
+





-
+







	[_path release];
	[_headers release];
	[_POSTData release];

	[super dealloc];
}

- (BOOL)socket: (OFTCPSocket*)socket
- (bool)socket: (OFTCPSocket*)socket
   didReadLine: (OFString*)line
     exception: (OFException*)exception
{
	if (line == nil || exception != nil)
		return NO;
		return false;

	@try {
		switch (_state) {
		case AWAITING_PROLOG:
			return [self parseProlog: line];
		case PARSING_HEADERS:
			if (![self parseHeaders: line])
				return NO;
				return false;

			if (_state == SEND_REPLY) {
				[self createReply];
				return NO;
				return false;
			}

			return YES;
			return true;
		default:
			return NO;
			return false;
		}
	} @catch (OFWriteFailedException *e) {
		return NO;
		return false;
	}

	abort();
}

- (BOOL)parseProlog: (OFString*)line
- (bool)parseProlog: (OFString*)line
{
	OFString *type;
	size_t pos;

	@try {
		OFString *version = [line
		    substringWithRange: of_range([line length] - 9, 9)];
426
427
428
429
430
431
432
433

434
435
436

437
438
439
440
441
442
443
426
427
428
429
430
431
432

433
434
435

436
437
438
439
440
441
442
443







-
+


-
+








	if (![_path hasPrefix: @"/"])
		return [self sendErrorAndClose: 400];

	_headers = [[OFMutableDictionary alloc] init];
	_state = PARSING_HEADERS;

	return YES;
	return true;
}

- (BOOL)parseHeaders: (OFString*)line
- (bool)parseHeaders: (OFString*)line
{
	OFString *key, *value;
	size_t pos;

	if ([line length] == 0) {
		switch (_requestType) {
		case OF_HTTP_REQUEST_TYPE_GET:
466
467
468
469
470
471
472
473

474
475
476

477
478
479
480
481
482
483
466
467
468
469
470
471
472

473
474
475

476
477
478
479
480
481
482
483







-
+


-
+







					      target: self
					    selector: @selector(socket:
							  didReadIntoBuffer:
							  length:exception:)];
			[_timer setFireDate:
			    [OFDate dateWithTimeIntervalSinceNow: 5]];

			return NO;
			return false;
		}

		return YES;
		return true;
	}

	pos = [line rangeOfString: @":"].location;
	if (pos == OF_NOT_FOUND)
		return [self sendErrorAndClose: 400];

	key = [line substringWithRange: of_range(0, pos)];
516
517
518
519
520
521
522
523

524
525
526

527
528
529
530
531
532

533
534
535
536
537
538
539
540
541

542
543
544

545
546
547
548
549

550
551
552

553
554
555
556
557
558
559
560
561
562
563
564
565

566
567
568
569
570
571
572
516
517
518
519
520
521
522

523
524
525

526
527
528
529
530
531

532
533
534
535
536
537
538
539
540

541
542
543

544
545
546
547
548

549
550
551

552
553
554
555
556
557
558
559
560
561
562
563
564

565
566
567
568
569
570
571
572







-
+


-
+





-
+








-
+


-
+




-
+


-
+












-
+







		} else {
			[_host release];
			_host = [value retain];
			_port = 80;
		}
	}

	return YES;
	return true;
}

-      (BOOL)socket: (OFTCPSocket*)socket
-      (bool)socket: (OFTCPSocket*)socket
  didReadIntoBuffer: (const char*)buffer
	     length: (size_t)length
	  exception: (OFException*)exception
{
	if ([socket isAtEndOfStream] || exception != nil)
		return NO;
		return false;

	[_POSTData addItems: buffer
		      count: length];

	if ([_POSTData count] >= _contentLength) {
		@try {
			[self createReply];
		} @catch (OFWriteFailedException *e) {
			return NO;
			return false;
		}

		return NO;
		return false;
	}

	[_timer setFireDate: [OFDate dateWithTimeIntervalSinceNow: 5]];

	return YES;
	return true;
}

- (BOOL)sendErrorAndClose: (short)statusCode
- (bool)sendErrorAndClose: (short)statusCode
{
	OFString *date = [[OFDate date]
	    dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"];

	[_socket writeFormat: @"HTTP/1.1 %d %s\r\n"
			      @"Date: %@\r\n"
			      @"Server: %@\r\n"
			      @"\r\n",
			      statusCode, status_code_to_string(statusCode),
			      date, [_server name]];
	[_socket close];

	return NO;
	return false;
}

- (void)createReply
{
	OFURL *URL;
	OFHTTPRequest *request;
	OFHTTPServerReply *reply;
645
646
647
648
649
650
651
652

653
654
655
656
657

658
659
660
661
662
663
664
645
646
647
648
649
650
651

652
653
654
655
656

657
658
659
660
661
662
663
664







-
+




-
+







	[_name release];

	[super dealloc];
}

- (void)setHost: (OFString*)host
{
	OF_SETTER(_host, host, YES, 1)
	OF_SETTER(_host, host, true, 1)
}

- (OFString*)host
{
	OF_GETTER(_host, YES)
	OF_GETTER(_host, true)
}

- (void)setPort: (uint16_t)port
{
	_port = port;
}

675
676
677
678
679
680
681
682

683
684
685
686
687

688
689
690
691
692
693
694
675
676
677
678
679
680
681

682
683
684
685
686

687
688
689
690
691
692
693
694







-
+




-
+







- (id <OFHTTPServerDelegate>)delegate
{
	return _delegate;
}

- (void)setName: (OFString*)name
{
	OF_SETTER(_name, name, YES, 1)
	OF_SETTER(_name, name, true, 1)
}

- (OFString*)name
{
	OF_GETTER(_name, YES)
	OF_GETTER(_name, true)
}

- (void)start
{
	if (_host == nil || _port == 0)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
713
714
715
716
717
718
719
720

721
722
723
724
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740
741
742
743

744
745
713
714
715
716
717
718
719

720
721
722
723
724
725
726
727
728
729
730
731

732
733
734
735
736
737
738
739
740
741
742

743
744
745







-
+











-
+










-
+


- (void)stop
{
	[_listeningSocket cancelAsyncRequests];
	[_listeningSocket release];
	_listeningSocket = nil;
}

- (BOOL)OF_socket: (OFTCPSocket*)socket
- (bool)OF_socket: (OFTCPSocket*)socket
  didAcceptSocket: (OFTCPSocket*)clientSocket
	exception: (OFException*)exception
{
	OFHTTPServer_Connection *connection;

	if (exception != nil) {
		if ([_delegate respondsToSelector:
		    @selector(server:didReceiveExceptionOnListeningSocket:)])
			return [_delegate		  server: self
			    didReceiveExceptionOnListeningSocket: exception];

		return NO;
		return false;
	}

	connection = [[[OFHTTPServer_Connection alloc]
	    initWithSocket: clientSocket
		    server: self] autorelease];

	[clientSocket asyncReadLineWithTarget: connection
				     selector: @selector(socket:didReadLine:
						  exception:)];

	return YES;
	return true;
}
@end

Modified src/OFHash.h from [f3fad14a9f] to [ecafca2322].

17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31







-
+







#import "OFObject.h"

/*!
 * @brief A protocol for classes providing hash functions.
 */
@protocol OFHash <OFObject>
#ifdef OF_HAVE_PROPERTIES
@property (readonly, getter=isCalculated) BOOL calculated;
@property (readonly, getter=isCalculated) bool calculated;
#endif

/*!
 * @brief Creates a new hash.
 *
 * @return A new autoreleased OFHash
 */
65
66
67
68
69
70
71
72

73
65
66
67
68
69
70
71

72
73







-
+

- (uint8_t*)digest OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns a boolean whether the hash has already been calculated.
 *
 * @return A boolean whether the hash has already been calculated
 */
- (BOOL)isCalculated;
- (bool)isCalculated;
@end

Modified src/OFIntrospection.m from [562aeea48c] to [f870fce7d2].

77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
103

104
105
106
107
108

109
110
111

112
113
114
115

116
117
118
119

120
121

122
123
124
125
126
127
128
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102

103
104
105
106
107

108
109
110

111
112
113
114

115
116
117
118

119
120

121
122
123
124
125
126
127
128







-
+













-
+




-
+




-
+


-
+



-
+



-
+

-
+







- (SEL)selector
{
	return _selector;
}

- (OFString*)name
{
	OF_GETTER(_name, YES)
	OF_GETTER(_name, true)
}

- (const char*)typeEncoding
{
	return _typeEncoding;
}

- (OFString*)description
{
	return [OFString stringWithFormat: @"<OFMethod: %@ [%s]>",
					   _name, _typeEncoding];
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFMethod *method;

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

	method = object;

	if (!sel_isEqual(method->_selector, _selector))
		return NO;
		return false;

	if (![method->_name isEqual: _name])
		return NO;
		return false;

	if ((method->_typeEncoding == NULL && _typeEncoding != NULL) ||
	    (method->_typeEncoding != NULL && _typeEncoding == NULL))
		return NO;
		return false;

	if (method->_typeEncoding != NULL && _typeEncoding != NULL &&
	    strcmp(method->_typeEncoding, _typeEncoding))
		return NO;
		return false;

	return YES;
	return true;
}

- (uint32_t)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
184
185
186
187
188
189
190

191
192
193
194
195
196
197
198







-
+







	[_name release];

	[super dealloc];
}

- (OFString*)name
{
	OF_GETTER(_name, YES);
	OF_GETTER(_name, true);
}

- (ptrdiff_t)offset
{
	return _offset;
}

335
336
337
338
339
340
341
342

343
344
345
346
347

348
349
350
351
352

353
354
335
336
337
338
339
340
341

342
343
344
345
346

347
348
349
350
351

352
353
354







-
+




-
+




-
+


	[_instanceVariables release];

	[super dealloc];
}

- (OFArray*)classMethods
{
	OF_GETTER(_classMethods, YES)
	OF_GETTER(_classMethods, true)
}

- (OFArray*)instanceMethods
{
	OF_GETTER(_instanceMethods, YES)
	OF_GETTER(_instanceMethods, true)
}

- (OFArray*)instanceVariables
{
	OF_GETTER(_instanceVariables, YES)
	OF_GETTER(_instanceVariables, true)
}
@end

Modified src/OFList.h from [723cbad907] to [04a5830c4d].

128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142







-
+







/*!
 * @brief Checks whether the list contains an object with the specified address.
 *
 * @param object The object which is checked for being in the list
 * @return A boolean whether the list contains an object with the specified
 *	   address.
 */
- (BOOL)containsObjectIdenticalTo: (id)object;
- (bool)containsObjectIdenticalTo: (id)object;

/*!
 * @brief Returns the first object of the list or nil.
 *
 * @warning The returned object is *not* retained and autoreleased for
 *	    performance reasons!
 *

Modified src/OFList.m from [c96b3b33fd] to [0d2e63e3da].

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
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







-
+





-
+




-
+





-
+




-
+


-
+




-
+



-
+

-
+


-
+




-
+



-
+

-
+







}

- (size_t)count
{
	return _count;
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFList *list;
	of_list_object_t *iter, *iter2;

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

	list = object;

	if ([list count] != _count)
		return NO;
		return false;

	for (iter = _firstListObject, iter2 = [list firstListObject];
	    iter != NULL && iter2 != NULL;
	    iter = iter->next, iter2 = iter2->next)
		if (![iter->object isEqual: iter2->object])
			return NO;
			return false;

	/* One is bigger than the other even though we checked the count */
	assert(iter == NULL && iter2 == NULL);

	return YES;
	return true;
}

- (BOOL)containsObject: (id)object
- (bool)containsObject: (id)object
{
	of_list_object_t *iter;

	if (_count == 0)
		return NO;
		return false;

	for (iter = _firstListObject; iter != NULL; iter = iter->next)
		if ([iter->object isEqual: object])
			return YES;
			return true;

	return NO;
	return false;
}

- (BOOL)containsObjectIdenticalTo: (id)object
- (bool)containsObjectIdenticalTo: (id)object
{
	of_list_object_t *iter;

	if (_count == 0)
		return NO;
		return false;

	for (iter = _firstListObject; iter != NULL; iter = iter->next)
		if (iter->object == object)
			return YES;
			return true;

	return NO;
	return false;
}

- (void)removeAllObjects
{
	of_list_object_t *iter, *next;

	_mutations++;

Modified src/OFLocking.h from [1831eed890] to [f41c1b5827].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44







-
+







- (void)lock;

/*!
 * @brief Tries to lock the lock.
 *
 * @return A boolean whether the lock could be locked
 */
- (BOOL)tryLock;
- (bool)tryLock;

/*!
 * @brief Unlocks the lock.
 */
- (void)unlock;

/*!

Modified src/OFMD5Hash.h from [833fa196ed] to [d2206bf3cb].

25
26
27
28
29
30
31
32

33
34
25
26
27
28
29
30
31

32
33
34







-
+


{
	uint32_t _buffer[4];
	uint32_t _bits[2];
	union {
		uint8_t	u8[64];
		uint32_t u32[16];
	} _in;
	BOOL _calculated;
	bool _calculated;
}
@end

Modified src/OFMD5Hash.m from [83d7c707b9] to [621cd607df].

255
256
257
258
259
260
261
262

263
264
265
266
267

268
269
270
271
255
256
257
258
259
260
261

262
263
264
265
266

267
268
269
270
271







-
+




-
+




	/* Append length in bits and transform */
	_in.u32[14] = _bits[0];
	_in.u32[15] = _bits[1];

	md5_transform(_buffer, _in.u32);
	BSWAP32_VEC_IF_BE(_buffer, 4);

	_calculated = YES;
	_calculated = true;

	return (uint8_t*)_buffer;
}

- (BOOL)isCalculated
- (bool)isCalculated
{
	return _calculated;
}
@end

Modified src/OFMapTable.h from [98630c9c0b] to [e819467858].

24
25
26
27
28
29
30
31

32
33
34
35
36

37
38

39
40
41
42
43
44
45
24
25
26
27
28
29
30

31
32
33
34
35

36
37

38
39
40
41
42
43
44
45







-
+




-
+

-
+







	/// The function to retain keys / values
	void* (*retain)(void *value);
	/// The function to release keys / values
	void (*release)(void *value);
	/// The function to hash keys
	uint32_t (*hash)(void *value);
	/// The function to compare keys / values
	BOOL (*equal)(void *value1, void *value2);
	bool (*equal)(void *value1, void *value2);
} of_map_table_functions_t;

#ifdef OF_HAVE_BLOCKS
typedef void (^of_map_table_enumeration_block_t)(void *key, void *value,
    BOOL *stop);
    bool *stop);
typedef void* (^of_map_table_replace_block_t)(void *key, void *value,
    BOOL *stop);
    bool *stop);
#endif

@class OFMapTableEnumerator;

/**
 * @brief A class similar to OFDictionary, but providing more options how keys
 *	  and values should be retained, released, compared and hashed.
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166







-
+









-
+







/*!
 * @brief Checks whether the map table contains a value equal to the specified
 *	  value.
 *
 * @param value The value which is checked for being in the map table
 * @return A boolean whether the map table contains the specified value
*/
- (BOOL)containsValue: (void*)value;
- (bool)containsValue: (void*)value;

/*!
 * @brief Checks whether the map table contains a value with the specified
 *        address.
 *
 * @param value The value which is checked for being in the map table
 * @return A boolean whether the map table contains a value with the specified
 *	   address.
 */
- (BOOL)containsValueIdenticalTo: (void*)value;
- (bool)containsValueIdenticalTo: (void*)value;

/*!
 * @brief Returns an OFMapTableEnumerator to enumerate through the map table's
 *	  keys.
 *
 * @return An OFMapTableEnumerator to enumerate through the map table's keys
 */

Modified src/OFMapTable.m from [1f61a324ed] to [f2d7d60333].

51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65







-
+








static uint32_t
default_hash(void *value)
{
	return (uint32_t)(uintptr_t)value;
}

static BOOL
static bool
default_equal(void *value1, void *value2)
{
	return (value1 == value2);
}

@interface OFMapTableKeyEnumerator: OFMapTableEnumerator
@end
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

206
207
208
209

210
211
212
213
214
215
216
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
206
207
208

209
210
211
212
213
214
215
216







-
+





-
+






-
+






-
+



-
+







			_valueFunctions.release(_buckets[i]->value);
		}
	}

	[super dealloc];
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFMapTable *mapTable;
	uint32_t i;

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

	mapTable = object;

	if (mapTable->_count != _count ||
	    mapTable->_keyFunctions.equal != _keyFunctions.equal ||
	    mapTable->_valueFunctions.equal != _valueFunctions.equal)
		return NO;
		return false;

	for (i = 0; i < _capacity; i++) {
		if (_buckets[i] != NULL && _buckets[i] != &deleted) {
			void *value = [mapTable valueForKey: _buckets[i]->key];

			if (!_valueFunctions.equal(value, _buckets[i]->value))
				return NO;
				return false;
		}
	}

	return YES;
	return true;
}

- (uint32_t)hash
{
	uint32_t i, hash = 0;

	for (i = 0; i < _capacity; i++) {
500
501
502
503
504
505
506
507

508
509
510
511
512

513
514
515
516
517

518
519

520
521
522

523
524
525
526
527

528
529
530
531
532

533
534

535
536
537
538
539
540
541
500
501
502
503
504
505
506

507
508
509
510
511

512
513
514
515
516

517
518

519
520
521

522
523
524
525
526

527
528
529
530
531

532
533

534
535
536
537
538
539
540
541







-
+




-
+




-
+

-
+


-
+




-
+




-
+

-
+







			[self OF_resizeForCount: _count];

			return;
		}
	}
}

- (BOOL)containsValue: (void*)value
- (bool)containsValue: (void*)value
{
	uint32_t i;

	if (value == NULL || _count == 0)
		return NO;
		return false;

	for (i = 0; i < _capacity; i++)
		if (_buckets[i] != NULL && _buckets[i] != &deleted)
			if (_valueFunctions.equal(_buckets[i]->value, value))
				return YES;
				return true;

	return NO;
	return false;
}

- (BOOL)containsValueIdenticalTo: (void*)value
- (bool)containsValueIdenticalTo: (void*)value
{
	uint32_t i;

	if (value == NULL || _count == 0)
		return NO;
		return false;

	for (i = 0; i < _capacity; i++)
		if (_buckets[i] != NULL && _buckets[i] != &deleted)
			if (_buckets[i]->value == value)
				return YES;
				return true;

	return NO;
	return false;
}

- (OFMapTableEnumerator*)keyEnumerator
{
	return [[[OFMapTableKeyEnumerator alloc]
	    OF_initWithMapTable: self
			buckets: _buckets
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602

603
604
605
606
607
608
609
578
579
580
581
582
583
584

585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601

602
603
604
605
606
607
608
609







-
+
















-
+







}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateKeysAndValuesUsingBlock:
    (of_map_table_enumeration_block_t)block
{
	size_t i;
	BOOL stop = NO;
	bool stop = false;
	unsigned long mutations = _mutations;

	for (i = 0; i < _capacity && !stop; i++) {
		if (_mutations != mutations)
			@throw [OFEnumerationMutationException
			    exceptionWithClass: [self class]
					object: self];

		if (_buckets[i] != NULL && _buckets[i] != &deleted)
			block(_buckets[i]->key, _buckets[i]->value, &stop);
	}
}

- (void)replaceValuesUsingBlock: (of_map_table_replace_block_t)block
{
	size_t i;
	BOOL stop = NO;
	bool stop = false;
	unsigned long mutations = _mutations;

	for (i = 0; i < _capacity && !stop; i++) {
		if (_mutations != mutations)
			@throw [OFEnumerationMutationException
			    exceptionWithClass: [self class]
					object: self];

Modified src/OFMutableArray.h from [fa7a4d0116] to [48e9f64998].

13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27







-
+







 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFArray.h"

#ifdef OF_HAVE_BLOCKS
typedef id (^of_array_replace_block_t)(id obj, size_t idx, BOOL *stop);
typedef id (^of_array_replace_block_t)(id obj, size_t idx, bool *stop);
#endif

/*!
 * @brief An abstract class for storing, adding and removing objects in an
 *	  array.
 */
@interface OFMutableArray: OFArray

Modified src/OFMutableArray.m from [0ae8da9046] to [53f13e2987].

371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
371
372
373
374
375
376
377

378
379
380
381
382
383
384
385







-
+







	[self removeObjectsInRange: of_range(0, [self count])];
}

#ifdef OF_HAVE_BLOCKS
- (void)replaceObjectsUsingBlock: (of_array_replace_block_t)block
{
	[self enumerateObjectsUsingBlock: ^ (id object, size_t index,
	    BOOL *stop) {
	    bool *stop) {
		[self replaceObjectAtIndex: index
				withObject: block(object, index, stop)];
	}];
}
#endif

- (void)exchangeObjectAtIndex: (size_t)index1

Modified src/OFMutableArray_adjacent.m from [a8ef885aa6] to [1c467efbfe].

331
332
333
334
335
336
337
338

339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355

356
357
358
359
360
361
362
331
332
333
334
335
336
337

338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362







-
+
















-
+







}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
	id *objects = [_array items];
	size_t i, count = [_array count];
	BOOL stop = NO;
	bool stop = false;
	unsigned long mutations = _mutations;

	for (i = 0; i < count && !stop; i++) {
		if (_mutations != mutations)
			@throw [OFEnumerationMutationException
			    exceptionWithClass: [self class]
					object: self];

		block(objects[i], i, &stop);
	}
}

- (void)replaceObjectsUsingBlock: (of_array_replace_block_t)block
{
	id *objects = [_array items];
	size_t i, count = [_array count];
	BOOL stop = NO;
	bool stop = false;
	unsigned long mutations = _mutations;

	for (i = 0; i < count && !stop; i++) {
		id newObject;

		if (_mutations != mutations)
			@throw [OFEnumerationMutationException

Modified src/OFMutableDictionary.h from [463267262c] to [87d84a54c5].

13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27







-
+







 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFDictionary.h"

#ifdef OF_HAVE_BLOCKS
typedef id (^of_dictionary_replace_block_t)(id key, id object, BOOL *stop);
typedef id (^of_dictionary_replace_block_t)(id key, id object, bool *stop);
#endif

/*!
 * @brief An abstract class for storing and changing objects in a dictionary.
 */
@interface OFMutableDictionary: OFDictionary
/*!

Modified src/OFMutableDictionary.m from [00eb95393f] to [e6fd44030a].

195
196
197
198
199
200
201
202

203
204
205
206
207
208
209
210
211
212
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211
212







-
+










	return [[OFDictionary alloc] initWithDictionary: self];
}

#ifdef OF_HAVE_BLOCKS
- (void)replaceObjectsUsingBlock: (of_dictionary_replace_block_t)block
{
	[self enumerateKeysAndObjectsUsingBlock: ^ (id key, id object,
	    BOOL *stop) {
	    bool *stop) {
		[self setObject: block(key, object, stop)
			 forKey: key];
	}];
}
#endif

- (void)makeImmutable
{
}
@end

Modified src/OFMutableDictionary_hashtable.m from [62c70227b5] to [09bf9855b2].

60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74







-
+







}

#ifdef OF_HAVE_BLOCKS
- (void)replaceObjectsUsingBlock: (of_dictionary_replace_block_t)block
{
	@try {
		[_mapTable replaceValuesUsingBlock:
		    ^ void* (void *key, void *value, BOOL *stop) {
		    ^ void* (void *key, void *value, bool *stop) {
			return block(key, value, stop);
		}];
	} @catch (OFEnumerationMutationException *e) {
		@throw [OFEnumerationMutationException
		    exceptionWithClass: [self class]
				object: self];
	}

Modified src/OFMutableString.m from [bfd221d698] to [ab8d403b2b].

266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280







-
+







		     wordMiddleTable: (const of_unichar_t *const[])middleTable
		  wordStartTableSize: (size_t)startTableSize
		 wordMiddleTableSize: (size_t)middleTableSize
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];
	size_t i, length = [self length];
	BOOL isStart = YES;
	bool isStart = true;

	for (i = 0; i < length; i++) {
		const of_unichar_t *const *table;
		size_t tableSize;
		of_unichar_t c = characters[i];

		if (isStart) {
290
291
292
293
294
295
296
297

298
299
300

301
302
303
304
305
306
307
290
291
292
293
294
295
296

297
298
299

300
301
302
303
304
305
306
307







-
+


-
+







				   atIndex: i];

		switch (c) {
		case ' ':
		case '\t':
		case '\n':
		case '\r':
			isStart = YES;
			isStart = true;
			break;
		default:
			isStart = NO;
			isStart = false;
			break;
		}
	}

	objc_autoreleasePoolPop(pool);
}

Modified src/OFMutableString_UTF8.m from [8a8377795b] to [50da202bb8].

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
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







-
+




















-
+







-
+












-
+


-
+







+ (void)initialize
{
	if (self == [OFMutableString_UTF8 class])
		[self inheritMethodsFromClass: [OFString_UTF8 class]];
}

- initWithUTF8StringNoCopy: (char*)UTF8String
	      freeWhenDone: (BOOL)freeWhenDone
	      freeWhenDone: (bool)freeWhenDone
{
	@try {
		self = [self initWithUTF8String: UTF8String];
	} @finally {
		if (freeWhenDone)
			free(UTF8String);
	}

	return self;
}

- (void)OF_convertWithWordStartTable: (const of_unichar_t *const[])startTable
		     wordMiddleTable: (const of_unichar_t *const[])middleTable
		  wordStartTableSize: (size_t)startTableSize
		 wordMiddleTableSize: (size_t)middleTableSize
{
	of_unichar_t *unicodeString;
	size_t unicodeLen, newCStringLength;
	size_t i, j;
	char *newCString;
	BOOL isStart = YES;
	bool isStart = true;

	if (!_s->isUTF8) {
		uint8_t t;
		const of_unichar_t *const *table;

		assert(startTableSize >= 1 && middleTableSize >= 1);

		_s->hashed = NO;
		_s->hashed = false;

		for (i = 0; i < _s->cStringLength; i++) {
			if (isStart)
				table = startTable;
			else
				table = middleTable;

			switch (_s->cString[i]) {
			case ' ':
			case '\t':
			case '\n':
			case '\r':
				isStart = YES;
				isStart = true;
				break;
			default:
				isStart = NO;
				isStart = false;
				break;
			}

			if ((t = table[0][(uint8_t)_s->cString[i]]) != 0)
				_s->cString[i] = t;
		}

132
133
134
135
136
137
138
139

140
141
142

143
144
145
146
147
148
149
132
133
134
135
136
137
138

139
140
141

142
143
144
145
146
147
148
149







-
+


-
+







		}

		switch (c) {
		case ' ':
		case '\t':
		case '\n':
		case '\r':
			isStart = YES;
			isStart = true;
			break;
		default:
			isStart = NO;
			isStart = false;
			break;
		}

		if (c >> 8 < tableSize) {
			of_unichar_t tc = table[c >> 8][c & 0xFF];

			if (tc)
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205







-
+







	}

	assert(j == newCStringLength);
	newCString[j] = 0;
	[self freeMemory: unicodeString];

	[self freeMemory: _s->cString];
	_s->hashed = NO;
	_s->hashed = false;
	_s->cString = newCString;
	_s->cStringLength = newCStringLength;

	/*
	 * Even though cStringLength can change, length cannot, therefore no
	 * need to change it.
	 */
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
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







-
+













-
+


















-
+







		    _s->cStringLength);

	if (index > _s->cStringLength)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	/* Shortcut if old and new character both are ASCII */
	if (!(character & 0x80) && !(_s->cString[index] & 0x80)) {
		_s->hashed = NO;
		_s->hashed = false;
		_s->cString[index] = character;
		return;
	}

	if ((lenNew = of_string_utf8_encode(character, buffer)) == 0)
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];

	if ((lenOld = of_string_utf8_decode(_s->cString + index,
	    _s->cStringLength - index, &c)) == 0)
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];

	_s->hashed = NO;
	_s->hashed = false;

	if (lenNew == lenOld)
		memcpy(_s->cString + index, buffer, lenNew);
	else if (lenNew > lenOld) {
		_s->cString = [self resizeMemory: _s->cString
					    size: _s->cStringLength -
						  lenOld + lenNew + 1];

		memmove(_s->cString + index + lenNew,
		    _s->cString + index + lenOld,
		    _s->cStringLength - index - lenOld);
		memcpy(_s->cString + index, buffer, lenNew);

		_s->cStringLength -= lenOld;
		_s->cStringLength += lenNew;
		_s->cString[_s->cStringLength] = '\0';

		if (character & 0x80)
			_s->isUTF8 = YES;
			_s->isUTF8 = true;
	} else if (lenNew < lenOld) {
		memmove(_s->cString + index + lenNew,
		    _s->cString + index + lenOld,
		    _s->cStringLength - index - lenOld);
		memcpy(_s->cString + index, buffer, lenNew);

		_s->cStringLength -= lenOld;
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298

299
300
301
302
303
304
305
284
285
286
287
288
289
290

291
292
293
294
295
296
297

298
299
300
301
302
303
304
305







-
+






-
+







	if (UTF8StringLength >= 3 && !memcmp(UTF8String, "\xEF\xBB\xBF", 3)) {
		UTF8String += 3;
		UTF8StringLength -= 3;
	}

	switch (of_string_utf8_check(UTF8String, UTF8StringLength, &length)) {
	case 1:
		_s->isUTF8 = YES;
		_s->isUTF8 = true;
		break;
	case -1:
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];
	}

	_s->hashed = NO;
	_s->hashed = false;
	_s->cString = [self resizeMemory: _s->cString
				    size: _s->cStringLength +
					  UTF8StringLength + 1];
	memcpy(_s->cString + _s->cStringLength, UTF8String,
	    UTF8StringLength + 1);

	_s->cStringLength += UTF8StringLength;
314
315
316
317
318
319
320
321

322
323
324
325
326
327
328

329
330
331
332
333
334
335
314
315
316
317
318
319
320

321
322
323
324
325
326
327

328
329
330
331
332
333
334
335







-
+






-
+







	if (UTF8StringLength >= 3 && !memcmp(UTF8String, "\xEF\xBB\xBF", 3)) {
		UTF8String += 3;
		UTF8StringLength -= 3;
	}

	switch (of_string_utf8_check(UTF8String, UTF8StringLength, &length)) {
	case 1:
		_s->isUTF8 = YES;
		_s->isUTF8 = true;
		break;
	case -1:
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];
	}

	_s->hashed = NO;
	_s->hashed = false;
	_s->cString = [self resizeMemory: _s->cString
				    size: _s->cStringLength +
					  UTF8StringLength + 1];
	memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength);

	_s->cStringLength += UTF8StringLength;
	_s->length += length;
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386
387
388
389
390
391

392
393

394
395
396
397
398
399
400
401
402
403
404

405
406
407
408
409
410
411
412
413
414

415
416
417
418
419
420
421

422
423
424
425
426
427
428

429
430
431
432
433
434
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450
451

452
453
454
455
456
457
458
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

391
392

393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420

421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458







-
+














-
+

-
+










-
+









-
+






-
+






-
+













-
+








-
+







	if (string == nil)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	UTF8StringLength = [string UTF8StringLength];

	_s->hashed = NO;
	_s->hashed = false;
	_s->cString = [self resizeMemory: _s->cString
				    size: _s->cStringLength +
					  UTF8StringLength + 1];
	memcpy(_s->cString + _s->cStringLength, [string UTF8String],
	    UTF8StringLength);

	_s->cStringLength += UTF8StringLength;
	_s->length += [string length];

	_s->cString[_s->cStringLength] = 0;

	if ([string isKindOfClass: [OFString_UTF8 class]] ||
	    [string isKindOfClass: [OFMutableString_UTF8 class]]) {
		if (((OFString_UTF8*)string)->_s->isUTF8)
			_s->isUTF8 = YES;
			_s->isUTF8 = true;
	} else
		_s->isUTF8 = YES;
		_s->isUTF8 = true;
}

- (void)appendCharacters: (of_unichar_t*)characters
		  length: (size_t)length
{
	char *tmp;

	tmp = [self allocMemoryWithSize: (length * 4) + 1];
	@try {
		size_t i, j = 0;
		BOOL isUTF8 = NO;
		bool isUTF8 = false;

		for (i = 0; i < length; i++) {
			char buffer[4];

			switch (of_string_utf8_encode(characters[i], buffer)) {
			case 1:
				tmp[j++] = buffer[0];
				break;
			case 2:
				isUTF8 = YES;
				isUTF8 = true;

				memcpy(tmp + j, buffer, 2);
				j += 2;

				break;
			case 3:
				isUTF8 = YES;
				isUTF8 = true;

				memcpy(tmp + j, buffer, 3);
				j += 3;

				break;
			case 4:
				isUTF8 = YES;
				isUTF8 = true;

				memcpy(tmp + j, buffer, 4);
				j += 4;

				break;
			default:
				@throw [OFInvalidEncodingException
				    exceptionWithClass: [self class]];
			}
		}

		tmp[j] = '\0';

		_s->hashed = NO;
		_s->hashed = false;
		_s->cString = [self resizeMemory: _s->cString
					    size: _s->cStringLength + j + 1];
		memcpy(_s->cString + _s->cStringLength, tmp, j + 1);

		_s->cStringLength += j;
		_s->length += length;

		if (isUTF8)
			_s->isUTF8 = YES;
			_s->isUTF8 = true;
	} @finally {
		[self freeMemory: tmp];
	}
}

- (void)appendFormat: (OFConstantString*)format
	   arguments: (va_list)arguments
478
479
480
481
482
483
484
485

486
487
488
489
490
491
492
478
479
480
481
482
483
484

485
486
487
488
489
490
491
492







-
+







	}
}

- (void)reverse
{
	size_t i, j;

	_s->hashed = NO;
	_s->hashed = false;

	/* We reverse all bytes and restore UTF-8 later, if necessary */
	for (i = 0, j = _s->cStringLength - 1; i < _s->cStringLength / 2;
	    i++, j--) {
		_s->cString[i] ^= _s->cString[j];
		_s->cString[j] ^= _s->cString[i];
		_s->cString[i] ^= _s->cString[j];
573
574
575
576
577
578
579
580

581
582
583
584
585
586
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
612
613
614
615
616
617
618

619
620
621
622
623
624
625
573
574
575
576
577
578
579

580
581
582
583
584
585
586
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
612
613
614
615
616
617

618
619
620
621
622
623
624
625







-
+















-
+

-
+



















-
+







		    exceptionWithClass: [self class]];

	if (_s->isUTF8)
		index = of_string_utf8_get_position(_s->cString, index,
		    _s->cStringLength);

	newCStringLength = _s->cStringLength + [string UTF8StringLength];
	_s->hashed = NO;
	_s->hashed = false;
	_s->cString = [self resizeMemory: _s->cString
				    size: newCStringLength + 1];

	memmove(_s->cString + index + [string UTF8StringLength],
	    _s->cString + index, _s->cStringLength - index);
	memcpy(_s->cString + index, [string UTF8String],
	    [string UTF8StringLength]);
	_s->cString[newCStringLength] = '\0';

	_s->cStringLength = newCStringLength;
	_s->length += [string length];

	if ([string isKindOfClass: [OFString_UTF8 class]] ||
	    [string isKindOfClass: [OFMutableString_UTF8 class]]) {
		if (((OFString_UTF8*)string)->_s->isUTF8)
			_s->isUTF8 = YES;
			_s->isUTF8 = true;
	} else
		_s->isUTF8 = YES;
		_s->isUTF8 = true;
}

- (void)deleteCharactersInRange: (of_range_t)range
{
	size_t start = range.location;
	size_t end = range.location + range.length;

	if (range.length > SIZE_MAX - range.location || end > _s->length)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	if (_s->isUTF8) {
		start = of_string_utf8_get_position(_s->cString, start,
		    _s->cStringLength);
		end = of_string_utf8_get_position(_s->cString, end,
		    _s->cStringLength);
	}

	memmove(_s->cString + start, _s->cString + end,
	    _s->cStringLength - end);
	_s->hashed = NO;
	_s->hashed = false;
	_s->length -= range.length;
	_s->cStringLength -= end - start;
	_s->cString[_s->cStringLength] = 0;

	@try {
		_s->cString = [self resizeMemory: _s->cString
					    size: _s->cStringLength + 1];
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659







-
+







		    _s->cStringLength);
		end = of_string_utf8_get_position(_s->cString, end,
		    _s->cStringLength);
	}

	newCStringLength = _s->cStringLength - (end - start) +
	    [replacement UTF8StringLength];
	_s->hashed = NO;
	_s->hashed = false;
	_s->cString = [self resizeMemory: _s->cString
				    size: newCStringLength + 1];

	memmove(_s->cString + start + [replacement UTF8StringLength],
	    _s->cString + end, _s->cStringLength - end);
	memcpy(_s->cString + start, [replacement UTF8String],
	    [replacement UTF8StringLength]);
730
731
732
733
734
735
736
737

738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753

754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773

774
775
776
777
778
779
780
730
731
732
733
734
735
736

737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752

753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772

773
774
775
776
777
778
779
780







-
+















-
+



















-
+







	}
	memcpy(newCString + newCStringLength, _s->cString + last,
	    _s->cStringLength - last);
	newCStringLength += _s->cStringLength - last;
	newCString[newCStringLength] = 0;

	[self freeMemory: _s->cString];
	_s->hashed = NO;
	_s->hashed = false;
	_s->cString = newCString;
	_s->cStringLength = newCStringLength;
	_s->length = newLength;
}

- (void)deleteLeadingWhitespaces
{
	size_t i;

	for (i = 0; i < _s->cStringLength; i++)
		if (_s->cString[i] != ' '  && _s->cString[i] != '\t' &&
		    _s->cString[i] != '\n' && _s->cString[i] != '\r' &&
		    _s->cString[i] != '\f')
			break;

	_s->hashed = NO;
	_s->hashed = false;
	_s->cStringLength -= i;
	_s->length -= i;

	memmove(_s->cString, _s->cString + i, _s->cStringLength);
	_s->cString[_s->cStringLength] = '\0';

	@try {
		_s->cString = [self resizeMemory: _s->cString
					    size: _s->cStringLength + 1];
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
	}
}

- (void)deleteTrailingWhitespaces
{
	size_t d;
	char *p;

	_s->hashed = NO;
	_s->hashed = false;

	d = 0;
	for (p = _s->cString + _s->cStringLength - 1; p >= _s->cString; p--) {
		if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r' &&
		    *p != '\f')
			break;

794
795
796
797
798
799
800
801

802
803
804
805
806
807
808
794
795
796
797
798
799
800

801
802
803
804
805
806
807
808







-
+







}

- (void)deleteEnclosingWhitespaces
{
	size_t d, i;
	char *p;

	_s->hashed = NO;
	_s->hashed = false;

	d = 0;
	for (p = _s->cString + _s->cStringLength - 1; p >= _s->cString; p--) {
		if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r' &&
		    *p != '\f')
			break;

Modified src/OFMutex.h from [4850473658] to [6538afa12e].

21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38







-
+











/*!
 * @brief A class for creating mutual exclusions.
 */
@interface OFMutex: OFObject <OFLocking>
{
	of_mutex_t _mutex;
	BOOL _initialized;
	bool _initialized;
	OFString *_name;
}

/*!
 * @brief Creates a new mutex.
 *
 * @return A new autoreleased mutex.
 */
+ (instancetype)mutex;
@end

Modified src/OFMutex.m from [d5036265a2] to [c030ce7087].

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
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







-
+











-
+













-
+




-
+








	if (!of_mutex_new(&_mutex)) {
		Class c = [self class];
		[self release];
		@throw [OFInitializationFailedException exceptionWithClass: c];
	}

	_initialized = YES;
	_initialized = true;

	return self;
}

- (void)lock
{
	if (!of_mutex_lock(&_mutex))
		@throw [OFLockFailedException exceptionWithClass: [self class]
							    lock: self];
}

- (BOOL)tryLock
- (bool)tryLock
{
	return of_mutex_trylock(&_mutex);
}

- (void)unlock
{
	if (!of_mutex_unlock(&_mutex))
		@throw [OFUnlockFailedException exceptionWithClass: [self class]
							      lock: self];
}

- (void)setName: (OFString*)name
{
	OF_SETTER(_name, name, YES, 1)
	OF_SETTER(_name, name, true, 1)
}

- (OFString*)name
{
	OF_GETTER(_name, YES)
	OF_GETTER(_name, true)
}

- (OFString*)description
{
	if (_name == nil)
		return [super description];

Modified src/OFNumber.h from [afb39b7429] to [29b807402b].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44







-
+








/*! @file */

/*!
 * @brief The C type of a number stored in an OFNumber.
 */
typedef enum of_number_type_t {
	/*! BOOL */
	/*! bool */
	OF_NUMBER_BOOL		= 0x01,
	/*! unsigned char */
	OF_NUMBER_UCHAR		= 0x02,
	/*! unsigned short */
	OF_NUMBER_USHORT	= 0x03,
	/*! unsigned int */
	OF_NUMBER_UINT		= 0x04,
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110







-
+







/*!
 * @brief Provides a way to store a number in an object.
 */
@interface OFNumber: OFObject <OFCopying, OFComparing, OFSerialization,
    OFJSONRepresentation, OFBinaryPackRepresentation>
{
	union of_number_value {
		BOOL		   bool_;
		bool		   bool_;
		signed char	   schar;
		signed short	   sshort;
		signed int	   sint;
		signed long	   slong;
		signed long long   slonglong;
		unsigned char	   uchar;
		unsigned short	   ushort;
133
134
135
136
137
138
139
140

141
142

143
144
145

146
147
148
149
150
151
152
133
134
135
136
137
138
139

140
141

142
143
144

145
146
147
148
149
150
151
152







-
+

-
+


-
+







}

#ifdef OF_HAVE_PROPERTIES
@property (readonly) of_number_type_t type;
#endif

/*!
 * @brief Creates a new OFNumber with the specified BOOL.
 * @brief Creates a new OFNumber with the specified bool.
 *
 * @param bool_ A BOOL which the OFNumber should contain
 * @param bool_ A bool which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithBool: (BOOL)bool_;
+ (instancetype)numberWithBool: (bool)bool_;

/*!
 * @brief Creates a new OFNumber with the specified signed char.
 *
 * @param schar A signed char which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
357
358
359
360
361
362
363
364

365
366

367
368
369

370
371
372
373
374
375
376
357
358
359
360
361
362
363

364
365

366
367
368

369
370
371
372
373
374
375
376







-
+

-
+


-
+







 *
 * @param double_ A double which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithDouble: (double)double_;

/*!
 * @brief Initializes an already allocated OFNumber with the specified BOOL.
 * @brief Initializes an already allocated OFNumber with the specified bool.
 *
 * @param bool_ A BOOL which the OFNumber should contain
 * @param bool_ A bool which the OFNumber should contain
 * @return An initialized OFNumber
 */
- initWithBool: (BOOL)bool_;
- initWithBool: (bool)bool_;

/*!
 * @brief Initializes an already allocated OFNumber with the specified signed
 *	  char.
 *
 * @param schar A signed char which the OFNumber should contain
 * @return An initialized OFNumber
601
602
603
604
605
606
607
608

609
610

611
612

613
614
615
616
617
618
619
601
602
603
604
605
606
607

608
609

610
611

612
613
614
615
616
617
618
619







-
+

-
+

-
+







 * @brief Returns the type of the number.
 *
 * @return An of_number_type_t indicating the type of the number
 */
- (of_number_type_t)type;

/*!
 * @brief Returns the OFNumber as a BOOL.
 * @brief Returns the OFNumber as a bool.
 *
 * @return The OFNumber as a BOOL
 * @return The OFNumber as a bool
 */
- (BOOL)boolValue;
- (bool)boolValue;

/*!
 * @brief Returns the OFNumber as a signed char.
 *
 * @return The OFNumber as a signed char
 */
- (signed char)charValue;

Modified src/OFNumber.m from [c13a2ddb4a] to [c9cabca4f9].

339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353







-
+







		return [OFNumber numberWithDouble: _value.double_ o];	\
	default:							\
		@throw [OFInvalidFormatException			\
		    exceptionWithClass: [self class]];			\
	}

@implementation OFNumber
+ (instancetype)numberWithBool: (BOOL)bool_
+ (instancetype)numberWithBool: (bool)bool_
{
	return [[[self alloc] initWithBool: bool_] autorelease];
}

+ (instancetype)numberWithChar: (signed char)schar
{
	return [[[self alloc] initWithChar: schar] autorelease];
491
492
493
494
495
496
497
498

499
500
501
502

503
504
505
506
507
508
509
491
492
493
494
495
496
497

498
499
500
501

502
503
504
505
506
507
508
509







-
+



-
+







		[self release];
		@throw e;
	}

	abort();
}

- initWithBool: (BOOL)bool_
- initWithBool: (bool)bool_
{
	self = [super init];

	_value.bool_ = (bool_ ? YES : NO);
	_value.bool_ = bool_;
	_type = OF_NUMBER_BOOL;

	return self;
}

- initWithChar: (signed char)schar
{
790
791
792
793
794
795
796
797
798
799
800




801
802
803
804
805
806
807
790
791
792
793
794
795
796




797
798
799
800
801
802
803
804
805
806
807







-
-
-
-
+
+
+
+







				      selector: _cmd];

		typeString = [[element attributeForName: @"type"] stringValue];

		if ([typeString isEqual: @"boolean"]) {
			_type = OF_NUMBER_BOOL;

			if ([[element stringValue] isEqual: @"YES"])
				_value.bool_ = YES;
			else if ([[element stringValue] isEqual: @"NO"])
				_value.bool_ = NO;
			if ([[element stringValue] isEqual: @"true"])
				_value.bool_ = true;
			else if ([[element stringValue] isEqual: @"false"])
				_value.bool_ = false;
			else
				@throw [OFInvalidArgumentException
				    exceptionWithClass: [self class]
					      selector: _cmd];
		} else if ([typeString isEqual: @"unsigned"]) {
			/*
			 * FIXME: This will fail if the value is bigger than
847
848
849
850
851
852
853
854

855
856
857
858

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
847
848
849
850
851
852
853

854
855



856


























































857
858
859
860
861
862
863







-
+

-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







}

- (of_number_type_t)type
{
	return _type;
}

- (BOOL)boolValue
- (bool)boolValue
{
	switch (_type) {
	case OF_NUMBER_BOOL:
		return !!_value.bool_;
	RETURN_AS(bool)
	case OF_NUMBER_CHAR:
		return !!_value.schar;
	case OF_NUMBER_SHORT:
		return !!_value.sshort;
	case OF_NUMBER_INT:
		return !!_value.sint;
	case OF_NUMBER_LONG:
		return !!_value.slong;
	case OF_NUMBER_LONGLONG:
		return !!_value.slonglong;
	case OF_NUMBER_UCHAR:
		return !!_value.uchar;
	case OF_NUMBER_USHORT:
		return !!_value.ushort;
	case OF_NUMBER_UINT:
		return !!_value.uint;
	case OF_NUMBER_ULONG:
		return !!_value.ulong;
	case OF_NUMBER_ULONGLONG:
		return !!_value.ulonglong;
	case OF_NUMBER_INT8:
		return !!_value.int8;
	case OF_NUMBER_INT16:
		return !!_value.int16;
	case OF_NUMBER_INT32:
		return !!_value.int32;
	case OF_NUMBER_INT64:
		return !!_value.int64;
	case OF_NUMBER_UINT8:
		return !!_value.uint8;
	case OF_NUMBER_UINT16:
		return !!_value.uint16;
	case OF_NUMBER_UINT32:
		return !!_value.uint32;
	case OF_NUMBER_UINT64:
		return !!_value.uint64;
	case OF_NUMBER_SIZE:
		return !!_value.size;
	case OF_NUMBER_SSIZE:
		return !!_value.ssize;
	case OF_NUMBER_INTMAX:
		return !!_value.intmax;
	case OF_NUMBER_UINTMAX:
		return !!_value.uintmax;
	case OF_NUMBER_PTRDIFF:
		return !!_value.ptrdiff;
	case OF_NUMBER_INTPTR:
		return !!_value.intptr;
	case OF_NUMBER_UINTPTR:
		return !!_value.uintptr;
	case OF_NUMBER_FLOAT:
		return !!_value.float_;
	case OF_NUMBER_DOUBLE:
		return !!_value.double_;
	default:
		@throw [OFInvalidFormatException
		    exceptionWithClass: [self class]];
	}
}

- (signed char)charValue
{
	RETURN_AS(signed char)
}

1047
1048
1049
1050
1051
1052
1053
1054

1055
1056
1057
1058
1059

1060
1061
1062
1063
1064
1065
1066
987
988
989
990
991
992
993

994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
1006







-
+




-
+







}

- (double)doubleValue
{
	RETURN_AS(double)
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFNumber *number;

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

	number = object;

	if (_type & OF_NUMBER_FLOAT || number->_type & OF_NUMBER_FLOAT)
		return ([number doubleValue] == [self doubleValue]);

	if (_type & OF_NUMBER_SIGNED || number->_type & OF_NUMBER_SIGNED)
1329
1330
1331
1332
1333
1334
1335
1336

1337
1338
1339
1340
1341
1342
1343
1269
1270
1271
1272
1273
1274
1275

1276
1277
1278
1279
1280
1281
1282
1283







-
+








- (OFString*)description
{
	OFMutableString *ret;

	switch (_type) {
	case OF_NUMBER_BOOL:
		return (_value.bool_ ? @"YES" : @"NO");
		return (_value.bool_ ? @"true" : @"false");
	case OF_NUMBER_UCHAR:
	case OF_NUMBER_USHORT:
	case OF_NUMBER_UINT:
	case OF_NUMBER_ULONG:
	case OF_NUMBER_ULONGLONG:
	case OF_NUMBER_UINT8:
	case OF_NUMBER_UINT16:

Modified src/OFObject.h from [c49016d190] to [668397dc9b].

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
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







-
+








-
+








-
+







-
+








/*!
 * @brief Returns a boolean whether the object of the specified kind.
 *
 * @param class_ The class whose kind is checked
 * @return A boolean whether the object is of the specified kind
 */
- (BOOL)isKindOfClass: (Class)class_;
- (bool)isKindOfClass: (Class)class_;

/*!
 * @brief Returns a boolean whether the object is a member of the specified
 *	  class.
 *
 * @param class_ The class for which the receiver is checked
 * @return A boolean whether the object is a member of the specified class
 */
- (BOOL)isMemberOfClass: (Class)class_;
- (bool)isMemberOfClass: (Class)class_;

/*!
 * @brief Returns a boolean whether the object responds to the specified
 *	  selector.
 *
 * @param selector The selector which should be checked for respondance
 * @return A boolean whether the objects responds to the specified selector
 */
- (BOOL)respondsToSelector: (SEL)selector;
- (bool)respondsToSelector: (SEL)selector;

/*!
 * @brief Checks whether the object conforms to the specified protocol.
 *
 * @param protocol The protocol which should be checked for conformance
 * @return A boolean whether the object conforms to the specified protocol
 */
- (BOOL)conformsToProtocol: (Protocol*)protocol;
- (bool)conformsToProtocol: (Protocol*)protocol;

/*!
 * @brief Returns the implementation for the specified selector.
 *
 * @param selector The selector for which the method should be returned
 * @return The implementation for the specified selector
 */
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295







-
+







 *
 * @warning If you reimplement this, you also need to reimplement @ref hash to
 *	    return the same hash for objects which are equal!
 *
 * @param object The object which should be tested for equality
 * @return A boolean whether the object is equal to the specified object
 */
- (BOOL)isEqual: (id)object;
- (bool)isEqual: (id)object;

/*!
 * @brief Calculates a hash for the object.
 *
 * Classes containing data (like strings, arrays, lists etc.) should reimplement
 * this!
 *
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354







-
+







- self;

/*!
 * @brief Returns whether the object is a proxy object.
 *
 * @return A boolean whether the object is a proxy object
 */
- (BOOL)isProxy;
- (bool)isProxy;
@end

/*!
 * @brief The root class for all other classes inside ObjFW.
 */
@interface OFObject <OFObject>
{
410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433

434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
410
411
412
413
414
415
416

417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440

441
442
443
444
445
446
447
448







-
+















-
+







-
+







/*!
 * @brief Returns a boolean whether the class is a subclass of the specified
 *	  class.
 *
 * @param class_ The class which is checked for being a superclass
 * @return A boolean whether the class is a subclass of the specified class
 */
+ (BOOL)isSubclassOfClass: (Class)class_;
+ (bool)isSubclassOfClass: (Class)class_;

/*!
 * @brief Returns the superclass of the class.
 *
 * @return The superclass of the class
 */
+ (Class)superclass;

/*!
 * @brief Checks whether instances of the class respond to a given selector.
 *
 * @param selector The selector which should be checked for respondance
 * @return A boolean whether instances of the class respond to the specified
 *	   selector
 */
+ (BOOL)instancesRespondToSelector: (SEL)selector;
+ (bool)instancesRespondToSelector: (SEL)selector;

/*!
 * @brief Checks whether the class conforms to a given protocol.
 *
 * @param protocol The protocol which should be checked for conformance
 * @return A boolean whether the class conforms to the specified protocol
 */
+ (BOOL)conformsToProtocol: (Protocol*)protocol;
+ (bool)conformsToProtocol: (Protocol*)protocol;

/*!
 * @brief Returns the implementation of the instance method for the specified
 *	  selector.
 *
 * @param selector The selector for which the method should be returned
 * @return The implementation of the instance method for the specified selector
545
546
547
548
549
550
551
552

553
554
555
556
557
558
559
560
561
562

563
564
565
566
567
568
569
545
546
547
548
549
550
551

552
553
554
555
556
557
558
559
560
561

562
563
564
565
566
567
568
569







-
+









-
+







 * @brief Try to resolve the specified class method.
 *
 * This method is called if a class method was not found, so that an
 * implementation can be provided at runtime.
 *
 * @return Whether the method has been added to the class
 */
+ (BOOL)resolveClassMethod: (SEL)selector;
+ (bool)resolveClassMethod: (SEL)selector;

/*!
 * @brief Try to resolve the specified instance method.
 *
 * This method is called if an instance method was not found, so that an
 * implementation can be provided at runtime.
 *
 * @return Whether the method has been added to the class
 */
+ (BOOL)resolveInstanceMethod: (SEL)selector;
+ (bool)resolveInstanceMethod: (SEL)selector;

/*!
 * @brief Initializes an already allocated object.
 *
 * Derived classes may override this, but need to do
 * @code
 *   self = [super init]
706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
721
722
723
724
725
726
727
728

729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746

747
748
749
750
751
752
753
754
755

756
757
758
759
760
761
762
763
764
765
766
767
768

769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784

785
786
787
788
789
790
791
706
707
708
709
710
711
712

713
714
715
716
717
718
719
720
721
722
723
724
725
726
727

728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745

746
747
748
749
750
751
752
753
754

755
756
757
758
759
760
761
762
763
764
765
766
767

768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783

784
785
786
787
788
789
790
791







-
+














-
+

















-
+








-
+












-
+















-
+







 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param waitUntilDone Whether to wait until the perform finished
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	  waitUntilDone: (BOOL)waitUntilDone;
	  waitUntilDone: (bool)waitUntilDone;

/*!
 * @brief Performs the specified selector on the specified thread with the
 *	  specified object.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param object The object that is passed to the method specified by the
 *		 selector
 * @param waitUntilDone Whether to wait until the perform finished
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	     withObject: (id)object
	  waitUntilDone: (BOOL)waitUntilDone;
	  waitUntilDone: (bool)waitUntilDone;

/*!
 * @brief Performs the specified selector on the specified thread with the
 *	  specified objects.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param object1 The first object that is passed to the method specified by the
 *		 selector
 * @param object2 The second object that is passed to the method specified by
 *		  the selector
 * @param waitUntilDone Whether to wait until the perform finished
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	     withObject: (id)object1
	     withObject: (id)object2
	  waitUntilDone: (BOOL)waitUntilDone;
	  waitUntilDone: (bool)waitUntilDone;

/*!
 * @brief Performs the specified selector on the main thread.
 *
 * @param selector The selector to perform
 * @param waitUntilDone Whether to wait until the perform finished
 */
- (void)performSelectorOnMainThread: (SEL)selector
		      waitUntilDone: (BOOL)waitUntilDone;
		      waitUntilDone: (bool)waitUntilDone;

/*!
 * @brief Performs the specified selector on the main thread with the specified
 *	  object.
 *
 * @param selector The selector to perform
 * @param object The object that is passed to the method specified by the
 *		 selector
 * @param waitUntilDone Whether to wait until the perform finished
 */
- (void)performSelectorOnMainThread: (SEL)selector
			 withObject: (id)object
		      waitUntilDone: (BOOL)waitUntilDone;
		      waitUntilDone: (bool)waitUntilDone;

/*!
 * @brief Performs the specified selector on the main thread with the specified
 *	  objects.
 *
 * @param selector The selector to perform
 * @param object1 The first object that is passed to the method specified by the
 *		 selector
 * @param object2 The second object that is passed to the method specified by
 *		  the selector
 * @param waitUntilDone Whether to wait until the perform finished
 */
- (void)performSelectorOnMainThread: (SEL)selector
			 withObject: (id)object1
			 withObject: (id)object2
		      waitUntilDone: (BOOL)waitUntilDone;
		      waitUntilDone: (bool)waitUntilDone;

/*!
 * @brief Performs the specified selector on the specified thread after the
 *	  specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
827
828
829
830
831
832
833
834

835
836
837
838
839
840
841
827
828
829
830
831
832
833

834
835
836
837
838
839
840
841







-
+







	     withObject: (id)object1
	     withObject: (id)object2
	     afterDelay: (double)delay;
#endif

/*!
 * @brief This method is called when @ref resolveClassMethod: or
 *	  @ref resolveInstanceMethod: returned NO. It should return a target
 *	  @ref resolveInstanceMethod: returned false. It should return a target
 *	  to which the message should be forwarded.
 *
 * @note When the message should not be forwarded, you should not return nil,
 *	 but instead return the result of the superclass!
 *
 * @return The target to forward the message to
 */

Modified src/OFObject.m from [68901c9b91] to [2d5ba7013a].

131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160







-
+














-
+







{
	/* Try resolveClassMethod:/resolveInstanceMethod: */
	if (class_isMetaClass(object_getClass(obj))) {
		if ([obj respondsToSelector: @selector(resolveClassMethod:)] &&
		    [obj resolveClassMethod: sel]) {
			if (![obj respondsToSelector: sel]) {
				fprintf(stderr, "Runtime error: [%s "
				    "resolveClassMethod: %s] returned YES "
				    "resolveClassMethod: %s] returned true "
				    "without adding the method!\n",
				    class_getName(obj), sel_getName(sel));
				abort();
			}

			return objc_msg_lookup(obj, sel);
		}
	} else {
		Class c = object_getClass(obj);

		if ([c respondsToSelector: @selector(resolveInstanceMethod:)] &&
		    [c resolveInstanceMethod: sel]) {
			if (![obj respondsToSelector: sel]) {
				fprintf(stderr, "Runtime error: [%s "
				    "resolveInstanceMethod: %s] returned YES "
				    "resolveInstanceMethod: %s] returned true "
				    "without adding the method!\n",
				    class_getName(object_getClass(obj)),
				    sel_getName(sel));
				abort();
			}

			return objc_msg_lookup(obj, sel);
290
291
292
293
294
295
296
297

298
299
300
301
302
303

304
305

306
307
308
309
310
311
312
313

314
315
316
317
318

319
320
321
322
323
324

325
326

327
328
329
330
331
332
333
290
291
292
293
294
295
296

297
298
299
300
301
302

303
304

305
306
307
308
309
310
311
312

313
314
315
316
317

318
319
320
321
322
323

324
325

326
327
328
329
330
331
332
333







-
+





-
+

-
+







-
+




-
+





-
+

-
+








+ (OFString*)className
{
	return [OFString stringWithCString: class_getName(self)
				  encoding: OF_STRING_ENCODING_ASCII];
}

+ (BOOL)isSubclassOfClass: (Class)class
+ (bool)isSubclassOfClass: (Class)class
{
	Class iter;

	for (iter = self; iter != Nil; iter = class_getSuperclass(iter))
		if (iter == class)
			return YES;
			return true;

	return NO;
	return false;
}

+ (Class)superclass
{
	return class_getSuperclass(self);
}

+ (BOOL)instancesRespondToSelector: (SEL)selector
+ (bool)instancesRespondToSelector: (SEL)selector
{
	return class_respondsToSelector(self, selector);
}

+ (BOOL)conformsToProtocol: (Protocol*)protocol
+ (bool)conformsToProtocol: (Protocol*)protocol
{
	Class c;

	for (c = self; c != Nil; c = class_getSuperclass(c))
		if (class_conformsToProtocol(c, protocol))
			return YES;
			return true;

	return NO;
	return false;
}

+ (IMP)instanceMethodForSelector: (SEL)selector
{
	return class_getMethodImplementation(self, selector);
}

487
488
489
490
491
492
493
494

495
496

497
498
499

500
501

502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520

521
522
523
524
525
526
527

528
529

530
531
532

533
534
535
536
537

538
539
540
541
542

543
544
545
546
547
548
549
487
488
489
490
491
492
493

494
495

496
497
498

499
500

501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519

520
521
522
523
524
525
526

527
528

529
530
531

532
533
534
535
536

537
538
539
540
541

542
543
544
545
546
547
548
549







-
+

-
+


-
+

-
+


















-
+






-
+

-
+


-
+




-
+




-
+







		free(methodList);
	}
#endif

	[self inheritMethodsFromClass: [class superclass]];
}

+ (BOOL)resolveClassMethod: (SEL)selector
+ (bool)resolveClassMethod: (SEL)selector
{
	return NO;
	return false;
}

+ (BOOL)resolveInstanceMethod: (SEL)selector
+ (bool)resolveInstanceMethod: (SEL)selector
{
	return NO;
	return false;
}

- init
{
	return self;
}

- (Class)class
{
	return object_getClass(self);
}

- (OFString*)className
{
	return [OFString stringWithCString: object_getClassName(self)
				  encoding: OF_STRING_ENCODING_ASCII];
}

- (BOOL)isKindOfClass: (Class)class
- (bool)isKindOfClass: (Class)class
{
	Class iter;

	for (iter = object_getClass(self); iter != Nil;
	    iter = class_getSuperclass(iter))
		if (iter == class)
			return YES;
			return true;

	return NO;
	return false;
}

- (BOOL)isMemberOfClass: (Class)class
- (bool)isMemberOfClass: (Class)class
{
	return (object_getClass(self) == class);
}

- (BOOL)respondsToSelector: (SEL)selector
- (bool)respondsToSelector: (SEL)selector
{
	return class_respondsToSelector(object_getClass(self), selector);
}

- (BOOL)conformsToProtocol: (Protocol*)protocol
- (bool)conformsToProtocol: (Protocol*)protocol
{
	return [object_getClass(self) conformsToProtocol: protocol];
}

- (IMP)methodForSelector: (SEL)selector
{
	return class_getMethodImplementation(object_getClass(self), selector);
588
589
590
591
592
593
594
595

596
597
598
599
600
601
602
603
604
605
606
607
608
609
610

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627

628
629
630
631
632
633
634
635

636
637
638
639
640
641

642
643
644
645
646
647
648
649
650
651
652
653

654
655
656
657
658
659
660

661
662
663
664
665
666
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681

682
683
684
685
686
687
688
689
690
691

692
693
694
695
696
697

698
699
700
701
702
703
704
705
706
707
708

709
710
711
712
713
714
715

716
717
718
719
720
721
722
723
724
725
726
727

728
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753

754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769

770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787

788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808

809
810
811
812
813
814
815
588
589
590
591
592
593
594

595
596
597
598
599
600
601
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626

627
628
629
630
631
632
633
634

635
636
637
638
639
640

641
642
643
644
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659

660
661
662
663
664
665
666
667
668
669
670
671
672

673
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688
689
690

691
692
693
694
695
696

697
698
699
700
701
702
703
704
705
706
707

708
709
710
711
712
713
714

715
716
717
718
719
720
721
722
723
724
725
726

727
728
729
730
731
732
733
734

735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752

753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768

769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786

787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807

808
809
810
811
812
813
814
815







-
+














-
+
















-
+







-
+





-
+











-
+






-
+












-
+







-
+









-
+





-
+










-
+






-
+











-
+







-
+

















-
+















-
+

















-
+




















-
+







	     afterDelay: (double)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					repeats: NO];
					repeats: false];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	     withObject: (id)object
	     afterDelay: (double)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					 object: object
					repeats: NO];
					repeats: false];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	     withObject: (id)object1
	     withObject: (id)object2
	     afterDelay: (double)delay
{
	void *pool = objc_autoreleasePoolPush();

	[OFTimer scheduledTimerWithTimeInterval: delay
					 target: self
				       selector: selector
					 object: object1
					 object: object2
					repeats: NO];
					repeats: false];

	objc_autoreleasePoolPop(pool);
}

#ifdef OF_HAVE_THREADS
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	  waitUntilDone: (BOOL)waitUntilDone
	  waitUntilDone: (bool)waitUntilDone
{
	void *pool = objc_autoreleasePoolPush();
	OFTimer *timer = [OFTimer timerWithTimeInterval: 0
						 target: self
					       selector: selector
						repeats: NO];
						repeats: false];
	[[thread runLoop] addTimer: timer];

	if (waitUntilDone)
		[timer waitUntilDone];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	     withObject: (id)object
	  waitUntilDone: (BOOL)waitUntilDone
	  waitUntilDone: (bool)waitUntilDone
{
	void *pool = objc_autoreleasePoolPush();
	OFTimer *timer = [OFTimer timerWithTimeInterval: 0
						 target: self
					       selector: selector
						 object: object
						repeats: NO];
						repeats: false];
	[[thread runLoop] addTimer: timer];

	if (waitUntilDone)
		[timer waitUntilDone];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	     withObject: (id)object1
	     withObject: (id)object2
	  waitUntilDone: (BOOL)waitUntilDone
	  waitUntilDone: (bool)waitUntilDone
{
	void *pool = objc_autoreleasePoolPush();
	OFTimer *timer = [OFTimer timerWithTimeInterval: 0
						 target: self
					       selector: selector
						 object: object1
						 object: object2
						repeats: NO];
						repeats: false];
	[[thread runLoop] addTimer: timer];

	if (waitUntilDone)
		[timer waitUntilDone];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelectorOnMainThread: (SEL)selector
		      waitUntilDone: (BOOL)waitUntilDone
		      waitUntilDone: (bool)waitUntilDone
{
	void *pool = objc_autoreleasePoolPush();
	OFTimer *timer = [OFTimer timerWithTimeInterval: 0
						 target: self
					       selector: selector
						repeats: NO];
						repeats: false];
	[[OFRunLoop mainRunLoop] addTimer: timer];

	if (waitUntilDone)
		[timer waitUntilDone];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelectorOnMainThread: (SEL)selector
			 withObject: (id)object
		      waitUntilDone: (BOOL)waitUntilDone
		      waitUntilDone: (bool)waitUntilDone
{
	void *pool = objc_autoreleasePoolPush();
	OFTimer *timer = [OFTimer timerWithTimeInterval: 0
						 target: self
					       selector: selector
						 object: object
						repeats: NO];
						repeats: false];
	[[OFRunLoop mainRunLoop] addTimer: timer];

	if (waitUntilDone)
		[timer waitUntilDone];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelectorOnMainThread: (SEL)selector
			 withObject: (id)object1
			 withObject: (id)object2
		      waitUntilDone: (BOOL)waitUntilDone
		      waitUntilDone: (bool)waitUntilDone
{
	void *pool = objc_autoreleasePoolPush();
	OFTimer *timer = [OFTimer timerWithTimeInterval: 0
						 target: self
					       selector: selector
						 object: object1
						 object: object2
						repeats: NO];
						repeats: false];
	[[OFRunLoop mainRunLoop] addTimer: timer];

	if (waitUntilDone)
		[timer waitUntilDone];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	     afterDelay: (double)delay
{
	void *pool = objc_autoreleasePoolPush();

	[[thread runLoop] addTimer: [OFTimer timerWithTimeInterval: delay
							    target: self
							  selector: selector
							   repeats: NO]];
							   repeats: false]];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	     withObject: (id)object
	     afterDelay: (double)delay
{
	void *pool = objc_autoreleasePoolPush();

	[[thread runLoop] addTimer: [OFTimer timerWithTimeInterval: delay
							    target: self
							  selector: selector
							    object: object
							   repeats: NO]];
							   repeats: false]];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	     withObject: (id)object1
	     withObject: (id)object2
	     afterDelay: (double)delay
{
	void *pool = objc_autoreleasePoolPush();

	[[thread runLoop] addTimer: [OFTimer timerWithTimeInterval: delay
							    target: self
							  selector: selector
							    object: object1
							    object: object2
							   repeats: NO]];
							   repeats: false]];

	objc_autoreleasePoolPop(pool);
}
#endif

- (const char*)typeEncodingForSelector: (SEL)selector
{
#if defined(OF_OBJFW_RUNTIME)
	return objc_get_type_encoding(object_getClass(self), selector);
#else
	Method m;

	if ((m = class_getInstanceMethod(object_getClass(self),
	    selector)) == NULL)
		return NULL;

	return method_getTypeEncoding(m);
#endif
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	return (self == object);
}

- (uint32_t)hash
{
	uintptr_t ptr = (uintptr_t)self;
1012
1013
1014
1015
1016
1017
1018
1019

1020
1021

1022
1023
1024
1025
1026
1027
1028
1012
1013
1014
1015
1016
1017
1018

1019
1020

1021
1022
1023
1024
1025
1026
1027
1028







-
+

-
+







}

- self
{
	return self;
}

- (BOOL)isProxy
- (bool)isProxy
{
	return NO;
	return false;
}

- (void)dealloc
{
	struct pre_mem *iter;

	objc_destructInstance(self);

Modified src/OFProcess.h from [97b7b3ccc7] to [6ab46f1eca].

41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55







-
+







#ifndef _WIN32
	pid_t _pid;
	int _readPipe[2], _writePipe[2];
#else
	HANDLE _process, _readPipe[2], _writePipe[2];
#endif
	int _status;
	BOOL _atEndOfStream;
	bool _atEndOfStream;
}

/*!
 * @brief Creates a new OFProcess with the specified program and invokes the
 *	  program.
 *
 * @param program The program to execute. If it does not start with a slash, the

Modified src/OFProcess.m from [ef90137219] to [c2449bdcce].

223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237







-
+







			[argumentsString appendString: @"\""];
		}

		enumerator = [arguments objectEnumerator];
		while ((argument = [enumerator nextObject]) != nil) {
			OFMutableString *tmp =
			    [[argument mutableCopy] autorelease];
			BOOL containsSpaces = [tmp containsString: @" "];
			bool containsSpaces = [tmp containsString: @" "];

			[argumentsString appendString: @" "];

			if (containsSpaces)
				[argumentsString appendString: @"\""];

			[tmp replaceOccurrencesOfString: @"\\\""
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
355
356
357
358
359
360
361

362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389

390
391
392
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408







-
+






-
+




















-
+










-
+







	[env addItems: &zero
		count: 1];

	return [env items];
}
#endif

- (BOOL)lowlevelIsAtEndOfStream
- (bool)lowlevelIsAtEndOfStream
{
#ifndef _WIN32
	if (_readPipe[0] == -1)
#else
	if (_readPipe[0] == NULL)
#endif
		return YES;
		return true;

	return _atEndOfStream;
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer
			  length: (size_t)length
{
#ifndef _WIN32
	ssize_t ret;
#else
	DWORD ret;
#endif

#ifndef _WIN32
	if (_readPipe[0] == -1 || _atEndOfStream ||
	    (ret = read(_readPipe[0], buffer, length)) < 0) {
#else
	if (_readPipe[0] == NULL || _atEndOfStream ||
	    !ReadFile(_readPipe[0], buffer, length, &ret, NULL)) {
		if (GetLastError() == ERROR_BROKEN_PIPE) {
			_atEndOfStream = YES;
			_atEndOfStream = true;
			return 0;
		}

#endif
		@throw [OFReadFailedException exceptionWithClass: [self class]
							  stream: self
						 requestedLength: length];
	}

	if (ret == 0)
		_atEndOfStream = YES;
		_atEndOfStream = true;

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
		     length: (size_t)length
{

Modified src/OFRecursiveMutex.h from [5b6f8dec9f] to [ee1a699091].

22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39







-
+










/*!
 * @brief A class for creating mutual exclusions which can be entered
 *	  recursively.
 */
@interface OFRecursiveMutex: OFObject <OFLocking>
{
	of_rmutex_t _rmutex;
	BOOL _initialized;
	bool _initialized;
	OFString *_name;
}

/*!
 * @brief Creates a new recursive mutex.
 *
 * @return A new autoreleased recursive mutex.
 */
+ (instancetype)mutex;
@end

Modified src/OFRecursiveMutex.m from [42996d602b] to [f580a06287].

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
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







-
+











-
+













-
+




-
+








	if (!of_rmutex_new(&_rmutex)) {
		Class c = [self class];
		[self release];
		@throw [OFInitializationFailedException exceptionWithClass: c];
	}

	_initialized = YES;
	_initialized = true;

	return self;
}

- (void)lock
{
	if (!of_rmutex_lock(&_rmutex))
		@throw [OFLockFailedException exceptionWithClass: [self class]
							    lock: self];
}

- (BOOL)tryLock
- (bool)tryLock
{
	return of_rmutex_trylock(&_rmutex);
}

- (void)unlock
{
	if (!of_rmutex_unlock(&_rmutex))
		@throw [OFUnlockFailedException exceptionWithClass: [self class]
							      lock: self];
}

- (void)setName: (OFString*)name
{
	OF_SETTER(_name, name, YES, 1)
	OF_SETTER(_name, name, true, 1)
}

- (OFString*)name
{
	OF_GETTER(_name, YES)
	OF_GETTER(_name, true)
}

- (OFString*)description
{
	if (_name == nil)
		return [super description];

Modified src/OFRunLoop.h from [8c2fa8ebb3] to [a581115aca].

33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47







-
+







{
	OFSortedList *_timersQueue;
#ifdef OF_HAVE_THREADS
	OFMutex *_timersQueueLock;
#endif
	OFStreamObserver *_streamObserver;
	OFMutableDictionary *_readQueues;
	volatile BOOL _running;
	volatile bool _running;
}

/*!
 * @brief Returns the main run loop.
 *
 * @return The main run loop
 */

Modified src/OFRunLoop.m from [d21ff8bef4] to [d42000199a].

396
397
398
399
400
401
402
403
404


405
406
407
408
409
410
411
396
397
398
399
400
401
402


403
404
405
406
407
408
409
410
411







-
-
+
+







					    removeStreamForReading: stream];
					[_readQueues
					    removeObjectForKey: stream];
				}
			}
		} else {
#endif
			BOOL (*func)(id, SEL, OFStream*, void*, size_t,
			    OFException*) = (BOOL(*)(id, SEL, OFStream*, void*,
			bool (*func)(id, SEL, OFStream*, void*, size_t,
			    OFException*) = (bool(*)(id, SEL, OFStream*, void*,
			    size_t, OFException*))
			    [queueItem->_target methodForSelector:
			    queueItem->_selector];

			if (!func(queueItem->_target, queueItem->_selector,
			    stream, queueItem->_buffer, length, exception)) {
				[queue removeListObject: listObject];
455
456
457
458
459
460
461
462
463


464
465
466
467
468
469
470
455
456
457
458
459
460
461


462
463
464
465
466
467
468
469
470







-
-
+
+







						    stream];
						[_readQueues
						    removeObjectForKey: stream];
					}
				}
			} else {
#endif
				BOOL (*func)(id, SEL, OFStream*, void*,
				    size_t, OFException*) = (BOOL(*)(id, SEL,
				bool (*func)(id, SEL, OFStream*, void*,
				    size_t, OFException*) = (bool(*)(id, SEL,
				    OFStream*, void*, size_t, OFException*))
				    [queueItem->_target
				    methodForSelector: queueItem->_selector];

				if (func(queueItem->_target,
				    queueItem->_selector, stream,
				    queueItem->_buffer, queueItem->_readLength,
513
514
515
516
517
518
519
520
521


522
523
524
525
526
527
528
513
514
515
516
517
518
519


520
521
522
523
524
525
526
527
528







-
-
+
+







						    stream];
						[_readQueues
						    removeObjectForKey: stream];
					}
				}
			} else {
#endif
				BOOL (*func)(id, SEL, OFStream*, OFString*,
				    OFException*) = (BOOL(*)(id, SEL, OFStream*,
				bool (*func)(id, SEL, OFStream*, OFString*,
				    OFException*) = (bool(*)(id, SEL, OFStream*,
				    OFString*, OFException*))
				    [queueItem->_target methodForSelector:
				    queueItem->_selector];

				if (!func(queueItem->_target,
				    queueItem->_selector, stream, line,
				    exception)) {
564
565
566
567
568
569
570
571

572
573

574
575
576
577
578
579
580
564
565
566
567
568
569
570

571
572

573
574
575
576
577
578
579
580







-
+

-
+







					    removeStreamForReading: stream];
					[_readQueues
					    removeObjectForKey: stream];
				}
			}
		} else {
#endif
			BOOL (*func)(id, SEL, OFTCPSocket*, OFTCPSocket*,
			bool (*func)(id, SEL, OFTCPSocket*, OFTCPSocket*,
			    OFException*) =
			    (BOOL(*)(id, SEL, OFTCPSocket*, OFTCPSocket*,
			    (bool(*)(id, SEL, OFTCPSocket*, OFTCPSocket*,
			    OFException*))
			    [queueItem->_target methodForSelector:
			    queueItem->_selector];

			if (!func(queueItem->_target, queueItem->_selector,
			    (OFTCPSocket*)stream, newSocket, exception)) {
				[queue removeListObject: listObject];
591
592
593
594
595
596
597
598

599
600
601
602
603
604
605
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605







-
+







#endif
	} else
		OF_ENSURE(0);
}

- (void)run
{
	_running = YES;
	_running = true;

	while (_running) {
		void *pool = objc_autoreleasePoolPush();
		OFDate *now = [OFDate date];
		OFTimer *timer;
		OFDate *nextTimer;

658
659
660
661
662
663
664
665

666
667
668
658
659
660
661
662
663
664

665
666
667
668







-
+




		objc_autoreleasePoolPop(pool);
	}
}

- (void)stop
{
	_running = NO;
	_running = false;
	[_streamObserver cancel];
}
@end

Modified src/OFSHA1Hash.h from [6e69faf3b5] to [88105141d2].

23
24
25
26
27
28
29
30

31
32
23
24
25
26
27
28
29

30
31
32







-
+


 */
@interface OFSHA1Hash: OFObject <OFHash>
{
	uint32_t _state[5];
	uint64_t _count;
	char	 _buffer[64];
	uint8_t	 _digest[OF_SHA1_DIGEST_SIZE];
	BOOL	 _calculated;
	bool	 _calculated;
}
@end

Modified src/OFSHA1Hash.m from [264141bf82] to [fbdf78c69a].

189
190
191
192
193
194
195
196

197
198
199
200
201

202
203
204
205
189
190
191
192
193
194
195

196
197
198
199
200

201
202
203
204
205







-
+




-
+




	/* Should cause a sha1_transform() */
	sha1_update(_state, &_count, _buffer, finalcount, 8);

	for (i = 0; i < OF_SHA1_DIGEST_SIZE; i++)
		_digest[i] = (char)((_state[i >> 2] >>
		    ((3 - (i & 3)) * 8)) & 255);

	_calculated = YES;
	_calculated = true;

	return _digest;
}

- (BOOL)isCalculated
- (bool)isCalculated
{
	return _calculated;
}
@end

Modified src/OFSet.h from [a68cfc7c01] to [bbf8e3f8e2].

26
27
28
29
30
31
32
33
34


35
36
37
38
39
40
41
26
27
28
29
30
31
32


33
34
35
36
37
38
39
40
41







-
-
+
+







#import "OFObject.h"
#import "OFCollection.h"
#import "OFSerialization.h"

@class OFArray;

#ifdef OF_HAVE_BLOCKS
typedef void (^of_set_enumeration_block_t)(id object, BOOL *stop);
typedef BOOL (^of_set_filter_block_t)(id object);
typedef void (^of_set_enumeration_block_t)(id object, bool *stop);
typedef bool (^of_set_filter_block_t)(id object);
#endif

/*!
 * @brief An abstract class for an unordered set of unique objects.
 *
 * @warning Do not mutate objects that are in a set! Changing the hash of
 *	    objects in a set breaks the internal representation of the set!
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152







-
+








-
+







       arguments: (va_list)arguments;

/*!
 * @brief Returns whether the receiver is a subset of the specified set.
 *
 * @return Whether the receiver is a subset of the specified set
 */
- (BOOL)isSubsetOfSet: (OFSet*)set;
- (bool)isSubsetOfSet: (OFSet*)set;

/*!
 * @brief Returns whether the receiver and the specified set have at least one
 *	  object in common.
 *
 * @return Whether the receiver and the specified set have at least one object
 *	   in common
 */
- (BOOL)intersectsSet: (OFSet*)set;
- (bool)intersectsSet: (OFSet*)set;

/*!
 * @brief Creates a new set which contains the objects which are in the
 *	  receiver, but not in the specified set.
 *
 * @param set The set whose objects will not be in the new set
 */
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188
189
190







-
+









 *
 * @param block The block to execute for each object in the set
 */
- (void)enumerateObjectsUsingBlock: (of_set_enumeration_block_t)block;

/*!
 * @brief Creates a new set, only containing the objects for which the block
 *	  returns YES.
 *	  returns true.
 *
 * @param block A block which determines if the object should be in the new set
 * @return A new, autoreleased OFSet
 */
- (OFSet*)filteredSetUsingBlock: (of_set_filter_block_t)block;
#endif
@end

#import "OFMutableSet.h"

Modified src/OFSet.m from [c4a3756934] to [35aae4e27a].

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

280
281
282
283
284

285
286
287
288
289
290
291
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
280
281
282
283

284
285
286
287
288
289
290
291







-
+



















-
+




-
+




-
+








- (size_t)count
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (BOOL)containsObject: (id)object
- (bool)containsObject: (id)object
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (OFEnumerator*)objectEnumerator
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
			     count: (int)count
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFSet *otherSet;

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

	otherSet = object;

	if ([otherSet count] != [self count])
		return NO;
		return false;

	return [otherSet isSubsetOfSet: self];
}

- (uint32_t)hash
{
	void *pool = objc_autoreleasePoolPush();
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360
361
362

363
364
365
366
367
368

369
370
371

372
373
374
375
376
377
378
379
380
381

382
383
384
385
386
387

388
389
390
391
392
393
394
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359
360
361

362
363
364
365
366
367

368
369
370

371
372
373
374
375
376
377
378
379
380

381
382
383
384
385
386

387
388
389
390
391
392
393
394







-
+









-
+





-
+


-
+









-
+





-
+







}

- mutableCopy
{
	return [[OFMutableSet alloc] initWithSet: self];
}

- (BOOL)isSubsetOfSet: (OFSet*)set
- (bool)isSubsetOfSet: (OFSet*)set
{
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator;
	id object;

	enumerator = [self objectEnumerator];
	while ((object = [enumerator nextObject]) != nil) {
		if (![set containsObject: object]) {
			objc_autoreleasePoolPop(pool);
			return NO;
			return false;
		}
	}

	objc_autoreleasePoolPop(pool);

	return YES;
	return true;
}

- (BOOL)intersectsSet: (OFSet*)set
- (bool)intersectsSet: (OFSet*)set
{
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator;
	id object;

	enumerator = [self objectEnumerator];
	while ((object = [enumerator nextObject]) != nil) {
		if ([set containsObject: object]) {
			objc_autoreleasePoolPop(pool);
			return YES;
			return true;
		}
	}

	objc_autoreleasePoolPop(pool);

	return NO;
	return false;
}

- (OFXMLElement*)XMLElementBySerializing
{
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;
	OFEnumerator *enumerator;
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476

477
478
479
480
481
482
483
484
485
486
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475

476
477
478
479
480
481
482
483
484
485
486







-
+















-
+











	return new;
}

#if defined(OF_HAVE_BLOCKS) && defined(OF_HAVE_FAST_ENUMERATION)
- (void)enumerateObjectsUsingBlock: (of_set_enumeration_block_t)block
{
	BOOL stop = NO;
	bool stop = false;

	for (id object in self) {
		block(object, &stop);

		if (stop)
			break;
	}
}
#endif

#ifdef OF_HAVE_BLOCKS
- (OFSet*)filteredSetUsingBlock: (of_set_filter_block_t)block
{
	OFMutableSet *ret = [OFMutableSet set];

	[self enumerateObjectsUsingBlock: ^ (id object, BOOL *stop) {
	[self enumerateObjectsUsingBlock: ^ (id object, bool *stop) {
		if (block(object))
			[ret addObject: object];
	}];

	[ret makeImmutable];

	return ret;
}
#endif
@end

Modified src/OFSet_hashtable.m from [86943d9b76] to [a6ac6bcbd5].

43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57







-
+








static uint32_t
hash(void *value)
{
	return [(id)value hash];
}

static BOOL
static bool
equal(void *value1, void *value2)
{
	return [(id)value1 isEqual: (id)value2];
}

static of_map_table_functions_t keyFunctions = {
	.retain = retain,
250
251
252
253
254
255
256
257

258
259
260

261
262
263
264
265

266
267
268
269
270
271
272
250
251
252
253
254
255
256

257
258
259

260
261
262
263
264

265
266
267
268
269
270
271
272







-
+


-
+




-
+







}

- (size_t)count
{
	return [_mapTable count];
}

- (BOOL)containsObject: (id)object
- (bool)containsObject: (id)object
{
	if (object == nil)
		return NO;
		return false;

	return ([_mapTable valueForKey: object] != nil);
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFSet_hashtable *set;

	if (![object isKindOfClass: [OFSet_hashtable class]] &&
	    ![object isKindOfClass: [OFMutableSet_hashtable class]] &&
	    ![object isKindOfClass: [OFCountedSet_hashtable class]])
		return [super isEqual: object];
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308
309
310
293
294
295
296
297
298
299

300
301
302
303
304
305
306
307
308
309
310







-
+










}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_set_enumeration_block_t)block
{
	@try {
		[_mapTable enumerateKeysAndValuesUsingBlock:
		    ^ (void *key, void *value, BOOL *stop) {
		    ^ (void *key, void *value, bool *stop) {
			block(key, stop);
		}];
	} @catch (OFEnumerationMutationException *e) {
		@throw [OFEnumerationMutationException
		    exceptionWithClass: [self class]
				object: self];
	}
}
#endif
@end

Modified src/OFStream.h from [74effa40b4] to [d1cbeea7d2].

27
28
29
30
31
32
33
34

35
36

37
38
39
40
41
42
43
27
28
29
30
31
32
33

34
35

36
37
38
39
40
41
42
43







-
+

-
+







#import "OFString.h"

@class OFStream;
@class OFDataArray;
@class OFException;

#ifdef OF_HAVE_BLOCKS
typedef BOOL (^of_stream_async_read_block_t)(OFStream*, void*, size_t,
typedef bool (^of_stream_async_read_block_t)(OFStream*, void*, size_t,
    OFException*);
typedef BOOL (^of_stream_async_read_line_block_t)(OFStream*, OFString*,
typedef bool (^of_stream_async_read_line_block_t)(OFStream*, OFString*,
    OFException*);
#endif

/*!
 * @brief A base class for different types of streams.
 *
 * @warning Even though the OFCopying protocol is implemented, it does *not*
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
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







-
+



-
-
-
+
+
+







-
+







 *	 override these methods without the lowlevel prefix, you *will* break
 *	 caching and get broken results!
 */
@interface OFStream: OFObject <OFCopying>
{
	char *_readBuffer, *_writeBuffer;
	size_t _readBufferLength, _writeBufferLength;
	BOOL _writeBufferEnabled, _blocking, _waitingForDelimiter;
	bool _writeBufferEnabled, _blocking, _waitingForDelimiter;
}

#ifdef OF_HAVE_PROPERTIES
@property (getter=isWriteBufferEnabled) BOOL writeBufferEnabled;
@property (getter=isBlocking) BOOL blocking;
@property (readonly, getter=isAtEndOfStream) BOOL atEndOfStream;
@property (getter=isWriteBufferEnabled) bool writeBufferEnabled;
@property (getter=isBlocking) bool blocking;
@property (readonly, getter=isAtEndOfStream) bool atEndOfStream;
#endif

/*!
 * @brief Returns a boolean whether the end of the stream has been reached.
 *
 * @return A boolean whether the end of the stream has been reached
 */
- (BOOL)isAtEndOfStream;
- (bool)isAtEndOfStream;

/*!
 * @brief Reads *at most* size bytes from the stream into a buffer.
 *
 * On network streams, this might read less than the specified number of bytes.
 * If you want to read exactly the specified number of bytes, use
 * @ref readIntoBuffer:exactLength:. Note that a read can even return 0 bytes -
121
122
123
124
125
126
127
128

129
130
131
132


133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159


160
161

162
163
164
165
166
167
168
121
122
123
124
125
126
127

128
129
130


131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157


158
159
160

161
162
163
164
165
166
167
168







-
+


-
-
+
+

-
+




















-
+


-
-
+
+

-
+







 * you still need to check @ref isAtEndOfStream.
 *
 * @param buffer The buffer into which the data is read.
 *		 The buffer must not be free'd before the async read completed!
 * @param length The length of the data that should be read at most.
 *		 The buffer *must* be *at least* this big!
 * @param target The target on which the selector should be called when the
 *		 data has been received. If the method returns YES, it will be
 *		 data has been received. If the method returns true, it will be
 *		 called again with the same buffer and maximum length when more
 *		 data has been received. If you want the next method in the
 *		 queue to handle the data received next, you need to return NO
 *		 from the method.
 *		 queue to handle the data received next, you need to return
 *		 false from the method.
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, void *buffer, size_t size,
 *		   bool (OFStream *stream, void *buffer, size_t size,
 *		   OFException *exception).
 */
- (void)asyncReadIntoBuffer: (void*)buffer
		     length: (size_t)length
		     target: (id)target
		   selector: (SEL)selector;

/*!
 * @brief Asyncronously reads exactly the specified length bytes from the
 *	  stream into a buffer.
 *
 * Unlike @ref asyncReadIntoBuffer:length:target:selector:, this method does
 * not call the method when less than the specified length has been read -
 * instead, it waits until it got exactly the specified length, the stream has
 * ended or an exception occurred.
 *
 * @param buffer The buffer into which the data is read
 * @param length The length of the data that should be read.
 *		 The buffer *must* be *at least* this big!
 * @param target The target on which the selector should be called when the
 *		 data has been received. If the method returns YES, it will be
 *		 data has been received. If the method returns true, it will be
 *		 called again with the same buffer and exact length when more
 *		 data has been received. If you want the next method in the
 *		 queue to handle the data received next, you need to return NO
 *		 from the method.
 *		 queue to handle the data received next, you need to return
 *		 false from the method.
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, void *buffer, size_t size,
 *		   bool (OFStream *stream, void *buffer, size_t size,
 *		   OFException *exception).
 */
 - (void)asyncReadIntoBuffer: (void*)buffer
		 exactLength: (size_t)length
		      target: (id)target
		    selector: (SEL)selector;

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
206
207

208
209
210

211
212
213
214
215
216
217
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
206

207
208
209

210
211
212
213
214
215
216
217







-
+


-
+


















-
+


-
+







 * you still need to check @ref isAtEndOfStream.
 *
 * @param buffer The buffer into which the data is read.
 *		 The buffer must not be free'd before the async read completed!
 * @param length The length of the data that should be read at most.
 *		 The buffer *must* be *at least* this big!
 * @param block The block to call when the data has been received.
 *		If the block returns YES, it will be called again with the same
 *		If the block returns true, it will be called again with the same
 *		buffer and maximum length when more data has been received. If
 *		you want the next block in the queue to handle the data
 *		received next, you need to return NO from the block.
 *		received next, you need to return false from the block.
 */
- (void)asyncReadIntoBuffer: (void*)buffer
		     length: (size_t)length
		      block: (of_stream_async_read_block_t)block;

/*!
 * @brief Asyncronously reads exactly the specified length bytes from the
 *	  stream into a buffer.
 *
 * Unlike @ref asyncReadIntoBuffer:length:block:, this method does not invoke
 * the block when less than the specified length has been read - instead, it
 * waits until it got exactly the specified length, the stream has ended or an
 * exception occurred.
 *
 * @param buffer The buffer into which the data is read
 * @param length The length of the data that should be read.
 *		 The buffer *must* be *at least* this big!
 * @param block The block to call when the data has been received.
 *		If the block returns YES, it will be called again with the same
 *		If the block returns true, it will be called again with the same
 *		buffer and exact length when more data has been received. If
 *		you want the next block in the queue to handle the data
 *		received next, you need to return NO from the block.
 *		received next, you need to return false from the block.
 */
 - (void)asyncReadIntoBuffer: (void*)buffer
		 exactLength: (size_t)length
		       block: (of_stream_async_read_block_t)block;
#endif

/*!
561
562
563
564
565
566
567
568

569
570
571

572
573

574
575
576
577
578
579
580
581
582
583
584
585

586
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
612
613
614
615

616
617


618
619
620
621
622
623
624
561
562
563
564
565
566
567

568
569
570

571
572

573
574
575
576
577
578
579
580
581
582
583
584

585
586
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
612
613
614
615

616
617

618
619
620
621
622
623
624
625
626







-
+


-
+

-
+











-
+


-
+

-
+












-
+

-
+
+









-
+

-
+
+







- (OFString*)readLineWithEncoding: (of_string_encoding_t)encoding;

/*!
 * @brief Asyncronously reads until a newline, \\0, end of stream or an
 *	  exception occurs.
 *
 * @param target The target on which to call the selector when the data has
 *		 been received. If the method returns YES, it will be called
 *		 been received. If the method returns true, it will be called
 *		 again when the next line has been received. If you want the
 *		 next method in the queue to handle the next line, you need to
 *		 return NO from the method
 *		 return false from the method
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, OFString *line,
 *		   bool (OFStream *stream, OFString *line,
 *		   OFException *exception).
 */
- (void)asyncReadLineWithTarget: (id)target
		       selector: (SEL)selector;

/*!
 * @brief Asyncronously reads with the specified encoding until a newline, \\0,
 *	  end of stream or an exception occurs.
 *
 * @param encoding The encoding used by the stream
 * @param target The target on which to call the selector when the data has
 *		 been received. If the method returns YES, it will be called
 *		 been received. If the method returns true, it will be called
 *		 again when the next line has been received. If you want the
 *		 next method in the queue to handle the next line, you need to
 *		 return NO from the method
 *		 return false from the method
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, OFString *line,
 *		   bool (OFStream *stream, OFString *line,
 *		   OFException *exception).
 */
- (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding
			   target: (id)target
			 selector: (SEL)selector;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Asyncronously reads until a newline, \\0, end of stream or an
 *	  exception occurs.
 *
 * @param block The block to call when the data has been received.
 *		If the block returns YES, it will be called again when the next
 *		If the block returns true, it will be called again when the next
 *		line has been received. If you want the next block in the queue
 *		to handle the next line, you need to return NO from the block.
 *		to handle the next line, you need to return false from the
 *		block.
 */
- (void)asyncReadLineWithBlock: (of_stream_async_read_line_block_t)block;

/*!
 * @brief Asyncronously reads with the specified encoding until a newline, \\0,
 *	  end of stream or an exception occurs.
 *
 * @param encoding The encoding used by the stream
 * @param block The block to call when the data has been received.
 *		If the block returns YES, it will be called again when the next
 *		If the block returns true, it will be called again when the next
 *		line has been received. If you want the next block in the queue
 *		to handle the next line, you need to return NO from the block.
 *		to handle the next line, you need to return false from the
 *		block.
 */
- (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding
			    block: (of_stream_async_read_line_block_t)block;
#endif

/*!
 * @brief Tries to read a line from the stream (see readLine) and returns nil if
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701

702
703
704
705
706
707
708
689
690
691
692
693
694
695

696
697
698
699
700
701
702

703
704
705
706
707
708
709
710







-
+






-
+







			 encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Returns a boolen whether writes are buffered.
 *
 * @return A boolean whether writes are buffered
 */
- (BOOL)isWriteBufferEnabled;
- (bool)isWriteBufferEnabled;

/*!
 * @brief Enables or disables the write buffer.
 *
 * @param enable Whether the write buffer should be enabled or disabled
 */
- (void)setWriteBufferEnabled: (BOOL)enable;
- (void)setWriteBufferEnabled: (bool)enable;

/*!
 * @brief Writes everythig in the write buffer to the stream.
 */
- (void)flushWriteBuffer;

/*!
989
990
991
992
993
994
995
996

997
998
999
1000
1001
1002
1003
1004
1005
1006

1007
1008
1009
1010
1011
1012
1013
991
992
993
994
995
996
997

998
999
1000
1001
1002
1003
1004
1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
1015







-
+









-
+







- (size_t)numberOfBytesInReadBuffer;

/*!
 * @brief Returns whether the stream is in blocking mode.
 *
 * @return Whether the stream is in blocking mode
 */
- (BOOL)isBlocking;
- (bool)isBlocking;

/*!
 * @brief Enables or disables non-blocking I/O.
 *
 * By default, a stream is in blocking mode.
 * On Win32, this currently only works for sockets!
 *
 * @param enable Whether the stream should be blocking
 */
- (void)setBlocking: (BOOL)enable;
- (void)setBlocking: (bool)enable;

/*!
 * @brief Returns the file descriptor for the read end of the stream.
 *
 * @return The file descriptor for the read end of the stream
 */
- (int)fileDescriptorForReading;
1062
1063
1064
1065
1066
1067
1068
1069

1070
1071

1072
1064
1065
1066
1067
1068
1069
1070

1071
1072

1073
1074







-
+

-
+

 * @warning Do not call this directly!
 *
 * Override this method with your actual end of stream checking implementation
 * when subclassing!
 *
 * @return Whether the lowlevel is at the end of the stream
 */
- (BOOL)lowlevelIsAtEndOfStream;
- (bool)lowlevelIsAtEndOfStream;

- (BOOL)OF_isWaitingForDelimiter;
- (bool)OF_isWaitingForDelimiter;
@end

Modified src/OFStream.m from [826cbee6d8] to [401460f5bb].

64
65
66
67
68
69
70
71

72
73
74
75
76

77
78
79
80
81
82
83
64
65
66
67
68
69
70

71
72
73
74
75

76
77
78
79
80
81
82
83







-
+




-
+







			[self release];
			@throw e;
		}
	}

	self = [super init];

	_blocking = YES;
	_blocking = true;

	return self;
}

- (BOOL)lowlevelIsAtEndOfStream
- (bool)lowlevelIsAtEndOfStream
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer
			  length: (size_t)length
94
95
96
97
98
99
100
101

102
103
104

105
106
107
108
109
110
111
94
95
96
97
98
99
100

101
102
103

104
105
106
107
108
109
110
111







-
+


-
+







}

- copy
{
	return [self retain];
}

- (BOOL)isAtEndOfStream
- (bool)isAtEndOfStream
{
	if (_readBufferLength > 0)
		return NO;
		return false;

	return [self lowlevelIsAtEndOfStream];
}

- (size_t)readIntoBuffer: (void*)buffer
		  length: (size_t)length
{
591
592
593
594
595
596
597
598

599
600
601
602
603
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628

629
630
631
632
633
634
635
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
609
610

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627

628
629
630
631
632
633
634
635







-
+












-
+
















-
+







					memcpy(readBuffer, _readBuffer + i + 1,
					    _readBufferLength - i - 1);

				[self freeMemory: _readBuffer];
				_readBuffer = readBuffer;
				_readBufferLength -= i + 1;

				_waitingForDelimiter = NO;
				_waitingForDelimiter = false;
				return ret;
			}
		}
	}

	/* Read and see if we got a newline or \0 */
	pageSize = [OFSystemInfo pageSize];
	buffer = [self allocMemoryWithSize: pageSize];

	@try {
		if ([self lowlevelIsAtEndOfStream]) {
			if (_readBuffer == NULL) {
				_waitingForDelimiter = NO;
				_waitingForDelimiter = false;
				return nil;
			}

			retLength = _readBufferLength;

			if (retLength > 0 && _readBuffer[retLength - 1] == '\r')
				retLength--;

			ret = [OFString stringWithCString: _readBuffer
						 encoding: encoding
						   length: retLength];

			[self freeMemory: _readBuffer];
			_readBuffer = NULL;
			_readBufferLength = 0;

			_waitingForDelimiter = NO;
			_waitingForDelimiter = false;
			return ret;
		}

		bufferLength = [self lowlevelReadIntoBuffer: buffer
						     length: pageSize];

		/* Look if there's a newline or \0 */
686
687
688
689
690
691
692
693

694
695
696
697
698
699
700
686
687
688
689
690
691
692

693
694
695
696
697
698
699
700







-
+







					memcpy(readBuffer, buffer + i + 1,
					    bufferLength - i - 1);

				[self freeMemory: _readBuffer];
				_readBuffer = readBuffer;
				_readBufferLength = bufferLength - i - 1;

				_waitingForDelimiter = NO;
				_waitingForDelimiter = false;
				return ret;
			}
		}

		/* There was no newline or \0 */
		_readBuffer = [self resizeMemory: _readBuffer
					    size: _readBufferLength +
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
709
710
711
712
713
714
715

716
717
718
719
720
721
722
723







-
+







			    buffer, bufferLength);

		_readBufferLength += bufferLength;
	} @finally {
		[self freeMemory: buffer];
	}

	_waitingForDelimiter = YES;
	_waitingForDelimiter = true;
	return nil;
}

- (OFString*)readLine
{
	return [self readLineWithEncoding: OF_STRING_ENCODING_UTF_8];
}
810
811
812
813
814
815
816
817

818
819
820
821
822
823
824
825
826
827
828
829
830

831
832
833
834
835
836
837
838
839
840
841
842

843
844
845
846
847
848
849
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824
825
826
827
828
829

830
831
832
833
834
835
836
837
838
839
840
841

842
843
844
845
846
847
848
849







-
+












-
+











-
+







					memcpy(readBuffer, _readBuffer + i + 1,
					    _readBufferLength - i - 1);

				[self freeMemory: _readBuffer];
				_readBuffer = readBuffer;
				_readBufferLength -= i + 1;

				_waitingForDelimiter = NO;
				_waitingForDelimiter = false;
				return ret;
			}
		}
	}

	/* Read and see if we got a delimiter or \0 */
	pageSize = [OFSystemInfo pageSize];
	buffer = [self allocMemoryWithSize: pageSize];

	@try {
		if ([self lowlevelIsAtEndOfStream]) {
			if (_readBuffer == NULL) {
				_waitingForDelimiter = NO;
				_waitingForDelimiter = false;
				return nil;
			}

			ret = [OFString stringWithCString: _readBuffer
						 encoding: encoding
						   length: _readBufferLength];

			[self freeMemory: _readBuffer];
			_readBuffer = NULL;
			_readBufferLength = 0;

			_waitingForDelimiter = NO;
			_waitingForDelimiter = false;
			return ret;
		}

		bufferLength = [self lowlevelReadIntoBuffer: buffer
						     length: pageSize];

		/* Look if there's a delimiter or \0 */
889
890
891
892
893
894
895
896

897
898
899
900
901
902
903
889
890
891
892
893
894
895

896
897
898
899
900
901
902
903







-
+







					memcpy(readBuffer, buffer + i + 1,
					    bufferLength - i - 1);

				[self freeMemory: _readBuffer];
				_readBuffer = readBuffer;
				_readBufferLength = bufferLength - i - 1;

				_waitingForDelimiter = NO;
				_waitingForDelimiter = false;
				return ret;
			}
		}

		/* Neither the delimiter nor \0 was found */
		_readBuffer = [self resizeMemory: _readBuffer
					    size: _readBufferLength +
912
913
914
915
916
917
918
919

920
921
922
923
924
925
926
912
913
914
915
916
917
918

919
920
921
922
923
924
925
926







-
+







			    buffer, bufferLength);

		_readBufferLength += bufferLength;
	} @finally {
		[self freeMemory: buffer];
	}

	_waitingForDelimiter = YES;
	_waitingForDelimiter = true;
	return nil;
}


- (OFString*)readTillDelimiter: (OFString*)delimiter
{
	return [self readTillDelimiter: delimiter
943
944
945
946
947
948
949
950

951
952
953
954
955

956
957
958
959
960
961
962
943
944
945
946
947
948
949

950
951
952
953
954

955
956
957
958
959
960
961
962







-
+




-
+








- (OFString*)tryReadTillDelimiter: (OFString*)delimiter
{
	return [self tryReadTillDelimiter: delimiter
				 encoding: OF_STRING_ENCODING_UTF_8];
}

- (BOOL)isWriteBufferEnabled
- (bool)isWriteBufferEnabled
{
	return _writeBufferEnabled;
}

- (void)setWriteBufferEnabled: (BOOL)enable
- (void)setWriteBufferEnabled: (bool)enable
{
	_writeBufferEnabled = enable;
}

- (void)flushWriteBuffer
{
	if (_writeBuffer == NULL)
1465
1466
1467
1468
1469
1470
1471
1472

1473
1474
1475
1476
1477

1478
1479
1480

1481
1482
1483
1484
1485
1486
1487

1488
1489
1490
1491
1492
1493
1494
1465
1466
1467
1468
1469
1470
1471

1472
1473
1474
1475
1476

1477
1478
1479

1480
1481
1482
1483
1484
1485
1486

1487
1488
1489
1490
1491
1492
1493
1494







-
+




-
+


-
+






-
+







}

- (size_t)numberOfBytesInReadBuffer
{
	return _readBufferLength;
}

- (BOOL)isBlocking
- (bool)isBlocking
{
	return _blocking;
}

- (void)setBlocking: (BOOL)enable
- (void)setBlocking: (bool)enable
{
#ifndef _WIN32
	BOOL readImplemented = NO, writeImplemented = NO;
	bool readImplemented = false, writeImplemented = false;

	@try {
		int readFlags;

		readFlags = fcntl([self fileDescriptorForReading], F_GETFL);

		readImplemented = YES;
		readImplemented = true;

		if (readFlags == -1)
			@throw [OFSetOptionFailedException
			    exceptionWithClass: [self class]
					stream: self];

		if (enable)
1505
1506
1507
1508
1509
1510
1511
1512

1513
1514
1515
1516
1517
1518
1519
1505
1506
1507
1508
1509
1510
1511

1512
1513
1514
1515
1516
1517
1518
1519







-
+







	}

	@try {
		int writeFlags;

		writeFlags = fcntl([self fileDescriptorForWriting], F_GETFL);

		writeImplemented = YES;
		writeImplemented = true;

		if (writeFlags == -1)
			@throw [OFSetOptionFailedException
			    exceptionWithClass: [self class]
					stream: self];

		if (enable)
1560
1561
1562
1563
1564
1565
1566
1567

1568
1569
1570
1571
1560
1561
1562
1563
1564
1565
1566

1567
1568
1569
1570
1571







-
+





- (void)close
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (BOOL)OF_isWaitingForDelimiter
- (bool)OF_isWaitingForDelimiter
{
	return _waitingForDelimiter;
}
@end

Modified src/OFStreamObserver.h from [cdfadcf2ee] to [36adc90c29].

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
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







-
+















-
+




/*!
 * @brief Observes all streams until an event happens on a stream or the
 *	  timeout is reached.
 *
 * @param timeout The time to wait for an event, in seconds
 * @return A boolean whether events occurred during the timeinterval
 */
- (BOOL)observeWithTimeout: (double)timeout;
- (bool)observeWithTimeout: (double)timeout;

/*!
 * @brief Cancels the currently blocking observe call.
 *
 * This is automatically done when a new stream is added or removed by another
 * thread, but in some circumstances, it might be desirable for a thread to
 * manually stop the observe running in another thread.
 */
- (void)cancel;

- (void)OF_addFileDescriptorForReading: (int)fd;
- (void)OF_addFileDescriptorForWriting: (int)fd;
- (void)OF_removeFileDescriptorForReading: (int)fd;
- (void)OF_removeFileDescriptorForWriting: (int)fd;
- (void)OF_processQueue;
- (BOOL)OF_processCache;
- (bool)OF_processCache;
@end

@interface OFObject (OFStreamObserverDelegate) <OFStreamObserverDelegate>
@end

Modified src/OFStreamObserver.m from [6df17e709d] to [14f367ec0c].

369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392

393
394
395
396

397
398
399
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
415
416
417
418

419
420

421
422
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391

392
393
394
395

396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417

418
419

420
421
422







-
+















-
+



-
+










-
+










-
+

-
+


}

- (void)observe
{
	[self observeWithTimeout: -1];
}

- (BOOL)observeWithTimeout: (double)timeout
- (bool)observeWithTimeout: (double)timeout
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (void)cancel
{
#ifndef _WIN32
	OF_ENSURE(write(_cancelFD[1], "", 1) > 0);
#else
	OF_ENSURE(sendto(_cancelFD[1], "", 1, 0, (struct sockaddr*)&_cancelAddr,
	    sizeof(_cancelAddr)) > 0);
#endif
}

- (BOOL)OF_processCache
- (bool)OF_processCache
{
	OFStream **objects = [_readStreams objects];
	size_t i, count = [_readStreams count];
	BOOL foundInCache = NO;
	bool foundInCache = false;

	for (i = 0; i < count; i++) {
		if ([objects[i] numberOfBytesInReadBuffer] > 0 &&
		    ![objects[i] OF_isWaitingForDelimiter]) {
			void *pool = objc_autoreleasePoolPush();

			if ([_delegate respondsToSelector:
			    @selector(streamIsReadyForReading:)])
				[_delegate streamIsReadyForReading: objects[i]];

			foundInCache = YES;
			foundInCache = true;

			objc_autoreleasePoolPop(pool);
		}
	}

	/*
	 * As long as we have data in the cache for any stream, we don't want
	 * to block.
	 */
	if (foundInCache)
		return YES;
		return true;

	return NO;
	return false;
}
@end

Modified src/OFStreamObserver_kqueue.m from [fd7c063d3b] to [ac3c9446ae].

101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132

133
134
135
136
137

138
139
140
141
142
143
144
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131

132
133
134
135
136

137
138
139
140
141
142
143
144







-
+













-
+









-
+




-
+







{
	struct kevent event;

	EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
	[_changeList addItem: &event];
}

- (BOOL)observeWithTimeout: (double)timeout
- (bool)observeWithTimeout: (double)timeout
{
	void *pool = objc_autoreleasePoolPush();
	struct timespec timespec;
	struct kevent eventList[EVENTLIST_SIZE];
	int i, events, realEvents = 0;

	timespec.tv_sec = (time_t)timeout;
	timespec.tv_nsec = (long)((timeout - timespec.tv_sec) * 1000000000);

	[self OF_processQueue];

	if ([self OF_processCache]) {
		objc_autoreleasePoolPop(pool);
		return YES;
		return true;
	}

	objc_autoreleasePoolPop(pool);

	events = kevent(_kernelQueue, [_changeList items],
	    (int)[_changeList count], eventList, EVENTLIST_SIZE,
	    (timeout == -1 ? NULL : &timespec));

	if (events < 0)
		return NO;
		return false;

	[_changeList removeAllItems];

	if (events == 0)
		return NO;
		return false;

	for (i = 0; i < events; i++) {
		if (eventList[i].ident == _cancelFD[0]) {
			char buffer;

			OF_ENSURE(read(_cancelFD[0], &buffer, 1) > 0);

176
177
178
179
180
181
182
183

184
185

186
187
176
177
178
179
180
181
182

183
184

185
186
187







-
+

-
+


			assert(0);
		}

		objc_autoreleasePoolPop(pool);
	}

	if (realEvents == 0)
		return NO;
		return false;

	return YES;
	return true;
}
@end

Modified src/OFStreamObserver_poll.m from [1648f30d0f] to [684851fd9c].

58
59
60
61
62
63
64
65

66
67
68
69
70

71
72
73
74
75
76
77
58
59
60
61
62
63
64

65
66
67
68
69

70
71
72
73
74
75
76
77







-
+




-
+







}

- (void)OF_addFileDescriptor: (int)fd
		  withEvents: (short)events
{
	struct pollfd *FDs = [_FDs items];
	size_t i, count = [_FDs count];
	BOOL found = NO;
	bool found = false;

	for (i = 0; i < count; i++) {
		if (FDs[i].fd == fd) {
			FDs[i].events |= events;
			found = YES;
			found = true;
			break;
		}
	}

	if (!found) {
		struct pollfd p = { fd, events | POLLERR, 0 };
		[_FDs addItem: &p];
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155







-
+









-
+














-
+








- (void)OF_removeFileDescriptorForWriting: (int)fd
{
	[self OF_removeFileDescriptor: fd
			   withEvents: POLLOUT];
}

- (BOOL)observeWithTimeout: (double)timeout
- (bool)observeWithTimeout: (double)timeout
{
	void *pool = objc_autoreleasePoolPush();
	struct pollfd *FDs;
	size_t i, nFDs, realEvents = 0;

	[self OF_processQueue];

	if ([self OF_processCache]) {
		objc_autoreleasePoolPop(pool);
		return YES;
		return true;
	}

	objc_autoreleasePoolPop(pool);

	FDs = [_FDs items];
	nFDs = [_FDs count];

#ifdef OPEN_MAX
	if (nFDs > OPEN_MAX)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#endif

	if (poll(FDs, (nfds_t)nFDs,
	    (int)(timeout != -1 ? timeout * 1000 : -1)) < 1)
		return NO;
		return false;

	for (i = 0; i < nFDs; i++) {
		pool = objc_autoreleasePoolPush();

		if (FDs[i].revents & POLLIN) {
			if (FDs[i].fd == _cancelFD[0]) {
				char buffer;
189
190
191
192
193
194
195
196

197
198

199
200
189
190
191
192
193
194
195

196
197

198
199
200







-
+

-
+



		FDs[i].revents = 0;

		objc_autoreleasePoolPop(pool);
	}

	if (realEvents == 0)
		return NO;
		return false;

	return YES;
	return true;
}
@end

Modified src/OFStreamObserver_select.m from [f904878755] to [0d55873c55].

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
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







-
+













-
+







{
	FD_CLR(fd, &_writeFDs);

	if (!FD_ISSET(fd, &_readFDs))
		FD_CLR(fd, &_exceptFDs);
}

- (BOOL)observeWithTimeout: (double)timeout
- (bool)observeWithTimeout: (double)timeout
{
	void *pool = objc_autoreleasePoolPush();
	OFStream **objects;
	fd_set readFDs;
	fd_set writeFDs;
	fd_set exceptFDs;
	struct timeval time;
	size_t i, count, realEvents = 0;

	[self OF_processQueue];

	if ([self OF_processCache]) {
		objc_autoreleasePoolPop(pool);
		return YES;
		return true;
	}

	objc_autoreleasePoolPop(pool);

#ifdef FD_COPY
	FD_COPY(&_readFDs, &readFDs);
	FD_COPY(&_writeFDs, &writeFDs);
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121







-
+







	 * satisfy the required range, we just cast to int.
	 */
	time.tv_sec = (time_t)timeout;
	time.tv_usec = (int)((timeout - time.tv_sec) * 1000);

	if (select((int)_maxFD + 1, &readFDs, &writeFDs, &exceptFDs,
	    (timeout != -1 ? &time : NULL)) < 1)
		return NO;
		return false;

	if (FD_ISSET(_cancelFD[0], &readFDs)) {
		char buffer;
#ifndef _WIN32
		OF_ENSURE(read(_cancelFD[0], &buffer, 1) > 0);
#else
		OF_ENSURE(recvfrom(_cancelFD[0], &buffer, 1, 0, NULL,
182
183
184
185
186
187
188
189

190
191

192
193
182
183
184
185
186
187
188

189
190

191
192
193







-
+

-
+


			realEvents++;
		}

		objc_autoreleasePoolPop(pool);
	}

	if (realEvents == 0)
		return NO;
		return false;

	return YES;
	return true;
}
@end

Modified src/OFStreamSocket.h from [f3d324a9cc] to [c23d3aed04].

25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41







-
+










/*!
 * @brief A class which provides functions to create and use stream sockets.
 */
@interface OFStreamSocket: OFStream
{
	int  _socket;
	BOOL _atEndOfStream;
	bool _atEndOfStream;
}

/*!
 * @brief Returns a new, autoreleased OFTCPSocket.
 *
 * @return A new, autoreleased OFTCPSocket
 */
+ (instancetype)socket;
@end

Modified src/OFStreamSocket.m from [a7e950a736] to [9ccd3888ba].

61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75







-
+







#endif

+ (instancetype)socket
{
	return [[[self alloc] init] autorelease];
}

- (BOOL)lowlevelIsAtEndOfStream
- (bool)lowlevelIsAtEndOfStream
{
	return _atEndOfStream;
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer
			  length: (size_t)length
{
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110







-
+








	if ((ret = recv(_socket, buffer, length, 0)) < 0)
		@throw [OFReadFailedException exceptionWithClass: [self class]
							  stream: self
						 requestedLength: length];

	if (ret == 0)
		_atEndOfStream = YES;
		_atEndOfStream = true;

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
		     length: (size_t)length
{
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144







-
+







	if (send(_socket, buffer, length, 0) < length)
		@throw [OFWriteFailedException exceptionWithClass: [self class]
							   stream: self
						  requestedLength: length];
}

#ifdef _WIN32
- (void)setBlocking: (BOOL)enable
- (void)setBlocking: (bool)enable
{
	u_long v = enable;
	_blocking = enable;

	if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR)
		@throw [OFSetOptionFailedException
		    exceptionWithClass: [self class]
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176
177
178







-
+










	if (_socket == INVALID_SOCKET)
		@throw [OFNotConnectedException exceptionWithClass: [self class]
							    socket: self];

	close(_socket);
	_socket = INVALID_SOCKET;

	_atEndOfStream = NO;
	_atEndOfStream = false;
}

- (void)dealloc
{
	if (_socket != INVALID_SOCKET)
		[self close];

	[super dealloc];
}
@end

Modified src/OFString+JSONValue.m from [16be464aa0] to [b110ce39ff].

60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74







-
+








	if (*pointer + 1 >= stop)
		return;

	(*pointer)++;

	if (**pointer == '*') {
		BOOL lastIsAsterisk = NO;
		bool lastIsAsterisk = false;

		(*pointer)++;

		while (*pointer < stop) {
			if (lastIsAsterisk && **pointer == '/') {
				(*pointer)++;
				return;
531
532
533
534
535
536
537
538
539


540
541
542
543
544
545
546

547
548
549
550
551
552
553
531
532
533
534
535
536
537


538
539
540
541
542
543
544
545

546
547
548
549
550
551
552
553







-
-
+
+






-
+







	return dictionary;
}

static inline OFNumber*
parseNumber(const char *restrict *pointer, const char *stop,
    size_t *restrict line)
{
	BOOL isHex = (*pointer + 1 < stop && (*pointer)[1] == 'x');
	BOOL hasDecimal = NO;
	bool isHex = (*pointer + 1 < stop && (*pointer)[1] == 'x');
	bool hasDecimal = false;
	size_t i;
	OFString *string;
	OFNumber *number;

	for (i = 0; *pointer + i < stop; i++) {
		if ((*pointer)[i] == '.')
			hasDecimal = YES;
			hasDecimal = true;

		if ((*pointer)[i] == ' ' || (*pointer)[i] == '\t' ||
		    (*pointer)[i] == '\r' || (*pointer)[i] == '\n' ||
		    (*pointer)[i] == ',' || (*pointer)[i] == ']' ||
		    (*pointer)[i] == '}') {
			if ((*pointer)[i] == '\n')
				(*line)++;
603
604
605
606
607
608
609
610

611
612
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
603
604
605
606
607
608
609

610
611
612
613
614
615
616
617
618
619

620
621
622
623
624
625
626
627







-
+









-
+







			return nil;

		if (memcmp(*pointer, "true", 4))
			return nil;

		(*pointer) += 4;

		return [OFNumber numberWithBool: YES];
		return [OFNumber numberWithBool: true];
	case 'f':
		if (*pointer + 4 >= stop)
			return nil;

		if (memcmp(*pointer, "false", 5))
			return nil;

		(*pointer) += 5;

		return [OFNumber numberWithBool: NO];
		return [OFNumber numberWithBool: false];
	case 'n':
		if (*pointer + 3 >= stop)
			return nil;

		if (memcmp(*pointer, "null", 4))
			return nil;

Modified src/OFString+XMLUnescaping.m from [9234efc5e1] to [467acead25].

82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113







-
+








-
+







-
+







}

- (OFString*)stringByXMLUnescapingWithDelegate:
    (id <OFStringXMLUnescapingDelegate>)delegate
{
	const char *string;
	size_t i, last, length;
	BOOL inEntity;
	bool inEntity;
	OFMutableString *ret;

	string = [self UTF8String];
	length = [self UTF8StringLength];

	ret = [OFMutableString string];

	last = 0;
	inEntity = NO;
	inEntity = false;

	for (i = 0; i < length; i++) {
		if (!inEntity && string[i] == '&') {
			[ret appendUTF8String: string + last
				       length: i - last];

			last = i + 1;
			inEntity = YES;
			inEntity = true;
		} else if (inEntity && string[i] == ';') {
			const char *entity = string + last;
			size_t entityLength = i - last;

			if (entityLength == 2 && !memcmp(entity, "lt", 2))
				[ret appendCString: "<"
					  encoding: OF_STRING_ENCODING_ASCII
163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177







-
+







				[ret appendString: tmp];
				objc_autoreleasePoolPop(pool);
			} else
				@throw [OFInvalidEncodingException
				    exceptionWithClass: [self class]];

			last = i + 1;
			inEntity = NO;
			inEntity = false;
		}
	}

	if (inEntity)
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];

185
186
187
188
189
190
191
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
185
186
187
188
189
190
191

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







-
+








-
+







-
+








#ifdef OF_HAVE_BLOCKS
- (OFString*)stringByXMLUnescapingWithBlock:
    (of_string_xml_unescaping_block_t)block
{
	const char *string;
	size_t i, last, length;
	BOOL inEntity;
	bool inEntity;
	OFMutableString *ret;

	string = [self UTF8String];
	length = [self UTF8StringLength];

	ret = [OFMutableString string];

	last = 0;
	inEntity = NO;
	inEntity = false;

	for (i = 0; i < length; i++) {
		if (!inEntity && string[i] == '&') {
			[ret appendUTF8String: string + last
				       length: i - last];

			last = i + 1;
			inEntity = YES;
			inEntity = true;
		} else if (inEntity && string[i] == ';') {
			const char *entity = string + last;
			size_t entityLength = i - last;

			if (entityLength == 2 && !memcmp(entity, "lt", 2))
				[ret appendCString: "<"
					  encoding: OF_STRING_ENCODING_ASCII
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277







-
+







					    exceptionWithClass: [self class]];

				[ret appendString: tmp];
				objc_autoreleasePoolPop(pool);
			}

			last = i + 1;
			inEntity = NO;
			inEntity = false;
		}
	}

	if (inEntity)
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];

Modified src/OFString.h from [e626a11209] to [855049f2d1].

65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79







-
+







	OF_STRING_SKIP_EMPTY	   = 2
};

/* FIXME */
#define OF_STRING_ENCODING_NATIVE OF_STRING_ENCODING_UTF_8

#ifdef OF_HAVE_BLOCKS
typedef void (^of_string_line_enumeration_block_t)(OFString *line, BOOL *stop);
typedef void (^of_string_line_enumeration_block_t)(OFString *line, bool *stop);
#endif

@class OFArray;
@class OFURL;

/*!
 * @brief A class for handling strings.
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130







-
+







 *
 * @param UTF8String A UTF-8 encoded C string to initialize the OFString with
 * @param freeWhenDone Whether to free the C string when the OFString gets
 *		       deallocated
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF8StringNoCopy: (char*)UTF8String
			      freeWhenDone: (BOOL)freeWhenDone;
			      freeWhenDone: (bool)freeWhenDone;

/*!
 * @brief Creates a new OFString from a C string with the specified encoding.
 *
 * @param cString A C string to initialize the OFString with
 * @param encoding The encoding of the C string
 * @return A new autoreleased OFString
344
345
346
347
348
349
350
351

352
353
354
355
356
357
358
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358







-
+







 *
 * @param UTF8String A UTF-8 encoded C string to initialize the OFString with
 * @param freeWhenDone Whether to free the C string when it is not needed
 *		       anymore
 * @return An initialized OFString
 */
- initWithUTF8StringNoCopy: (char*)UTF8String
	      freeWhenDone: (BOOL)freeWhenDone;
	      freeWhenDone: (bool)freeWhenDone;

/*!
 * @brief Initializes an already allocated OFString from a C string with the
 *	  specified encoding.
 *
 * @param cString A C string to initialize the OFString with
 * @param encoding The encoding of the C string
703
704
705
706
707
708
709
710

711
712
713
714
715
716
717
703
704
705
706
707
708
709

710
711
712
713
714
715
716
717







-
+








/*!
 * @brief Returns whether the string contains the specified string.
 *
 * @param string The string to search
 * @return Whether the string contains the specified string
 */
- (BOOL)containsString: (OFString*)string;
- (bool)containsString: (OFString*)string;

/*!
 * @brief Creates a substring with the specified range.
 *
 * @param range The range of the substring
 * @return The substring as a new autoreleased OFString
 */
836
837
838
839
840
841
842
843

844
845
846
847
848
849
850
851

852
853
854
855
856
857
858
836
837
838
839
840
841
842

843
844
845
846
847
848
849
850

851
852
853
854
855
856
857
858







-
+







-
+








/*!
 * @brief Checks whether the string has the specified prefix.
 *
 * @param prefix The prefix to check for
 * @return A boolean whether the string has the specified prefix
 */
- (BOOL)hasPrefix: (OFString*)prefix;
- (bool)hasPrefix: (OFString*)prefix;

/*!
 * @brief Checks whether the string has the specified suffix.
 *
 * @param suffix The suffix to check for
 * @return A boolean whether the string has the specified suffix
 */
- (BOOL)hasSuffix: (OFString*)suffix;
- (bool)hasSuffix: (OFString*)suffix;

/*!
 * @brief Separates an OFString into an OFArray of OFStrings.
 *
 * @param delimiter The delimiter for separating
 * @return An autoreleased OFArray with the separated string
 */

Modified src/OFString.m from [2d59404d46] to [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
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;
	bool done = false;

	array = [[components mutableCopy] autorelease];

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

		done = YES;
		done = true;

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

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

				break;
			}

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

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

				done = NO;
				done = false;

				break;
			}
		}
	}

	ret = [[array componentsJoinedByString: joinString] retain];
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
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
	      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
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
			      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
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
	      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
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
- (bool)isEqual: (id)object
{
	void *pool;
	OFString *otherString;
	const of_unichar_t *characters, *otherCharacters;
	size_t length;

	if (object == self)
		return YES;
		return true;

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

	otherString = object;
	length = [self length];

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

	pool = objc_autoreleasePoolPush();

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

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

	objc_autoreleasePoolPop(pool);

	return YES;
	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
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
- (bool)containsString: (OFString*)string
{
	void *pool;
	const of_unichar_t *characters, *searchCharacters;
	size_t i, length, searchLength;

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

	if (searchLength > (length = [self length]))
		return NO;
		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 YES;
			return true;
		}
	}

	objc_autoreleasePoolPop(pool);

	return NO;
	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
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
- (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;
		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
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
- (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;
		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
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);
	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
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;
	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
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;
			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 = NO, foundValue = NO;
	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
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;
			foundValue = true;
		} else if (characters[i] >= 'A' && characters[i] <= 'F') {
			newValue = (value << 4) | (characters[i] - 'A' + 10);
			foundValue = YES;
			foundValue = true;
		} else if (characters[i] >= 'a' && characters[i] <= 'f') {
			newValue = (value << 4) | (characters[i] - 'a' + 10);
			foundValue = YES;
			foundValue = true;
		} else if (characters[i] == 'h' || characters[i] == ' ' ||
		    characters[i] == '\t' || characters[i] == '\n' ||
		    characters[i] == '\r' || characters[i] == '\f') {
			expectWhitespace = YES;
			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
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);
	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
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;
	bool stop = false, lastCarriageReturn = false;

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

			continue;
		}

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

Modified src/OFString_UTF8.h from [f4f94da890] to [9a39a2d989].

25
26
27
28
29
30
31
32

33
34

35
36
37
38
39
40
41
25
26
27
28
29
30
31

32
33

34
35
36
37
38
39
40
41







-
+

-
+







	 * Since constant strings don't have _storage, they have to malloc it
	 * on the first access. Strings created at runtime just set the pointer
	 * to &_storage.
	 */
	struct of_string_utf8_ivars {
		char	 *cString;
		size_t	 cStringLength;
		BOOL	 isUTF8;
		bool	 isUTF8;
		size_t	 length;
		BOOL	 hashed;
		bool	 hashed;
		uint32_t hash;
		char	 *freeWhenDone;
	} *restrict _s;
	struct of_string_utf8_ivars _storage;
}

- OF_initWithUTF8String: (const char*)UTF8String

Modified src/OFString_UTF8.m from [503640087e] to [3ce37a1895].

184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
184
185
186
187
188
189
190

191
192
193
194
195
196
197
198







-
+








		_s->cString = storage;
		_s->cStringLength = UTF8StringLength;

		switch (of_string_utf8_check(UTF8String, UTF8StringLength,
		    &_s->length)) {
		case 1:
			_s->isUTF8 = YES;
			_s->isUTF8 = true;
			break;
		case -1:
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];
		}

		memcpy(_s->cString, UTF8String, UTF8StringLength);
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245







-
+







			switch (of_string_utf8_check(cString, cStringLength,
			    &_s->length)) {
			case 1:
				if (encoding == OF_STRING_ENCODING_ASCII)
					@throw [OFInvalidEncodingException
					    exceptionWithClass: [self class]];

				_s->isUTF8 = YES;
				_s->isUTF8 = true;
				break;
			case -1:
				@throw [OFInvalidEncodingException
				    exceptionWithClass: [self class]];
			}

			memcpy(_s->cString, cString, cStringLength);
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271







-
+







				size_t bytes;

				if (!(cString[i] & 0x80)) {
					_s->cString[j++] = cString[i];
					continue;
				}

				_s->isUTF8 = YES;
				_s->isUTF8 = true;
				bytes = of_string_utf8_encode(
				    (uint8_t)cString[i], buffer);

				if (bytes == 0)
					@throw [OFInvalidEncodingException
					    exceptionWithClass: [self class]];

307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321







-
+








			character = table[(uint8_t)cString[i]];

			if (character == 0xFFFD)
				@throw [OFInvalidEncodingException
				    exceptionWithClass: [self class]];

			_s->isUTF8 = YES;
			_s->isUTF8 = true;
			characterBytes = of_string_utf8_encode(character,
			    buffer);

			if (characterBytes == 0)
				@throw [OFInvalidEncodingException
				    exceptionWithClass: [self class]];

334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348







-
+







		@throw e;
	}

	return self;
}

- initWithUTF8StringNoCopy: (char*)UTF8String
	      freeWhenDone: (BOOL)freeWhenDone
	      freeWhenDone: (bool)freeWhenDone
{
	self = [super init];

	@try {
		size_t UTF8StringLength = strlen(UTF8String);

		if (UTF8StringLength >= 3 &&
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372







-
+








		if (freeWhenDone)
			_s->freeWhenDone = UTF8String;

		switch (of_string_utf8_check(UTF8String, UTF8StringLength,
		    &_s->length)) {
		case 1:
			_s->isUTF8 = YES;
			_s->isUTF8 = true;
			break;
		case -1:
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];
		}
	} @catch (id e) {
		[self release];
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399







-
+








		_s->cStringLength = [string UTF8StringLength];

		if ([string isKindOfClass: [OFString_UTF8 class]] ||
		    [string isKindOfClass: [OFMutableString_UTF8 class]])
			_s->isUTF8 = ((OFString_UTF8*)string)->_s->isUTF8;
		else
			_s->isUTF8 = YES;
			_s->isUTF8 = true;

		_s->length = [string length];

		_s->cString = [self allocMemoryWithSize: _s->cStringLength + 1];
		memcpy(_s->cString, [string UTF8String], _s->cStringLength + 1);
	} @catch (id e) {
		[self release];
424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
424
425
426
427
428
429
430

431
432
433
434
435
436
437
438







-
+







			switch (len) {
			case 1:
				_s->cString[j++] = buffer[0];
				break;
			case 2:
			case 3:
			case 4:
				_s->isUTF8 = YES;
				_s->isUTF8 = true;

				memcpy(_s->cString + j, buffer, len);
				j += len;

				break;
			default:
				@throw [OFInvalidEncodingException
461
462
463
464
465
466
467
468

469
470
471
472
473
474

475
476
477
478

479
480
481
482
483
484
485
461
462
463
464
465
466
467

468
469
470
471
472
473

474
475
476
477

478
479
480
481
482
483
484
485







-
+





-
+



-
+







	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	self = [super init];

	@try {
		size_t i, j = 0;
		BOOL swap = NO;
		bool swap = false;

		if (length > 0 && *string == 0xFEFF) {
			string++;
			length--;
		} else if (length > 0 && *string == 0xFFFE) {
			swap = YES;
			swap = true;
			string++;
			length--;
		} else if (byteOrder != OF_BYTE_ORDER_NATIVE)
			swap = YES;
			swap = true;

		_s = &_storage;

		_s->cString = [self allocMemoryWithSize: (length * 4) + 1];
		_s->length = length;

		for (i = 0; i < length; i++) {
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534







-
+







			switch (len) {
			case 1:
				_s->cString[j++] = buffer[0];
				break;
			case 2:
			case 3:
			case 4:
				_s->isUTF8 = YES;
				_s->isUTF8 = true;

				memcpy(_s->cString + j, buffer, len);
				j += len;

				break;
			default:
				@throw [OFInvalidEncodingException
557
558
559
560
561
562
563
564

565
566
567
568
569
570

571
572
573
574

575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594

595
596
597
598
599
600
601
557
558
559
560
561
562
563

564
565
566
567
568
569

570
571
572
573

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593

594
595
596
597
598
599
600
601







-
+





-
+



-
+



















-
+







	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	self = [super init];

	@try {
		size_t i, j = 0;
		BOOL swap = NO;
		bool swap = false;

		if (length > 0 && *characters == 0xFEFF) {
			characters++;
			length--;
		} else if (length > 0 && *characters == 0xFFFE0000) {
			swap = YES;
			swap = true;
			characters++;
			length--;
		} else if (byteOrder != OF_BYTE_ORDER_NATIVE)
			swap = YES;
			swap = true;

		_s = &_storage;

		_s->cString = [self allocMemoryWithSize: (length * 4) + 1];
		_s->length = length;

		for (i = 0; i < length; i++) {
			char buffer[4];
			size_t len = of_string_utf8_encode(
			    (swap ? OF_BSWAP32(characters[i]) : characters[i]),
			    buffer);

			switch (len) {
			case 1:
				_s->cString[j++] = buffer[0];
				break;
			case 2:
			case 3:
			case 4:
				_s->isUTF8 = YES;
				_s->isUTF8 = true;

				memcpy(_s->cString + j, buffer, len);
				j += len;

				break;
			default:
				@throw [OFInvalidEncodingException
643
644
645
646
647
648
649
650

651
652
653
654
655
656
657
643
644
645
646
647
648
649

650
651
652
653
654
655
656
657







-
+








		_s->cStringLength = cStringLength;

		@try {
			switch (of_string_utf8_check(tmp, cStringLength,
			    &_s->length)) {
			case 1:
				_s->isUTF8 = YES;
				_s->isUTF8 = true;
				break;
			case -1:
				@throw [OFInvalidEncodingException
				    exceptionWithClass: [self class]];
			}

			_s->cString = [self
684
685
686
687
688
689
690
691

692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707

708
709
710
711
712
713
714
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706

707
708
709
710
711
712
713
714







-
+















-
+








		if ([firstComponent isKindOfClass: [OFString_UTF8 class]] ||
		    [firstComponent isKindOfClass:
		    [OFMutableString_UTF8 class]])
			_s->isUTF8 =
			    ((OFString_UTF8*)firstComponent)->_s->isUTF8;
		else
			_s->isUTF8 = YES;
			_s->isUTF8 = true;

		_s->length = [firstComponent length];

		/* Calculate length and see if we need UTF-8 */
		va_copy(argumentsCopy, arguments);
		while ((component = va_arg(argumentsCopy, OFString*)) != nil) {
			_s->cStringLength += 1 + [component UTF8StringLength];
			_s->length += 1 + [component length];

			if ([component isKindOfClass: [OFString_UTF8 class]] ||
			    [component isKindOfClass:
			    [OFMutableString_UTF8 class]])
				_s->isUTF8 =
				    ((OFString_UTF8*)component)->_s->isUTF8;
			else
				_s->isUTF8 = YES;
				_s->isUTF8 = true;
		}

		_s->cString = [self allocMemoryWithSize: _s->cStringLength + 1];

		cStringLength = [firstComponent UTF8StringLength];
		memcpy(_s->cString, [firstComponent UTF8String], cStringLength);
		i = cStringLength;
802
803
804
805
806
807
808
809

810
811
812
813
814

815
816
817

818
819
820
821
822
823

824
825
826
827
828
829

830
831
832

833
834

835
836
837
838
839
840
841
802
803
804
805
806
807
808

809
810
811
812
813

814
815
816

817
818
819
820
821
822

823
824
825
826
827
828

829
830
831

832
833

834
835
836
837
838
839
840
841







-
+




-
+


-
+





-
+





-
+


-
+

-
+







}

- (size_t)UTF8StringLength
{
	return _s->cStringLength;
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFString_UTF8 *otherString;

	if (object == self)
		return YES;
		return true;

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

	otherString = object;

	if ([otherString UTF8StringLength] != _s->cStringLength ||
	    [otherString length] != _s->length)
		return NO;
		return false;

	if (([otherString isKindOfClass: [OFString_UTF8 class]] ||
	    [otherString isKindOfClass: [OFMutableString_UTF8 class]]) &&
	    _s->hashed && otherString->_s->hashed &&
	    _s->hash != otherString->_s->hash)
		return NO;
		return false;

	if (strcmp(_s->cString, [otherString UTF8String]))
		return NO;
		return false;

	return YES;
	return true;
}

- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	OFString *otherString;
	size_t otherCStringLength, minimumCStringLength;
	int compare;
977
978
979
980
981
982
983
984

985
986
987
988
989
990
991
977
978
979
980
981
982
983

984
985
986
987
988
989
990
991







-
+








		i += length - 1;
	}

	OF_HASH_FINALIZE(hash);

	_s->hash = hash;
	_s->hashed = YES;
	_s->hashed = true;

	return hash;
}

- (of_unichar_t)characterAtIndex: (size_t)index
{
	of_unichar_t character;
1080
1081
1082
1083
1084
1085
1086
1087

1088
1089
1090
1091
1092
1093

1094
1095
1096

1097
1098
1099
1100

1101
1102

1103
1104
1105
1106
1107
1108
1109
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092

1093
1094
1095

1096
1097
1098
1099

1100
1101

1102
1103
1104
1105
1106
1107
1108
1109







-
+





-
+


-
+



-
+

-
+







			}
		}
	}

	return of_range(OF_NOT_FOUND, 0);
}

- (BOOL)containsString: (OFString*)string
- (bool)containsString: (OFString*)string
{
	const char *cString = [string UTF8String];
	size_t i, cStringLength = [string UTF8StringLength];

	if (cStringLength == 0)
		return YES;
		return true;

	if (cStringLength > _s->cStringLength)
		return NO;
		return false;

	for (i = 0; i <= _s->cStringLength - cStringLength; i++)
		if (!memcmp(_s->cString + i, cString, cStringLength))
			return YES;
			return true;

	return NO;
	return false;
}

- (OFString*)substringWithRange: (of_range_t)range
{
	size_t start = range.location;
	size_t end = range.location + range.length;

1117
1118
1119
1120
1121
1122
1123
1124

1125
1126
1127
1128
1129

1130
1131
1132
1133
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
1117
1118
1119
1120
1121
1122
1123

1124
1125
1126
1127
1128

1129
1130
1131
1132
1133

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







-
+




-
+




-
+




-
+












-
+







		    _s->cStringLength);
	}

	return [OFString stringWithUTF8String: _s->cString + start
				       length: end - start];
}

- (BOOL)hasPrefix: (OFString*)prefix
- (bool)hasPrefix: (OFString*)prefix
{
	size_t cStringLength = [prefix UTF8StringLength];

	if (cStringLength > _s->cStringLength)
		return NO;
		return false;

	return !memcmp(_s->cString, [prefix UTF8String], cStringLength);
}

- (BOOL)hasSuffix: (OFString*)suffix
- (bool)hasSuffix: (OFString*)suffix
{
	size_t cStringLength = [suffix UTF8StringLength];

	if (cStringLength > _s->cStringLength)
		return NO;
		return false;

	return !memcmp(_s->cString + (_s->cStringLength - cStringLength),
	    [suffix UTF8String], cStringLength);
}

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
				options: (int)options
{
	void *pool;
	OFMutableArray *array;
	const char *cString = [delimiter UTF8String];
	size_t cStringLength = [delimiter UTF8StringLength];
	BOOL skipEmpty = (options & OF_STRING_SKIP_EMPTY);
	bool skipEmpty = (options & OF_STRING_SKIP_EMPTY);
	size_t i, last;
	OFString *component;

	array = [OFMutableArray array];
	pool = objc_autoreleasePoolPush();

	if (cStringLength > _s->cStringLength) {
1372
1373
1374
1375
1376
1377
1378
1379

1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
1372
1373
1374
1375
1376
1377
1378

1379
1380
1381
1382

1383
1384
1385
1386
1387
1388
1389
1390







-
+



-
+








#ifdef OF_HAVE_BLOCKS
- (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block
{
	void *pool;
	const char *cString = _s->cString;
	const char *last = cString;
	BOOL stop = NO, lastCarriageReturn = NO;
	bool stop = false, lastCarriageReturn = false;

	while (!stop && *cString != 0) {
		if (lastCarriageReturn && *cString == '\n') {
			lastCarriageReturn = NO;
			lastCarriageReturn = false;

			cString++;
			last++;

			continue;
		}

Modified src/OFTCPSocket+SOCKS5.m from [34ea1ba63e] to [76d38f9e30].

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
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







-
+


















-
+








@implementation OFTCPSocket (SOCKS5)
- (void)OF_SOCKS5ConnectToHost: (OFString*)host
			  port: (uint16_t)port
{
	const char request[] = { 5, 1, 0, 3 };
	char reply[256];
	BOOL wasWriteBufferEnabled;
	bool wasWriteBufferEnabled;

	/* 5 1 0 -> no authentication */
	[self writeBuffer: request
		   length: 3];

	[self readIntoBuffer: reply
		 exactLength: 2];

	if (reply[0] != 5 || reply[1] != 0) {
		[self close];
		@throw [OFConnectionFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host
				  port: port];
	}

	wasWriteBufferEnabled = [self isWriteBufferEnabled];
	[self setWriteBufferEnabled: YES];
	[self setWriteBufferEnabled: true];

	/* CONNECT request */
	[self writeBuffer: request
		   length: 4];
	[self writeInt8: [host UTF8StringLength]];
	[self writeBuffer: [host UTF8String]
		   length: [host UTF8StringLength]];

Modified src/OFTCPSocket.h from [99ba0b78fd] to [b4d76328d1].

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
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







-
+











-
+







-
+







#endif

@class OFTCPSocket;
@class OFString;

#ifdef OF_HAVE_BLOCKS
typedef void (^of_tcpsocket_async_connect_block_t)(OFTCPSocket*, OFException*);
typedef BOOL (^of_tcpsocket_async_accept_block_t)(OFTCPSocket*, OFTCPSocket*,
typedef bool (^of_tcpsocket_async_accept_block_t)(OFTCPSocket*, OFTCPSocket*,
    OFException*);
#endif

/*!
 * @brief A class which provides functions to create and use TCP sockets.
 *
 * To connect to a server, create a socket and connect it.
 * To create a server, create a socket, bind it and listen on it.
 */
@interface OFTCPSocket: OFStreamSocket
{
	BOOL _listening;
	bool _listening;
	struct sockaddr_storage *_sockAddr;
	socklen_t _sockAddrLen;
	OFString *_SOCKS5Host;
	uint16_t _SOCKS5Port;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, getter=isListening) BOOL listening;
@property (readonly, getter=isListening) bool listening;
@property (copy) OFString *SOCKS5Host;
@property uint16_t SOCKS5Port;
#endif

/*!
 * @brief Sets the global SOCKS5 proxy host to use when creating a new socket
 *
196
197
198
199
200
201
202
203

204
205
206
207
208
209
210
196
197
198
199
200
201
202

203
204
205
206
207
208
209
210







-
+







 * @brief Asyncronously accept an incoming connection.
 *
 * @param target The target on which to execute the selector when a new
 *		 connection has been accepted. The method returns whether the
 *		 next incoming connection should be accepted by the specified
 *		 block as well.
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFTCPSocket *socket, OFTCPSocket *acceptedSocket,
 *		   bool (OFTCPSocket *socket, OFTCPSocket *acceptedSocket,
 *		   OFException *exception).
 */
- (void)asyncAcceptWithTarget: (id)target
		     selector: (SEL)selector;

#ifdef OF_HAVE_BLOCKS
/*!
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
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







-
+















-
+









#endif

/*!
 * @brief Enable or disable keep alives for the connection.
 *
 * @param enable Whether to enable or disable keep alives for the connection
 */
- (void)setKeepAlivesEnabled: (BOOL)enable;
- (void)setKeepAlivesEnabled: (bool)enable;

/*!
 * @brief Returns the remote address of the socket.
 *
 * Only works with accepted sockets!
 *
 * @return The remote address as a string
 */
- (OFString*)remoteAddress;

/*!
 * @brief Returns whether the socket is a listening socket.
 *
 * @return Whether the socket is a listening socket
 */
- (BOOL)isListening;
- (bool)isListening;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern Class of_tls_socket_class;
#ifdef __cplusplus
}
#endif

Modified src/OFTCPSocket.m from [742dd6ce2f] to [5920a82404].

211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225







-
+







				  port: _port];
	} @catch (OFException *e) {
		_exception = [[e retain] autorelease];
	}

	[self performSelector: @selector(didConnect)
		     onThread: _sourceThread
		waitUntilDone: NO];
		waitUntilDone: false];

	objc_autoreleasePoolPop(pool);

	return nil;
}
@end
#endif
277
278
279
280
281
282
283
284

285
286
287
288
289

290
291
292
293
294
295
296
277
278
279
280
281
282
283

284
285
286
287
288

289
290
291
292
293
294
295
296







-
+




-
+







	[_SOCKS5Host release];

	[super dealloc];
}

- (void)setSOCKS5Host: (OFString*)SOCKS5Host
{
	OF_SETTER(_SOCKS5Host, SOCKS5Host, YES, 1)
	OF_SETTER(_SOCKS5Host, SOCKS5Host, true, 1)
}

- (OFString*)SOCKS5Host
{
	OF_GETTER(_SOCKS5Host, YES)
	OF_GETTER(_SOCKS5Host, true)
}

- (void)setSOCKS5Port: (uint16_t)SOCKS5Port
{
	_SOCKS5Port = SOCKS5Port;
}

345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359







-
+







		}

		break;
	}

	freeaddrinfo(res0);
#else
	BOOL connected = NO;
	bool connected = false;
	struct hostent *he;
	struct sockaddr_in addr;
	char **ip;
# ifdef OF_HAVE_THREADS
	OFDataArray *addrlist;

	addrlist = [[OFDataArray alloc] initWithItemSize: sizeof(char**)];
409
410
411
412
413
414
415
416

417
418
419
420
421
422
423
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423







-
+







# endif
		memcpy(&addr.sin_addr.s_addr, *ip, he->h_length);

		if (connect(_socket, (struct sockaddr*)&addr,
		    sizeof(addr)) == -1)
			continue;

		connected = YES;
		connected = true;
		break;
	}

# ifdef OF_HAVE_THREADS
	[addrlist release];
# endif

631
632
633
634
635
636
637
638

639
640
641
642
643
644
645
631
632
633
634
635
636
637

638
639
640
641
642
643
644
645







-
+







							    socket: self];

	if (listen(_socket, backLog) == -1)
		@throw [OFListenFailedException exceptionWithClass: [self class]
							    socket: self
							   backLog: backLog];

	_listening = YES;
	_listening = true;
}

- (void)listen
{
	[self listenWithBackLog: SOMAXCONN];
}

678
679
680
681
682
683
684
685

686
687
688
689
690
691
692
678
679
680
681
682
683
684

685
686
687
688
689
690
691
692







-
+







- (void)asyncAcceptWithBlock: (of_tcpsocket_async_accept_block_t)block
{
	[OFRunLoop OF_addAsyncAcceptForTCPSocket: self
					   block: block];
}
#endif

- (void)setKeepAlivesEnabled: (BOOL)enable
- (void)setKeepAlivesEnabled: (bool)enable
{
	int v = enable;

	if (setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&v, sizeof(v)))
		@throw [OFSetOptionFailedException
		    exceptionWithClass: [self class]
				stream: self];
736
737
738
739
740
741
742
743

744
745
746
747
748
749
750
751
752

753
754
755
756
757
736
737
738
739
740
741
742

743
744
745
746
747
748
749
750
751

752
753
754
755
756
757







-
+








-
+





# endif
#endif

	/* Get rid of a warning, never reached anyway */
	assert(0);
}

- (BOOL)isListening
- (bool)isListening
{
	return _listening;
}

- (void)close
{
	[super close];

	_listening = NO;
	_listening = false;
	[self freeMemory: _sockAddr];
	_sockAddr = NULL;
	_sockAddrLen = 0;
}
@end

Modified src/OFTLSKey.h from [9ad9a41960] to [cf323057cd].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44







-
+







@interface OFTLSKey: OFObject
{
@public
	of_tlskey_t _key;
@protected
	void (*_destructor)(id);
	of_list_object_t *_listObject;
	BOOL _initialized;
	bool _initialized;
}

/*!
 * @brief Creates a new Thread Local Storage key
 *
 * @return A new, autoreleased Thread Local Storage key
 */

Modified src/OFTLSKey.m from [90e1fd67d0] to [4d1766e66c].

59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73







-
+







	self = [super init];

	@try {
		if (!of_tlskey_new(&_key))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		_initialized = YES;
		_initialized = true;

		@synchronized (TLSKeys) {
			_listObject = [TLSKeys appendObject: self];
		}
	} @catch (id e) {
		[self release];
		@throw e;

Modified src/OFTLSSocket.h from [262e8ae0bb] to [dde8b87a0d].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44







-
+







 *
 * @param socket The socket which wants to know if it should accept the received
 *		 keychain
 * @param keychain An array of objects implementing the OFX509Certificate
 *		   protocol
 * @return Whether the TLS socket should accept the received keychain
 */
-	  (BOOL)socket: (id <OFTLSSocket>)socket
-	  (bool)socket: (id <OFTLSSocket>)socket
  shouldAcceptKeychain: (OFArray*)keychain;
@end

/*!
 * @brief A protocol that should be implemented by 3rd-party libraries
 *	  implementing TLS.
 */

Modified src/OFThread.m from [d1deb64582] to [36c4793f97].

344
345
346
347
348
349
350
351

352
353
354
355
356

357
358
359
360
361
362
363
344
345
346
347
348
349
350

351
352
353
354
355

356
357
358
359
360
361
362
363







-
+




-
+







#endif

	return [[_runLoop retain] autorelease];
}

- (OFString*)name
{
	OF_GETTER(_name, YES)
	OF_GETTER(_name, true)
}

- (void)setName: (OFString*)name
{
	OF_SETTER(_name, name, YES, 1)
	OF_SETTER(_name, name, true, 1)

	if (_running == OF_THREAD_RUNNING)
		set_thread_name(self);
}

- (void)dealloc
{

Modified src/OFThreadPool.m from [75625ed3ab] to [0d55db513d].

126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140







-
+







@end

@interface OFThreadPoolThread: OFThread
{
	OFList *_queue;
	OFCondition *_queueCondition, *_countCondition;
@public
	volatile BOOL _terminate;
	volatile bool _terminate;
	volatile int *_doneCount;
}

+ (instancetype)threadWithThreadPool: (OFThreadPool*)threadPool;
- initWithThreadPool: (OFThreadPool*)threadPool;
@end

303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317







-
+







	@try {
		[_countCondition lock];
		@try {
			OFEnumerator *enumerator = [_threads objectEnumerator];
			OFThreadPoolThread *thread;

			while ((thread = [enumerator nextObject]) != nil)
				thread->_terminate = YES;
				thread->_terminate = true;
		} @finally {
			[_countCondition unlock];
		}

		[_queueCondition broadcast];
	} @finally {
		[_queueCondition unlock];

Modified src/OFTimer.h from [06b74b5159] to [eafb8bd36e].

33
34
35
36
37
38
39
40

41
42
43
44

45
46
47

48
49
50
51
52
53
54
33
34
35
36
37
38
39

40
41
42
43

44
45
46

47
48
49
50
51
52
53
54







-
+



-
+


-
+







@interface OFTimer: OFObject <OFComparing>
{
	OFDate *_fireDate;
	double _interval;
	id _target, _object1, _object2;
	SEL _selector;
	uint8_t _arguments;
	BOOL _repeats;
	bool _repeats;
#ifdef OF_HAVE_BLOCKS
	of_timer_block_t _block;
#endif
	BOOL _valid;
	bool _valid;
#ifdef OF_HAVE_THREADS
	OFCondition *_condition;
	BOOL _done;
	bool _done;
#endif
	OFRunLoop *_inRunLoop;
}

#ifdef OF_HAVE_PROPERTIES
@property (retain) OFDate *fireDate;
#endif
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
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
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
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
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
101
102
103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
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
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







-
+
















-
+




















-
+












-
+
















-
+
















-
+




















-
+












-
+



















-
+



















-
+







 * @param selector The selector to call on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (double)interval
					target: (id)target
				      selector: (SEL)selector
				       repeats: (BOOL)repeats;
				       repeats: (bool)repeats;

/*!
 * @brief Creates and schedules a new timer with the specified time interval.
 *
 * @param interval The time interval after which the timer should be executed
 *		   when fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object An object to pass when calling the selector on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (double)interval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object
				       repeats: (BOOL)repeats;
				       repeats: (bool)repeats;

/*!
 * @brief Creates and schedules a new timer with the specified time interval.
 *
 * @param interval The time interval after which the timer should be executed
 *		   when fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object1 The first object to pass when calling the selector on the
 *		  target
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (double)interval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object1
					object: (id)object2
				       repeats: (BOOL)repeats;
				       repeats: (bool)repeats;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Creates and schedules a new timer with the specified time interval.
 *
 * @param interval The time interval after which the timer should be executed
 *		   when fired
 * @param repeats Whether the timer repeats after it has been executed
 * @param block The block to invoke when the timer fires
 * @return A new, autoreleased timer
 */
+ (instancetype)scheduledTimerWithTimeInterval: (double)interval
				       repeats: (BOOL)repeats
				       repeats: (bool)repeats
					 block: (of_timer_block_t)block;
#endif

/*!
 * @brief Creates a new timer with the specified time interval.
 *
 * @param interval The time interval after which the timer should be executed
 *		   when fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (double)interval
			       target: (id)target
			     selector: (SEL)selector
			      repeats: (BOOL)repeats;
			      repeats: (bool)repeats;

/*!
 * @brief Creates a new timer with the specified time interval.
 *
 * @param interval The time interval after which the timer should be executed
 *		   when fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object An object to pass when calling the selector on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (double)interval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object
			      repeats: (BOOL)repeats;
			      repeats: (bool)repeats;

/*!
 * @brief Creates a new timer with the specified time interval.
 *
 * @param interval The time interval after which the timer should be executed
 *		   when fired
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object1 The first object to pass when calling the selector on the
 *		  target
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (double)interval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object1
			       object: (id)object2
			      repeats: (BOOL)repeats;
			      repeats: (bool)repeats;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Creates a new timer with the specified time interval.
 *
 * @param interval The time interval after which the timer should be executed
 *		   when fired
 * @param repeats Whether the timer repeats after it has been executed
 * @param block The block to invoke when the timer fires
 * @return A new, autoreleased timer
 */
+ (instancetype)timerWithTimeInterval: (double)interval
			      repeats: (BOOL)repeats
			      repeats: (bool)repeats
				block: (of_timer_block_t)block;
#endif

/*!
 * @brief Initializes an already allocated timer with the specified time
 *	  interval.
 *
 * @param fireDate The date at which the timer should fire
 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- initWithFireDate: (OFDate*)fireDate
	  interval: (double)interval
	    target: (id)target
	  selector: (SEL)selector
	   repeats: (BOOL)repeats;
	   repeats: (bool)repeats;

/*!
 * @brief Initializes an already allocated timer with the specified time
 *	  interval.
 *
 * @param fireDate The date at which the timer should fire
 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object An object to pass when calling the selector on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- initWithFireDate: (OFDate*)fireDate
	  interval: (double)interval
	    target: (id)target
	  selector: (SEL)selector
	    object: (id)object
	   repeats: (BOOL)repeats;
	   repeats: (bool)repeats;

/*!
 * @brief Initializes an already allocated timer with the specified time
 *	  interval.
 *
 * @param fireDate The date at which the timer should fire
 * @param interval The time interval after which to repeat the timer, if it is
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
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







-
+















-
+







 */
- initWithFireDate: (OFDate*)fireDate
	  interval: (double)interval
	    target: (id)target
	  selector: (SEL)selector
	    object: (id)object1
	    object: (id)object2
	   repeats: (BOOL)repeats;
	   repeats: (bool)repeats;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Initializes an already allocated timer with the specified time
 *	  interval.
 *
 * @param fireDate The date at which the timer should fire
 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param repeats Whether the timer repeats after it has been executed
 * @param block The block to invoke when the timer fires
 * @return An initialized timer
 */
- initWithFireDate: (OFDate*)fireDate
	  interval: (double)interval
	   repeats: (BOOL)repeats
	   repeats: (bool)repeats
	     block: (of_timer_block_t)block;
#endif

/*!
 * @brief Fires the timer, meaning it will execute the specified selector on the
 *	  target.
 */
300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314







-
+







- (void)invalidate;

/*!
 * @brief Returns whether the timer is valid.
 *
 * @return Whether the timer is valid
 */
- (BOOL)isValid;
- (bool)isValid;

/*!
 * @brief Returns the time interval in which the timer will repeat, if it is a
 *	  repeating timer.
 *
 * @return The time interval in which the timer will repeat, if it is a
 *	   repeating timer

Modified src/OFTimer.m from [f650b3c206] to [a9cca4ec95].

32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46







-
+







#import "autorelease.h"
#import "macros.h"

@implementation OFTimer
+ (instancetype)scheduledTimerWithTimeInterval: (double)interval
					target: (id)target
				      selector: (SEL)selector
				       repeats: (BOOL)repeats
				       repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: interval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: interval
					    target: target
					  selector: selector
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68







-
+







	return [timer autorelease];
}

+ (instancetype)scheduledTimerWithTimeInterval: (double)interval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object
				       repeats: (BOOL)repeats
				       repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: interval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: interval
					    target: target
					  selector: selector
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92







-
+







}

+ (instancetype)scheduledTimerWithTimeInterval: (double)interval
					target: (id)target
				      selector: (SEL)selector
					object: (id)object1
					object: (id)object2
				       repeats: (BOOL)repeats
				       repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: interval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: interval
					    target: target
					  selector: selector
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114







-
+







	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

#ifdef OF_HAVE_BLOCKS
+ (instancetype)scheduledTimerWithTimeInterval: (double)interval
				       repeats: (BOOL)repeats
				       repeats: (bool)repeats
					 block: (of_timer_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: interval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: interval
					   repeats: repeats
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156







-
+



















-
+







	return [timer autorelease];
}
#endif

+ (instancetype)timerWithTimeInterval: (double)interval
			       target: (id)target
			     selector: (SEL)selector
			      repeats: (BOOL)repeats
			      repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: interval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: interval
					    target: target
					  selector: selector
					   repeats: repeats] autorelease];

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

+ (instancetype)timerWithTimeInterval: (double)interval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object
			      repeats: (BOOL)repeats
			      repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: interval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: interval
					    target: target
					  selector: selector
164
165
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
164
165
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







-
+



















-
+







}

+ (instancetype)timerWithTimeInterval: (double)interval
			       target: (id)target
			     selector: (SEL)selector
			       object: (id)object1
			       object: (id)object2
			      repeats: (BOOL)repeats
			      repeats: (bool)repeats
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: interval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: interval
					    target: target
					  selector: selector
					    object: object1
					    object: object2
					   repeats: repeats] autorelease];

	[timer retain];
	objc_autoreleasePoolPop(pool);

	return [timer autorelease];
}

#ifdef OF_HAVE_BLOCKS
+ (instancetype)timerWithTimeInterval: (double)interval
			      repeats: (BOOL)repeats
			      repeats: (bool)repeats
				block: (of_timer_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: interval];
	id timer = [[[self alloc] initWithFireDate: fireDate
					  interval: interval
					   repeats: repeats
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
280
281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316

317
318
319
320
321
322
323
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
280
281
282
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305

306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323







-
+












-
+















-
+
















-
+

















-
+














-
+









-
+







- OF_initWithFireDate: (OFDate*)fireDate
	     interval: (double)interval
	       target: (id)target
	     selector: (SEL)selector
	       object: (id)object1
	       object: (id)object2
	    arguments: (uint8_t)arguments
	      repeats: (BOOL)repeats
	      repeats: (bool)repeats
{
	self = [super init];

	@try {
		_fireDate = [fireDate retain];
		_interval = interval;
		_target = [target retain];
		_selector = selector;
		_object1 = [object1 retain];
		_object2 = [object2 retain];
		_arguments = arguments;
		_repeats = repeats;
		_valid = YES;
		_valid = true;
#ifdef OF_HAVE_THREADS
		_condition = [[OFCondition alloc] init];
#endif
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithFireDate: (OFDate*)fireDate
	  interval: (double)interval
	    target: (id)target
	  selector: (SEL)selector
	   repeats: (BOOL)repeats
	   repeats: (bool)repeats
{
	return [self OF_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: nil
				  object: nil
			       arguments: 0
				 repeats: repeats];
}

- initWithFireDate: (OFDate*)fireDate
	  interval: (double)interval
	    target: (id)target
	  selector: (SEL)selector
	    object: (id)object
	   repeats: (BOOL)repeats
	   repeats: (bool)repeats
{
	return [self OF_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object
				  object: nil
			       arguments: 1
				 repeats: repeats];
}

- initWithFireDate: (OFDate*)fireDate
	  interval: (double)interval
	    target: (id)target
	  selector: (SEL)selector
	    object: (id)object1
	    object: (id)object2
	   repeats: (BOOL)repeats
	   repeats: (bool)repeats
{
	return [self OF_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object1
				  object: object2
			       arguments: 2
				 repeats: repeats];
}

#ifdef OF_HAVE_BLOCKS
- initWithFireDate: (OFDate*)fireDate
	   interval: (double)interval
	    repeats: (BOOL)repeats
	    repeats: (bool)repeats
	      block: (of_timer_block_t)block
{
	self = [super init];

	@try {
		_fireDate = [fireDate retain];
		_interval = interval;
		_repeats = repeats;
		_block = [block copy];
		_valid = YES;
		_valid = true;
# ifdef OF_HAVE_THREADS
		_condition = [[OFCondition alloc] init];
# endif
	} @catch (id e) {
		[self release];
		@throw e;
	}
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423
424
425

426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

442
443
444
445
446
447

448
449
450
451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466
467
468
469
470
471

472
473
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

415
416
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440

441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457

458
459
460
461
462
463
464
465
466
467
468
469
470

471
472
473







-
+



















-
+









-
+















-
+





-
+










-
+












-
+


#ifdef OF_HAVE_BLOCKS
	}
#endif

#ifdef OF_HAVE_THREADS
	[_condition lock];
	@try {
		_done = YES;
		_done = true;
		[_condition signal];
	} @finally {
		[_condition unlock];
	}
#endif

	if (_repeats && _valid) {
		OFDate *old = _fireDate;
		_fireDate = [[OFDate alloc]
		    initWithTimeIntervalSinceNow: _interval];
		[old release];

		[[OFRunLoop currentRunLoop] addTimer: self];
	} else
		[self invalidate];
}

- (OFDate*)fireDate
{
	OF_GETTER(_fireDate, YES)
	OF_GETTER(_fireDate, true)
}

- (void)setFireDate: (OFDate*)fireDate
{
	[self retain];
	@try {
		@synchronized (self) {
			[_inRunLoop OF_removeTimer: self];

			OF_SETTER(_fireDate, fireDate, YES, 0)
			OF_SETTER(_fireDate, fireDate, true, 0)

			[_inRunLoop addTimer: self];
		}
	} @finally {
		[self release];
	}
}

- (double)timeInterval
{
	return _interval;
}

- (void)invalidate
{
	_valid = NO;
	_valid = false;

	[_target release];
	_target = nil;
}

- (BOOL)isValid
- (bool)isValid
{
	return _valid;
}

#ifdef OF_HAVE_THREADS
- (void)waitUntilDone
{
	[_condition lock];
	@try {
		if (_done) {
			_done = NO;
			_done = false;
			return;
		}

		[_condition wait];
	} @finally {
		[_condition unlock];
	}
}
#endif

- (void)OF_setInRunLoop: (OFRunLoop*)inRunLoop
{
	OF_SETTER(_inRunLoop, inRunLoop, YES, 0)
	OF_SETTER(_inRunLoop, inRunLoop, true, 0)
}
@end

Modified src/OFURL.m from [fcf898c186] to [269af2cde7].

285
286
287
288
289
290
291
292

293
294
295
296
297

298
299
300
301
302

303
304

305
306

307
308

309
310
311

312
313

314
315
316

317
318
319

320
321
322

323
324

325
326
327
328
329
330
331
285
286
287
288
289
290
291

292
293
294
295
296

297
298
299
300
301

302
303

304
305

306
307

308
309
310

311
312

313
314
315

316
317
318

319
320
321

322
323

324
325
326
327
328
329
330
331







-
+




-
+




-
+

-
+

-
+

-
+


-
+

-
+


-
+


-
+


-
+

-
+







	[_parameters release];
	[_query release];
	[_fragment release];

	[super dealloc];
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFURL *URL;

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

	URL = object;

	if (![URL->_scheme isEqual: _scheme])
		return NO;
		return false;
	if (![URL->_host isEqual: _host])
		return NO;
		return false;
	if (URL->_port != _port)
		return NO;
		return false;
	if (URL->_user != _user && ![URL->_user isEqual: _user])
		return NO;
		return false;
	if (URL->_password != _password &&
	    ![URL->_password isEqual: _password])
		return NO;
		return false;
	if (![URL->_path isEqual: _path])
		return NO;
		return false;
	if (URL->_parameters != _parameters &&
	    ![URL->_parameters isEqual: _parameters])
		return NO;
		return false;
	if (URL->_query != _query &&
	    ![URL->_query isEqual: _query])
		return NO;
		return false;
	if (URL->_fragment != _fragment &&
	    ![URL->_fragment isEqual: _fragment])
		return NO;
		return false;

	return YES;
	return true;
}

- (uint32_t)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);
366
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381
382
383

384
385
386
387
388

389
390
391
392
393

394
395
396
397
398
399
400
401
402
403
404
405
406
407
408

409
410
411
412
413

414
415
416
417
418

419
420
421
422
423

424
425
426
427
428

429
430
431
432
433
434
435
436
437
438
439

440
441
442
443
444

445
446
447
448
449

450
451
452
453
454

455
456
457
458
459

460
461
462
463
464

465
466
467
468
469

470
471
472
473
474
475
476
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380
381
382

383
384
385
386
387

388
389
390
391
392

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407

408
409
410
411
412

413
414
415
416
417

418
419
420
421
422

423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438

439
440
441
442
443

444
445
446
447
448

449
450
451
452
453

454
455
456
457
458

459
460
461
462
463

464
465
466
467
468

469
470
471
472
473
474
475
476







-
+









-
+




-
+




-
+














-
+




-
+




-
+




-
+




-
+










-
+




-
+




-
+




-
+




-
+




-
+




-
+







	}

	return copy;
}

- (OFString*)scheme
{
	OF_GETTER(_scheme, YES)
	OF_GETTER(_scheme, true)
}

- (void)setScheme: (OFString*)scheme
{
	if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	OF_SETTER(_scheme, scheme, YES, 1)
	OF_SETTER(_scheme, scheme, true, 1)
}

- (OFString*)host
{
	OF_GETTER(_host, YES)
	OF_GETTER(_host, true)
}

- (void)setHost: (OFString*)host
{
	OF_SETTER(_host, host, YES, 1)
	OF_SETTER(_host, host, true, 1)
}

- (uint16_t)port
{
	return _port;
}

- (void)setPort: (uint16_t)port
{
	_port = port;
}

- (OFString*)user
{
	OF_GETTER(_user, YES)
	OF_GETTER(_user, true)
}

- (void)setUser: (OFString*)user
{
	OF_SETTER(_user, user, YES, 1)
	OF_SETTER(_user, user, true, 1)
}

- (OFString*)password
{
	OF_GETTER(_password, YES)
	OF_GETTER(_password, true)
}

- (void)setPassword: (OFString*)password
{
	OF_SETTER(_password, password, YES, 1)
	OF_SETTER(_password, password, true, 1)
}

- (OFString*)path
{
	OF_GETTER(_path, YES)
	OF_GETTER(_path, true)
}

- (void)setPath: (OFString*)path
{
	if (([_scheme isEqual: @"http"] || [_scheme isEqual: @"https"]) &&
	    ![path hasPrefix: @"/"])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	OF_SETTER(_path, path, YES, 1)
	OF_SETTER(_path, path, true, 1)
}

- (OFString*)parameters
{
	OF_GETTER(_parameters, YES)
	OF_GETTER(_parameters, true)
}

- (void)setParameters: (OFString*)parameters
{
	OF_SETTER(_parameters, parameters, YES, 1)
	OF_SETTER(_parameters, parameters, true, 1)
}

- (OFString*)query
{
	OF_GETTER(_query, YES)
	OF_GETTER(_query, true)
}

- (void)setQuery: (OFString*)query
{
	OF_SETTER(_query, query, YES, 1)
	OF_SETTER(_query, query, true, 1)
}

- (OFString*)fragment
{
	OF_GETTER(_fragment, YES)
	OF_GETTER(_fragment, true)
}

- (void)setFragment: (OFString*)fragment
{
	OF_SETTER(_fragment, fragment, YES, 1)
	OF_SETTER(_fragment, fragment, true, 1)
}

- (OFString*)string
{
	OFMutableString *ret = [OFMutableString stringWithFormat: @"%@://",
								  _scheme];

Modified src/OFXMLAttribute.m from [a242f67939] to [7c243af737].

105
106
107
108
109
110
111
112

113
114
115
116
117

118
119
120
121
122

123
124
125

126
127
128
129
130

131
132
133
134
135

136
137
138

139
140

141
142

143
144
145
146
147
148
149
105
106
107
108
109
110
111

112
113
114
115
116

117
118
119
120
121

122
123
124

125
126
127
128
129

130
131
132
133
134

135
136
137

138
139

140
141

142
143
144
145
146
147
148
149







-
+




-
+




-
+


-
+




-
+




-
+


-
+

-
+

-
+







	[_stringValue release];

	[super dealloc];
}

- (OFString*)name
{
	OF_GETTER(_name, YES)
	OF_GETTER(_name, true)
}

- (OFString*)namespace
{
	OF_GETTER(_namespace, YES)
	OF_GETTER(_namespace, true)
}

- (OFString*)stringValue
{
	OF_GETTER(_stringValue, YES)
	OF_GETTER(_stringValue, true)
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFXMLAttribute *attribute;

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

	attribute = object;

	if (![attribute->_name isEqual: _name])
		return NO;
		return false;
	if (attribute->_namespace != _namespace &&
	    ![attribute->_namespace isEqual: _namespace])
		return NO;
		return false;
	if (![attribute->_stringValue isEqual: _stringValue])
		return NO;
		return false;

	return YES;
	return true;
}

- (uint32_t)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

Modified src/OFXMLCDATA.m from [3a90c3abbf] to [23c76edb90].

64
65
66
67
68
69
70
71

72
73
74
75
76

77
78
79
80
81
82
83
64
65
66
67
68
69
70

71
72
73
74
75

76
77
78
79
80
81
82
83







-
+




-
+







		[self release];
		@throw e;
	}

	return self;
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFXMLCDATA *CDATA;

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

	CDATA = object;

	return ([CDATA->_CDATA isEqual: _CDATA]);
}

- (uint32_t)hash

Modified src/OFXMLCharacters.m from [872a1be8d0] to [980de5ea74].

64
65
66
67
68
69
70
71

72
73
74
75
76

77
78
79
80
81
82
83
64
65
66
67
68
69
70

71
72
73
74
75

76
77
78
79
80
81
82
83







-
+




-
+







		[self release];
		@throw e;
	}

	return self;
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFXMLCharacters *characters;

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

	characters = object;

	return ([characters->_characters isEqual: _characters]);
}

- (uint32_t)hash

Modified src/OFXMLComment.m from [4d978dda45] to [664ced47ee].

66
67
68
69
70
71
72
73

74
75
76
77
78

79
80
81
82
83
84
85
66
67
68
69
70
71
72

73
74
75
76
77

78
79
80
81
82
83
84
85







-
+




-
+







		[self release];
		@throw e;
	}

	return self;
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFXMLComment *comment;

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

	comment = object;

	return ([comment->_comment isEqual: _comment]);
}

- (uint32_t)hash

Modified src/OFXMLElement.m from [177671f0ee] to [a91eb986c2].

401
402
403
404
405
406
407
408

409
410
411
412
413

414
415
416
417
418

419
420
421
422
423

424
425
426
427
428

429
430
431
432
433

434
435
436
437
438

439
440
441
442
443
444
445
401
402
403
404
405
406
407

408
409
410
411
412

413
414
415
416
417

418
419
420
421
422

423
424
425
426
427

428
429
430
431
432

433
434
435
436
437

438
439
440
441
442
443
444
445







-
+




-
+




-
+




-
+




-
+




-
+




-
+







- (void)setName: (OFString*)name
{
	if (name == nil)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	OF_SETTER(_name, name, YES, 1)
	OF_SETTER(_name, name, true, 1)
}

- (OFString*)name
{
	OF_GETTER(_name, YES)
	OF_GETTER(_name, true)
}

- (void)setNamespace: (OFString*)namespace
{
	OF_SETTER(_namespace, namespace, YES, 1)
	OF_SETTER(_namespace, namespace, true, 1)
}

- (OFString*)namespace
{
	OF_GETTER(_namespace, YES)
	OF_GETTER(_namespace, true)
}

- (OFArray*)attributes
{
	OF_GETTER(_attributes, YES)
	OF_GETTER(_attributes, true)
}

- (void)setChildren: (OFArray*)children
{
	OF_SETTER(_children, children, YES, 2)
	OF_SETTER(_children, children, true, 2)
}

- (OFArray*)children
{
	OF_GETTER(_children, YES)
	OF_GETTER(_children, true)
}

- (void)setStringValue: (OFString*)stringValue
{
	void *pool = objc_autoreleasePoolPush();

	[self setChildren: [OFArray arrayWithObject:
622
623
624
625
626
627
628
629

630
631
632

633
634
635
636
637
638

639
640
641
642
643

644
645
646
647
648
649
650
622
623
624
625
626
627
628

629
630
631

632
633
634
635
636
637

638
639
640
641
642

643
644
645
646
647
648
649
650







-
+


-
+





-
+




-
+







	}

	/* Childen */
	if (_children != nil) {
		OFXMLElement **childrenObjects = [_children objects];
		size_t childrenCount = [_children count];
		OFDataArray *tmp = [OFDataArray dataArray];
		BOOL indent;
		bool indent;

		if (indentation > 0) {
			indent = YES;
			indent = true;

			for (j = 0; j < childrenCount; j++) {
				if ([childrenObjects[j] isKindOfClass:
				    charactersClass] || [childrenObjects[j]
				    isKindOfClass: CDATAClass]) {
					indent = NO;
					indent = false;
					break;
				}
			}
		} else
			indent = NO;
			indent = false;

		for (j = 0; j < childrenCount; j++) {
			OFString *child;
			unsigned int ind = (indent ? indentation : 0);

			if (ind)
				[tmp addItem: "\n"];
940
941
942
943
944
945
946
947

948
949
950
951
952

953
954
955
956
957
958
959
940
941
942
943
944
945
946

947
948
949
950
951

952
953
954
955
956
957
958
959







-
+




-
+







	[self addAttributeWithName: prefix
			 namespace: @"http://www.w3.org/2000/xmlns/"
		       stringValue: namespace];
}

- (OFString*)defaultNamespace
{
	OF_GETTER(_defaultNamespace, YES)
	OF_GETTER(_defaultNamespace, true)
}

- (void)setDefaultNamespace: (OFString*)defaultNamespace
{
	OF_SETTER(_defaultNamespace, defaultNamespace, YES, 1)
	OF_SETTER(_defaultNamespace, defaultNamespace, true, 1)
}

- (void)addChild: (OFXMLNode*)child
{
	if ([child isKindOfClass: [OFXMLAttribute class]])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
1121
1122
1123
1124
1125
1126
1127
1128

1129
1130
1131
1132
1133

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
1121
1122
1123
1124
1125
1126
1127

1128
1129
1130
1131
1132

1133
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







-
+




-
+




-
+


-
+


-
+


-
+


-
+


-
+

-
+







			[ret addObject: objects[i]];

	[ret makeImmutable];

	return ret;
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFXMLElement *element;

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

	element = object;

	if (element->_name != _name && ![element->_name isEqual: _name])
		return NO;
		return false;
	if (element->_namespace != _namespace &&
	    ![element->_namespace isEqual: _namespace])
		return NO;
		return false;
	if (element->_defaultNamespace != _defaultNamespace &&
	    ![element->_defaultNamespace isEqual: _defaultNamespace])
		return NO;
		return false;
	if (element->_attributes != _attributes &&
	    ![element->_attributes isEqual: _attributes])
		return NO;
		return false;
	if (element->_namespaces != _namespaces &&
	    ![element->_namespaces isEqual: _namespaces])
		return NO;
		return false;
	if (element->_children != _children &&
	    ![element->_children isEqual: _children])
		return NO;
		return false;

	return YES;
	return true;
}

- (uint32_t)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

Modified src/OFXMLParser.h from [366806b936] to [586e50cb7b].

151
152
153
154
155
156
157
158

159
160

161
162
163
164
165
166
167
151
152
153
154
155
156
157

158
159

160
161
162
163
164
165
166
167







-
+

-
+







	OFDataArray *_buffer;
	OFString *_name, *_prefix;
	OFMutableArray *_namespaces, *_attributes;
	OFString *_attributeName, *_attributePrefix;
	char _delimiter;
	OFMutableArray *_previous;
	size_t _level;
	BOOL _acceptProlog;
	bool _acceptProlog;
	size_t _lineNumber;
	BOOL _lastCarriageReturn, _finishedParsing;
	bool _lastCarriageReturn, _finishedParsing;
	of_string_encoding_t _encoding;
	size_t _depthLimit;
}

#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFXMLParserDelegate> delegate;
@property size_t depthLimit;
244
245
246
247
248
249
250
251

252
253
254
255
244
245
246
247
248
249
250

251
252
253
254
255







-
+




- (size_t)lineNumber;

/*!
 * @brief Returns whether the XML parser has finished parsing.
 *
 * @return Whether the XML parser has finished parsing
 */
- (BOOL)finishedParsing;
- (bool)finishedParsing;
@end

@interface OFObject (OFXMLParserDelegate) <OFXMLParserDelegate>
@end

Modified src/OFXMLParser.m from [a35aa2dad5] to [a389df28b8].

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
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







-
+




-
+
















-
+







		[buffer addItems: [tmp UTF8String]
			   count: [tmp UTF8StringLength]];
		objc_autoreleasePoolPop(pool);
	}
}

static OFString*
transform_string(OFDataArray *buffer, size_t cut, BOOL unescape,
transform_string(OFDataArray *buffer, size_t cut, bool unescape,
    id <OFStringXMLUnescapingDelegate> delegate)
{
	char *items;
	size_t i, length;
	BOOL hasEntities = NO;
	bool hasEntities = false;
	OFString *ret;

	items = [buffer items];
	length = [buffer count] - cut;

	for (i = 0; i < length; i++) {
		if (items[i] == '\r') {
			if (i + 1 < length && items[i + 1] == '\n') {
				[buffer removeItemAtIndex: i];
				items = [buffer items];

				i--;
				length--;
			} else
				items[i] = '\n';
		} else if (items[i] == '&')
			hasEntities = YES;
			hasEntities = true;
	}

	ret = [OFString stringWithUTF8String: items
				      length: length];

	if (unescape && hasEntities)
		return [ret stringByXMLUnescapingWithDelegate: delegate];
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206







-
+








		pool = objc_autoreleasePoolPush();
		dict = [OFMutableDictionary dictionaryWithKeysAndObjects:
		    @"xml", @"http://www.w3.org/XML/1998/namespace",
		    @"xmlns", @"http://www.w3.org/2000/xmlns/", nil];
		[_namespaces addObject: dict];

		_acceptProlog = YES;
		_acceptProlog = true;
		_lineNumber = 1;
		_encoding = OF_STRING_ENCODING_UTF_8;
		_depthLimit = 32;

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
329
330
331
332
333
334
335
336

337
338
339
340
341
342
343
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343







-
+







		return;

	if ((length = *i - *last) > 0)
		buffer_append(_buffer, buffer + *last, _encoding, length);

	if ([_buffer count] > 0) {
		void *pool = objc_autoreleasePoolPush();
		OFString *characters = transform_string(_buffer, 0, YES, self);
		OFString *characters = transform_string(_buffer, 0, true, self);

		if ([_delegate respondsToSelector:
		    @selector(parser:foundCharacters:)])
			[_delegate parser: self
			  foundCharacters: characters];

		objc_autoreleasePoolPop(pool);
363
364
365
366
367
368
369
370

371
372
373
374
375

376
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401

402
403

404
405
406
407
408
409
410
363
364
365
366
367
368
369

370
371
372
373
374

375
376
377
378
379
380
381
382
383

384
385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400

401
402

403
404
405
406
407
408
409
410







-
+




-
+








-
+






-
+









-
+

-
+







		*last = *i + 1;
		_state = OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS;
		_level = 0;
		break;
	case '/':
		*last = *i + 1;
		_state = OF_XMLPARSER_IN_CLOSE_TAG_NAME;
		_acceptProlog = NO;
		_acceptProlog = false;
		break;
	case '!':
		*last = *i + 1;
		_state = OF_XMLPARSER_IN_EXCLAMATIONMARK;
		_acceptProlog = NO;
		_acceptProlog = false;
		break;
	default:
		if (_depthLimit > 0 && [_previous count] >= _depthLimit)
			@throw [OFMalformedXMLException
			    exceptionWithClass: [self class]
					parser: self];

		_state = OF_XMLPARSER_IN_TAG_NAME;
		_acceptProlog = NO;
		_acceptProlog = false;
		(*i)--;
		break;
	}
}

/* <?xml […]?> */
- (BOOL)OF_parseXMLProcessingInstructions: (OFString*)pi
- (bool)OF_parseXMLProcessingInstructions: (OFString*)pi
{
	const char *cString;
	size_t i, last, length;
	int PIState = 0;
	OFString *attribute = nil;
	OFMutableString *value = nil;
	char piDelimiter = 0;

	if (!_acceptProlog)
		return NO;
		return false;

	_acceptProlog = NO;
	_acceptProlog = false;

	pi = [pi substringWithRange: of_range(3, [pi length] - 3)];
	pi = [pi stringByDeletingEnclosingWhitespaces];

	cString = [pi UTF8String];
	length = [pi UTF8StringLength];

429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470

471
472
473
474
475
476
477
478
479
480
481

482
483

484
485
486
487
488
489
490
491
492
493
494
495
496
497
498

499
500
501
502
503
504
505
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452

453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
477
478
479
480

481
482

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
505







-
+
















-
+
















-
+










-
+

-
+














-
+







					  length: i - last];
			last = i + 1;
			PIState = 2;

			break;
		case 2:
			if (cString[i] != '\'' && cString[i] != '"')
				return NO;
				return false;

			piDelimiter = cString[i];
			last = i + 1;
			PIState = 3;

			break;
		case 3:
			if (cString[i] != piDelimiter)
				continue;

			value = [OFMutableString
			    stringWithUTF8String: cString + last
					  length: i - last];

			if ([attribute isEqual: @"version"])
				if (![value hasPrefix: @"1."])
					return NO;
					return false;

			if ([attribute isEqual: @"encoding"]) {
				[value lowercase];

				if ([value isEqual: @"utf-8"])
					_encoding = OF_STRING_ENCODING_UTF_8;
				else if ([value isEqual: @"iso-8859-1"])
					_encoding =
					    OF_STRING_ENCODING_ISO_8859_1;
				else if ([value isEqual: @"iso-8859-15"])
					_encoding =
					    OF_STRING_ENCODING_ISO_8859_15;
				else if ([value isEqual: @"windows-1252"])
					_encoding =
					    OF_STRING_ENCODING_WINDOWS_1252;
				else
					return NO;
					return false;
			}

			last = i + 1;
			PIState = 0;

			break;
		}
	}

	if (PIState != 0)
		return NO;
		return false;

	return YES;
	return true;
}

/* Inside processing instructions */
- (void)OF_parseInProcessingInstructionsWithBuffer: (const char*)buffer
						 i: (size_t*)i
					      last: (size_t*)last
{
	if (buffer[*i] == '?')
		_level = 1;
	else if (_level == 1 && buffer[*i] == '>') {
		void *pool = objc_autoreleasePoolPush();
		OFString *PI;

		buffer_append(_buffer, buffer + *last, _encoding, *i - *last);
		PI = transform_string(_buffer, 1, NO, nil);
		PI = transform_string(_buffer, 1, false, nil);

		if ([PI isEqual: @"xml"] || [PI hasPrefix: @"xml "] ||
		    [PI hasPrefix: @"xml\t"] || [PI hasPrefix: @"xml\r"] ||
		    [PI hasPrefix: @"xml\n"])
			if (![self OF_parseXMLProcessingInstructions: PI])
				@throw [OFMalformedXMLException
				    exceptionWithClass: [self class]
580
581
582
583
584
585
586
587

588
589
590
591
592
593
594
580
581
582
583
584
585
586

587
588
589
590
591
592
593
594







-
+







			    @selector(parser:didEndElement:prefix:namespace:)])
				[_delegate parser: self
				    didEndElement: _name
					   prefix: _prefix
					namespace: namespace];

			if ([_previous count] == 0)
				_finishedParsing = YES;
				_finishedParsing = true;
		} else
			[_previous addObject: bufferString];

		[_name release];
		[_prefix release];
		_name = _prefix = nil;

674
675
676
677
678
679
680
681

682
683
684
685
686
687
688
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688







-
+








	*last = *i + 1;
	_state = (buffer[*i] == '>'
	    ? OF_XMLPARSER_OUTSIDE_TAG
	    : OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE);

	if ([_previous count] == 0)
		_finishedParsing = YES;
		_finishedParsing = true;
}

/* Inside a tag, name found */
- (void)OF_parseInTagWithBuffer: (const char*)buffer
			      i: (size_t*)i
			   last: (size_t*)last
{
731
732
733
734
735
736
737
738

739
740
741
742
743
744
745
731
732
733
734
735
736
737

738
739
740
741
742
743
744
745







-
+







		    @selector(parser:didEndElement:prefix:namespace:)])
			[_delegate parser: self
			    didEndElement: _name
				   prefix: _prefix
				namespace: namespace];

		if ([_previous count] == 0)
			_finishedParsing = YES;
			_finishedParsing = true;

		[_namespaces removeLastObject];
	} else if (_prefix != nil) {
		OFString *str = [OFString stringWithFormat: @"%@:%@",
							    _prefix, _name];
		[_previous addObject: str];
	} else
837
838
839
840
841
842
843
844

845
846
847
848
849
850
851
837
838
839
840
841
842
843

844
845
846
847
848
849
850
851







-
+







	if (buffer[*i] != _delimiter)
		return;

	if ((length = *i - *last) > 0)
		buffer_append(_buffer, buffer + *last, _encoding, length);

	pool = objc_autoreleasePoolPush();
	attributeValue = transform_string(_buffer, 0, YES, self);
	attributeValue = transform_string(_buffer, 0, true, self);

	if (_attributePrefix == nil && [_attributeName isEqual: @"xmlns"])
		[[_namespaces lastObject] setObject: attributeValue
					     forKey: @""];
	if ([_attributePrefix isEqual: @"xmlns"])
		[[_namespaces lastObject] setObject: attributeValue
					     forKey: _attributeName];
960
961
962
963
964
965
966
967

968
969
970
971
972
973
974
960
961
962
963
964
965
966

967
968
969
970
971
972
973
974







-
+








		return;
	}

	pool = objc_autoreleasePoolPush();

	buffer_append(_buffer, buffer + *last, _encoding, *i - *last);
	CDATA = transform_string(_buffer, 2, NO, nil);
	CDATA = transform_string(_buffer, 2, false, nil);

	if ([_delegate respondsToSelector: @selector(parser:foundCDATA:)])
		[_delegate parser: self
		       foundCDATA: CDATA];

	objc_autoreleasePoolPop(pool);

1015
1016
1017
1018
1019
1020
1021
1022

1023
1024
1025
1026
1027
1028
1029
1015
1016
1017
1018
1019
1020
1021

1022
1023
1024
1025
1026
1027
1028
1029







-
+







	if (buffer[*i] != '>')
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	pool = objc_autoreleasePoolPush();

	buffer_append(_buffer, buffer + *last, _encoding, *i - *last);
	comment = transform_string(_buffer, 2, NO, nil);
	comment = transform_string(_buffer, 2, false, nil);

	if ([_delegate respondsToSelector: @selector(parser:foundComment:)])
		[_delegate parser: self
		     foundComment: comment];

	objc_autoreleasePoolPop(pool);

1058
1059
1060
1061
1062
1063
1064
1065

1066
1067
1068
1069
1070
1071
1072
1058
1059
1060
1061
1062
1063
1064

1065
1066
1067
1068
1069
1070
1071
1072







-
+







}

- (size_t)lineNumber
{
	return _lineNumber;
}

- (BOOL)finishedParsing
- (bool)finishedParsing
{
	return _finishedParsing;
}

-	   (OFString*)string: (OFString*)string
  containsUnknownEntityNamed: (OFString*)entity
{

Modified src/OFXMLProcessingInstructions.m from [ba4e0fdeba] to [30df94b534].

66
67
68
69
70
71
72
73

74
75
76
77
78

79
80
81
82
83
84
85
66
67
68
69
70
71
72

73
74
75
76
77

78
79
80
81
82
83
84
85







-
+




-
+







		[self release];
		@throw e;
	}

	return self;
}

- (BOOL)isEqual: (id)object
- (bool)isEqual: (id)object
{
	OFXMLProcessingInstructions *processingInstructions;

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

	processingInstructions = object;

	return ([processingInstructions->_processingInstructions
	    isEqual: _processingInstructions]);
}

Modified src/atomic.h from [e354f89407] to [a4f95ba0da].

652
653
654
655
656
657
658
659

660
661
662
663
664
665

666
667
668

669
670
671
672
673
674
675
652
653
654
655
656
657
658

659
660
661
662
663
664

665
666
667

668
669
670
671
672
673
674
675







-
+





-
+


-
+







#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicXor32Barrier(i, p);
#else
# error No atomic operations available!
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_atomic_cmpswap_int(volatile int *p, int o, int n)
{
#if !defined(OF_HAVE_THREADS)
	if (*p == o) {
		*p = n;
		return YES;
		return true;
	}

	return NO;
	return false;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	int r;

	__asm__ (
	    "xorl	%0, %0\n\t"
	    "lock\n\t"
	    "cmpxchg	%2, %3\n\t"
686
687
688
689
690
691
692
693

694
695
696
697
698
699

700
701
702

703
704
705
706
707
708
709
686
687
688
689
690
691
692

693
694
695
696
697
698

699
700
701

702
703
704
705
706
707
708
709







-
+





-
+


-
+







#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicCompareAndSwapIntBarrier(o, n, p);
#else
# error No atomic operations available!
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_atomic_cmpswap_32(volatile int32_t *p, int32_t o, int32_t n)
{
#if !defined(OF_HAVE_THREADS)
	if (*p == o) {
		*p = n;
		return YES;
		return true;
	}

	return NO;
	return false;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	int r;

	__asm__ (
	    "xorl	%0, %0\n\t"
	    "lock\n\t"
	    "cmpxchg	%2, %3\n\t"
720
721
722
723
724
725
726
727

728
729
730
731
732
733

734
735
736

737
738
739
740
741
742
743
720
721
722
723
724
725
726

727
728
729
730
731
732

733
734
735

736
737
738
739
740
741
742
743







-
+





-
+


-
+







#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicCompareAndSwap32Barrier(o, n, p);
#else
# error No atomic operations available!
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_atomic_cmpswap_ptr(void* volatile *p, void *o, void *n)
{
#if !defined(OF_HAVE_THREADS)
	if (*p == o) {
		*p = n;
		return YES;
		return true;
	}

	return NO;
	return false;
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	int r;

	__asm__ (
	    "xorl	%0, %0\n\t"
	    "lock\n\t"
	    "cmpxchg	%2, %3\n\t"

Modified src/base64.h from [dec2243267] to [fd2e3a1fe6].

33
34
35
36
37
38
39
40

41
42
43
33
34
35
36
37
38
39

40
41
42
43







-
+



@class OFDataArray;

#ifdef __cplusplus
extern "C" {
#endif
extern const char of_base64_table[64];
extern OFString *of_base64_encode(const void*, size_t);
extern BOOL of_base64_decode(OFDataArray*, const char*, size_t);
extern bool of_base64_decode(OFDataArray*, const char*, size_t);
#ifdef __cplusplus
}
#endif

Modified src/base64.m from [1b021abfd1] to [9189d4cfcf].

91
92
93
94
95
96
97
98

99
100
101
102
103
104
105

106
107
108

109
110
111
112
113
114
115
116
117
118

119
120
121
122

123
124
125
126
127
128
129
130

131
132
133
134
135

136
137
138
139
140

141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157

158
91
92
93
94
95
96
97

98
99
100
101
102
103
104

105
106
107

108
109
110
111
112
113
114
115
116
117

118
119
120
121

122
123
124
125
126
127
128
129

130
131
132
133
134

135
136
137
138
139

140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156

157
158







-
+






-
+


-
+









-
+



-
+







-
+




-
+




-
+




-
+











-
+

	}

	[ret makeImmutable];

	return ret;
}

BOOL
bool
of_base64_decode(OFDataArray *data, const char *string, size_t length)
{
	const uint8_t *buffer = (const uint8_t*)string;
	size_t i;

	if ((length & 3) != 0)
		return NO;
		return false;

	if ([data itemSize] != 1)
		return NO;
		return false;

	for (i = 0; i < length; i += 4) {
		uint32_t sb = 0;
		uint8_t count = 3;
		char db[3];
		int8_t tmp;

		if (buffer[i] > 0x7F || buffer[i + 1] > 0x7F ||
		    buffer[i + 2] > 0x7F || buffer[i + 3] > 0x7F)
			return NO;
			return false;

		if (buffer[i] == '=' || buffer[i + 1] == '=' ||
		    (buffer[i + 2] == '=' && buffer[i + 3] != '='))
			return NO;
			return false;

		if (buffer[i + 2] == '=')
			count--;
		if (buffer[i + 3] == '=')
			count--;

		if ((tmp = of_base64_decode_table[buffer[i]]) == -1)
			return NO;
			return false;

		sb |= tmp << 18;

		if ((tmp = of_base64_decode_table[buffer[i + 1]]) == -1)
			return NO;
			return false;

		sb |= tmp << 12;

		if ((tmp = of_base64_decode_table[buffer[i + 2]]) == -1)
			return NO;
			return false;

		sb |= tmp << 6;

		if ((tmp = of_base64_decode_table[buffer[i + 3]]) == -1)
			return NO;
			return false;

		sb |= tmp;

		db[0] = (sb & 0xFF0000) >> 16;
		db[1] = (sb & 0x00FF00) >> 8;
		db[2] = sb & 0x0000FF;

		[data addItems: db
			 count: count];
	}

	return YES;
	return true;
}

Modified src/exceptions/OFAcceptFailedException.m from [a308e0b787] to [27f8f634eb].

67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81







-
+







	return [OFString stringWithFormat:
	    @"Failed to accept connection in socket of type %@! " ERRFMT,
	    _inClass, ERRPARAM];
}

- (OFTCPSocket*)socket
{
	OF_GETTER(_socket, NO)
	OF_GETTER(_socket, false)
}

- (int)errNo
{
	return _errNo;
}
@end

Modified src/exceptions/OFAddressTranslationFailedException.m from [1896452c73] to [2191f51302].

80
81
82
83
84
85
86
87

88
89
90
91
92

93
94
95
96
97
98
99
80
81
82
83
84
85
86

87
88
89
90
91

92
93
94
95
96
97
98
99







-
+




-
+







		return [OFString stringWithFormat:
		    @"An address translation failed in class %@! " ERRFMT,
		    _inClass, AT_ERRPARAM];
}

- (OFTCPSocket*)socket
{
	OF_GETTER(_socket, NO)
	OF_GETTER(_socket, false)
}

- (OFString*)host
{
	OF_GETTER(_host, NO)
	OF_GETTER(_host, false)
}

- (int)errNo
{
	return _errNo;
}
@end

Modified src/exceptions/OFAlreadyConnectedException.m from [baa01ca8b0] to [599e14bfbf].

66
67
68
69
70
71
72
73

74
75
66
67
68
69
70
71
72

73
74
75







-
+


	return [OFString stringWithFormat:
	    @"The socket of type %@ is already connected or bound and thus "
	    @"can't be connected or bound again!", _inClass];
}

- (OFTCPSocket*)socket
{
	OF_GETTER(_socket, NO)
	OF_GETTER(_socket, false)
}
@end

Modified src/exceptions/OFBindFailedException.m from [21f3f29bde] to [857a2f6180].

81
82
83
84
85
86
87
88

89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
81
82
83
84
85
86
87

88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105







-
+




-
+












	return [OFString stringWithFormat:
	    @"Binding to port %" @PRIu16 @" on host %@ failed in class %@! "
	    ERRFMT, _port, _host, _inClass, ERRPARAM];
}

- (OFTCPSocket*)socket
{
	OF_GETTER(_socket, NO)
	OF_GETTER(_socket, false)
}

- (OFString*)host
{
	OF_GETTER(_host, NO)
	OF_GETTER(_host, false)
}

- (uint16_t)port
{
	return _port;
}

- (int)errNo
{
	return _errNo;
}
@end

Modified src/exceptions/OFChangeDirectoryFailedException.m from [557e04ff4b] to [d55c526118].

76
77
78
79
80
81
82
83

84
85
76
77
78
79
80
81
82

83
84
85







-
+


- (int)errNo
{
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(_path, NO)
	OF_GETTER(_path, false)
}
@end

Modified src/exceptions/OFChangeFileModeFailedException.m from [26f1001170] to [b8c50ad165].

80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94







-
+







- (int)errNo
{
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(_path, NO)
	OF_GETTER(_path, false)
}

- (mode_t)mode
{
	return _mode;
}
@end

Modified src/exceptions/OFChangeFileOwnerFailedException.m from [2d53fe58fd] to [a798b2bddb].

96
97
98
99
100
101
102
103

104
105
106
107
108

109
110
111
112
113

114
115
116
96
97
98
99
100
101
102

103
104
105
106
107

108
109
110
111
112

113
114
115
116







-
+




-
+




-
+



- (int)errNo
{
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(_path, NO)
	OF_GETTER(_path, false)
}

- (OFString*)owner
{
	OF_GETTER(_owner, NO)
	OF_GETTER(_owner, false)
}

- (OFString*)group
{
	OF_GETTER(_group, NO)
	OF_GETTER(_group, false)
}
@end
#endif

Modified src/exceptions/OFConditionBroadcastFailedException.m from [273e41aca8] to [342d177e68].

63
64
65
66
67
68
69
70

71
72
63
64
65
66
67
68
69

70
71
72







-
+


{
	return [OFString stringWithFormat:
	    @"Broadcasting a condition of type %@ failed!", _inClass];
}

- (OFCondition*)condition
{
	OF_GETTER(_condition, NO)
	OF_GETTER(_condition, false)
}
@end

Modified src/exceptions/OFConditionSignalFailedException.m from [1db3313eef] to [f4a5f8a3ff].

63
64
65
66
67
68
69
70

71
72
63
64
65
66
67
68
69

70
71
72







-
+


{
	return [OFString stringWithFormat:
	    @"Signaling a condition of type %@ failed!", _inClass];
}

- (OFCondition*)condition
{
	OF_GETTER(_condition, NO)
	OF_GETTER(_condition, false)
}
@end

Modified src/exceptions/OFConditionStillWaitingException.m from [e4dc8f234e] to [0bf03779d3].

64
65
66
67
68
69
70
71

72
73
64
65
66
67
68
69
70

71
72
73







-
+


	return [OFString stringWithFormat:
	    @"Deallocation of a condition of type %@ was tried, even though a "
	    @"thread was still waiting for it!", _inClass];
}

- (OFCondition*)condition
{
	OF_GETTER(_condition, NO)
	OF_GETTER(_condition, false)
}
@end

Modified src/exceptions/OFConditionWaitFailedException.m from [15401b6dca] to [6c0165461b].

63
64
65
66
67
68
69
70

71
72
63
64
65
66
67
68
69

70
71
72







-
+


{
	return [OFString stringWithFormat:
	    @"Waiting for a condition of type %@ failed!", _inClass];
}

- (OFCondition*)condition
{
	OF_GETTER(_condition, NO)
	OF_GETTER(_condition, false)
}
@end

Modified src/exceptions/OFConnectionFailedException.m from [039141bbfb] to [aea20b11c3].

82
83
84
85
86
87
88
89

90
91
92
93
94

95
96
97
98
99
100
101
102
103
104
105
106
82
83
84
85
86
87
88

89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106







-
+




-
+












	    @"A connection to %@ on port %" @PRIu16 @" could not be "
	    @"established in class %@! " ERRFMT, _host, _port, _inClass,
	    ERRPARAM];
}

- (OFTCPSocket*)socket
{
	OF_GETTER(_socket, NO)
	OF_GETTER(_socket, false)
}

- (OFString*)host
{
	OF_GETTER(_host, NO)
	OF_GETTER(_host, false)
}

- (uint16_t)port
{
	return _port;
}

- (int)errNo
{
	return _errNo;
}
@end

Modified src/exceptions/OFCopyFileFailedException.m from [0b1755f087] to [8f083aa045].

81
82
83
84
85
86
87
88

89
90
91
92
93

94
95
81
82
83
84
85
86
87

88
89
90
91
92

93
94
95







-
+




-
+


- (int)errNo
{
	return _errNo;
}

- (OFString*)sourcePath
{
	OF_GETTER(_sourcePath, NO)
	OF_GETTER(_sourcePath, false)
}

- (OFString*)destinationPath
{
	OF_GETTER(_destinationPath, NO)
	OF_GETTER(_destinationPath, false)
}
@end

Modified src/exceptions/OFCreateDirectoryFailedException.m from [2d67232c96] to [65f145a0a1].

76
77
78
79
80
81
82
83

84
85
76
77
78
79
80
81
82

83
84
85







-
+


- (int)errNo
{
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(_path, NO)
	OF_GETTER(_path, false)
}
@end

Modified src/exceptions/OFDeleteDirectoryFailedException.m from [ad7ba77cb1] to [3c8954df51].

76
77
78
79
80
81
82
83

84
85
76
77
78
79
80
81
82

83
84
85







-
+


- (int)errNo
{
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(_path, NO)
	OF_GETTER(_path, false)
}
@end

Modified src/exceptions/OFDeleteFileFailedException.m from [443055fc12] to [71b956856c].

76
77
78
79
80
81
82
83

84
85
76
77
78
79
80
81
82

83
84
85







-
+


- (int)errNo
{
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(_path, NO)
	OF_GETTER(_path, false)
}
@end

Modified src/exceptions/OFEnumerationMutationException.m from [b04cbc1705] to [df929876a2].

64
65
66
67
68
69
70
71

72
73
64
65
66
67
68
69
70

71
72
73







-
+


{
	return [OFString stringWithFormat:
	    @"Object of class %@ was mutated during enumeration!", _inClass];
}

- (id)object
{
	OF_GETTER(_object, NO)
	OF_GETTER(_object, false)
}
@end

Modified src/exceptions/OFHTTPRequestFailedException.m from [00ce035b14] to [5bea1d2dbc].

86
87
88
89
90
91
92
93

94
95
96
97
98

99
100
86
87
88
89
90
91
92

93
94
95
96
97

98
99
100







-
+




-
+


	return [OFString stringWithFormat:
	    @"A HTTP %s request in class %@ with URL %@ failed with code %d",
	    type, _inClass, [_request URL], [_reply statusCode]];
}

- (OFHTTPRequest*)request
{
	OF_GETTER(_request, NO)
	OF_GETTER(_request, false)
}

- (OFHTTPRequestReply*)reply
{
	OF_GETTER(_reply, NO)
	OF_GETTER(_reply, false)
}
@end

Modified src/exceptions/OFHashAlreadyCalculatedException.m from [c96d938c3c] to [6e036672c0].

65
66
67
68
69
70
71
72

73
74
65
66
67
68
69
70
71

72
73
74







-
+


	return [OFString stringWithFormat:
	    @"The hash has already been calculated in class %@ and thus no new "
	    @"data can be added", _inClass];
}

- (id <OFHash>)hashObject
{
	OF_GETTER(_hashObject, NO)
	OF_GETTER(_hashObject, false)
}
@end

Modified src/exceptions/OFLinkFailedException.m from [e104c85a1d] to [a892f44d4d].

82
83
84
85
86
87
88
89

90
91
92
93
94

95
96
97
82
83
84
85
86
87
88

89
90
91
92
93

94
95
96
97







-
+




-
+



- (int)errNo
{
	return _errNo;
}

- (OFString*)sourcePath
{
	OF_GETTER(_sourcePath, NO)
	OF_GETTER(_sourcePath, false)
}

- (OFString*)destinationPath
{
	OF_GETTER(_destinationPath, NO)
	OF_GETTER(_destinationPath, false)
}
@end
#endif

Modified src/exceptions/OFListenFailedException.m from [ebfc86a92a] to [4897d5930c].

71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90







-
+












	return [OFString stringWithFormat:
	    @"Failed to listen in socket of type %@ with a back log of %d! "
	    ERRFMT, _inClass, _backLog, ERRPARAM];
}

- (OFTCPSocket*)socket
{
	OF_GETTER(_socket, NO)
	OF_GETTER(_socket, false)
}

- (int)backLog
{
	return _backLog;
}

- (int)errNo
{
	return _errNo;
}
@end

Modified src/exceptions/OFLockFailedException.m from [99d66d97f5] to [3e3ea0f0d5].

51
52
53
54
55
56
57
58

59
60
51
52
53
54
55
56
57

58
59
60







-
+


	return [OFString stringWithFormat:
	    @"A lock of type %@ could not be locked in class %@!",
	    [_lock class], _inClass];
}

- (id <OFLocking>)lock
{
	OF_GETTER(_lock, NO)
	OF_GETTER(_lock, false)
}
@end

Modified src/exceptions/OFMalformedXMLException.m from [ea4e6e4445] to [9e9069d031].

55
56
57
58
59
60
61
62

63
64
55
56
57
58
59
60
61

62
63
64







-
+


		    _inClass];
	else
		return @"An XML parser encountered malformed XML!";
}

- (OFXMLParser*)parser
{
	OF_GETTER(_parser, NO)
	OF_GETTER(_parser, false)
}
@end

Modified src/exceptions/OFNotConnectedException.m from [096c56ad4d] to [aa4875b712].

65
66
67
68
69
70
71
72

73
74
65
66
67
68
69
70
71

72
73
74







-
+


{
	return [OFString stringWithFormat:
	    @"The socket of type %@ is not connected or bound!", _inClass];
}

- (OFStreamSocket*)socket
{
	OF_GETTER(_socket, NO)
	OF_GETTER(_socket, false)
}
@end

Modified src/exceptions/OFOpenFileFailedException.m from [4e0dc54767] to [1c310618be].

81
82
83
84
85
86
87
88

89
90
91
92
93

94
95
81
82
83
84
85
86
87

88
89
90
91
92

93
94
95







-
+




-
+


- (int)errNo
{
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(_path, NO)
	OF_GETTER(_path, false)
}

- (OFString*)mode
{
	OF_GETTER(_mode, NO)
	OF_GETTER(_mode, false)
}
@end

Modified src/exceptions/OFReadOrWriteFailedException.m from [29e58b37e2] to [74aee00696].

68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87







-
+












	[_stream release];

	[super dealloc];
}

- (OFStream*)stream
{
	OF_GETTER(_stream, NO)
	OF_GETTER(_stream, false)
}

- (size_t)requestedLength
{
	return _requestedLength;
}

- (int)errNo
{
	return _errNo;
}
@end

Modified src/exceptions/OFRenameFileFailedException.m from [33a7d5cf29] to [dc6d7c619a].

81
82
83
84
85
86
87
88

89
90
91
92
93

94
95
81
82
83
84
85
86
87

88
89
90
91
92

93
94
95







-
+




-
+


- (int)errNo
{
	return _errNo;
}

- (OFString*)sourcePath
{
	OF_GETTER(_sourcePath, NO)
	OF_GETTER(_sourcePath, false)
}

- (OFString*)destinationPath
{
	OF_GETTER(_destinationPath, NO)
	OF_GETTER(_destinationPath, false)
}
@end

Modified src/exceptions/OFSeekFailedException.m from [23aa08e709] to [d5da00b403].

74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88







-
+







{
	return [OFString stringWithFormat:
	    @"Seeking failed in class %@! " ERRFMT, _inClass, ERRPARAM];
}

- (OFSeekableStream*)stream
{
	OF_GETTER(_stream, NO)
	OF_GETTER(_stream, false)
}

- (off_t)offset
{
	return _offset;
}

Modified src/exceptions/OFSetOptionFailedException.m from [ba006ade87] to [5401f8aab0].

65
66
67
68
69
70
71
72

73
74
65
66
67
68
69
70
71

72
73
74







-
+


{
	return [OFString stringWithFormat:
	    @"Setting an option in class %@ failed!", _inClass];
}

- (OFStream*)stream
{
	OF_GETTER(_stream, NO)
	OF_GETTER(_stream, false)
}
@end

Modified src/exceptions/OFStillLockedException.m from [2869a17627] to [509b1a9438].

51
52
53
54
55
56
57
58

59
60
51
52
53
54
55
56
57

58
59
60







-
+


	return [OFString stringWithFormat:
	    @"Deallocation of a lock of type %@ was tried in class %@, even "
	    @"though it was still locked!", [_lock class], _inClass];
}

- (id <OFLocking>)lock
{
	OF_GETTER(_lock, NO)
	OF_GETTER(_lock, false)
}
@end

Modified src/exceptions/OFSymlinkFailedException.m from [fbff44390e] to [514ef35454].

82
83
84
85
86
87
88
89

90
91
92
93
94

95
96
97
82
83
84
85
86
87
88

89
90
91
92
93

94
95
96
97







-
+




-
+



- (int)errNo
{
	return _errNo;
}

- (OFString*)sourcePath
{
	OF_GETTER(_sourcePath, NO)
	OF_GETTER(_sourcePath, false)
}

- (OFString*)destinationPath
{
	OF_GETTER(_destinationPath, NO)
	OF_GETTER(_destinationPath, false)
}
@end
#endif

Modified src/exceptions/OFThreadJoinFailedException.m from [03a6cbd6da] to [8fca498969].

64
65
66
67
68
69
70
71

72
73
64
65
66
67
68
69
70

71
72
73







-
+


	return [OFString stringWithFormat:
	    @"Joining a thread of class %@ failed! Most likely, another thread "
	    @"already waits for the thread to join.", _inClass];
}

- (OFThread*)thread
{
	OF_GETTER(_thread, NO)
	OF_GETTER(_thread, false)
}
@end

Modified src/exceptions/OFThreadStartFailedException.m from [091ac82c2b] to [936c6420ec].

63
64
65
66
67
68
69
70

71
72
63
64
65
66
67
68
69

70
71
72







-
+


{
	return [OFString stringWithFormat:
	    @"Starting a thread of class %@ failed!", _inClass];
}

- (OFThread*)thread
{
	OF_GETTER(_thread, NO)
	OF_GETTER(_thread, false)
}
@end

Modified src/exceptions/OFThreadStillRunningException.m from [c9eed87446] to [d9f583edf6].

64
65
66
67
68
69
70
71

72
73
64
65
66
67
68
69
70

71
72
73







-
+


	return [OFString stringWithFormat:
	    @"Deallocation of a thread of type %@ was tried, even though it "
	    @"was still running!", _inClass];
}

- (OFThread*)thread
{
	OF_GETTER(_thread, NO)
	OF_GETTER(_thread, false)
}
@end

Modified src/exceptions/OFUnboundNamespaceException.m from [e961348a70] to [1510166b61].

102
103
104
105
106
107
108
109

110
111
112
113
114

115
116
102
103
104
105
106
107
108

109
110
111
112
113

114
115
116







-
+




-
+


		return [OFString stringWithFormat:
		    @"A namespace or prefix is not bound in class %@",
		    _inClass];
}

- (OFString*)namespace
{
	OF_GETTER(_namespace, NO)
	OF_GETTER(_namespace, false)
}

- (OFString*)prefix
{
	OF_GETTER(_prefix, NO)
	OF_GETTER(_prefix, false)
}
@end

Modified src/exceptions/OFUnlockFailedException.m from [5404c0c1bb] to [6c903a202a].

51
52
53
54
55
56
57
58

59
60
51
52
53
54
55
56
57

58
59
60







-
+


	return [OFString stringWithFormat:
	    @"A lock of class %@ could not be unlocked in class %@!",
	    [_lock class], _inClass];
}

- (id <OFLocking>)lock
{
	OF_GETTER(_lock, NO)
	OF_GETTER(_lock, false)
}
@end

Modified src/exceptions/OFUnsupportedProtocolException.m from [69198622a9] to [86615f4dc4].

71
72
73
74
75
76
77
78

79
80
71
72
73
74
75
76
77

78
79
80







-
+


	return [OFString stringWithFormat:
	    @"The protocol of URL %@ is not supported by class %@", _URL,
	    _inClass];
}

- (OFURL*)URL
{
	OF_GETTER(_URL, NO)
	OF_GETTER(_URL, false)
}
@end

Modified src/exceptions/OFUnsupportedVersionException.m from [a07066326a] to [d304c8874c].

70
71
72
73
74
75
76
77

78
79
70
71
72
73
74
75
76

77
78
79







-
+


	return [OFString stringWithFormat:
	    @"Version %@ of the format or protocol is not supported by class "
	    @"%@", _version, _inClass];
}

- (OFString*)version
{
	OF_GETTER(_version, NO)
	OF_GETTER(_version, false)
}
@end

Modified src/instance.m from [4886f63f00] to [f378d99417].

17
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
17
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







-
+








-
+





-
+







-
+

-
+







#include "config.h"

#import "OFObject.h"

static SEL cxx_construct = NULL;
static SEL cxx_destruct = NULL;

static BOOL
static bool
call_ctors(Class cls, id obj)
{
	Class super = class_getSuperclass(cls);
	id (*ctor)(id, SEL);
	id (*last)(id, SEL);

	if (super != nil)
		if (!call_ctors(super, obj))
			return NO;
			return false;

	if (cxx_construct == NULL)
		cxx_construct = sel_registerName(".cxx_construct");

	if (!class_respondsToSelector(cls, cxx_construct))
		return YES;
		return true;

	ctor = (id(*)(id, SEL))
	    class_getMethodImplementation(cls, cxx_construct);
	last = (id(*)(id, SEL))
	    class_getMethodImplementation(super, cxx_construct);

	if (ctor == last)
		return YES;
		return true;

	return (ctor(obj, cxx_construct) != nil ? YES : NO);
	return (ctor(obj, cxx_construct) != nil);
}

id
objc_constructInstance(Class cls, void *bytes)
{
	id obj = (id)bytes;

Modified src/runtime/class.m from [640206d718] to [d8be8e78d1].

95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113
114

115
116

117
118
119
120
121
122
123
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109
110
111
112
113

114
115

116
117
118
119
120
121
122
123







-
+











-
+

-
+







	for (ml = cls->isa->methodlist; ml != NULL; ml = ml->next)
		for (i = 0; i < ml->count; i++)
			if (sel_isEqual((SEL)&ml->methods[i].sel, selector))
				((void(*)(id, SEL))ml->methods[i].imp)(cls,
				    selector);
}

static BOOL
static bool
has_load(Class cls)
{
	struct objc_method_list *ml;
	SEL selector;
	unsigned int i;

	selector = sel_registerName("load");

	for (ml = cls->isa->methodlist; ml != NULL; ml = ml->next)
		for (i = 0; i < ml->count; i++)
			if (sel_isEqual((SEL)&ml->methods[i].sel, selector))
				return YES;
				return true;

	return NO;
	return false;
}

static void
call_load(Class cls)
{
	if (cls->info & OBJC_CLASS_INFO_LOADED)
		return;
402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434

435
436

437
438
439
440
441
442
443
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426

427
428
429
430
431
432
433

434
435

436
437
438
439
440
441
442
443







-
+

















-
+






-
+

-
+








Class
objc_get_class(const char *name)
{
	return objc_getRequiredClass(name);
}

BOOL
bool
class_isMetaClass(Class cls)
{
	return (cls->info & OBJC_CLASS_INFO_METACLASS);
}

const char*
class_getName(Class cls)
{
	return cls->name;
}

Class
class_getSuperclass(Class cls)
{
	return cls->superclass;
}

BOOL
bool
class_isKindOfClass(Class cls1, Class cls2)
{
	Class iter;

	for (iter = cls1; iter != Nil; iter = iter->superclass)
		if (iter == cls2)
			return YES;
			return true;

	return NO;
	return false;
}

unsigned long
class_getInstanceSize(Class cls)
{
	return cls->instance_size;
}

Modified src/runtime/exception.m from [375c6e97c6] to [33f7be3a9f].

330
331
332
333
334
335
336
337

338
339
340
341
342
343
344
330
331
332
333
334
335
336

337
338
339
340
341
342
343
344







-
+







	lsda->callsites_enc = *ptr++;
	callsites_size = (uintptr_t)read_uleb128(&ptr);
	lsda->callsites = ptr;

	lsda->actiontable = lsda->callsites + callsites_size;
}

static BOOL
static bool
find_callsite(struct _Unwind_Context *ctx, struct lsda *lsda,
    uintptr_t *landingpad, const uint8_t **actionrecords)
{
	uintptr_t ip = _Unwind_GetIP(ctx);
	const uint8_t *ptr;

	*landingpad = 0;
364
365
366
367
368
369
370
371

372
373
374
375

376
377
378

379
380
381
382
383
384

385
386
387

388
389
390
391
392

393
394

395
396
397
398
399

400
401
402
403
404
405
406
364
365
366
367
368
369
370

371
372
373
374

375
376
377

378
379
380
381
382
383

384
385
386

387
388
389
390
391

392
393

394
395
396
397
398

399
400
401
402
403
404
405
406







-
+



-
+


-
+





-
+


-
+




-
+

-
+




-
+







			if (callsite_landingpad != 0)
				*landingpad = lsda->landingpads_start +
				    callsite_landingpad;
			if (callsite_action != 0)
				*actionrecords = lsda->actiontable +
				    callsite_action - 1;

			return YES;
			return true;
		}
	}

	return NO;
	return false;
}

static BOOL
static bool
class_matches(Class class, id object)
{
	Class iter;

	if (class == Nil)
		return YES;
		return true;

	if (object == nil)
		return NO;
		return false;

	for (iter = object_getClass(object); iter != Nil;
	    iter = class_getSuperclass(iter))
		if (iter == class)
			return YES;
			return true;

	return NO;
	return false;
}

static uint8_t
find_actionrecord(const uint8_t *actionrecords, struct lsda *lsda, int actions,
    BOOL foreign, struct objc_exception *e, intptr_t *filtervalue)
    bool foreign, struct objc_exception *e, intptr_t *filtervalue)
{
	const uint8_t *ptr;
	intptr_t filter, displacement;

	do {
		ptr = actionrecords;
		filter = (intptr_t)read_sleb128(&ptr);
486
487
488
489
490
491
492
493

494
495
496
497
498
499
500
486
487
488
489
490
491
492

493
494
495
496
497
498
499
500







-
+







#else
_Unwind_Reason_Code
__gnu_objc_personality_v0(int version, int actions, uint64_t ex_class,
    struct _Unwind_Exception *ex, struct _Unwind_Context *ctx)
{
#endif
	struct objc_exception *e = (struct objc_exception*)ex;
	BOOL foreign = (ex_class != objc_exception_class);
	bool foreign = (ex_class != objc_exception_class);
	const uint8_t *lsda_addr, *actionrecords;
	struct lsda lsda;
	uintptr_t landingpad = 0;
	uint8_t found = 0;
	intptr_t filter = 0;

	if (version != 1)

Modified src/runtime/lookup.m from [7510694bab] to [7a62dc26ba].

24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38







-
+







#import "macros.h"

IMP (*objc_forward_handler)(id, SEL) = NULL;

IMP
objc_not_found_handler(id obj, SEL sel)
{
	BOOL is_class = object_getClass(obj)->info & OBJC_CLASS_INFO_METACLASS;
	bool is_class = object_getClass(obj)->info & OBJC_CLASS_INFO_METACLASS;

	if (!(object_getClass(obj)->info & OBJC_CLASS_INFO_INITIALIZED)) {
		Class cls = (is_class ? (Class)obj : object_getClass(obj));

		objc_initialize_class(cls);

		if (!(cls->info & OBJC_CLASS_INFO_SETUP)) {
55
56
57
58
59
60
61
62

63
64
65
66

67
68

69
70
71
72
73
74
75
76
55
56
57
58
59
60
61

62
63
64
65

66
67

68

69
70
71
72
73
74
75







-
+



-
+

-
+
-







	if (objc_forward_handler != NULL)
		return objc_forward_handler(obj, sel);

	OBJC_ERROR("Selector %c[%s] is not implemented for class %s!",
	    (is_class ? '+' : '-'), sel_getName(sel), object_getClassName(obj));
}

BOOL
bool
class_respondsToSelector(Class cls, SEL sel)
{
	if (cls == Nil)
		return NO;
		return false;

	return (objc_sparsearray_get(cls->dtable, (uint32_t)sel->uid) != NULL
	return (objc_sparsearray_get(cls->dtable, (uint32_t)sel->uid) != NULL);
	    ? YES : NO);
}

#ifndef OF_ASM_LOOKUP
static id
nil_method(id self, SEL _cmd)
{
	return nil;

Modified src/runtime/protocol.m from [7ba1a7ad23] to [b56dfa610a].

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
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







-
+





-
+






-
+




-
+

-
+


-
+









-
+





-
+








-
+







-
+


inline const char*
protocol_getName(Protocol *p)
{
	return p->name;
}

inline BOOL
inline bool
protocol_isEqual(Protocol *a, Protocol *b)
{
	return !strcmp(protocol_getName(a), protocol_getName(b));
}

BOOL
bool
protocol_conformsToProtocol(Protocol *a, Protocol *b)
{
	struct objc_protocol_list *pl;
	size_t i;

	if (protocol_isEqual(a, b))
		return YES;
		return true;

	for (pl = a->protocol_list; pl != NULL; pl = pl->next)
		for (i = 0; i < pl->count; i++)
			if (protocol_conformsToProtocol(pl->list[i], b))
				return YES;
				return true;

	return NO;
	return false;
}

BOOL
bool
class_conformsToProtocol(Class cls, Protocol *p)
{
	struct objc_protocol_list *pl;
	struct objc_category **cats;
	long i, j;

	for (pl = cls->protocols; pl != NULL; pl = pl->next)
		for (i = 0; i < pl->count; i++)
			if (protocol_conformsToProtocol(pl->list[i], p))
				return YES;
				return true;

	objc_global_mutex_lock();

	if ((cats = objc_categories_for_class(cls)) == NULL) {
		objc_global_mutex_unlock();
		return NO;
		return false;
	}

	for (i = 0; cats[i] != NULL; i++) {
		for (pl = cats[i]->protocols; pl != NULL; pl = pl->next) {
			for (j = 0; j < pl->count; j++) {
				if (protocol_conformsToProtocol(
				    pl->list[j], p)) {
					objc_global_mutex_unlock();
					return YES;
					return true;
				}
			}
		}
	}

	objc_global_mutex_unlock();

	return NO;
	return false;
}

Modified src/runtime/runtime-private.h from [c43269a3b6] to [466c124f70].

105
106
107
108
109
110
111
112

113
114
115
116
117

118
119
120
121
122

123
124
125
126
127
128
129
105
106
107
108
109
110
111

112
113
114
115
116

117
118
119
120
121

122
123
124
125
126
127
128
129







-
+




-
+




-
+







struct objc_sparsearray {
	struct objc_sparsearray_level2 *buckets[256];
};

#ifdef OF_SELUID24
struct objc_sparsearray_level2 {
	struct objc_sparsearray_level3 *buckets[256];
	BOOL empty;
	bool empty;
};

struct objc_sparsearray_level3 {
	const void *buckets[256];
	BOOL empty;
	bool empty;
};
#else
struct objc_sparsearray_level2 {
	const void *buckets[256];
	BOOL empty;
	bool empty;
};
#endif

extern void objc_register_all_categories(struct objc_abi_symtab*);
extern struct objc_category** objc_categories_for_class(Class);
extern void objc_free_all_categories(void);
extern void objc_initialize_class(Class);

Modified src/runtime/runtime.h from [577c4aab36] to [32f939b80e].

13
14
15
16
17
18
19

20
21
22
23
24
25
26
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27







+







 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#ifndef __OBJFW_RUNTIME_H__
#define __OBJFW_RUNTIME_H__
#include <stdint.h>
#include <stdbool.h>

#ifndef __has_feature
# define __has_feature(x) 0
#endif

#if __has_feature(objc_arc)
# define OBJC_UNSAFE_UNRETAINED __unsafe_unretained
165
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
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







-
+



-
+


-
+

-
-
+
+









-
-
+
+







typedef void (*objc_uncaught_exception_handler)(id);

#ifdef __cplusplus
extern "C" {
#endif
extern SEL sel_registerName(const char*);
extern const char* sel_getName(SEL);
extern BOOL sel_isEqual(SEL, SEL);
extern bool sel_isEqual(SEL, SEL);
extern id objc_lookUpClass(const char*);
extern id objc_getClass(const char*);
extern id objc_getRequiredClass(const char*);
extern BOOL class_isMetaClass(Class);
extern bool class_isMetaClass(Class);
extern const char* class_getName(Class);
extern Class class_getSuperclass(Class);
extern BOOL class_isKindOfClass(Class, Class);
extern bool class_isKindOfClass(Class, Class);
extern unsigned long class_getInstanceSize(Class);
extern BOOL class_respondsToSelector(Class, SEL);
extern BOOL class_conformsToProtocol(Class, Protocol*);
extern bool class_respondsToSelector(Class, SEL);
extern bool class_conformsToProtocol(Class, Protocol*);
extern IMP class_getMethodImplementation(Class, SEL);
extern IMP class_replaceMethod(Class, SEL, IMP, const char*);
extern const char* objc_get_type_encoding(Class, SEL);
extern Class object_getClass(id);
extern Class object_setClass(id, Class);
extern const char* object_getClassName(id);
extern IMP objc_msg_lookup(id, SEL);
extern IMP objc_msg_lookup_super(struct objc_super*, SEL);
extern const char* protocol_getName(Protocol*);
extern BOOL protocol_isEqual(Protocol*, Protocol*);
extern BOOL protocol_conformsToProtocol(Protocol*, Protocol*);
extern bool protocol_isEqual(Protocol*, Protocol*);
extern bool protocol_conformsToProtocol(Protocol*, Protocol*);
extern void objc_exit(void);
extern objc_uncaught_exception_handler objc_setUncaughtExceptionHandler(
    objc_uncaught_exception_handler);
extern IMP (*objc_forward_handler)(id, SEL);
extern id objc_autorelease(id);
extern void* objc_autoreleasePoolPush(void);
extern void objc_autoreleasePoolPop(void*);

Modified src/runtime/selector.m from [bb5e87f578] to [64e4076187].

109
110
111
112
113
114
115
116

117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
109
110
111
112
113
114
115

116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131







-
+


-
+












	objc_global_mutex_lock();
	ret = objc_sparsearray_get(selector_names, (uint32_t)sel->uid);
	objc_global_mutex_unlock();

	return ret;
}

BOOL
bool
sel_isEqual(SEL sel1, SEL sel2)
{
	return sel1->uid == sel2->uid;
	return (sel1->uid == sel2->uid);
}

void
objc_free_all_selectors(void)
{
	objc_hashtable_free(selectors);
	objc_sparsearray_free(selector_names);

	selectors = NULL;
	selectors_cnt = 0;
	selector_names = NULL;
}

Modified src/runtime/sparsearray.m from [010ad633c1] to [ad0ab80318].

32
33
34
35
36
37
38
39

40
41
42
43
44
45
46

47
48
49
50
51
52
53
32
33
34
35
36
37
38

39
40
41
42
43
44
45

46
47
48
49
50
51
52
53







-
+






-
+







{
	uint_fast16_t i;

	empty_level2 = malloc(sizeof(struct objc_sparsearray_level2));
	if (empty_level2 == NULL)
		OBJC_ERROR("Not enough memory to allocate sparse array!");

	empty_level2->empty = YES;
	empty_level2->empty = true;

#ifdef OF_SELUID24
	empty_level3 = malloc(sizeof(struct objc_sparsearray_level3));
	if (empty_level3 == NULL)
		OBJC_ERROR("Not enough memory to allocate sparse array!");

	empty_level3->empty = YES;
	empty_level3->empty = true;
#endif

#ifdef OF_SELUID24
	for (i = 0; i < 256; i++) {
		empty_level2->buckets[i] = empty_level3;
		empty_level3->buckets[i] = NULL;
	}
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160







-
+








		t = malloc(sizeof(struct objc_sparsearray_level2));

		if (t == NULL)
			OBJC_ERROR("Not enough memory to insert into sparse "
			    "array!");

		t->empty = NO;
		t->empty = false;

		for (l = 0; l < 256; l++)
#ifdef OF_SELUID24
			t->buckets[l] = empty_level3;
#else
			t->buckets[l] = NULL;
#endif
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183







-
+








		t = malloc(sizeof(struct objc_sparsearray_level3));

		if (t == NULL)
			OBJC_ERROR("Not enough memory to insert into sparse "
			    "array!");

		t->empty = NO;
		t->empty = false;

		for (l = 0; l < 256; l++)
			t->buckets[l] = NULL;

		s->buckets[i]->buckets[j] = t;
	}

Modified src/runtime/threading.m from [1ff2ae8b0b] to [8179cd42a3].

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42







-
+







-
+







#include <stdlib.h>

#import "runtime.h"
#import "runtime-private.h"
#import "threading.h"

static of_rmutex_t global_mutex;
static BOOL global_mutex_init = NO;
static bool global_mutex_init = false;

static void
objc_global_mutex_new(void)
{
	if (!of_rmutex_new(&global_mutex))
		OBJC_ERROR("Failed to create global mutex!");

	global_mutex_init = YES;
	global_mutex_init = true;
}

void
objc_global_mutex_lock(void)
{
	if (!global_mutex_init)
		objc_global_mutex_new();

Modified src/threading.h from [ba948db4c9] to [c5163894df].

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

101
102
103
104

105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132

133
134
135
136

137
138
139
140
141
142
143

144
145
146
147

148
149
150
151
152
153
154

155
156
157
158

159
160
161
162
163
164
165
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
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
280
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296
297
298

299
300
301
302
303

304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319
320
321
322
323

324
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352

353
354
355
356
357

358
359
360
361
362
363
364
365

366
367
368
369

370
371
372
373
374
375
376
377
378

379
380
381
382
383
384

385
386
387

388
389
390

391
392
393

394
395

396
397
398
399
400
401
402
403

404
405
406
407

408
409
410

411
412

413
414
415

416
417
418
419
420
421
422
423



424
425
426
427

428
429
430
431

432
433
434

435
436
437

438
439
440
441
442
443
444
445



446
447
448
449

450
451
452
453

454
455
456

457
458
459

460
461
462
463
464
465
466
467



468
469
470
471

472
473
474

475
476

477
478
479

480
481
482
483

484
485
486

487
488

489
490
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
101
102
103

104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131

132
133
134
135

136
137
138
139
140
141
142

143
144
145
146

147
148
149
150
151
152
153

154
155
156
157

158
159
160
161
162
163
164
165
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
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
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297

298
299
300
301
302

303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351

352
353
354
355
356

357
358
359
360
361
362
363
364

365
366
367
368

369
370
371
372
373
374
375
376
377

378
379
380
381
382
383

384
385
386

387
388
389

390
391
392

393
394

395
396
397
398
399
400
401
402

403
404
405
406

407
408
409

410
411

412
413
414

415
416
417
418
419
420
421


422
423
424
425
426
427

428
429
430
431

432
433
434

435
436
437

438
439
440
441
442
443
444


445
446
447
448
449
450

451
452
453
454

455
456
457

458
459
460

461
462
463
464
465
466
467


468
469
470
471
472
473

474
475
476

477
478

479
480
481

482
483
484
485

486
487
488

489
490

491
492
493







-
+













-
+






-
+




-
+



-
+



-
+






-
+













-
+






-
+



-
+






-
+



-
+






-
+



-
+









-
+






-
+



-
+








-
+

-
+



-
+






-
+





-
+





-
+

-
+



-
+









-
+









-
+

-
+



-
+






-
+





-
+



















-
+









-
+









-
+




-
+







-
+











-
+








-
+











-
+







-
+




-
+







-
+



-
+








-
+





-
+


-
+


-
+


-
+

-
+







-
+



-
+


-
+

-
+


-
+






-
-
+
+
+



-
+



-
+


-
+


-
+






-
-
+
+
+



-
+



-
+


-
+


-
+






-
-
+
+
+



-
+


-
+

-
+


-
+



-
+


-
+

-
+


# define of_thread_is_current(t) pthread_equal(t, pthread_self())
# define of_thread_current pthread_self
#elif defined(_WIN32)
# define of_thread_is_current(t) (t == GetCurrentThread())
# define of_thread_current GetCurrentThread
#endif

static OF_INLINE BOOL
static OF_INLINE bool
of_thread_new(of_thread_t *thread, id (*function)(id), id data)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_create(thread, NULL, (void*(*)(void*))function,
	    (__bridge void*)data);
#elif defined(_WIN32)
	*thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)function,
	    (__bridge void*)data, 0, NULL);

	return (thread != NULL);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_thread_join(of_thread_t thread)
{
#if defined(OF_HAVE_PTHREADS)
	void *ret;

	if (pthread_join(thread, &ret))
		return NO;
		return false;

	return (ret != PTHREAD_CANCELED);
#elif defined(_WIN32)
	if (WaitForSingleObject(thread, INFINITE))
		return NO;
		return false;

	CloseHandle(thread);

	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_thread_detach(of_thread_t thread)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_detach(thread);
#elif defined(_WIN32)
	/* FIXME */
	return YES;
	return true;
#endif
}

static OF_INLINE void
of_thread_exit(void)
{
#if defined(OF_HAVE_PTHREADS)
	pthread_exit(NULL);
#elif defined(_WIN32)
	ExitThread(0);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_mutex_new(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_init(mutex, NULL);
#elif defined(_WIN32)
	InitializeCriticalSection(mutex);
	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_mutex_free(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_destroy(mutex);
#elif defined(_WIN32)
	DeleteCriticalSection(mutex);
	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_mutex_lock(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_lock(mutex);
#elif defined(_WIN32)
	EnterCriticalSection(mutex);
	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_mutex_trylock(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_trylock(mutex);
#elif defined(_WIN32)
	return TryEnterCriticalSection(mutex);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_mutex_unlock(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_unlock(mutex);
#elif defined(_WIN32)
	LeaveCriticalSection(mutex);
	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_condition_new(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_init(condition, NULL);
#elif defined(_WIN32)
	condition->count = 0;

	if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL)
		return NO;
		return false;

	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_wait(condition, mutex);
#elif defined(_WIN32)
	if (!of_mutex_unlock(mutex))
		return NO;
		return false;

	of_atomic_inc_int(&condition->count);

	if (WaitForSingleObject(condition->event, INFINITE) != WAIT_OBJECT_0) {
		of_mutex_lock(mutex);
		return NO;
		return false;
	}

	of_atomic_dec_int(&condition->count);

	if (!of_mutex_lock(mutex))
		return NO;
		return false;

	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_condition_signal(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_signal(condition);
#elif defined(_WIN32)
	return SetEvent(condition->event);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_condition_broadcast(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_broadcast(condition);
#elif defined(_WIN32)
	size_t i;

	for (i = 0; i < condition->count; i++)
		if (!SetEvent(condition->event))
			return NO;
			return false;

	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_condition_free(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_destroy(condition);
#elif defined(_WIN32)
	if (condition->count)
		return NO;
		return false;

	return CloseHandle(condition->event);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_tlskey_new(of_tlskey_t *key)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_key_create(key, NULL);
#elif defined(_WIN32)
	return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES);
#endif
}

static OF_INLINE void*
of_tlskey_get(of_tlskey_t key)
{
#if defined(OF_HAVE_PTHREADS)
	return pthread_getspecific(key);
#elif defined(_WIN32)
	return TlsGetValue(key);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_tlskey_set(of_tlskey_t key, void *ptr)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_setspecific(key, ptr);
#elif defined(_WIN32)
	return TlsSetValue(key, ptr);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_tlskey_free(of_tlskey_t key)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_key_delete(key);
#elif defined(_WIN32)
	return TlsFree(key);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_spinlock_new(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	*spinlock = 0;
	return YES;
	return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_init(spinlock, 0);
#else
	return of_mutex_new(spinlock);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_spinlock_trylock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	return of_atomic_cmpswap_int(spinlock, 0, 1);
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_trylock(spinlock);
#else
	return of_mutex_trylock(spinlock);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_spinlock_lock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
# if defined(OF_HAVE_SCHED_YIELD) || defined(_WIN32)
	int i;

	for (i = 0; i < OF_SPINCOUNT; i++)
		if (of_spinlock_trylock(spinlock))
			return YES;
			return true;

	while (!of_spinlock_trylock(spinlock))
#  ifndef _WIN32
		sched_yield();
#  else
		Sleep(0);
#  endif
# else
	while (!of_spinlock_trylock(spinlock));
# endif

	return YES;
	return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_lock(spinlock);
#else
	return of_mutex_lock(spinlock);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_spinlock_unlock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	*spinlock = 0;
	return YES;
	return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_unlock(spinlock);
#else
	return of_mutex_unlock(spinlock);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_spinlock_free(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	return YES;
	return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_destroy(spinlock);
#else
	return of_mutex_free(spinlock);
#endif
}

#ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES
static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_new(of_mutex_t *mutex)
{
	pthread_mutexattr_t attr;

	if (pthread_mutexattr_init(&attr))
		return NO;
		return false;

	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE))
		return NO;
		return false;

	if (pthread_mutex_init(mutex, &attr))
		return NO;
		return false;

	if (pthread_mutexattr_destroy(&attr))
		return NO;
		return false;

	return YES;
	return true;
}

# define of_rmutex_lock of_mutex_lock
# define of_rmutex_trylock of_mutex_trylock
# define of_rmutex_unlock of_mutex_unlock
# define of_rmutex_free of_mutex_free
#else
static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_new(of_rmutex_t *rmutex)
{
	if (!of_mutex_new(&rmutex->mutex))
		return NO;
		return false;

	if (!of_tlskey_new(&rmutex->count))
		return NO;
		return false;

	return YES;
	return true;
}

static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_lock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);

	if (count > 0) {
		if (!of_tlskey_set(rmutex->count, (void*)(count + 1)))
			return NO;
		return YES;
			return false;

		return true;
	}

	if (!of_mutex_lock(&rmutex->mutex))
		return NO;
		return false;

	if (!of_tlskey_set(rmutex->count, (void*)1)) {
		of_mutex_unlock(&rmutex->mutex);
		return NO;
		return false;
	}

	return YES;
	return true;
}

static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_trylock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);

	if (count > 0) {
		if (!of_tlskey_set(rmutex->count, (void*)(count + 1)))
			return NO;
		return YES;
			return false;

		return true;
	}

	if (!of_mutex_trylock(&rmutex->mutex))
		return NO;
		return false;

	if (!of_tlskey_set(rmutex->count, (void*)1)) {
		of_mutex_unlock(&rmutex->mutex);
		return NO;
		return false;
	}

	return YES;
	return true;
}

static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);

	if (count > 1) {
		if (!of_tlskey_set(rmutex->count, (void*)(count - 1)))
			return NO;
		return YES;
			return false;

		return true;
	}

	if (!of_tlskey_set(rmutex->count, (void*)0))
		return NO;
		return false;

	if (!of_mutex_unlock(&rmutex->mutex))
		return NO;
		return false;

	return YES;
	return true;
}

static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_free(of_rmutex_t *rmutex)
{
	if (!of_mutex_free(&rmutex->mutex))
		return NO;
		return false;

	if (!of_tlskey_free(rmutex->count))
		return NO;
		return false;

	return YES;
	return true;
}
#endif

Modified tests/ForwardingTests.m from [f57b713faf] to [d9a0d74b25].

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
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







-
+












-
+



-
+







-
+


-
+


-
+







-
+


-
+














-
+








#import "OFString.h"
#import "OFAutoreleasePool.h"

#import "TestsAppDelegate.h"

static OFString *module = @"Forwarding";
static size_t forwardings = 0;
static BOOL success = NO;
static bool success = false;

@interface ForwardingTest: OFObject
@end

@interface ForwardingTest (Test)
+ (void)test;
- (void)test;
@end

static void
test(id self, SEL _cmd)
{
	success = YES;
	success = true;
}

@implementation ForwardingTest
+ (BOOL)resolveClassMethod: (SEL)selector
+ (bool)resolveClassMethod: (SEL)selector
{
	forwardings++;

	if (sel_isEqual(selector, @selector(test))) {
		[self replaceClassMethod: @selector(test)
		      withImplementation: (IMP)test
			    typeEncoding: "v#:"];
		return YES;
		return true;
	}

	return NO;
	return false;
}

+ (BOOL)resolveInstanceMethod: (SEL)selector
+ (bool)resolveInstanceMethod: (SEL)selector
{
	forwardings++;

	if (sel_isEqual(selector, @selector(test))) {
		[self replaceInstanceMethod: @selector(test)
			 withImplementation: (IMP)test
			       typeEncoding: "v@:"];
		return YES;
		return true;
	}

	return NO;
	return false;
}
@end

@implementation TestsAppDelegate (ForwardingTests)
- (void)forwardingTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];

	TEST(@"Forwarding a message and adding a class method",
	    R([ForwardingTest test]) && success &&
	    R([ForwardingTest test]) && forwardings == 1);

	ForwardingTest *t = [[[ForwardingTest alloc] init] autorelease];

	success = NO;
	success = false;
	forwardings = 0;

	TEST(@"Forwarding a message and adding an instance method",
	    R([t test]) && success && R([t test]) && forwardings == 1);

	[pool drain];
}
@end

Modified tests/OFArrayTests.m from [a50d671c0a] to [4c7095914c].

38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52







-
+







- (void)arrayTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFArray *a[3];
	OFMutableArray *m[2];
	OFEnumerator *enumerator;
	id obj;
	BOOL ok;
	bool ok;
	size_t i;

	TEST(@"+[array]", (m[0] = [OFMutableArray array]))

	TEST(@"+[arrayWithObjects:]",
	    (a[0] = [OFArray arrayWithObjects: @"Foo", @"Bar", @"Baz", nil]))

77
78
79
80
81
82
83
84
85


86
87
88
89
90



91
92
93
94
95
96
97
77
78
79
80
81
82
83


84
85
86
87



88
89
90
91
92
93
94
95
96
97







-
-
+
+


-
-
-
+
+
+







	    [[a[0] objectAtIndex: 1] isEqual: c_ary[1]] &&
	    [[a[0] objectAtIndex: 2] isEqual: c_ary[2]] &&
	    [[a[1] objectAtIndex: 0] isEqual: c_ary[0]] &&
	    [[a[1] objectAtIndex: 1] isEqual: c_ary[1]] &&
	    [[a[1] objectAtIndex: 2] isEqual: c_ary[2]])

	TEST(@"-[containsObject:]",
	    [a[0] containsObject: c_ary[1]] == YES &&
	    [a[0] containsObject: @"nonexistant"] == NO)
	    [a[0] containsObject: c_ary[1]] &&
	    ![a[0] containsObject: @"nonexistant"])

	TEST(@"-[containsObjectIdenticalTo:]",
	    [a[0] containsObjectIdenticalTo: c_ary[1]] == YES &&
	    [a[0] containsObjectIdenticalTo:
	    [OFString stringWithString: c_ary[1]]] == NO)
	    [a[0] containsObjectIdenticalTo: c_ary[1]] &&
	    ![a[0] containsObjectIdenticalTo:
	    [OFString stringWithString: c_ary[1]]])

	TEST(@"-[indexOfObject:]", [a[0] indexOfObject: c_ary[1]] == 1)

	TEST(@"-[indexOfObjectIdenticalTo:]",
	    [a[1] indexOfObjectIdenticalTo: c_ary[1]] == 1)

	TEST(@"-[objectsInRange:]",
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
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
280
281
282
283

284
285
286
287
288
289
290
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

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
280
281
282

283
284
285
286
287
288
289
290







-
+






-
+






-
+











-
+




-
+






-
+










-
+








-
+









-
+






-
+


-
+



-
+



-
+



-
+



-
+













-
+







	TEST(@"-[componentsJoinedByString:]",
	    (a[1] = [OFArray arrayWithObjects: @"foo", @"bar", @"baz", nil]) &&
	    [[a[1] componentsJoinedByString: @" "] isEqual: @"foo bar baz"] &&
	    (a[1] = [OFArray arrayWithObject: @"foo"]) &&
	    [[a[1] componentsJoinedByString: @" "] isEqual: @"foo"])

	m[0] = [[a[0] mutableCopy] autorelease];
	ok = YES;
	ok = true;
	i = 0;

	TEST(@"-[objectEnumerator]", (enumerator = [m[0] objectEnumerator]))

	while ((obj = [enumerator nextObject]) != nil) {
		if (![obj isEqual: c_ary[i]])
			ok = NO;
			ok = false;
		[m[0] replaceObjectAtIndex: i
				withObject: @""];
		i++;
	}

	if ([m[0] count] != i)
		ok = NO;
		ok = false;

	TEST(@"OFEnumerator's -[nextObject]", ok)

	[enumerator reset];
	[m[0] removeObjectAtIndex: 0];

	EXPECT_EXCEPTION(@"Detection of mutation during enumeration",
	    OFEnumerationMutationException, [enumerator nextObject])

#ifdef OF_HAVE_FAST_ENUMERATION
	m[0] = [[a[0] mutableCopy] autorelease];
	ok = YES;
	ok = true;
	i = 0;

	for (OFString *s in m[0]) {
		if (![s isEqual: c_ary[i]])
			ok = NO;
			ok = false;
		[m[0] replaceObjectAtIndex: i
				withObject: @""];
		i++;
	}

	if ([m[0] count] != i)
		ok = NO;
		ok = false;

	TEST(@"Fast Enumeration", ok)

	[m[0] replaceObjectAtIndex: 0
			withObject: c_ary[0]];
	[m[0] replaceObjectAtIndex: 1
			withObject: c_ary[1]];
	[m[0] replaceObjectAtIndex: 2
			withObject: c_ary[2]];

	ok = NO;
	ok = false;
	i = 0;
	@try {
		for (OFString *s in m[0]) {
			if (i == 0)
				[m[0] addObject: @""];
			i++;
		}
	} @catch (OFEnumerationMutationException *e) {
		ok = YES;
		ok = true;
	}

	TEST(@"Detection of mutation during Fast Enumeration", ok)

	[m[0] removeLastObject];
#endif

#ifdef OF_HAVE_BLOCKS
	{
		__block BOOL ok = YES;
		__block bool ok = true;
		__block size_t count = 0;
		OFArray *cmp = a[0];
		OFMutableArray *a2;

		m[0] = [[a[0] mutableCopy] autorelease];
		[m[0] enumerateObjectsUsingBlock:
		    ^ (id obj, size_t idx, BOOL *stop) {
		    ^ (id obj, size_t idx, bool *stop) {
			    count++;
			    if (![obj isEqual: [cmp objectAtIndex: idx]])
				    ok = NO;
				    ok = false;
		}];

		if (count != [cmp count])
			ok = NO;
			ok = false;

		TEST(@"Enumeration using blocks", ok)

		ok = NO;
		ok = false;
		a2 = m[0];
		@try {
			[a2 enumerateObjectsUsingBlock:
			    ^ (id obj, size_t idx, BOOL *stop) {
			    ^ (id obj, size_t idx, bool *stop) {
				[a2 removeObjectAtIndex: idx];
			}];
		} @catch (OFEnumerationMutationException *e) {
			ok = YES;
			ok = true;
		} @catch (OFOutOfRangeException *e) {
			/*
			 * Out of bounds access due to enumeration not being
			 * detected.
			 */
		}

		TEST(@"Detection of mutation during enumeration using blocks",
		    ok)
	}

	TEST(@"-[replaceObjectsUsingBlock:]",
	    R([m[0] replaceObjectsUsingBlock:
	    ^ id (id obj, size_t idx, BOOL *stop) {
	    ^ id (id obj, size_t idx, bool *stop) {
		switch (idx) {
		case 0:
			return @"foo";
		case 1:
			return @"bar";
		}

300
301
302
303
304
305
306
307
308


309
310
311
312
313
314
315
316
317
318
319
320
321
300
301
302
303
304
305
306


307
308
309
310
311
312
313
314
315
316
317
318
319
320
321







-
-
+
+













			return @"qux";
		}

		return nil;
	    }] description] isEqual: @"(\n\tfoobar,\n\tqux\n)"])

	TEST(@"-[filteredArrayUsingBlock:]",
	   [[[m[0] filteredArrayUsingBlock: ^ BOOL (id obj, size_t idx) {
		return ([obj isEqual: @"foo"] ? YES : NO);
	   [[[m[0] filteredArrayUsingBlock: ^ bool (id obj, size_t idx) {
		return [obj isEqual: @"foo"];
	    }] description] isEqual: @"(\n\tfoo\n)"])

	TEST(@"-[foldUsingBlock:]",
	    [([OFArray arrayWithObjects: [OFMutableString string], @"foo",
	    @"bar", @"baz", nil]) foldUsingBlock: ^ id (id left, id right) {
		[left appendString: right];
		return left;
	    }])
#endif

	[pool drain];
}
@end

Modified tests/OFDictionaryTests.m from [220414cfb6] to [e04f963308].

51
52
53
54
55
56
57
58
59


60
61
62
63
64



65
66
67
68
69
70
71
51
52
53
54
55
56
57


58
59
60
61



62
63
64
65
66
67
68
69
70
71







-
-
+
+


-
-
-
+
+
+








	TEST(@"-[objectForKey:]",
	    [[dict objectForKey: keys[0]] isEqual: values[0]] &&
	    [[dict objectForKey: keys[1]] isEqual: values[1]] &&
	    [dict objectForKey: @"key3"] == nil)

	TEST(@"-[containsObject:]",
	    [dict containsObject: values[0]] == YES &&
	    [dict containsObject: @"nonexistant"] == NO)
	    [dict containsObject: values[0]] &&
	    ![dict containsObject: @"nonexistant"])

	TEST(@"-[containsObjectIdenticalTo:]",
	    [dict containsObjectIdenticalTo: values[0]] == YES &&
	    [dict containsObjectIdenticalTo:
	    [OFString stringWithString: values[0]]] == NO)
	    [dict containsObjectIdenticalTo: values[0]] &&
	    ![dict containsObjectIdenticalTo:
	    [OFString stringWithString: values[0]]])

	TEST(@"-[description]",
	    [[dict description] isEqual:
	    @"{\n\tkey1 = value1;\n\tkey2 = value2;\n}"])

	TEST(@"-[allKeys]",
	    [[dict allKeys] isEqual: ([OFArray arrayWithObjects: keys[0],
92
93
94
95
96
97
98
99

100
101
102
103

104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131

132
133
134

135
136
137


138
139
140
141
142
143
144
145
146
147
148

149
150
151

152
153
154
155
156

157
158
159
160
161
162
163
164
165
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
92
93
94
95
96
97
98

99
100
101
102

103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130

131
132
133

134
135


136
137
138
139
140
141
142
143
144
145
146
147

148
149
150

151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
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







-
+



-
+










-
+





-
+










-
+


-
+

-
-
+
+










-
+


-
+




-
+










-
+




















-
-
+
+







	    OFEnumerationMutationException, [key_enum nextObject]);

	[dict setObject: values[0]
		 forKey: keys[0]];

#ifdef OF_HAVE_FAST_ENUMERATION
	size_t i = 0;
	BOOL ok = YES;
	bool ok = true;

	for (OFString *key in dict) {
		if (i > 1 || ![key isEqual: keys[i]]) {
			ok = NO;
			ok = false;
			break;
		}

		[dict setObject: [dict objectForKey: key]
			 forKey: key];
		i++;
	}

	TEST(@"Fast Enumeration", ok)

	ok = NO;
	ok = false;
	@try {
		for (OFString *key in dict)
			[dict setObject: @""
				 forKey: @""];
	} @catch (OFEnumerationMutationException *e) {
		ok = YES;
		ok = true;
	}

	TEST(@"Detection of mutation during Fast Enumeration", ok)

	[dict removeObjectForKey: @""];
#endif

#ifdef OF_HAVE_BLOCKS
	{
		__block size_t i = 0;
		__block BOOL ok = YES;
		__block bool ok = true;

		[dict enumerateKeysAndObjectsUsingBlock:
		    ^ (id key, id obj, BOOL *stop) {
		    ^ (id key, id obj, bool *stop) {
			if (i > 1 || ![key isEqual: keys[i]]) {
				ok = NO;
				*stop = YES;
				ok = false;
				*stop = true;
				return;
			}

			[dict setObject: [dict objectForKey: key]
				 forKey: key];
			i++;
		}];

		TEST(@"Enumeration using blocks", ok)

		ok = NO;
		ok = false;
		@try {
			[dict enumerateKeysAndObjectsUsingBlock:
			    ^ (id key, id obj, BOOL *stop) {
			    ^ (id key, id obj, bool *stop) {
				[dict setObject: @""
					 forKey: @""];
			}];
		} @catch (OFEnumerationMutationException *e) {
			ok = YES;
			ok = true;
		}

		TEST(@"Detection of mutation during enumeration using blocks",
		    ok)

		[dict removeObjectForKey: @""];
	}

	TEST(@"-[replaceObjectsUsingBlock:]",
	    R([dict replaceObjectsUsingBlock:
	    ^ id (id key, id obj, BOOL *stop) {
	    ^ id (id key, id obj, bool *stop) {
		if ([key isEqual: keys[0]])
			return @"value_1";
		if ([key isEqual: keys[1]])
			return @"value_2";

		return nil;
	    }]) && [[dict objectForKey: keys[0]] isEqual: @"value_1"] &&
	    [[dict objectForKey: keys[1]] isEqual: @"value_2"])

	TEST(@"-[mappedDictionaryUsingBlock:]",
	    [[[dict mappedDictionaryUsingBlock: ^ id (id key, id obj) {
		if ([key isEqual: keys[0]])
			return @"val1";
		if ([key isEqual: keys[1]])
			return @"val2";

		return nil;
	    }] description] isEqual: @"{\n\tkey1 = val1;\n\tkey2 = val2;\n}"])

	TEST(@"-[filteredDictionaryUsingBlock:]",
	    [[[dict filteredDictionaryUsingBlock: ^ BOOL (id key, id obj) {
		return ([key isEqual: keys[0]] ?  YES : NO);
	    [[[dict filteredDictionaryUsingBlock: ^ bool (id key, id obj) {
		return [key isEqual: keys[0]];
	    }] description] isEqual: @"{\n\tkey1 = value_1;\n}"])
#endif

	TEST(@"-[count]", [dict count] == 2)

	TEST(@"+[dictionaryWithKeysAndObjects:]",
	    (idict = [OFDictionary dictionaryWithKeysAndObjects: @"foo", @"bar",

Modified tests/OFJSONTests.m from [cfa228d8ae] to [c7925a23f4].

38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52







-
+







	OFDictionary *d = [OFDictionary dictionaryWithKeysAndObjects:
	    @"foo", @"ba\r",
	    @"x", [OFArray arrayWithObjects:
		[OFNumber numberWithFloat: .5f],
		[OFNumber numberWithInt: 0xF],
		[OFNull null],
		@"foo",
		[OFNumber numberWithBool: NO],
		[OFNumber numberWithBool: false],
		nil],
	    nil];

	TEST(@"-[JSONValue #1]", [[s JSONValue] isEqual: d])

	TEST(@"-[JSONRepresentation]", [[d JSONRepresentation] isEqual:
	    @"{\"x\":[0.5,15,null,\"foo\",false],\"foo\":\"ba\\r\"}"])

Modified tests/OFListTests.m from [f3e8ef8a53] to [a1285e945c].

36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50







-
+







{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFList *list;
	OFEnumerator *enumerator;
	of_list_object_t *loe;
	OFString *obj;
	size_t i;
	BOOL ok;
	bool ok;

	TEST(@"+[list]", (list = [OFList list]))

	TEST(@"-[appendObject:]", [list appendObject: strings[0]] &&
	    [list appendObject: strings[1]] && [list appendObject: strings[2]])

	TEST(@"-[firstListObject]",
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
101
102
103
104

105
106
107

108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133

134
135
136
137
138
139
140

141
142
143
144

145
146
147
148
149

150
151
152
153
154
155
156
157
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
101
102
103

104
105
106

107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

129
130
131
132

133
134
135
136
137
138
139

140
141
142
143

144
145
146
147
148

149
150
151
152
153
154
155
156
157







-
-
+
+


-
-
-
+
+
+















-
+


-
+






-
+














-
+



-
+






-
+



-
+




-
+








	    [list insertObject: strings[2]
	       afterListObject: [list firstListObject]->next] &&
	    [[list lastListObject]->object isEqual: strings[2]])

	TEST(@"-[count]", [list count] == 3)

	TEST(@"-[containsObject:]",
	    [list containsObject: strings[1]] == YES &&
	    [list containsObject: @"nonexistant"] == NO)
	    [list containsObject: strings[1]] &&
	    ![list containsObject: @"nonexistant"])

	TEST(@"-[containsObjectIdenticalTo:]",
	    [list containsObjectIdenticalTo: strings[1]] == YES &&
	    [list containsObjectIdenticalTo:
	    [OFString stringWithString: strings[1]]] == NO)
	    [list containsObjectIdenticalTo: strings[1]] &&
	    ![list containsObjectIdenticalTo:
	    [OFString stringWithString: strings[1]]])

	TEST(@"-[copy]", (list = [[list copy] autorelease]) &&
	    [[list firstListObject]->object isEqual: strings[0]] &&
	    [[list firstListObject]->next->object isEqual: strings[1]] &&
	    [[list lastListObject]->object isEqual: strings[2]])

	TEST(@"-[isEqual:]", [list isEqual: [[list copy] autorelease]])

	TEST(@"-[description]",
	    [[list description] isEqual: @"[\n\tFoo,\n\tBar,\n\tBaz\n]"])

	TEST(@"-[objectEnumerator]", (enumerator = [list objectEnumerator]))

	loe = [list firstListObject];
	i = 0;
	ok = YES;
	ok = true;
	while ((obj = [enumerator nextObject]) != nil) {
		if (![obj isEqual: loe->object])
			ok = NO;
			ok = false;

		loe = loe->next;
		i++;
	}

	if ([list count] != i)
		ok = NO;
		ok = false;

	TEST(@"OFEnumerator's -[nextObject]", ok);

	[enumerator reset];
	[list removeListObject: [list firstListObject]];

	EXPECT_EXCEPTION(@"Detection of mutation during enumeration",
	    OFEnumerationMutationException, [enumerator nextObject])

	[list prependObject: strings[0]];

#ifdef OF_HAVE_FAST_ENUMERATION
	loe = [list firstListObject];
	i = 0;
	ok = YES;
	ok = true;

	for (OFString *obj in list) {
		if (![obj isEqual: loe->object])
			ok = NO;
			ok = false;

		loe = loe->next;
		i++;
	}

	if ([list count] != i)
		ok = NO;
		ok = false;

	TEST(@"Fast Enumeration", ok)

	ok = NO;
	ok = false;
	@try {
		for (OFString *obj in list)
			[list removeListObject: [list lastListObject]];
	} @catch (OFEnumerationMutationException *e) {
		ok = YES;
		ok = true;
	}

	TEST(@"Detection of mutation during Fast Enumeration", ok)
#endif

	[pool drain];
}
@end

Modified tests/OFSet.m from [bf4e4ccf3c] to [6ea1882c4f].

29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43







-
+







@implementation TestsAppDelegate (OFSetTests)
- (void)setTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFSet *set1, *set2;
	OFMutableSet *mutableSet;
#ifdef OF_HAVE_FAST_ENUMERATION
	BOOL ok;
	bool ok;
	size_t i;
#endif

	TEST(@"+[setWithArray:]",
	    (set1 = [OFSet setWithArray: [OFArray arrayWithObjects: @"foo",
	    @"bar", @"baz", @"foo", @"x", nil]]))

88
89
90
91
92
93
94
95

96
97
98
99
100
101
102

103
104
105
106

107
108
109
110

111
112
113
114

115
116
117
118
119
120
121
122

123
124
125
126

127
128
129
130
131

132
133
134
135
136
137
138
139
88
89
90
91
92
93
94

95
96
97
98
99
100
101

102
103
104
105

106
107
108
109

110
111
112
113

114
115
116
117
118
119
120
121

122
123
124
125

126
127
128
129
130

131
132
133
134
135
136
137
138
139







-
+






-
+



-
+



-
+



-
+







-
+



-
+




-
+









	TEST(@"-[unionSet:]",
	    R([mutableSet unionSet: ([OFSet setWithObjects: @"x", @"bar",
	    nil])]) && [mutableSet isEqual: ([OFSet setWithObjects: @"baz",
	    @"bar", @"x", nil])])

#ifdef OF_HAVE_FAST_ENUMERATION
	ok = YES;
	ok = true;
	i = 0;

	for (OFString *s in set1) {
		switch (i) {
		case 0:
			if (![s isEqual: @"x"])
				ok = NO;
				ok = false;
			break;
		case 1:
			if (![s isEqual: @"bar"])
				ok = NO;
				ok = false;
			break;
		case 2:
			if (![s isEqual: @"foo"])
				ok = NO;
				ok = false;
			break;
		case 3:
			if (![s isEqual: @"baz"])
				ok = NO;
				ok = false;
			break;
		}

		i++;
	}

	if (i != 4)
		ok = NO;
		ok = false;

	TEST(@"Fast enumeration", ok)

	ok = NO;
	ok = false;
	@try {
		for (OFString *s in mutableSet)
			[mutableSet removeObject: s];
	} @catch (OFEnumerationMutationException *e) {
		ok = YES;
		ok = true;
	}

	TEST(@"Detection of mutation during Fast Enumeration", ok);
#endif

	[pool drain];
}
@end

Modified tests/OFStreamTests.m from [3c057c5909] to [6eb89e56e4].

30
31
32
33
34
35
36
37

38
39

40
41
42
43
44
45
46
30
31
32
33
34
35
36

37
38

39
40
41
42
43
44
45
46







-
+

-
+







@interface StreamTester: OFStream
{
	int state;
}
@end

@implementation StreamTester
- (BOOL)lowlevelIsAtEndOfStream
- (bool)lowlevelIsAtEndOfStream
{
	return (state > 1 ? YES : NO);
	return (state > 1);
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer
			  length: (size_t)size
{
	size_t pageSize = [OFSystemInfo pageSize];

Modified tests/OFStringTests.m from [61ef4cadec] to [5f1c00ddf1].

76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90







-
+







	OFString *is;
	OFArray *a;
	int i;
	const of_unichar_t *ua;
	const uint16_t *u16a;
	EntityHandler *h;
#ifdef OF_HAVE_BLOCKS
	__block BOOL ok;
	__block bool ok;
#endif

	s[0] = [OFMutableString stringWithString: @"täs€"];
	s[1] = [OFMutableString string];
	s[2] = [[s[0] copy] autorelease];

	TEST(@"-[isEqual:]", [s[0] isEqual: s[2]] &&
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119







-
+







	    [@"я" caseInsensitiveCompare: @"Я"] == OF_ORDERED_SAME &&
	    [@"€" caseInsensitiveCompare: @"ß"] == OF_ORDERED_DESCENDING &&
	    [@"ß" caseInsensitiveCompare: @"→"] == OF_ORDERED_ASCENDING &&
	    [@"AA" caseInsensitiveCompare: @"z"] == OF_ORDERED_ASCENDING &&
	    [[OFString stringWithUTF8String: "ABC"] caseInsensitiveCompare:
	    [OFString stringWithUTF8String: "AbD"]] == [@"abc" compare: @"abd"])

	TEST(@"-[hash] is the same if -[isEqual:] is YES",
	TEST(@"-[hash] is the same if -[isEqual:] is true",
	    [s[0] hash] == [s[2] hash])

	TEST(@"-[description]", [[s[0] description] isEqual: s[0]])

	TEST(@"-[appendString:] and -[appendUTF8String:]",
	    R([s[1] appendUTF8String: "1𝄞"]) && R([s[1] appendString: @"3"]) &&
	    R([s[0] appendString: s[1]]) && [s[0] isEqual: @"täs€1𝄞3"])
585
586
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

612
613
614
615
616
617
618
619
620
621
585
586
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
612
613
614
615
616
617
618
619
620
621







-
+

-
+





-
+



-
+



-
+


-
+










	        ^ OFString* (OFString *str, OFString *entity) {
		    if ([entity isEqual: @"foo"])
			    return @"bar";

		    return nil;
	    }] isEqual: @"xbary"])

	ok = YES;
	ok = true;
	[@"foo\nbar\nbaz" enumerateLinesUsingBlock:
	    ^ (OFString *line, BOOL *stop) {
	    ^ (OFString *line, bool *stop) {
		static int i = 0;

		switch (i) {
		case 0:
			if (![line isEqual: @"foo"])
				ok = NO;
				ok = false;
			break;
		case 1:
			if (![line isEqual: @"bar"])
				ok = NO;
				ok = false;
			break;
		case 2:
			if (![line isEqual: @"baz"])
				ok = NO;
				ok = false;
			break;
		default:
			ok = NO;
			ok = false;
		}

		i++;
	}];
	TEST(@"-[enumerateLinesUsingBlock:]", ok)
#endif

	[pool drain];
}
@end

Modified tests/TestsAppDelegate.h from [d5a4c58861] to [0a217cd05f].

29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51







-
+







-
+







			[self outputFailure: test	\
				   inModule: module];	\
			_fails++;			\
		}					\
	}
#define EXPECT_EXCEPTION(test, exception, code)		\
	{						\
		BOOL caught = NO;			\
		bool caught = false;			\
							\
		[self outputTesting: test		\
			   inModule: module];		\
							\
		@try {					\
			code;				\
		} @catch (exception *e) {		\
			caught = YES;			\
			caught = true;			\
		}					\
							\
		if (caught)				\
			[self outputSuccess: test	\
				   inModule: module];	\
		else {					\
			[self outputFailure: test	\