ObjFW  Check-in [e40729d406]

Overview
Comment:Prefix all ivars with an underscore.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e40729d406606caf241f251f9e0125647c1a6bca59b3a3d91ee5c37335abd03f
User & Date: js on 2013-02-12 18:22:15
Other Links: manifest | tags
Context
2013-02-12
19:59
Add -Wno-objc-root-class to Xcode project. check-in: 8fb566e562 user: js tags: trunk
18:22
Prefix all ivars with an underscore. check-in: e40729d406 user: js tags: trunk
18:14
OFXMLElement: Retain + autorelease attributes. check-in: 40f7e8bd2e user: js tags: trunk
Changes

Modified src/OFApplication.h from [8e58702259] to [4a2c8eebf0].

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







-
-
-
-
-
+
+
+
+
+

-
-
+
+

-
-
-
+
+
+







@end

/*!
 * @brief Represents the application as an object.
 */
@interface OFApplication: OFObject
{
	OFString *programName;
	OFMutableArray *arguments;
	OFMutableDictionary *environment;
	int *argc;
	char ***argv;
	OFString *_programName;
	OFArray *_arguments;
	OFDictionary *_environment;
	int *_argc;
	char ***_argv;
@public
	id <OFApplicationDelegate> delegate;
	void (*SIGINTHandler)(id, SEL);
	id <OFApplicationDelegate> _delegate;
	void (*_SIGINTHandler)(id, SEL);
#ifndef _WIN32
	void (*SIGHUPHandler)(id, SEL);
	void (*SIGUSR1Handler)(id, SEL);
	void (*SIGUSR2Handler)(id, SEL);
	void (*_SIGHUPHandler)(id, SEL);
	void (*_SIGUSR1Handler)(id, SEL);
	void (*_SIGUSR2Handler)(id, SEL);
#endif
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *programName;
@property (readonly, copy, nonatomic) OFArray *arguments;
@property (readonly, copy, nonatomic) OFDictionary *environment;

Modified src/OFApplication.m from [af4f6fe02e] to [10883a3ba0].

51
52
53
54
55
56
57
58

59
60
61
62
63
64
65

66
67
68
69
70
71
72
51
52
53
54
55
56
57

58
59
60
61
62
63
64

65
66
67
68
69
70
71
72







-
+






-
+







atexit_handler(void)
{
	id <OFApplicationDelegate> delegate = [app delegate];

	if ([delegate respondsToSelector: @selector(applicationWillTerminate)])
		[delegate applicationWillTerminate];

	[(id)delegate release];
	[delegate release];
}

#define SIGNAL_HANDLER(sig)					\
	static void						\
	handle##sig(int signal)					\
	{							\
		app->sig##Handler(app->delegate,		\
		app->_##sig##Handler(app->_delegate,		\
		    @selector(applicationDidReceive##sig));	\
	}
SIGNAL_HANDLER(SIGINT)
#ifndef _WIN32
SIGNAL_HANDLER(SIGHUP)
SIGNAL_HANDLER(SIGUSR1)
SIGNAL_HANDLER(SIGUSR2)
135
136
137
138
139
140
141

142
143
144
145
146
147
148
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149







+








- init
{
	self = [super init];

	@try {
		void *pool;
		OFMutableDictionary *environment;
#if defined(__MACH__) && !defined(OF_IOS)
		char **env = *_NSGetEnviron();
#elif defined(__WIN32)
		uint16_t *env;
#elif !defined(OF_IOS)
		char **env = environ;
#else
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
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







+








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



+


-
-
+
+

-
+










+



-
-
+
+




-
-
+
+


+


-
+


-
+

-
+


+





-
-
+
+

-
-
+
+




-
+




-
+




-
+




-
+


-
+

-
+




-
+







					forKey: @"USER"];
		}

		objc_autoreleasePoolPop(pool);
#endif

		[environment makeImmutable];
		_environment = environment;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_arguments release];
	[_environment release];

	[super dealloc];
}

- (void)OF_setArgumentCount: (int*)argc_
	  andArgumentValues: (char***)argv_
- (void)OF_setArgumentCount: (int*)argc
	  andArgumentValues: (char***)argv
{
#ifndef _WIN32
	void *pool = objc_autoreleasePoolPush();
	OFMutableArray *arguments;
	int i;

	argc = argc_;
	argv = argv_;
	_argc = argc;
	_argv = argv;

	programName = [[OFString alloc]
	_programName = [[OFString alloc]
	    initWithCString: (*argv)[0]
		   encoding: OF_STRING_ENCODING_NATIVE];
	arguments = [[OFMutableArray alloc] init];

	for (i = 1; i < *argc; i++)
		[arguments addObject:
		    [OFString stringWithCString: (*argv)[i]
				       encoding: OF_STRING_ENCODING_NATIVE]];

	[arguments makeImmutable];
	_arguments = arguments;

	objc_autoreleasePoolPop(pool);
#else
	argc = argc_;
	argv = argv_;
	_argc = argc;
	_argv = argv;
#endif
}

#ifdef _WIN32
- (void)OF_setArgumentCount: (int)argc_
      andWideArgumentValues: (wchar_t**)argv_
- (void)OF_setArgumentCount: (int)argc
      andWideArgumentValues: (wchar_t**)argv
{
	void *pool = objc_autoreleasePoolPush();
	OFMutableArray *arguments;
	int i;

	programName = [[OFString alloc] initWithUTF16String: argv_[0]];
	_programName = [[OFString alloc] initWithUTF16String: argv[0]];
	arguments = [[OFMutableArray alloc] init];

	for (i = 1; i < argc_; i++)
	for (i = 1; i < argc; i++)
		[arguments addObject:
		    [OFString stringWithUTF16String: argv_[i]]];
		    [OFString stringWithUTF16String: argv[i]]];

	[arguments makeImmutable];
	_arguments = arguments;

	objc_autoreleasePoolPop(pool);
}
#endif

- (void)getArgumentCount: (int**)argc_
       andArgumentValues: (char****)argv_
- (void)getArgumentCount: (int**)argc
       andArgumentValues: (char****)argv
{
	*argc_ = argc;
	*argv_ = argv;
	*argc = _argc;
	*argv = _argv;
}

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

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

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

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

- (void)setDelegate: (id <OFApplicationDelegate>)delegate_
- (void)setDelegate: (id <OFApplicationDelegate>)delegate
{
	delegate = delegate_;
	_delegate = delegate;

#define REGISTER_SIGNAL(sig)						\
	if ([delegate respondsToSelector:				\
	    @selector(applicationDidReceive##sig)]) {			\
		sig##Handler = (void(*)(id, SEL))[(id)delegate		\
		_##sig##Handler = (void(*)(id, SEL))[(id)delegate	\
		    methodForSelector:					\
		    @selector(applicationDidReceive##sig)];		\
		signal(sig, handle##sig);				\
	} else								\
		signal(sig, SIG_DFL);
	REGISTER_SIGNAL(SIGINT)
#ifndef _WIN32
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
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







+
+
+
+
+
+

-
+














-
-
-
-
-
-
-
-

	runLoop = [[[OFRunLoop alloc] init] autorelease];
#endif

	[OFRunLoop OF_setMainRunLoop: runLoop];

	objc_autoreleasePoolPop(pool);

	/*
	 * Note: runLoop is still valid after the release of the pool, as
	 * OF_setMainRunLoop: retained it. However, we only have a weak
	 * reference to it now, whereas we had a strong reference before.
	 */

	pool = objc_autoreleasePoolPush();
	[delegate applicationDidFinishLaunching];
	[_delegate applicationDidFinishLaunching];
	objc_autoreleasePoolPop(pool);

	[runLoop run];
}

- (void)terminate
{
	exit(0);
}

- (void)terminateWithStatus: (int)status
{
	exit(status);
}

- (void)dealloc
{
	[arguments release];
	[environment release];

	[super dealloc];
}
@end

Modified src/OFArray_adjacent.h from [df8cae2d28] to [a695cf002b].

16
17
18
19
20
21
22
23

24
25
16
17
18
19
20
21
22

23
24
25







-
+



#import "OFArray.h"

@class OFDataArray;

@interface OFArray_adjacent: OFArray
{
	OFDataArray *array;
	OFDataArray *_array;
}
@end

Modified src/OFArray_adjacent.m from [c91deb9080] to [a68b59eaa5].

34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81

82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99

100
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
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
79
80

81
82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98

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







-
+

















-
+

















-
+



-
+










-
+






-
+



-
-
+
+









-
-
+
+





-
-
+
+








@implementation OFArray_adjacent
- init
{
	self = [super init];

	@try {
		array = [[OFDataArray alloc] initWithItemSize: sizeof(id)];
		_array = [[OFDataArray alloc] initWithItemSize: sizeof(id)];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithObject: (id)object
{
	self = [self init];

	@try {
		if (object == nil)
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]];

		[array addItem: &object];
		[_array addItem: &object];
		[object retain];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithObject: (id)firstObject
       arguments: (va_list)arguments
{
	self = [self init];

	@try {
		id object;

		[array addItem: &firstObject];
		[_array addItem: &firstObject];
		[firstObject retain];

		while ((object = va_arg(arguments, id)) != nil) {
			[array addItem: &object];
			[_array addItem: &object];
			[object retain];
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithArray: (OFArray*)array_
- initWithArray: (OFArray*)array
{
	id *objects;
	size_t i, count;

	self = [self init];

	if (array_ == nil)
	if (array == nil)
		return self;

	@try {
		objects = [array_ objects];
		count = [array_ count];
		objects = [array objects];
		count = [array count];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	@try {
		for (i = 0; i < count; i++)
			[objects[i] retain];

		[array addItems: objects
			  count: count];
		[_array addItems: objects
			   count: count];
	} @catch (id e) {
		for (i = 0; i < count; i++)
			[objects[i] release];

		/* Prevent double-release of objects */
		[array release];
		array = nil;
		[_array release];
		_array = nil;

		[self release];
		@throw e;
	}

	return self;
}
144
145
146
147
148
149
150
151
152


153
154
155
156
157
158
159
144
145
146
147
148
149
150


151
152
153
154
155
156
157
158
159







-
-
+
+







			[objects[i] retain];
		}

		if (!ok)
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]];

		[array addItems: objects
			  count: count];
		[_array addItems: objects
			   count: count];
	} @catch (id e) {
		size_t i;

		for (i = 0; i < count; i++)
			[objects[i] release];

		[self release];
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
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







-
+
















-
+




-
+




-
+




-
+





-
-
+
+

















-
-
+
+
















-
-
+
+












-
+





-
+



















-
+




-
+











-
-
+
+















-
-
+
+









-
-
+
+




-
+




		    OF_SERIALIZATION_NS] objectEnumerator];

		while ((child = [enumerator nextObject]) != nil) {
			void *pool2 = objc_autoreleasePoolPush();
			id object;

			object = [child objectByDeserializing];
			[array addItem: &object];
			[_array addItem: &object];
			[object retain];

			objc_autoreleasePoolPop(pool2);
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (size_t)count
{
	return [array count];
	return [_array count];
}

- (id*)objects
{
	return [array items];
	return [_array items];
}

- (id)objectAtIndex: (size_t)index
{
	return *((id*)[array itemAtIndex: index]);
	return *((id*)[_array itemAtIndex: index]);
}

- (id)objectAtIndexedSubscript: (size_t)index
{
	return *((id*)[array itemAtIndex: index]);
	return *((id*)[_array itemAtIndex: index]);
}

- (void)getObjects: (id*)buffer
	   inRange: (of_range_t)range
{
	id *objects = [array items];
	size_t i, count = [array count];
	id *objects = [_array items];
	size_t i, count = [_array count];

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

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

- (size_t)indexOfObject: (id)object
{
	id *objects;
	size_t i, count;

	if (object == nil)
		return OF_NOT_FOUND;

	objects = [array items];
	count = [array count];
	objects = [_array items];
	count = [_array count];

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

	return OF_NOT_FOUND;
}

- (size_t)indexOfObjectIdenticalTo: (id)object
{
	id *objects;
	size_t i, count;

	if (object == nil)
		return OF_NOT_FOUND;

	objects = [array items];
	count = [array count];
	objects = [_array items];
	count = [_array count];

	for (i = 0; i < count; i++)
		if (objects[i] == object)
			return i;

	return OF_NOT_FOUND;
}


- (OFArray*)objectsInRange: (of_range_t)range
{
	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > [array count])
	    range.location + range.length > [_array count])
		@throw [OFOutOfRangeException
		    exceptionWithClass: [self class]];

	if ([self isKindOfClass: [OFMutableArray class]])
		return [OFArray
		    arrayWithObjects: (id*)[array items] + range.location
		    arrayWithObjects: (id*)[_array items] + range.location
			       count: range.length];

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

- (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];
	count = [_array count];

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

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

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

	return YES;
}

- (uint32_t)hash
{
	id *objects = [array items];
	size_t i, count = [array count];
	id *objects = [_array items];
	size_t i, count = [_array count];
	uint32_t hash;

	OF_HASH_INIT(hash);

	for (i = 0; i < count; i++)
		OF_HASH_ADD_HASH(hash, [objects[i] hash]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

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

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

- (void)dealloc
{
	id *objects = [array items];
	size_t i, count = [array count];
	id *objects = [_array items];
	size_t i, count = [_array count];

	for (i = 0; i < count; i++)
		[objects[i] release];

	[array release];
	[_array release];

	[super dealloc];
}
@end

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

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







-
+















-
+





-
+













-
+




#import "OFArray_adjacentSubarray.h"
#import "OFArray_adjacent.h"
#import "OFMutableArray_adjacent.h"

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

- (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])
	if (_range.length != [otherArray count])
		return NO;

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

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

	return YES;
}

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

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

Modified src/OFArray_subarray.h from [2b2c04c402] to [8e2aa92a1b].

14
15
16
17
18
19
20
21
22


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


21
22
23
24
25
26
27
28
29







-
-
+
+







 * file.
 */

#import "OFArray.h"

@interface OFArray_subarray: OFArray
{
	OFArray *array;
	of_range_t range;
	OFArray *_array;
	of_range_t _range;
}

+ (instancetype)arrayWithArray: (OFArray*)array
			 range: (of_range_t)range;
- initWithArray: (OFArray*)array
	  range: (of_range_t)range;
@end

Modified src/OFArray_subarray.m from [43b86d4da0] to [4d0eadf9ff].

24
25
26
27
28
29
30
31
32


33
34
35
36
37
38
39


40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57

58
59
60
61
62

63
64
65

66
67
68
69

70
71
72


73
74
75

76
77
78


79
80
81
82
83

84
85

86
87
88

89
90

91
92
93
94
95
96
97
98

99
100

101
102
103

104
105

106
107
108
109
110
111

112
113
114


115
116
117

118
119

120
121
24
25
26
27
28
29
30


31
32
33
34
35
36
37


38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56

57
58
59
60
61

62
63
64

65
66
67
68

69
70


71
72
73
74

75
76


77
78
79
80
81
82

83
84

85
86
87

88
89

90
91
92
93
94
95
96
97

98
99

100
101
102

103
104

105
106
107
108
109
110

111
112


113
114
115
116

117
118

119
120
121







-
-
+
+





-
-
+
+










-
+






-
+




-
+


-
+



-
+

-
-
+
+


-
+

-
-
+
+




-
+

-
+


-
+

-
+







-
+

-
+


-
+

-
+





-
+

-
-
+
+


-
+

-
+


+ (instancetype)arrayWithArray: (OFArray*)array
			 range: (of_range_t)range
{
	return [[[self alloc] initWithArray: array
				      range: range] autorelease];
}

- initWithArray: (OFArray*)array_
	  range: (of_range_t)range_
- initWithArray: (OFArray*)array
	  range: (of_range_t)range
{
	self = [super init];

	@try {
		/* Should usually be retain, as it's useless with a copy */
		array = [array_ copy];
		range = range_;
		_array = [array copy];
		_range = range;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[array release];
	[_array release];

	[super dealloc];
}

- (size_t)count
{
	return range.length;
	return _range.length;
}

- (id)objectAtIndex: (size_t)index
{
	if (index >= range.length)
	if (index >= _range.length)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	return [array objectAtIndex: index + range.location];
	return [_array objectAtIndex: index + _range.location];
}

- (void)getObjects: (id*)buffer
	   inRange: (of_range_t)range_
	   inRange: (of_range_t)range
{
	if (range_.length > SIZE_MAX - range_.location ||
	    range_.location + range_.length > range.length)
	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > _range.length)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	range_.location += range.location;
	range.location += _range.location;

	return [array getObjects: buffer
			 inRange: range_];
	return [_array getObjects: buffer
			  inRange: range];
}

- (size_t)indexOfObject: (id)object
{
	size_t index = [array indexOfObject: object];
	size_t index = [_array indexOfObject: object];

	if (index < range.location)
	if (index < _range.location)
		return OF_NOT_FOUND;

	index -= range.location;
	index -= _range.location;

	if (index >= range.length)
	if (index >= _range.length)
		return OF_NOT_FOUND;

	return index;
}

- (size_t)indexOfObjectIdenticalTo: (id)object
{
	size_t index = [array indexOfObjectIdenticalTo: object];
	size_t index = [_array indexOfObjectIdenticalTo: object];

	if (index < range.location)
	if (index < _range.location)
		return OF_NOT_FOUND;

	index -= range.location;
	index -= _range.location;

	if (index >= range.length)
	if (index >= _range.length)
		return OF_NOT_FOUND;

	return index;
}

- (OFArray*)objectsInRange: (of_range_t)range_
- (OFArray*)objectsInRange: (of_range_t)range
{
	if (range_.length > SIZE_MAX - range_.location ||
	    range_.location + range_.length > range.length)
	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > _range.length)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	range_.location += range.location;
	range.location += _range.location;

	return [array objectsInRange: range_];
	return [_array objectsInRange: range];
}
@end

Modified src/OFAutoreleasePool.h from [6e97eee322] to [c4bc0a71ca].

22
23
24
25
26
27
28
29
30


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


29
30
31
32
33
34
35
36
37







-
-
+
+







 * The OFAutoreleasePool class is a class that keeps track of objects that will
 * be released when the autorelease pool is released.
 *
 * Every thread has its own stack of autorelease pools.
 */
@interface OFAutoreleasePool: OFObject
{
	void *pool;
	BOOL ignoreRelease;
	void *_pool;
	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 [b51231d742] to [d0fc457afc].

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







-
+












-
+

-
-
+
+



-
+


















-
+


-
+

-
+

















-
-
+
+







}

- init
{
	self = [super init];

	@try {
		pool = objc_autoreleasePoolPush();
		_pool = objc_autoreleasePoolPush();

		_objc_rootAutorelease(self);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

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

	objc_autoreleasePoolPop(pool);
	pool = objc_autoreleasePoolPush();
	objc_autoreleasePoolPop(_pool);
	_pool = objc_autoreleasePoolPush();

	_objc_rootAutorelease(self);

	ignoreRelease = NO;
	_ignoreRelease = NO;
}

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

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

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

	if (ignoreRelease)
	if (_ignoreRelease)
		return;

	ignoreRelease = YES;
	_ignoreRelease = YES;

	objc_autoreleasePoolPop(pool);
	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;
				_pool = NULL;
				_ignoreRelease = NO;

				cache[i] = self;

				return;
			}
		}
	}

Modified src/OFCondition.h from [5908f93915] to [c116d03373].

17
18
19
20
21
22
23
24
25


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


24
25
26
27
28
29
30
31
32







-
-
+
+







#import "OFMutex.h"

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

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

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

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







-
+





-
+



+
+
+
+
+
+
+
+
+
+
+



-
+







-
+







-
+




-
-
-
-
-
-
-
-
-
-
-

	return [[[self alloc] init] autorelease];
}

- init
{
	self = [super init];

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

	conditionInitialized = YES;
	_conditionInitialized = YES;

	return self;
}

- (void)dealloc
{
	if (_conditionInitialized)
		if (!of_condition_free(&_condition))
			@throw [OFConditionStillWaitingException
			    exceptionWithClass: [self class]
				     condition: self];

	[super dealloc];
}

- (void)wait
{
	if (!of_condition_wait(&condition, &mutex))
	if (!of_condition_wait(&_condition, &_mutex))
		@throw [OFConditionWaitFailedException
		    exceptionWithClass: [self class]
			     condition: self];
}

- (void)signal
{
	if (!of_condition_signal(&condition))
	if (!of_condition_signal(&_condition))
		@throw [OFConditionSignalFailedException
		    exceptionWithClass: [self class]
			     condition: self];
}

- (void)broadcast
{
	if (!of_condition_broadcast(&condition))
	if (!of_condition_broadcast(&_condition))
		@throw [OFConditionBroadcastFailedException
		    exceptionWithClass: [self class]
			     condition: self];
}

- (void)dealloc
{
	if (conditionInitialized)
		if (!of_condition_free(&condition))
			@throw [OFConditionStillWaitingException
			    exceptionWithClass: [self class]
				     condition: self];

	[super dealloc];
}
@end

Modified src/OFConstantString.h from [a4e3964c53] to [6b6b3d5b5b].

28
29
30
31
32
33
34
35
36


37
38
28
29
30
31
32
33
34


35
36
37
38







-
-
+
+


#endif

/*!
 * @brief A class for storing constant strings using the \@"" literal.
 */
@interface OFConstantString: OFString
{
	char *cString;
	size_t cStringLength;
	char *_cString;
	size_t _cStringLength;
}
@end

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

72
73
74
75
76
77
78
79
80


81
82
83
84
85
86
87
72
73
74
75
76
77
78


79
80
81
82
83
84
85
86
87







-
-
+
+







		 size: (size_t)size
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (void*)resizeMemory: (void*)ptr
	     toNItems: (size_t)nitems
	     withSize: (size_t)size
		 size: (size_t)nitems
		count: (size_t)size
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (void)freeMemory: (void*)ptr
{
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
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







-
-
+
+












-
+







	struct of_string_utf8_ivars *ivars;

	if ((ivars = calloc(1, sizeof(*ivars))) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithClass: [self class]
			 requestedSize: sizeof(*ivars)];

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

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

	cString = (char*)ivars;
	_cString = (char*)ivars;
	object_setClass(self, [OFString_const class]);
}

+ alloc
{
	[self doesNotRecognizeSelector: _cmd];
	abort();

Modified src/OFCountedSet_hashtable.h from [f3fb841536] to [9946a99cd2].

16
17
18
19
20
21
22
23

24
25
16
17
18
19
20
21
22

23
24
25







-
+



#import "OFCountedSet.h"

@class OFMapTable;

@interface OFCountedSet_hashtable: OFCountedSet
{
	OFMapTable *mapTable;
	OFMapTable *_mapTable;
}
@end

Modified src/OFCountedSet_hashtable.m from [23039ce7da] to [1c8a9015a1].

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







-
-
+
+















-
+







-
+













-
+




-
-
+
+




-
+







-
-
+
+

-
+







			if (object == nil || count_ == nil)
				@throw [OFInvalidFormatException
				    exceptionWithClass: [self class]];

			count = (size_t)[[count_ stringValue] decimalValue];

			[mapTable setValue: (void*)(uintptr_t)count
				    forKey: [object objectByDeserializing]];
			[_mapTable setValue: (void*)(uintptr_t)count
				     forKey: [object objectByDeserializing]];

			objc_autoreleasePoolPop(pool2);
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (size_t)countForObject: (id)object
{
	return (size_t)(uintptr_t)[mapTable valueForKey: object];
	return (size_t)(uintptr_t)[_mapTable valueForKey: object];
}

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

- (void)addObject: (id)object
{
	size_t count = (size_t)(uintptr_t)[mapTable valueForKey: object];
	size_t count = (size_t)(uintptr_t)[_mapTable valueForKey: object];

	if (SIZE_MAX - count < 1)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	[mapTable setValue: (void*)(uintptr_t)(count + 1)
		    forKey: object];
	[_mapTable setValue: (void*)(uintptr_t)(count + 1)
		     forKey: object];
}

- (void)removeObject: (id)object
{
	size_t count = (size_t)(uintptr_t)[mapTable valueForKey: object];
	size_t count = (size_t)(uintptr_t)[_mapTable valueForKey: object];

	if (count == 0)
		return;

	count--;

	if (count > 0)
		[mapTable setValue: (void*)(uintptr_t)count
			    forKey: object];
		[_mapTable setValue: (void*)(uintptr_t)count
			     forKey: object];
	else
		[mapTable removeValueForKey: object];
		[_mapTable removeValueForKey: object];
}

- (void)makeImmutable
{
}
@end

Modified src/OFDataArray+Hashing.m from [681c8a7ef5] to [2171c1b800].

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







-
-
+
+







{
	void *pool = objc_autoreleasePoolPush();
	OFMD5Hash *hash = [OFMD5Hash hash];
	uint8_t *digest;
	char cString[OF_MD5_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: items
			length: count * itemSize];
	[hash updateWithBuffer: _items
			length: _count * _itemSize];
	digest = [hash digest];

	for (i = 0; i < OF_MD5_DIGEST_SIZE; i++) {
		uint8_t high, low;

		high = digest[i] >> 4;
		low  = digest[i] & 0x0F;
59
60
61
62
63
64
65
66
67


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


66
67
68
69
70
71
72
73
74







-
-
+
+







{
	void *pool = objc_autoreleasePoolPush();
	OFSHA1Hash *hash = [OFSHA1Hash hash];
	uint8_t *digest;
	char cString[OF_SHA1_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: items
			length: count * itemSize];
	[hash updateWithBuffer: _items
			length: _count * _itemSize];
	digest = [hash digest];

	for (i = 0; i < OF_SHA1_DIGEST_SIZE; i++) {
		uint8_t high, low;

		high = digest[i] >> 4;
		low  = digest[i] & 0x0F;

Modified src/OFDataArray.h from [6f4ab00da5] to [ccf132759c].

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







-
-
-
+
+
+







 * OFBigDataArray, which allocates the memory in pages rather than in bytes.
 *
 * For security reasons, serialization and deserialization is only implemented
 * for OFDataArrays with item size 1.
 */
@interface OFDataArray: OFObject <OFCopying, OFComparing, OFSerialization>
{
	uint8_t *items;
	size_t count;
	size_t itemSize;
	uint8_t *_items;
	size_t _count;
	size_t _itemSize;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly) void *items;
@property (readonly) size_t count;
@property (readonly) size_t itemSize;
#endif
274
275
276
277
278
279
280
281

282
283
284
285
274
275
276
277
278
279
280

281
282
283
284
285







-
+




 *
 * The OFBigDataArray class is a class for storing arbitrary data in an array
 * and is designed to store large hunks of data. Therefore, it allocates
 * memory in pages rather than a chunk of memory for each item.
 */
@interface OFBigDataArray: OFDataArray
{
	size_t size;
	size_t _size;
}
@end

#import "OFDataArray+Hashing.h"

Modified src/OFDataArray.m from [993787fe25] to [85eaead6fd].

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







-
+




-
+



-
+






-
+












-
+







	return [[[self alloc] initWithBase64EncodedString: string] autorelease];
}

- init
{
	self = [super init];

	itemSize = 1;
	_itemSize = 1;

	return self;
}

- initWithItemSize: (size_t)itemSize_
- initWithItemSize: (size_t)itemSize
{
	self = [super init];

	if (itemSize_ == 0) {
	if (itemSize == 0) {
		Class c = [self class];
		[self release];
		@throw [OFInvalidArgumentException exceptionWithClass: c
							     selector: _cmd];
	}

	itemSize = itemSize_;
	_itemSize = itemSize;

	return self;
}

- initWithContentsOfFile: (OFString*)path
{
	self = [super init];

	@try {
		OFFile *file = [[OFFile alloc] initWithPath: path
						       mode: @"rb"];

		itemSize = 1;
		_itemSize = 1;

		@try {
			size_t pageSize = [OFSystemInfo pageSize];
			char *buffer = [self allocMemoryWithSize: pageSize];

			while (![file isAtEndOfStream]) {
				size_t length;
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
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







-
-
+
+


-
+



-
+


-
+

-
+







{
	self = [super init];

	@try {
		const char *cString;
		size_t i;

		itemSize = 1;
		count = [string
		_itemSize = 1;
		_count = [string
		    cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII];

		if (count & 1)
		if (_count & 1)
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];

		count >>= 1;
		_count >>= 1;
		cString = [string
		    cStringWithEncoding: OF_STRING_ENCODING_ASCII];
		items = [self allocMemoryWithSize: count];
		_items = [self allocMemoryWithSize: _count];

		for (i = 0; i < count; i++) {
		for (i = 0; i < _count; i++) {
			uint8_t c1 = cString[2 * i];
			uint8_t c2 = cString[2 * i + 1];
			uint8_t byte;

			if (c1 >= '0' && c1 <= '9')
				byte = (c1 - '0') << 4;
			else if (c1 >= 'a' && c1 <= 'f')
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
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







-
+














-
+




















-
+







				byte |= c2 - 'a' + 10;
			else if (c2 >= 'A' && c2 <= 'F')
				byte |= c2 - 'A' + 10;
			else
				@throw [OFInvalidFormatException
				    exceptionWithClass: [self class]];

			items[i] = byte;
			_items[i] = byte;
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithBase64EncodedString: (OFString*)string
{
	self = [super init];

	@try {
		itemSize = 1;
		_itemSize = 1;

		if (!of_base64_decode(self, [string cStringWithEncoding:
		    OF_STRING_ENCODING_ASCII], [string
		    cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII])) {
			Class c = [self class];
			[self release];
			@throw [OFInvalidFormatException exceptionWithClass: c];
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithSerialization: (OFXMLElement*)element
{
	self = [super init];

	itemSize = 1;
	_itemSize = 1;

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFString *stringValue;

		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
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

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
550
551
552
553
554

555
556
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
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
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
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
550
551
552
553
554

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







-
+




-
+




-
+




-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
-
-
+
+
+

-
+

-
+










-
-
+
+

-
+


-
-
-
+
+
+

-
-
+
+


-
+

-
+

-
+


-
-
-
+
+
+

-
-
-
+
+
+

-
+










-
+


-
-
-
+
+
+

-
+

-
-
-
+
+
+







-
+


-
+

-
-
-
+
+
+







-
+

-
-
+
+




-
+

-
-
+
+






-
+




-
+

-
-
+
+

-
+







-
+

-
+





-
+

-
+




-
-
+
+

-
-
-
+
+
+

-
+

+
















-
-
+
+











-
+





-
-
+
+













-
-
-
+
+
+







-
+








-
-
+
+










-
+







-
+












-
+

-
+



-
+

-
-
-
+
+
+

-
+

-
-
+
+


-
-
+
+

-
+

-
+



-
+

-
-
-
+
+
+

-
+

-
-
+
+


-
+

-
+

-
+

-
-
+
+



-
+

-
-
-
+
+
+

-
-
-
+
+
+

-
-
+
+




-
+


-
+


-
-
-
+
+
+

-
+

-
+

-
+

-
-
+
+




-
+





-
+

-
+


-
+

-
+

-
+

-
-
+
+




-
+








-
-
-
+
+
+




-
+


	}

	return self;
}

- (size_t)count
{
	return count;
	return _count;
}

- (size_t)itemSize
{
	return itemSize;
	return _itemSize;
}

- (void*)items
{
	return items;
	return _items;
}

- (void*)itemAtIndex: (size_t)index
{
	if (index >= count)
	if (index >= _count)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	return items + index * itemSize;
	return _items + index * _itemSize;
}

- (void*)firstItem
{
	if (items == NULL || count == 0)
	if (_items == NULL || _count == 0)
		return NULL;

	return items;
	return _items;
}

- (void*)lastItem
{
	if (items == NULL || count == 0)
	if (_items == NULL || _count == 0)
		return NULL;

	return items + (count - 1) * itemSize;
	return _items + (_count - 1) * _itemSize;
}

- (void)addItem: (const void*)item
{
	if (SIZE_MAX - count < 1)
	if (SIZE_MAX - _count < 1)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	items = [self resizeMemory: items
			      size: itemSize
			     count: count + 1];
	_items = [self resizeMemory: _items
			       size: _itemSize
			      count: _count + 1];

	memcpy(items + count * itemSize, item, itemSize);
	memcpy(_items + _count * _itemSize, item, _itemSize);

	count++;
	_count++;
}

- (void)insertItem: (const void*)item
	   atIndex: (size_t)index
{
	[self insertItems: item
		  atIndex: index
		    count: 1];
}

- (void)addItems: (const void*)items_
	   count: (size_t)count_
- (void)addItems: (const void*)items
	   count: (size_t)count
{
	if (count_ > SIZE_MAX - count)
	if (count > SIZE_MAX - count)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	items = [self resizeMemory: items
			      size: itemSize
			     count: count + count_];
	_items = [self resizeMemory: _items
			       size: _itemSize
			      count: _count + count];

	memcpy(items + count * itemSize, items_, count_ * itemSize);
	count += count_;
	memcpy(_items + _count * _itemSize, items, count * _itemSize);
	_count += count;
}

- (void)insertItems: (const void*)items_
- (void)insertItems: (const void*)items
	    atIndex: (size_t)index
	      count: (size_t)count_
	      count: (size_t)count
{
	if (count_ > SIZE_MAX - count || index > count)
	if (count > SIZE_MAX - _count || index > _count)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	items = [self resizeMemory: items
			      size: itemSize
			     count: count + count_];
	_items = [self resizeMemory: _items
			       size: _itemSize
			      count: _count + count];

	memmove(items + (index + count_) * itemSize, items + index * itemSize,
	    (count - index) * itemSize);
	memcpy(items + index * itemSize, items_, count_ * itemSize);
	memmove(_items + (index + count) * _itemSize,
	    _items + index * _itemSize, (_count - index) * _itemSize);
	memcpy(_items + index * _itemSize, items, count * _itemSize);

	count += count_;
	_count += count;
}

- (void)removeItemAtIndex: (size_t)index
{
	[self removeItemsInRange: of_range(index, 1)];
}

- (void)removeItemsInRange: (of_range_t)range
{
	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > count)
	    range.location + range.length > _count)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	memmove(items + range.location * itemSize,
	    items + (range.location + range.length) * itemSize,
	    (count - range.location - range.length) * itemSize);
	memmove(_items + range.location * _itemSize,
	    _items + (range.location + range.length) * _itemSize,
	    (_count - range.location - range.length) * _itemSize);

	count -= range.length;
	_count -= range.length;
	@try {
		items = [self resizeMemory: items
				      size: itemSize
				     count: count];
		_items = [self resizeMemory: _items
				       size: _itemSize
				      count: _count];
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
	}
}

- (void)removeLastItem
{
	if (count == 0)
	if (_count == 0)
		return;

	count--;
	_count--;
	@try {
		items = [self resizeMemory: items
				      size: itemSize
				     count: count];
		_items = [self resizeMemory: _items
				       size: _itemSize
				      count: _count];
	} @catch (OFOutOfMemoryException *e) {
		/* We don't care, as we only made it smaller */
	}
}

- (void)removeAllItems
{
	[self freeMemory: items];
	[self freeMemory: _items];

	items = NULL;
	count = 0;
	_items = NULL;
	_count = 0;
}

- copy
{
	OFDataArray *copy = [[[self class] alloc] initWithItemSize: itemSize];
	OFDataArray *copy = [[[self class] alloc] initWithItemSize: _itemSize];

	[copy addItems: items
		 count: count];
	[copy addItems: _items
		 count: _count];

	return copy;
}

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

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

	otherDataArray = object;
	dataArray = object;

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

	return YES;
}

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

	if (![object isKindOfClass: [OFDataArray class]])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];
	otherDataArray = (OFDataArray*)object;
	dataArray = (OFDataArray*)object;

	if ([otherDataArray itemSize] != itemSize)
	if ([dataArray itemSize] != _itemSize)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	otherCount = [otherDataArray count];
	minimumCount = (count > otherCount ? otherCount : count);
	count = [dataArray count];
	minCount = (_count > count ? count : _count);

	if ((comparison = memcmp(items, [otherDataArray items],
	    minimumCount * itemSize)) == 0) {
		if (count > otherCount)
	if ((comparison = memcmp(_items, [dataArray items],
	    minCount * _itemSize)) == 0) {
		if (_count > count)
			return OF_ORDERED_DESCENDING;
		if (count < otherCount)
		if (_count < count)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
	}

	if (comparison > 0)
		return OF_ORDERED_DESCENDING;
	else
		return OF_ORDERED_ASCENDING;
}

- (uint32_t)hash
{
	uint32_t hash;
	size_t i;

	OF_HASH_INIT(hash);

	for (i = 0; i < count * itemSize; i++)
		OF_HASH_ADD(hash, ((uint8_t*)items)[i]);
	for (i = 0; i < _count * _itemSize; i++)
		OF_HASH_ADD(hash, ((uint8_t*)_items)[i]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

- (OFString*)description
{
	OFMutableString *ret = [OFMutableString stringWithString: @"<"];
	size_t i;

	for (i = 0; i < count; i++) {
	for (i = 0; i < _count; i++) {
		size_t j;

		if (i > 0)
			[ret appendString: @" "];

		for (j = 0; j < itemSize; j++)
			[ret appendFormat: @"%02x", items[i * itemSize + j]];
		for (j = 0; j < _itemSize; j++)
			[ret appendFormat: @"%02x", _items[i * _itemSize + j]];
	}

	[ret appendString: @">"];

	[ret makeImmutable];
	return ret;
}

- (OFString*)stringRepresentation
{
	OFMutableString *ret = [OFMutableString string];
	size_t i, j;

	for (i = 0; i < count; i++)
		for (j = 0; j < itemSize; j++)
			[ret appendFormat: @"%02x", items[i * itemSize + j]];
	for (i = 0; i < _count; i++)
		for (j = 0; j < _itemSize; j++)
			[ret appendFormat: @"%02x", _items[i * _itemSize + j]];

	[ret makeImmutable];
	return ret;
}

- (OFString*)stringByBase64Encoding
{
	return of_base64_encode(items, count * itemSize);
	return of_base64_encode(_items, _count * _itemSize);
}

- (void)writeToFile: (OFString*)path
{
	OFFile *file = [[OFFile alloc] initWithPath: path
					       mode: @"wb"];

	@try {
		[file writeBuffer: items
			   length: count * itemSize];
		[file writeBuffer: _items
			   length: _count * _itemSize];
	} @finally {
		[file release];
	}
}

- (OFXMLElement*)XMLElementBySerializing
{
	void *pool;
	OFXMLElement *element;

	if (itemSize != 1)
	if (_itemSize != 1)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]];

	pool = objc_autoreleasePoolPush();
	element = [OFXMLElement
	    elementWithName: [self className]
		  namespace: OF_SERIALIZATION_NS
		stringValue: of_base64_encode(items, count * itemSize)];
		stringValue: of_base64_encode(_items, _count * _itemSize)];

	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}
@end

@implementation OFBigDataArray
- (void)addItem: (const void*)item
{
	size_t newSize, lastPageByte;
	size_t size, lastPageByte;

	if (SIZE_MAX - count < 1 || count + 1 > SIZE_MAX / itemSize)
	if (SIZE_MAX - _count < 1 || _count + 1 > SIZE_MAX / _itemSize)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	lastPageByte = [OFSystemInfo pageSize] - 1;
	newSize = ((count + 1) * itemSize + lastPageByte) & ~lastPageByte;
	size = ((_count + 1) * _itemSize + lastPageByte) & ~lastPageByte;

	if (size != newSize)
		items = [self resizeMemory: items
				      size: newSize];
	if (_size != size)
		_items = [self resizeMemory: _items
				       size: size];

	memcpy(items + count * itemSize, item, itemSize);
	memcpy(_items + _count * _itemSize, item, _itemSize);

	count++;
	size = newSize;
	_count++;
	_size = size;
}

- (void)addItems: (const void*)items_
	   count: (size_t)count_
- (void)addItems: (const void*)items
	   count: (size_t)count
{
	size_t newSize, lastPageByte;
	size_t size, lastPageByte;

	if (count_ > SIZE_MAX - count || count + count_ > SIZE_MAX / itemSize)
	if (count > SIZE_MAX - _count || _count + count > SIZE_MAX / _itemSize)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	lastPageByte = [OFSystemInfo pageSize] - 1;
	newSize = ((count + count_) * itemSize + lastPageByte) & ~lastPageByte;
	size = ((_count + count) * _itemSize + lastPageByte) & ~lastPageByte;

	if (size != newSize)
		items = [self resizeMemory: items
				      size: newSize];
	if (_size != size)
		_items = [self resizeMemory: _items
				       size: size];

	memcpy(items + count * itemSize, items_, count_ * itemSize);
	memcpy(_items + _count * _itemSize, items, count * _itemSize);

	count += count_;
	size = newSize;
	_count += count;
	_size = size;
}

- (void)insertItems: (const void*)items_
- (void)insertItems: (const void*)items
	    atIndex: (size_t)index
	      count: (size_t)count_
	      count: (size_t)count
{
	size_t newSize, lastPageByte;
	size_t size, lastPageByte;

	if (count_ > SIZE_MAX - count || index > count ||
	    count + count_ > SIZE_MAX / itemSize)
	if (count > SIZE_MAX - _count || index > _count ||
	    _count + count > SIZE_MAX / _itemSize)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	lastPageByte = [OFSystemInfo pageSize] - 1;
	newSize = ((count + count_) * itemSize + lastPageByte) & ~lastPageByte;
	size = ((_count + count) * _itemSize + lastPageByte) & ~lastPageByte;

	if (size != newSize)
		items = [self resizeMemory: items
				      size: newSize];
	if (_size != size)
		_items = [self resizeMemory: _items
				       size: size];

	memmove(items + (index + count_) * itemSize, items + index * itemSize,
	    (count - index) * itemSize);
	memcpy(items + index * itemSize, items_, count_ * itemSize);
	memmove(_items + (index + count) * _itemSize,
	    _items + index * _itemSize, (_count - index) * _itemSize);
	memcpy(_items + index * _itemSize, items, count * _itemSize);

	count += count_;
	size = newSize;
	_count += count;
	_size = size;
}

- (void)removeItemsInRange: (of_range_t)range
{
	size_t pageSize, newSize;
	size_t pageSize, size;

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

	memmove(items + range.location * itemSize,
	    items + (range.location + range.length) * itemSize,
	    (count - range.location - range.length) * itemSize);
	memmove(_items + range.location * _itemSize,
	    _items + (range.location + range.length) * _itemSize,
	    (_count - range.location - range.length) * _itemSize);

	count -= range.length;
	_count -= range.length;
	pageSize = [OFSystemInfo pageSize];
	newSize = (count * itemSize + pageSize - 1) & ~(pageSize - 1);
	size = (_count * _itemSize + pageSize - 1) & ~(pageSize - 1);

	if (size != newSize && newSize >= pageSize) {
	if (_size != size && size >= pageSize) {
		@try {
			items = [self resizeMemory: items
					      size: newSize];
			_items = [self resizeMemory: _items
					       size: size];
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only made it smaller */
		}

		size = newSize;
		_size = size;
	}
}

- (void)removeLastItem
{
	size_t pageSize, newSize;
	size_t pageSize, size;

	if (count == 0)
	if (_count == 0)
		return;

	count--;
	_count--;
	pageSize = [OFSystemInfo pageSize];
	newSize = (count * itemSize + pageSize - 1) & ~(pageSize - 1);
	size = (_count * _itemSize + pageSize - 1) & ~(pageSize - 1);

	if (size != newSize && newSize >= pageSize) {
	if (_size != size && size >= pageSize) {
		@try {
			items = [self resizeMemory: items
					      size: newSize];
			_items = [self resizeMemory: _items
					       size: size];
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only made it smaller */
		}

		size = newSize;
		_size = size;
	}
}

- (void)removeAllItems
{
	size_t pageSize = [OFSystemInfo pageSize];

	@try {
		items = [self resizeMemory: items
				      size: pageSize];
		size = pageSize;
		_items = [self resizeMemory: _items
				       size: pageSize];
		_size = pageSize;
	} @catch (OFOutOfMemoryException *e) {
		/* We don't care, as we only made it smaller */
	}

	count = 0;
	_count = 0;
}
@end

Modified src/OFDate.h from [ba694484be] to [fe89bdb0e0].

21
22
23
24
25
26
27
28

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

28
29
30
31
32
33
34
35







-
+







@class OFConstantString;

/*!
 * @brief A class for storing, accessing and comparing dates.
 */
@interface OFDate: OFObject <OFCopying, OFComparing, OFSerialization>
{
	double seconds;
	double _seconds;
}

/*!
 * @brief Creates a new OFDate with the current date and time.
 *
 * @return A new, autoreleased OFDate with the current date and time
 */

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

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

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







-
+


-
+



-
+





-
+


-
+



-
+







-
+


-
+






-
+








-
+


-
+






-
+









-
+


-
+



-
+





-
+


-
+



-
+







#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_HAVE_THREADS)
static OFMutex *mutex;
#endif

#ifdef HAVE_GMTIME_R
# define GMTIME_RET(field)						\
	time_t seconds_ = (time_t)seconds;				\
	time_t seconds = (time_t)_seconds;				\
	struct tm tm;							\
									\
	if (seconds_ != floor(seconds))					\
	if (seconds != floor(_seconds))					\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	if (gmtime_r(&seconds_, &tm) == NULL)				\
	if (gmtime_r(&seconds, &tm) == NULL)				\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	return tm.field;
# define LOCALTIME_RET(field)						\
	time_t seconds_ = (time_t)seconds;				\
	time_t seconds = (time_t)_seconds;				\
	struct tm tm;							\
									\
	if (seconds_ != floor(seconds))					\
	if (seconds != floor(_seconds))					\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	if (localtime_r(&seconds_, &tm) == NULL)			\
	if (localtime_r(&seconds, &tm) == NULL)				\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	return tm.field;
#else
# ifdef OF_HAVE_THREADS
#  define GMTIME_RET(field)						\
	time_t seconds_ = (time_t)seconds;				\
	time_t seconds = (time_t)_seconds;				\
	struct tm *tm;							\
									\
	if (seconds_ != floor(seconds))					\
	if (seconds != floor(_seconds))					\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	[mutex lock];							\
									\
	@try {								\
		if ((tm = gmtime(&seconds_)) == NULL)			\
		if ((tm = gmtime(&seconds)) == NULL)			\
			@throw [OFOutOfRangeException			\
			    exceptionWithClass: [self class]];		\
									\
		return tm->field;					\
	} @finally {							\
		[mutex unlock];						\
	}
#  define LOCALTIME_RET(field)						\
	time_t seconds_ = (time_t)seconds;				\
	time_t seconds = (time_t)_seconds;				\
	struct tm *tm;							\
									\
	if (seconds_ != floor(seconds))					\
	if (seconds != floor(_seconds))					\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	[mutex lock];							\
									\
	@try {								\
		if ((tm = localtime(&seconds_)) == NULL)		\
		if ((tm = localtime(&seconds)) == NULL)			\
			@throw [OFOutOfRangeException			\
			    exceptionWithClass: [self class]];		\
									\
		return tm->field;					\
	} @finally {							\
		[mutex unlock];						\
	}
# else
#  define GMTIME_RET(field)						\
	time_t seconds_ = (time_t)seconds;				\
	time_t seconds = (time_t)_seconds;				\
	struct tm *tm;							\
									\
	if (seconds_ != floor(seconds))					\
	if (seconds != floor(_seconds))					\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	if ((tm = gmtime(&seconds_)) == NULL)				\
	if ((tm = gmtime(&seconds)) == NULL)				\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	return tm->field;
#  define LOCALTIME_RET(field)						\
	time_t seconds_ = (time_t)seconds;				\
	time_t seconds = (time_t)_seconds;				\
	struct tm *tm;							\
									\
	if (seconds_ != floor(seconds))					\
	if (seconds != floor(_seconds))					\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	if ((tm = localtime(&seconds_)) == NULL)			\
	if ((tm = localtime(&seconds)) == NULL)				\
		@throw [OFOutOfRangeException				\
		    exceptionWithClass: [self class]];			\
									\
	return tm->field;
# endif
#endif

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







-
+

-
-
+
+




-
+



-
+




-
+



-
+




















-
+

-
-
-
+
+
+




-
+




-
+

-
+

-
+

-
+

-
+








- init
{
	struct timeval t;

	self = [super init];

	OF_ENSURE(!gettimeofday(&t, NULL));
	OF_ENSURE(gettimeofday(&t, NULL) == 0);

	seconds = t.tv_sec;
	seconds += (double)t.tv_usec / 1000000;
	_seconds = t.tv_sec;
	_seconds += (double)t.tv_usec / 1000000;

	return self;
}

- initWithTimeIntervalSince1970: (double)seconds_
- initWithTimeIntervalSince1970: (double)seconds
{
	self = [super init];

	seconds = seconds_;
	_seconds = seconds;

	return self;
}

- initWithTimeIntervalSinceNow: (double)seconds_
- initWithTimeIntervalSinceNow: (double)seconds
{
	self = [self init];

	seconds += seconds_;
	_seconds += seconds;

	return self;
}

- initWithDateString: (OFString*)string
	      format: (OFString*)format
{
	self = [super init];

	@try {
		struct tm tm = {};

		tm.tm_isdst = -1;

		if (of_strptime([string UTF8String], [format UTF8String],
		    &tm) == NULL)
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];

		/* Years */
		seconds = (int64_t)(tm.tm_year - 70) * 31536000;
		_seconds = (int64_t)(tm.tm_year - 70) * 31536000;
		/* Days of leap years, excluding the year to look at */
		seconds += (((tm.tm_year + 1899) / 4) - 492) * 86400;
		seconds -= (((tm.tm_year + 1899) / 100) - 19) * 86400;
		seconds += (((tm.tm_year + 1899) / 400) - 4) * 86400;
		_seconds += (((tm.tm_year + 1899) / 4) - 492) * 86400;
		_seconds -= (((tm.tm_year + 1899) / 100) - 19) * 86400;
		_seconds += (((tm.tm_year + 1899) / 400) - 4) * 86400;
		/* Leap day */
		if (tm.tm_mon >= 2 && (((tm.tm_year + 1900) % 4 == 0 &&
		    (tm.tm_year + 1900) % 100 != 0) ||
		    (tm.tm_year + 1900) % 400 == 0))
			seconds += 86400;
			_seconds += 86400;
		/* Months */
		if (tm.tm_mon < 0 || tm.tm_mon > 12)
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];
		seconds += month_to_day_of_year[tm.tm_mon] * 86400;
		_seconds += month_to_day_of_year[tm.tm_mon] * 86400;
		/* Days */
		seconds += (tm.tm_mday - 1) * 86400;
		_seconds += (tm.tm_mday - 1) * 86400;
		/* Hours */
		seconds += tm.tm_hour * 3600;
		_seconds += tm.tm_hour * 3600;
		/* Minutes */
		seconds += tm.tm_min * 60;
		_seconds += tm.tm_min * 60;
		/* Seconds */
		seconds += tm.tm_sec;
		_seconds += tm.tm_sec;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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







-
+







		tm.tm_isdst = -1;

		if (of_strptime([string UTF8String], [format UTF8String],
		    &tm) == NULL)
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];

		if ((seconds = mktime(&tm)) == -1)
		if ((_seconds = mktime(&tm)) == -1)
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

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







-
+



















-
+














-
+







		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

		d.u = (uint64_t)[element hexadecimalValue];
		seconds = d.d;
		_seconds = d.d;

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

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

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

	otherDate = object;

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

	return YES;
}

- (uint32_t)hash
{
	uint32_t hash;
	union {
		double d;
		uint8_t b[sizeof(double)];
	} d;
	uint_fast8_t i;

	d.d = OF_BSWAP_DOUBLE_IF_BE(seconds);
	d.d = OF_BSWAP_DOUBLE_IF_BE(_seconds);

	OF_HASH_INIT(hash);

	for (i = 0; i < sizeof(double); i++)
		OF_HASH_ADD(hash, d.b[i]);

	OF_HASH_FINALIZE(hash);
395
396
397
398
399
400
401
402

403
404

405
406
407
408
409
410
411
395
396
397
398
399
400
401

402
403

404
405
406
407
408
409
410
411







-
+

-
+







	if (![object isKindOfClass: [OFDate class]])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	otherDate = (OFDate*)object;

	if (seconds < otherDate->seconds)
	if (_seconds < otherDate->_seconds)
		return OF_ORDERED_ASCENDING;
	if (seconds > otherDate->seconds)
	if (_seconds > otherDate->_seconds)
		return OF_ORDERED_DESCENDING;

	return OF_ORDERED_SAME;
}

- (OFString*)description
{
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
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







-
+












-
+







		double d;
		uint64_t u;
	} d;

	element = [OFXMLElement elementWithName: [self className]
				      namespace: OF_SERIALIZATION_NS];

	d.d = seconds;
	d.d = _seconds;
	[element setStringValue:
	    [OFString stringWithFormat: @"%016" PRIx64, d.u]];

	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (uint32_t)microsecond
{
	return (uint32_t)rint((seconds - floor(seconds)) * 1000000);
	return (uint32_t)rint((_seconds - floor(_seconds)) * 1000000);
}

- (uint8_t)second
{
	GMTIME_RET(tm_sec)
}

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







-
+




-
+



-
+









-
+







{
	LOCALTIME_RET(tm_yday + 1)
}

- (OFString*)dateStringWithFormat: (OFConstantString*)format
{
	OFString *ret;
	time_t seconds_ = (time_t)seconds;
	time_t seconds = (time_t)_seconds;
	struct tm tm;
	size_t pageSize;
	char *buffer;

	if (seconds_ != floor(seconds))
	if (seconds != floor(_seconds))
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

#ifdef HAVE_GMTIME_R
	if (gmtime_r(&seconds_, &tm) == NULL)
	if (gmtime_r(&seconds, &tm) == NULL)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#else
# ifdef OF_HAVE_THREADS
	[mutex lock];

	@try {
# endif
		struct tm *tmp;

		if ((tmp = gmtime(&seconds_)) == NULL)
		if ((tmp = gmtime(&seconds)) == NULL)
			@throw [OFOutOfRangeException
			    exceptionWithClass: [self class]];

		tm = *tmp;
# ifdef OF_HAVE_THREADS
	} @finally {
		[mutex unlock];
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
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







-
+




-
+



-
+









-
+








	return ret;
}

- (OFString*)localDateStringWithFormat: (OFConstantString*)format
{
	OFString *ret;
	time_t seconds_ = (time_t)seconds;
	time_t seconds = (time_t)_seconds;
	struct tm tm;
	size_t pageSize;
	char *buffer;

	if (seconds_ != floor(seconds))
	if (seconds != floor(_seconds))
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

#ifdef HAVE_LOCALTIME_R
	if (localtime_r(&seconds_, &tm) == NULL)
	if (localtime_r(&seconds, &tm) == NULL)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#else
# ifdef OF_HAVE_THREADS
	[mutex lock];

	@try {
# endif
		struct tm *tmp;

		if ((tmp = localtime(&seconds_)) == NULL)
		if ((tmp = localtime(&seconds)) == NULL)
			@throw [OFOutOfRangeException
			    exceptionWithClass: [self class]];

		tm = *tmp;
# ifdef OF_HAVE_THREADS
	} @finally {
		[mutex unlock];
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
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







-
+




-
+





-
+



-
-
+
+

-
+


-
+

-
+


		return [[otherDate retain] autorelease];

	return [[self retain] autorelease];
}

- (double)timeIntervalSince1970
{
	return seconds;
	return _seconds;
}

- (double)timeIntervalSinceDate: (OFDate*)otherDate
{
	return seconds - otherDate->seconds;
	return _seconds - otherDate->_seconds;
}

- (double)timeIntervalSinceNow
{
	struct timeval t;
	double seconds_;
	double seconds;

	OF_ENSURE(!gettimeofday(&t, NULL));

	seconds_ = t.tv_sec;
	seconds_ += (double)t.tv_usec / 1000000;
	seconds = t.tv_sec;
	seconds += (double)t.tv_usec / 1000000;

	return seconds - seconds_;
	return _seconds - seconds;
}

- (OFDate*)dateByAddingTimeInterval: (double)seconds_
- (OFDate*)dateByAddingTimeInterval: (double)seconds
{
	return [OFDate dateWithTimeIntervalSince1970: seconds + seconds_];
	return [OFDate dateWithTimeIntervalSince1970: _seconds + seconds];
}
@end

Modified src/OFDictionary_hashtable.h from [3842e437d1] to [9ac7ec716c].

17
18
19
20
21
22
23
24

25
26
27
28
17
18
19
20
21
22
23

24
25
26
27
28







-
+




#import "OFDictionary.h"

@class OFMapTable;
@class OFMapTableEnumerator;

@interface OFDictionary_hashtable: OFDictionary
{
	OFMapTable *mapTable;
	OFMapTable *_mapTable;
}

- initWithCapacity: (size_t)capacity;
@end

Modified src/OFDictionary_hashtable.m from [27697200eb] to [6f8779fe47].

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







-
+







}

- initWithCapacity: (size_t)capacity
{
	self = [super init];

	@try {
		mapTable = [[OFMapTable alloc]
		_mapTable = [[OFMapTable alloc]
		    initWithKeyFunctions: keyFunctions
			  valueFunctions: valueFunctions
				capacity: capacity];
	} @catch (id e) {
		[self release];
		@throw e;
	}
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122







-
+







	    [dictionary class] == [OFMutableDictionary_hashtable class]) {
		self = [super init];

		@try {
			OFDictionary_hashtable *dictionary_ =
			    (OFDictionary_hashtable*)dictionary;

			mapTable = [dictionary_->mapTable copy];
			_mapTable = [dictionary_->_mapTable copy];
		} @catch (id e) {
			[self release];
			@throw e;
		}

		return self;
	}
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
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







-
-
+
+
















-
-
+
+


















-
-
+
+







		OFEnumerator *keyEnumerator, *objectEnumerator;
		id key, object;

		keyEnumerator = [dictionary keyEnumerator];
		objectEnumerator = [dictionary objectEnumerator];
		while ((key = [keyEnumerator nextObject]) != nil &&
		    (object = [objectEnumerator nextObject]) != nil)
			[mapTable setValue: object
				    forKey: key];
			[_mapTable setValue: object
				     forKey: key];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithObject: (id)object
	  forKey: (id)key
{
	self = [self initWithCapacity: 1];

	@try {
		[mapTable setValue: object
			    forKey: key];
		[_mapTable setValue: object
			     forKey: key];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		size_t i;

		for (i = 0; i < count; i++)
			[mapTable setValue: objects[i]
				    forKey: keys[i]];
			[_mapTable setValue: objects[i]
				     forKey: keys[i]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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







-
+




-
-
+
+










-
-
+
+







			    exceptionWithClass: [self class]
				      selector: _cmd];

		count = 1;
		for (; va_arg(argumentsCopy, id) != nil; count++);
		count >>= 1;

		mapTable = [[OFMapTable alloc]
		_mapTable = [[OFMapTable alloc]
		    initWithKeyFunctions: keyFunctions
			  valueFunctions: valueFunctions
				capacity: count];

		[mapTable setValue: object
			    forKey: key];
		[_mapTable setValue: object
			     forKey: key];

		for (i = 1; i < count; i++) {
			key = va_arg(arguments, id);
			object = va_arg(arguments, id);

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

			[mapTable setValue: object
				    forKey: key];
			[_mapTable setValue: object
				     forKey: key];
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
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
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







-
+




















-
-
+
+












+
+
+
+
+
+
+



-
+




-
+












-
+




-
+




-
+








-
+










-
+







		objects = [element elementsForName: @"object"
					 namespace: OF_SERIALIZATION_NS];

		if ([keys count] != [objects count])
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];

		mapTable = [[OFMapTable alloc]
		_mapTable = [[OFMapTable alloc]
		    initWithKeyFunctions: keyFunctions
			  valueFunctions: valueFunctions
				capacity: [keys count]];

		keyEnumerator = [keys objectEnumerator];
		objectEnumerator = [objects objectEnumerator];
		while ((keyElement = [keyEnumerator nextObject]) != nil &&
		    (objectElement = [objectEnumerator nextObject]) != nil) {
			void *pool2 = objc_autoreleasePoolPush();
			OFXMLElement *key, *object;

			key = [[keyElement elementsForNamespace:
			    OF_SERIALIZATION_NS] firstObject];
			object = [[objectElement elementsForNamespace:
			    OF_SERIALIZATION_NS] firstObject];

			if (key == nil || object == nil)
				@throw [OFInvalidFormatException
				    exceptionWithClass: [self class]];

			[mapTable setValue: [object objectByDeserializing]
				    forKey: [key objectByDeserializing]];
			[_mapTable setValue: [object objectByDeserializing]
				     forKey: [key objectByDeserializing]];

			objc_autoreleasePoolPop(pool2);
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_mapTable dealloc];

	[super dealloc];
}

- (id)objectForKey: (id)key
{
	return [mapTable valueForKey: key];
	return [_mapTable valueForKey: key];
}

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

- (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];
	return [dictionary_->_mapTable isEqual: _mapTable];
}

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

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

- (OFArray*)allKeys
{
	OFArray *ret;
	id *keys;
	size_t count;

	count = [mapTable count];
	count = [_mapTable count];
	keys = [self allocMemoryWithSize: sizeof(*keys)
				   count: count];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMapTableEnumerator *enumerator;
		id key;
		size_t i;

		i = 0;
		enumerator = [mapTable keyEnumerator];
		enumerator = [_mapTable keyEnumerator];
		while ((key = [enumerator nextValue]) != nil) {
			assert(i < count);

			keys[i++] = key;
		}

		objc_autoreleasePoolPop(pool);
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
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







-
+










-
+




















-
+






-
+





-
+

-
-
-
+
+
+







-
+











-
-
-
-
-
-
-


-
+



- (OFArray*)allObjects
{
	OFArray *ret;
	id *objects;
	size_t count;

	count = [mapTable count];
	count = [_mapTable count];
	objects = [self allocMemoryWithSize: sizeof(*objects)
				      count: count];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMapTableEnumerator *enumerator;
		id object;
		size_t i;

		i = 0;
		enumerator = [mapTable valueEnumerator];
		enumerator = [_mapTable valueEnumerator];
		while ((object = [enumerator nextValue]) != nil) {
			assert(i < count);

			objects[i++] = object;
		}

		objc_autoreleasePoolPop(pool);

		ret = [OFArray arrayWithObjects: objects
					  count: count];
	} @finally {
		[self freeMemory: objects];
	}

	return ret;
}

- (OFEnumerator*)keyEnumerator
{
	return [[[OFMapTableEnumeratorWrapper alloc]
	    initWithEnumerator: [mapTable keyEnumerator]
	    initWithEnumerator: [_mapTable keyEnumerator]
			object: self] autorelease];
}

- (OFEnumerator*)objectEnumerator
{
	return [[[OFMapTableEnumeratorWrapper alloc]
	    initWithEnumerator: [mapTable valueEnumerator]
	    initWithEnumerator: [_mapTable valueEnumerator]
			object: self] autorelease];
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
			     count: (int)count_
			     count: (int)count
{
	return [mapTable countByEnumeratingWithState: state
					     objects: objects
					       count: count_];
	return [_mapTable countByEnumeratingWithState: state
					      objects: objects
						count: count];
}

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

- (void)dealloc
{
	[mapTable dealloc];

	[super dealloc];
}

- (uint32_t)hash
{
	return [mapTable hash];
	return [_mapTable hash];
}
@end

Modified src/OFFile.h from [76b233d4a0] to [5c8981b0ad].

37
38
39
40
41
42
43
44
45
46



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



44
45
46
47
48
49
50
51
52
53







-
-
-
+
+
+







#endif

/*!
 * @brief A class which provides functions to read, write and manipulate files.
 */
@interface OFFile: OFSeekableStream
{
	int  fd;
	BOOL closable;
	BOOL atEndOfStream;
	int  _fd;
	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
70
71
72
73
74
75
76
77
78


79
80
81

82
83
84
85
86
87
88
70
71
72
73
74
75
76


77
78
79
80

81
82
83
84
85
86
87
88







-
-
+
+


-
+







 */
+ (instancetype)fileWithPath: (OFString*)path
			mode: (OFString*)mode;

/*!
 * @brief Creates a new OFFile with the specified file descriptor.
 *
 * @param fileDescriptor A file descriptor, returned from for example open().
 *			 It is not closed when the OFFile object is deallocated!
 * @param fd A file descriptor, returned from for example open().
 *	     It is not closed when the OFFile object is deallocated!
 * @return A new autoreleased OFFile
 */
+ (instancetype)fileWithFileDescriptor: (int)fileDescriptor;
+ (instancetype)fileWithFileDescriptor: (int)fd;

/*!
 * @brief Returns the path fo the current working directory.
 *
 * @return The path of the current working directory
 */
+ (OFString*)currentDirectoryPath;
260
261
262
263
264
265
266
267
268


269
270

271
272
273
274
275
276
277
260
261
262
263
264
265
266


267
268
269

270
271
272
273
274
275
276
277







-
-
+
+

-
+







 */
- initWithPath: (OFString*)path
	  mode: (OFString*)mode;

/*!
 * @brief Initializes an already allocated OFFile.
 *
 * @param fileDescriptor A file descriptor, returned from for example open().
 *			 It is not closed when the OFFile object is deallocated!
 * @param fd A file descriptor, returned from for example open().
 *	     It is not closed when the OFFile object is deallocated!
 */
- initWithFileDescriptor: (int)fileDescriptor;
- initWithFileDescriptor: (int)fd;
@end

#ifdef __cplusplus
extern "C" {
#endif
/*! @file */

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

547
548
549
550
551
552
553
554
555


556
557
558
559
560
561
562
547
548
549
550
551
552
553


554
555
556
557
558
559
560
561
562







-
-
+
+







					      length: length];
		}

#if !defined(_WIN32) && !defined(_PSP)
		if (!override) {
			struct stat s;

			if (fstat(sourceFile->fd, &s) == 0)
				fchmod(destinationFile->fd, s.st_mode);
			if (fstat(sourceFile->_fd, &s) == 0)
				fchmod(destinationFile->_fd, s.st_mode);
		}
#else
		(void)override;
#endif
	} @finally {
		[sourceFile close];
		[destinationFile close];
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
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







-
+


-
+







-
+








-
+



-
+






-
+


-
+







+
-
+





-
+







-
+








-
+








-
+




-
+




-
-
+
+

-
+




-
-
+
+








		if ((flags = parse_mode([mode UTF8String])) == -1)
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

#ifndef _WIN32
		if ((fd = open([path cStringWithEncoding:
		if ((_fd = open([path cStringWithEncoding:
		    OF_STRING_ENCODING_NATIVE], flags, DEFAULT_MODE)) == -1)
#else
		if ((fd = _wopen([path UTF16String], flags,
		if ((_fd = _wopen([path UTF16String], flags,
		    DEFAULT_MODE)) == -1)
#endif
			@throw [OFOpenFileFailedException
			    exceptionWithClass: [self class]
					  path: path
					  mode: mode];

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

	return self;
}

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

	fd = fileDescriptor;
	_fd = fd;

	return self;
}

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

	return atEndOfStream;
	return _atEndOfStream;
}

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

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

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

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
		     length: (size_t)length
{
	if (fd == -1 || atEndOfStream || write(fd, buffer, length) < length)
	if (_fd == -1 || _atEndOfStream || write(_fd, buffer, length) < length)
		@throw [OFWriteFailedException exceptionWithClass: [self class]
							   stream: self
						  requestedLength: length];
}

- (void)lowlevelSeekToOffset: (off_t)offset
		      whence: (int)whence
{
	if (lseek(fd, offset, whence) == -1)
	if (lseek(_fd, offset, whence) == -1)
		@throw [OFSeekFailedException exceptionWithClass: [self class]
							  stream: self
							  offset: offset
							  whence: whence];
}

- (int)fileDescriptorForReading
{
	return fd;
	return _fd;
}

- (int)fileDescriptorForWriting
{
	return fd;
	return _fd;
}

- (void)close
{
	if (fd != -1)
		close(fd);
	if (_fd != -1)
		close(_fd);

	fd = -1;
	_fd = -1;
}

- (void)dealloc
{
	if (closable && fd != -1)
		close(fd);
	if (_closable && _fd != -1)
		close(_fd);

	[super dealloc];
}
@end

@implementation OFFileSingleton
+ (void)load

Modified src/OFHTTPClient.h from [19781d2abd] to [97e24a8655].

85
86
87
88
89
90
91
92
93


94
95
96
97
98
99
100
85
86
87
88
89
90
91


92
93
94
95
96
97
98
99
100







-
-
+
+







@end

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

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

Modified src/OFHTTPClient.m from [8655f7b1b3] to [bfff30b129].

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







-
-
-
+
+
+


-
+



-
+



-
+






-
+




-
+

-
+

-
+






-
-
-
+
+
+

-
-
-
+
+
+

-
-
+
+

-
+

-
-
+
+










-
+











-
+






-
-
-
+
+
+










-
-
+
+

-
+




-
+




-
+




-
+









-
+

-
+




-
+




-
+




-
+

















-
+














-
+






-
+


-
+

-
-
-
+
+
+

-
-
+
+





-
+












-
+


-
+



-
+

-
+


-
+


-
-
+
+






-
+








-
-
+
+



-
+


-
-
+
+


-
-
+
+


-
+







		firstLetter = NO;
		str++;
	}
}

@interface OFHTTPClientReply: OFHTTPRequestReply
{
	OFTCPSocket *sock;
	BOOL chunked, atEndOfStream;
	size_t toRead;
	OFTCPSocket *_socket;
	BOOL _chunked, _atEndOfStream;
	size_t _toRead;
}

- initWithSocket: (OFTCPSocket*)sock;
- initWithSocket: (OFTCPSocket*)socket;
@end

@implementation OFHTTPClientReply
- initWithSocket: (OFTCPSocket*)sock_
- initWithSocket: (OFTCPSocket*)socket
{
	self = [super init];

	sock = [sock_ retain];
	_socket = [socket retain];

	return self;
}

- (void)dealloc
{
	[sock release];
	[_socket release];

	[super dealloc];
}

- (void)setHeaders: (OFDictionary*)headers_
- (void)setHeaders: (OFDictionary*)headers
{
	[super setHeaders: headers_];
	[super setHeaders: headers];

	chunked = [[headers_ objectForKey: @"Transfer-Encoding"]
	_chunked = [[headers objectForKey: @"Transfer-Encoding"]
	    isEqual: @"chunked"];
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer
			  length: (size_t)length
{
	if (!chunked)
		return [sock readIntoBuffer: buffer
				     length: length];
	if (!_chunked)
		return [_socket readIntoBuffer: buffer
					length: length];

	if (toRead > 0) {
		if (length > toRead)
			length = toRead;
	if (_toRead > 0) {
		if (length > _toRead)
			length = _toRead;

		length = [sock readIntoBuffer: buffer
				       length: length];
		length = [_socket readIntoBuffer: buffer
					  length: length];

		toRead -= length;
		_toRead -= length;

		if (toRead == 0)
			if ([[sock readLine] length] > 0)
		if (_toRead == 0)
			if ([[_socket readLine] length] > 0)
				@throw [OFInvalidServerReplyException
				    exceptionWithClass: [self class]];

		return length;
	} else {
		void *pool = objc_autoreleasePoolPush();
		OFString *line;
		of_range_t range;

		@try {
			line = [sock readLine];
			line = [_socket readLine];
		} @catch (OFInvalidEncodingException *e) {
			@throw [OFInvalidServerReplyException
			    exceptionWithClass: [self class]];
		}

		range = [line rangeOfString: @";"];
		if (range.location != OF_NOT_FOUND)
			line = [line substringWithRange:
			    of_range(0, range.location)];

		@try {
			toRead =
			_toRead =
			    (size_t)[line hexadecimalValue];
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidServerReplyException
			    exceptionWithClass: [self class]];
		}

		if (toRead == 0) {
			[sock close];
			atEndOfStream = YES;
		if (_toRead == 0) {
			[_socket close];
			_atEndOfStream = YES;
		}

		objc_autoreleasePoolPop(pool);

		return 0;
	}
}

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

	return atEndOfStream;
	return _atEndOfStream;
}

- (int)fileDescriptorForReading
{
	return [sock fileDescriptorForReading];
	return [_socket fileDescriptorForReading];
}

- (size_t)pendingBytes
{
	return [super pendingBytes] + [sock pendingBytes];
	return [super pendingBytes] + [_socket pendingBytes];
}

- (void)close
{
	[sock close];
	[_socket close];
}
@end

@implementation OFHTTPClient
+ (instancetype)client
{
	return [[[self alloc] init] autorelease];
}

- (void)setDelegate: (id <OFHTTPClientDelegate>)delegate_
- (void)setDelegate: (id <OFHTTPClientDelegate>)delegate
{
	delegate = delegate_;
	_delegate = delegate;
}

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

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

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

- (OFHTTPRequestReply*)performRequest: (OFHTTPRequest*)request
{
	return [self performRequest: request
			  redirects: 10];
}

- (OFHTTPRequestReply*)performRequest: (OFHTTPRequest*)request
			    redirects: (size_t)redirects
{
	void *pool = objc_autoreleasePoolPush();
	OFURL *URL = [request URL];
	OFString *scheme = [URL scheme];
	of_http_request_type_t requestType = [request requestType];
	OFDictionary *headers = [request headers];
	OFDataArray *POSTData = [request POSTData];
	OFTCPSocket *sock;
	OFTCPSocket *socket;
	OFHTTPClientReply *reply;
	OFString *line, *path, *version;
	OFMutableDictionary *serverHeaders;
	OFEnumerator *keyEnumerator, *objectEnumerator;
	OFString *key, *object;
	int status;
	const char *type = NULL;

	if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"])
		@throw [OFUnsupportedProtocolException
		    exceptionWithClass: [self class]
				   URL: URL];

	if ([scheme isEqual: @"http"])
		sock = [OFTCPSocket socket];
		socket = [OFTCPSocket socket];
	else {
		if (of_tls_socket_class == Nil)
			@throw [OFUnsupportedProtocolException
			    exceptionWithClass: [self class]
					   URL: URL];

		sock = [[[of_tls_socket_class alloc] init] autorelease];
		socket = [[[of_tls_socket_class alloc] init] autorelease];
	}

	if ([delegate respondsToSelector:
	if ([_delegate respondsToSelector:
	    @selector(client:didCreateSocket:request:)])
		[delegate client: self
		 didCreateSocket: sock
			 request: request];
		[_delegate client: self
		  didCreateSocket: socket
			  request: request];

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

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

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

	if ([(path = [URL path]) length] == 0)
		path = @"/";

	if ([URL query] != nil)
		[sock writeFormat: @"%s %@?%@ HTTP/%@\r\n",
		[socket writeFormat: @"%s %@?%@ HTTP/%@\r\n",
		    type, path, [URL query], [request protocolVersionString]];
	else
		[sock writeFormat: @"%s %@ HTTP/%@\r\n",
		[socket writeFormat: @"%s %@ HTTP/%@\r\n",
		    type, path, [request protocolVersionString]];

	if ([URL port] == 80)
		[sock writeFormat: @"Host: %@\r\n", [URL host]];
		[socket writeFormat: @"Host: %@\r\n", [URL host]];
	else
		[sock writeFormat: @"Host: %@:%d\r\n", [URL host],
		[socket writeFormat: @"Host: %@:%d\r\n", [URL host],
		    [URL port]];

	[sock writeString: @"Connection: close\r\n"];
	[socket writeString: @"Connection: close\r\n"];

	if ([headers objectForKey: @"User-Agent"] == nil)
		[sock writeString: @"User-Agent: Something using ObjFW "
				   @"<https://webkeks.org/objfw>\r\n"];
		[socket writeString: @"User-Agent: Something using ObjFW "
				     @"<https://webkeks.org/objfw>\r\n"];

	keyEnumerator = [headers keyEnumerator];
	objectEnumerator = [headers objectEnumerator];

	while ((key = [keyEnumerator nextObject]) != nil &&
	    (object = [objectEnumerator nextObject]) != nil)
		[sock writeFormat: @"%@: %@\r\n", key, object];
		[socket writeFormat: @"%@: %@\r\n", key, object];

	if (requestType == OF_HTTP_REQUEST_TYPE_POST) {
		OFString *contentType = [request MIMEType];

		if (contentType == nil)
			contentType = @"application/x-www-form-urlencoded; "
			    @"charset=UTF-8\r\n";

		[sock writeFormat: @"Content-Type: %@\r\n", contentType];
		[sock writeFormat: @"Content-Length: %d\r\n",
		[socket writeFormat: @"Content-Type: %@\r\n", contentType];
		[socket writeFormat: @"Content-Length: %d\r\n",
		    [POSTData count] * [POSTData itemSize]];
	}

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

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

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

	@try {
		line = [sock readLine];
		line = [socket readLine];
	} @catch (OFInvalidEncodingException *e) {
		@throw [OFInvalidServerReplyException
		    exceptionWithClass: [self class]];
	}

	if (![line hasPrefix: @"HTTP/"] || [line characterAtIndex: 8] != ' ')
		@throw [OFInvalidServerReplyException
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







-
+








	for (;;) {
		OFString *key, *value;
		const char *lineC, *tmp;
		char *keyC;

		@try {
			line = [sock readLine];
			line = [socket readLine];
		} @catch (OFInvalidEncodingException *e) {
			@throw [OFInvalidServerReplyException
			    exceptionWithClass: [self class]];
		}

		if (line == nil)
			@throw [OFInvalidServerReplyException
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
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







-
+









-
+

-
-
-
+
+
+







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

		value = [OFString stringWithUTF8String: tmp];

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

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

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

			if (!follow) {
				[serverHeaders setObject: value
						  forKey: key];
				continue;
			}

433
434
435
436
437
438
439
440

441
442

443
444
445
446
447

448
449
450
451
452
453
454
433
434
435
436
437
438
439

440
441

442
443
444
445
446

447
448
449
450
451
452
453
454







-
+

-
+




-
+








		[serverHeaders setObject: value
				  forKey: key];
	}

	[serverHeaders makeImmutable];

	if ([delegate respondsToSelector:
	if ([_delegate respondsToSelector:
	    @selector(client:didReceiveHeaders:statusCode:request:)])
		[delegate      client: self
		[_delegate     client: self
		    didReceiveHeaders: serverHeaders
			   statusCode: status
			      request: request];

	reply = [[OFHTTPClientReply alloc] initWithSocket: sock];
	reply = [[OFHTTPClientReply alloc] initWithSocket: socket];
	[reply setProtocolVersionFromString: version];
	[reply setStatusCode: status];
	[reply setHeaders: serverHeaders];

	objc_autoreleasePoolPop(pool);

	[reply autorelease];

Modified src/OFHTTPRequest.h from [eeab32f289] to [f26f1fecd0].

46
47
48
49
50
51
52
53
54
55
56
57
58
59







60
61
62
63
64
65
66
46
47
48
49
50
51
52







53
54
55
56
57
58
59
60
61
62
63
64
65
66







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







} of_http_request_protocol_version_t;

/*!
 * @brief A class for storing HTTP requests.
 */
@interface OFHTTPRequest: OFObject
{
	OFURL *URL;
	of_http_request_type_t requestType;
	of_http_request_protocol_version_t protocolVersion;
	OFDictionary *headers;
	OFDataArray *POSTData;
	OFString *MIMEType;
	OFString *remoteAddress;
	OFURL *_URL;
	of_http_request_type_t _requestType;
	of_http_request_protocol_version_t _protocolVersion;
	OFDictionary *_headers;
	OFDataArray *_POSTData;
	OFString *_MIMEType;
	OFString *_remoteAddress;
}

#ifdef OF_HAVE_PROPERTIES
@property (copy) OFURL *URL;
@property of_http_request_type_t requestType;
@property of_http_request_protocol_version_t protocolVersion;
@property (copy) OFDictionary *headers;

Modified src/OFHTTPRequest.m from [69b973a377] to [67ed2116e0].

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

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







-
-
-
+
+
+




-
+




-
+










-
-
-
-
-
+
+
+
+
+




-
+

-
+




-
+


-
+

-
+




-
+


-
+

-
+



-
-
+
+

-
+




-
+







-
+











-
-
+
+

-
+






-
-
+
+


-
+

-
+




-
+


-
+

-
+




-
+


-
+

-
+




-
+


-
+

-
+




-
+








-
+











-
+


-
+











-
-
+
+






	return [[[self alloc] initWithURL: URL] autorelease];
}

- init
{
	self = [super init];

	requestType = OF_HTTP_REQUEST_TYPE_GET;
	protocolVersion.major = 1;
	protocolVersion.minor = 1;
	_requestType = OF_HTTP_REQUEST_TYPE_GET;
	_protocolVersion.major = 1;
	_protocolVersion.minor = 1;

	return self;
}

- initWithURL: (OFURL*)URL_
- initWithURL: (OFURL*)URL
{
	self = [self init];

	@try {
		[self setURL: URL_];
		[self setURL: URL];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[URL release];
	[headers release];
	[POSTData release];
	[MIMEType release];
	[remoteAddress release];
	[_URL release];
	[_headers release];
	[_POSTData release];
	[_MIMEType release];
	[_remoteAddress release];

	[super dealloc];
}

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

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

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

- (of_http_request_type_t)requestType
{
	return requestType;
	return _requestType;
}

- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion_
- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion
{
	if (protocolVersion_.major != 1 || protocolVersion.minor > 1)
	if (protocolVersion.major != 1 || protocolVersion.minor > 1)
		@throw [OFUnsupportedVersionException
		    exceptionWithClass: [self class]
			       version: [OFString stringWithFormat: @"%u.%u",
					    protocolVersion_.major,
					    protocolVersion_.minor]];
					    protocolVersion.major,
					    protocolVersion.minor]];

	protocolVersion = protocolVersion_;
	_protocolVersion = protocolVersion;
}

- (of_http_request_protocol_version_t)protocolVersion
{
	return protocolVersion;
	return _protocolVersion;
}

- (void)setProtocolVersionFromString: (OFString*)string
{
	void *pool = objc_autoreleasePoolPush();
	OFArray *components = [string componentsSeparatedByString: @"."];
	intmax_t major, minor;
	of_http_request_protocol_version_t protocolVersion_;
	of_http_request_protocol_version_t protocolVersion;

	if ([components count] != 2)
		@throw [OFInvalidFormatException
		    exceptionWithClass: [self class]];

	major = [[components firstObject] decimalValue];
	minor = [[components lastObject] decimalValue];

	if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	protocolVersion_.major = (uint8_t)major;
	protocolVersion_.minor = (uint8_t)minor;
	protocolVersion.major = (uint8_t)major;
	protocolVersion.minor = (uint8_t)minor;

	[self setProtocolVersion: protocolVersion_];
	[self setProtocolVersion: protocolVersion];

	objc_autoreleasePoolPop(pool);
}

- (OFString*)protocolVersionString
{
	return [OFString stringWithFormat: @"%u.%u", protocolVersion.major,
					   protocolVersion.minor];
	return [OFString stringWithFormat: @"%u.%u", _protocolVersion.major,
					   _protocolVersion.minor];
}

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

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

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

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

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

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

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

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

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

	switch (requestType) {
	switch (_requestType) {
	case OF_HTTP_REQUEST_TYPE_GET:
		requestTypeStr = "GET";
		break;
	case OF_HTTP_REQUEST_TYPE_POST:
		requestTypeStr = "POST";
		break;
	case OF_HTTP_REQUEST_TYPE_HEAD:
		requestTypeStr = "HEAD";
		break;
	}

	indentedHeaders = [[headers description]
	indentedHeaders = [[_headers description]
	    stringByReplacingOccurrencesOfString: @"\n"
				      withString: @"\n\t"];
	indentedPOSTData = [[POSTData description]
	indentedPOSTData = [[_POSTData description]
	    stringByReplacingOccurrencesOfString: @"\n"
				      withString: @"\n\t"];

	ret = [[OFString alloc] initWithFormat:
	    @"<%@:\n\tURL = %@\n"
	    @"\tRequest type = %s\n"
	    @"\tHeaders = %@\n"
	    @"\tPOST data = %@\n"
	    @"\tPOST data MIME type = %@\n"
	    @"\tRemote address = %@\n"
	    @">",
	    [self class], URL, requestTypeStr, indentedHeaders,
	    indentedPOSTData, MIMEType, remoteAddress];
	    [self class], _URL, requestTypeStr, indentedHeaders,
	    indentedPOSTData, _MIMEType, _remoteAddress];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}
@end

Modified src/OFHTTPRequestReply.h from [7576232cb8] to [b047464ff4].

20
21
22
23
24
25
26
27
28
29



30
31
32
33
34
35
36
20
21
22
23
24
25
26



27
28
29
30
31
32
33
34
35
36







-
-
-
+
+
+







@class OFDictionary;

/*!
 * @brief A class for representing an HTTP request reply as a stream.
 */
@interface OFHTTPRequestReply: OFStream
{
	of_http_request_protocol_version_t protocolVersion;
	short statusCode;
	OFDictionary *headers;
	of_http_request_protocol_version_t _protocolVersion;
	short _statusCode;
	OFDictionary *_headers;
}

#ifdef OF_HAVE_PROPERTIES
@property of_http_request_protocol_version_t protocolVersion;
@property short statusCode;
@property (copy) OFDictionary *headers;
#endif

Modified src/OFHTTPRequestReply.m from [eadf4aca10] to [bae34e8d9b].

29
30
31
32
33
34
35
36
37


38
39
40
41
42
43
44

45
46
47
48
49

50
51

52
53
54
55
56


57
58

59
60
61
62
63

64
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79
80
81
82
83
84


85
86

87
88
89
90
91
92
93
94


95
96
97
98
99

100
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
29
30
31
32
33
34
35


36
37
38
39
40
41
42
43

44
45
46
47
48

49
50

51
52
53
54


55
56
57

58
59
60
61
62

63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80
81
82


83
84
85

86
87
88
89
90
91
92


93
94
95
96
97
98

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







-
-
+
+






-
+




-
+

-
+



-
-
+
+

-
+




-
+







-
+











-
-
+
+

-
+






-
-
+
+




-
+


-
+

-
+




-
+


-
+

-
+







-
+








-
+






#import "OFUnsupportedVersionException.h"

@implementation OFHTTPRequestReply
- init
{
	self = [super init];

	protocolVersion.major = 1;
	protocolVersion.minor = 1;
	_protocolVersion.major = 1;
	_protocolVersion.minor = 1;

	return self;
}

- (void)dealloc
{
	[headers release];
	[_headers release];

	[super dealloc];
}

- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion_
- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion
{
	if (protocolVersion_.major != 1 || protocolVersion.minor > 1)
	if (protocolVersion.major != 1 || protocolVersion.minor > 1)
		@throw [OFUnsupportedVersionException
		    exceptionWithClass: [self class]
			       version: [OFString stringWithFormat: @"%u.%u",
					    protocolVersion_.major,
					    protocolVersion_.minor]];
					    protocolVersion.major,
					    protocolVersion.minor]];

	protocolVersion = protocolVersion_;
	_protocolVersion = protocolVersion;
}

- (of_http_request_protocol_version_t)protocolVersion
{
	return protocolVersion;
	return _protocolVersion;
}

- (void)setProtocolVersionFromString: (OFString*)string
{
	void *pool = objc_autoreleasePoolPush();
	OFArray *components = [string componentsSeparatedByString: @"."];
	intmax_t major, minor;
	of_http_request_protocol_version_t protocolVersion_;
	of_http_request_protocol_version_t protocolVersion;

	if ([components count] != 2)
		@throw [OFInvalidFormatException
		    exceptionWithClass: [self class]];

	major = [[components firstObject] decimalValue];
	minor = [[components lastObject] decimalValue];

	if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	protocolVersion_.major = (uint8_t)major;
	protocolVersion_.minor = (uint8_t)minor;
	protocolVersion.major = (uint8_t)major;
	protocolVersion.minor = (uint8_t)minor;

	[self setProtocolVersion: protocolVersion_];
	[self setProtocolVersion: protocolVersion];

	objc_autoreleasePoolPop(pool);
}

- (OFString*)protocolVersionString
{
	return [OFString stringWithFormat: @"%u.%u", protocolVersion.major,
					   protocolVersion.minor];
	return [OFString stringWithFormat: @"%u.%u", _protocolVersion.major,
					   _protocolVersion.minor];
}

- (short)statusCode
{
	return statusCode;
	return _statusCode;
}

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

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

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

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

	indentedHeaders = [[headers description]
	indentedHeaders = [[_headers description]
	    stringByReplacingOccurrencesOfString: @"\n"
				      withString: @"\n\t"];

	ret = [[OFString alloc] initWithFormat:
	    @"<%@:\n"
	    @"\tStatus code = %d\n"
	    @"\tHeaders = %@\n"
	    @">",
	    [self class], statusCode, indentedHeaders];
	    [self class], _statusCode, indentedHeaders];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}
@end

Modified src/OFHTTPServer.h from [3553c698ef] to [bf775ba1f9].

57
58
59
60
61
62
63
64
65
66
67
68





69
70
71
72
73
74
75
57
58
59
60
61
62
63





64
65
66
67
68
69
70
71
72
73
74
75







-
-
-
-
-
+
+
+
+
+







@end

/*!
 * @brief A class for creating a simple HTTP server inside of applications.
 */
@interface OFHTTPServer: OFObject
{
	OFString *host;
	uint16_t port;
	id <OFHTTPServerDelegate> delegate;
	OFString *name;
	OFTCPSocket *listeningSocket;
	OFString *_host;
	uint16_t _port;
	id <OFHTTPServerDelegate> _delegate;
	OFString *_name;
	OFTCPSocket *_listeningSocket;
}

#ifdef OF_HAVE_PROPERTIES
@property (copy) OFString *host;
@property uint16_t port;
@property (assign) id <OFHTTPServerDelegate> delegate;
@property (copy) OFString *name;

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

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







-
-
-
+
+
+


-
+




-
-
+
+



-
-
-
+
+
+






-
+


-
-
+
+












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

-
-
+
+



-
+

-
+

-
-
+
+










-
+


-
-
-
+
+
+




-
+


-
-
-
-
+
+
+
+




-
+


-
-
-
+
+
+

-
+

-
+




-
+





-
-
-
+
+
+




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




-
+




-
+








-
-
+
+




-
-
-
+
+
+

-
+



-
+










-
-
+
+

-
-
+
+

-
-
-
-
+
+
+
+




-
+







-
+






-
+








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

@interface OFHTTPServerReply: OFHTTPRequestReply
{
	OFTCPSocket *sock;
	OFHTTPServer *server;
	BOOL chunked, headersSent, closed;
	OFTCPSocket *_socket;
	OFHTTPServer *_server;
	BOOL _chunked, _headersSent, _closed;
}

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

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

	statusCode = 500;
	sock = [sock_ retain];
	server = [server_ retain];
	_statusCode = 500;
	_socket = [socket retain];
	_server = [server retain];

	return self;
}

- (void)dealloc
{
	if (!closed)
	if (!_closed)
		[self close];

	[sock release];
	[server release];
	[_socket release];
	[_server release];

	[super dealloc];
}

- (void)sendHeaders
{
	void *pool = objc_autoreleasePoolPush();
	OFString *date = [[OFDate date]
	    dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"];
	OFEnumerator *keyEnumerator, *valueEnumerator;
	OFString *key, *value;

	[sock writeFormat: @"HTTP/%@ %d %s\r\n"
			   @"Server: %@\r\n"
			   @"Date: %@\r\n",
			   [self protocolVersionString], statusCode,
			   status_code_to_string(statusCode),
			   [server name], date];
	[_socket writeFormat: @"HTTP/%@ %d %s\r\n"
			      @"Server: %@\r\n"
			      @"Date: %@\r\n",
			      [self protocolVersionString], _statusCode,
			      status_code_to_string(_statusCode),
			      [_server name], date];

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

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

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

	objc_autoreleasePoolPop(pool);
}

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

	if (!headersSent)
	if (!_headersSent)
		[self sendHeaders];

	if (!chunked) {
		[sock writeBuffer: buffer
			   length: length];
	if (!_chunked) {
		[_socket writeBuffer: buffer
			      length: length];
		return;
	}

	pool = objc_autoreleasePoolPush();
	[sock writeString: [OFString stringWithFormat: @"%zx\r\n", length]];
	[_socket writeString: [OFString stringWithFormat: @"%zx\r\n", length]];
	objc_autoreleasePoolPop(pool);

	[sock writeBuffer: buffer
		   length: length];
	[sock writeBuffer: "\r\n"
		   length: 2];
	[_socket writeBuffer: buffer
		      length: length];
	[_socket writeBuffer: "\r\n"
		      length: 2];
}

- (void)close
{
	if (!headersSent)
	if (!_headersSent)
		[self sendHeaders];

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

	[sock close];
	[_socket close];

	closed = YES;
	_closed = YES;
}

- (int)fileDescriptorForWriting
{
	return [sock fileDescriptorForWriting];
	return [_socket fileDescriptorForWriting];
}
@end

@interface OFHTTPServer_Connection: OFObject
{
	OFTCPSocket *sock;
	OFHTTPServer *server;
	OFTimer *timer;
	OFTCPSocket *_socket;
	OFHTTPServer *_server;
	OFTimer *_timer;
	enum {
		AWAITING_PROLOG,
		PARSING_HEADERS,
		SEND_REPLY
	} state;
	uint8_t HTTPMinorVersion;
	of_http_request_type_t requestType;
	OFString *host, *path;
	uint16_t port;
	OFMutableDictionary *headers;
	size_t contentLength;
	OFDataArray *POSTData;
	} _state;
	uint8_t _HTTPMinorVersion;
	of_http_request_type_t _requestType;
	OFString *_host, *_path;
	uint16_t _port;
	OFMutableDictionary *_headers;
	size_t _contentLength;
	OFDataArray *_POSTData;
}

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

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

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

	return self;
}

- (void)dealloc
{
	[sock release];
	[server release];
	[_socket release];
	[_server release];

	[timer invalidate];
	[timer release];
	[_timer invalidate];
	[_timer release];

	[host release];
	[path release];
	[headers release];
	[POSTData release];
	[_host release];
	[_path release];
	[_headers release];
	[_POSTData release];

	[super dealloc];
}

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

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

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

			return YES;
		default:
			return NO;
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
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
550
551
552
553
554
555
556
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

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
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
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
550
551
552
553
554
555
556







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

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







-
+










-
+

-
+

-
+




-
+




-
+

-
+


-
-
+
+










-
+


-
+





-
+




-
+





-
+

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



















-
-
+
+







-
-
+
+











-
+




-
-
-
+
+
+






-
+




-
+


-
-
+
+

-
+









-
+









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











-
-
-
+
+
+

-
-
+
+




+
-
-
+
+




-
-
+
+

-
-
+
+

-
-
+
+


-
+


-
+


-
+

-
-
-
-
+
+
+
+


-
-
+
+

-
-
-
+
+
+













-
+







-
-
-
+
+
+




-
+

-
+




-
+


-
+

-
+




-
+


-
+

-
+




-
+


-
+

-
+




-
+




-
+




-
+


-
+

-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+




-
-
-
+
+
+









-
+

-
+







		if (![version hasPrefix: @" HTTP/1."])
			return [self sendErrorAndClose: 505];

		tmp = [version characterAtIndex: 8];
		if (tmp < '0' || tmp > '9')
			return [self sendErrorAndClose: 400];

		HTTPMinorVersion = (uint8_t)(tmp - '0');
		_HTTPMinorVersion = (uint8_t)(tmp - '0');
	} @catch (OFOutOfRangeException *e) {
		return [self sendErrorAndClose: 400];
	}

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

	type = [line substringWithRange: of_range(0, pos)];
	if ([type isEqual: @"GET"])
		requestType = OF_HTTP_REQUEST_TYPE_GET;
		_requestType = OF_HTTP_REQUEST_TYPE_GET;
	else if ([type isEqual: @"POST"])
		requestType = OF_HTTP_REQUEST_TYPE_POST;
		_requestType = OF_HTTP_REQUEST_TYPE_POST;
	else if ([type isEqual: @"HEAD"])
		requestType = OF_HTTP_REQUEST_TYPE_HEAD;
		_requestType = OF_HTTP_REQUEST_TYPE_HEAD;
	else
		return [self sendErrorAndClose: 501];

	@try {
		path = [line substringWithRange:
		_path = [line substringWithRange:
		    of_range(pos + 1, [line length] - pos - 10)];
	} @catch (OFOutOfRangeException *e) {
		return [self sendErrorAndClose: 400];
	}
	path = [[path stringByDeletingEnclosingWhitespaces] retain];
	_path = [[_path stringByDeletingEnclosingWhitespaces] retain];

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

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

	return YES;
}

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

	if ([line length] == 0) {
		switch (requestType) {
		switch (_requestType) {
		case OF_HTTP_REQUEST_TYPE_GET:
		case OF_HTTP_REQUEST_TYPE_HEAD:
			state = SEND_REPLY;
			_state = SEND_REPLY;
			break;
		case OF_HTTP_REQUEST_TYPE_POST:;
			OFString *tmp;
			char *buffer;

			tmp = [headers objectForKey: @"Content-Length"];
			tmp = [_headers objectForKey: @"Content-Length"];
			if (tmp == nil)
				return [self sendErrorAndClose: 411];

			@try {
				contentLength = (size_t)[tmp decimalValue];
				_contentLength = (size_t)[tmp decimalValue];
			} @catch (OFInvalidFormatException *e) {
				return [self sendErrorAndClose: 400];
			}

			buffer = [self allocMemoryWithSize: BUFFER_SIZE];
			POSTData = [[OFDataArray alloc] init];
			_POSTData = [[OFDataArray alloc] init];

			[sock asyncReadIntoBuffer: buffer
					   length: BUFFER_SIZE
					   target: self
					 selector: @selector(socket:
						       didReadIntoBuffer:
						       length:exception:)];
			[timer setFireDate:
			[_socket asyncReadIntoBuffer: buffer
					      length: BUFFER_SIZE
					      target: self
					    selector: @selector(socket:
							  didReadIntoBuffer:
							  length:exception:)];
			[_timer setFireDate:
			    [OFDate dateWithTimeIntervalSinceNow: 5]];

			return NO;
		}

		return YES;
	}

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

	key = [line substringWithRange: of_range(0, pos)];
	value = [line substringWithRange:
	    of_range(pos + 1, [line length] - pos - 1)];

	key = normalized_key([key stringByDeletingTrailingWhitespaces]);
	value = [value stringByDeletingLeadingWhitespaces];

	[headers setObject: value
		    forKey: key];
	[_headers setObject: value
		     forKey: key];

	if ([key isEqual: @"Host"]) {
		pos = [value
		    rangeOfString: @":"
			  options: OF_STRING_SEARCH_BACKWARDS].location;

		if (pos != OF_NOT_FOUND) {
			[host release];
			host = [[value substringWithRange:
			[_host release];
			_host = [[value substringWithRange:
			    of_range(0, pos)] retain];

			@try {
				of_range_t range =
				    of_range(pos + 1, [value length] - pos - 1);
				intmax_t portTmp = [[value
				    substringWithRange: range] decimalValue];

				if (portTmp < 1 || portTmp > UINT16_MAX)
					return [self sendErrorAndClose: 400];

				port = (uint16_t)portTmp;
				_port = (uint16_t)portTmp;
			} @catch (OFInvalidFormatException *e) {
				return [self sendErrorAndClose: 400];
			}
		} else {
			[host release];
			host = [value retain];
			port = 80;
			[_host release];
			_host = [value retain];
			_port = 80;
		}
	}

	return YES;
}

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

	[POSTData addItems: buffer
		     count: length];
	[_POSTData addItems: buffer
		      count: length];

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

		return NO;
	}

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

	return YES;
}

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

	[sock 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]];
	[sock close];
	[_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;
}

- (void)createReply
{
	OFURL *URL;
	OFHTTPRequest *request;
	OFHTTPServerReply *reply;
	size_t pos;

	[timer invalidate];
	[timer release];
	timer = nil;
	[_timer invalidate];
	[_timer release];
	_timer = nil;

	if (host == nil || port == 0) {
		if (HTTPMinorVersion > 0) {
	if (_host == nil || _port == 0) {
		if (_HTTPMinorVersion > 0) {
			[self sendErrorAndClose: 400];
			return;
		}

		[_host release];
		host = [[server host] retain];
		port = [server port];
		_host = [[_server host] retain];
		_port = [_server port];
	}

	URL = [OFURL URL];
	[URL setScheme: @"http"];
	[URL setHost: host];
	[URL setPort: port];
	[URL setHost: _host];
	[URL setPort: _port];

	if ((pos = [path rangeOfString: @"?"].location) != OF_NOT_FOUND) {
		OFString *path_, *query;
	if ((pos = [_path rangeOfString: @"?"].location) != OF_NOT_FOUND) {
		OFString *path, *query;

		path_ = [path substringWithRange: of_range(0, pos)];
		query = [path substringWithRange:
		path = [_path substringWithRange: of_range(0, pos)];
		query = [_path substringWithRange:
		    of_range(pos + 1, [path length] - pos - 1)];

		[URL setPath: path_];
		[URL setPath: path];
		[URL setQuery: query];
	} else
		[URL setPath: path];
		[URL setPath: _path];

	request = [OFHTTPRequest requestWithURL: URL];
	[request setRequestType: requestType];
	[request setRequestType: _requestType];
	[request setProtocolVersion:
	    (of_http_request_protocol_version_t){ 1, HTTPMinorVersion }];
	[request setHeaders: headers];
	[request setPOSTData: POSTData];
	[request setRemoteAddress: [sock remoteAddress]];
	    (of_http_request_protocol_version_t){ 1, _HTTPMinorVersion }];
	[request setHeaders: _headers];
	[request setPOSTData: _POSTData];
	[request setRemoteAddress: [_socket remoteAddress]];

	reply = [[[OFHTTPServerReply alloc]
	    initWithSocket: sock
		    server: server] autorelease];
	    initWithSocket: _socket
		    server: _server] autorelease];

	[[server delegate] server: server
		didReceiveRequest: request
			    reply: reply];
	[[_server delegate] server: _server
		 didReceiveRequest: request
			     reply: reply];
}
@end

@implementation OFHTTPServer
+ (instancetype)server
{
	return [[[self alloc] init] autorelease];
}

- init
{
	self = [super init];

	name = @"OFHTTPServer (ObjFW's HTTP server class "
	_name = @"OFHTTPServer (ObjFW's HTTP server class "
	    @"<https://webkeks.org/objfw/>)";

	return self;
}

- (void)dealloc
{
	[host release];
	[listeningSocket release];
	[name release];
	[_host release];
	[_listeningSocket release];
	[_name release];

	[super dealloc];
}

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

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

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

- (uint16_t)port
{
	return port;
	return _port;
}

- (void)setDelegate: (id <OFHTTPServerDelegate>)delegate_
- (void)setDelegate: (id <OFHTTPServerDelegate>)delegate
{
	delegate = delegate_;
	_delegate = delegate;
}

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

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

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

- (void)start
{
	if (host == nil || port == 0)
	if (_host == nil || _port == 0)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	if (listeningSocket != nil)
	if (_listeningSocket != nil)
		@throw [OFAlreadyConnectedException
		    exceptionWithClass: [self class]
				socket: listeningSocket];
				socket: _listeningSocket];

	listeningSocket = [[OFTCPSocket alloc] init];
	[listeningSocket bindToHost: host
			       port: port];
	[listeningSocket listen];
	_listeningSocket = [[OFTCPSocket alloc] init];
	[_listeningSocket bindToHost: _host
				port: _port];
	[_listeningSocket listen];

	[listeningSocket asyncAcceptWithTarget: self
				      selector: @selector(OF_socket:
						    didAcceptSocket:
						    exception:)];
	[_listeningSocket asyncAcceptWithTarget: self
				       selector: @selector(OF_socket:
						     didAcceptSocket:
						     exception:)];
}

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

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

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

		return NO;
	}

	connection = [[[OFHTTPServer_Connection alloc]
	    initWithSocket: clientSocket

Modified src/OFHash.h from [f49dffade2] to [9f5b79c75d].

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 base class for classes providing hash functions.
 */
@interface OFHash: OFObject
{
	BOOL calculated;
	BOOL _calculated;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, getter=isCalculated) BOOL calculated;
#endif

/*!

Modified src/OFHash.m from [20ad65b662] to [f22a074494].

49
50
51
52
53
54
55
56

57
58
49
50
51
52
53
54
55

56
57
58







-
+


{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

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

Modified src/OFIntrospection.h from [8fcdbf99f7] to [4b5b7170d8].

21
22
23
24
25
26
27
28
29
30



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



28
29
30
31
32
33
34
35
36
37







-
-
-
+
+
+







@class OFMutableArray;

/*!
 * @brief A class for describing a method.
 */
@interface OFMethod: OFObject
{
	SEL selector;
	OFString *name;
	const char *typeEncoding;
	SEL _selector;
	OFString *_name;
	const char *_typeEncoding;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly) SEL selector;
@property (readonly, copy) OFString *name;
@property (readonly) const char *typeEncoding;
#endif
59
60
61
62
63
64
65
66
67
68



69
70
71
72
73
74
75
59
60
61
62
63
64
65



66
67
68
69
70
71
72
73
74
75







-
-
-
+
+
+







@end

/*!
 * @brief A class for describing an instance variable.
 */
@interface OFInstanceVariable: OFObject
{
	OFString *name;
	const char *typeEncoding;
	ptrdiff_t offset;
	OFString *_name;
	const char *_typeEncoding;
	ptrdiff_t _offset;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy) OFString *name;
@property (readonly) ptrdiff_t offset;
@property (readonly) const char *typeEncoding;
#endif
97
98
99
100
101
102
103
104
105
106



107
108

109
110
111
112
113
114
115
97
98
99
100
101
102
103



104
105
106
107

108
109
110
111
112
113
114
115







-
-
-
+
+
+

-
+







@end

/*!
 * @brief A class for introspecting classes.
 */
@interface OFIntrospection: OFObject
{
	OFMutableArray *classMethods;
	OFMutableArray *instanceMethods;
	OFMutableArray *instanceVariables;
	OFMutableArray *_classMethods;
	OFMutableArray *_instanceMethods;
	OFMutableArray *_instanceVariables;
#ifdef OF_HAVE_PROPERTIES
	OFMutableArray *properties;
	OFMutableArray *_properties;
#endif
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy) OFArray *classMethods;
@property (readonly, copy) OFArray *instanceMethods;
@property (readonly, copy) OFArray *instanceVariables;

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

33
34
35
36
37
38
39
40
41
42
43




44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60




61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79

80
81
82
83
84

85
86
87
88
89

90
91
92
93
94
95

96
97
98
99
100

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
33
34
35
36
37
38
39




40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56




57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

72
73
74
75
76
77
78

79
80
81
82
83

84
85
86
87
88

89
90
91
92
93
94

95
96
97
98
99

100
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







-
-
-
-
+
+
+
+













-
-
-
-
+
+
+
+











-
+






-
+




-
+




-
+





-
+




-
+




-
+

-
+


-
+


-
-
+
+


-
-
+
+











-
+

-
+


-
+

-
+















-
-
-
+
+
+













-
+

-
-
+
+











-
+






-
+




-
+




-
+






-
+







@implementation OFMethod
#if defined(OF_OBJFW_RUNTIME)
- OF_initWithMethod: (struct objc_method*)method
{
	self = [super init];

	@try {
		selector = (SEL)&method->sel;
		name = [[OFString alloc]
		    initWithUTF8String: sel_getName(selector)];
		typeEncoding = method->sel.types;
		_selector = (SEL)&method->sel;
		_name = [[OFString alloc]
		    initWithUTF8String: sel_getName(_selector)];
		_typeEncoding = method->sel.types;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
#elif defined(OF_APPLE_RUNTIME)
- OF_initWithMethod: (Method)method
{
	self = [super init];

	@try {
		selector = method_getName(method);
		name = [[OFString alloc]
		    initWithUTF8String: sel_getName(selector)];
		typeEncoding = method_getTypeEncoding(method);
		_selector = method_getName(method);
		_name = [[OFString alloc]
		    initWithUTF8String: sel_getName(_selector)];
		_typeEncoding = method_getTypeEncoding(method);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
#endif

- (void)dealloc
{
	[name release];
	[_name release];

	[super dealloc];
}

- (SEL)selector
{
	return selector;
	return _selector;
}

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

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

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

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

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

	otherMethod = object;
	method = object;

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

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

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

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

	return YES;
}

- (uint32_t)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, [name hash]);
	OF_HASH_ADD_HASH(hash, [_name hash]);

	if (typeEncoding != NULL) {
	if (_typeEncoding != NULL) {
		size_t i, length;

		length = strlen(typeEncoding);
		length = strlen(_typeEncoding);
		for (i = 0; i < length; i++)
			OF_HASH_ADD(hash, typeEncoding[i]);
			OF_HASH_ADD(hash, _typeEncoding[i]);
	}

	OF_HASH_FINALIZE(hash);

	return hash;
}
@end

@implementation OFInstanceVariable
#if defined(OF_OBJFW_RUNTIME)
- OF_initWithIvar: (struct objc_ivar*)ivar
{
	self = [super init];

	@try {
		name = [[OFString alloc] initWithUTF8String: ivar->name];
		typeEncoding = ivar->type;
		offset = ivar->offset;
		_name = [[OFString alloc] initWithUTF8String: ivar->name];
		_typeEncoding = ivar->type;
		_offset = ivar->offset;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
#elif defined(OF_APPLE_RUNTIME)
- OF_initWithIvar: (Ivar)ivar
{
	self = [super init];

	@try {
		name = [[OFString alloc]
		_name = [[OFString alloc]
		    initWithUTF8String: ivar_getName(ivar)];
		typeEncoding = ivar_getTypeEncoding(ivar);
		offset = ivar_getOffset(ivar);
		_typeEncoding = ivar_getTypeEncoding(ivar);
		_offset = ivar_getOffset(ivar);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
#endif

- (void)dealloc
{
	[name release];
	[_name release];

	[super dealloc];
}

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

- (ptrdiff_t)offset
{
	return offset;
	return _offset;
}

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

- (OFString*)description
{
	return [OFString stringWithFormat:
	    @"<OFInstanceVariable: %@ [%s] @ 0x%tx>",
	    name, typeEncoding, offset];
	    _name, _typeEncoding, _offset];
}
@end

@implementation OFIntrospection
+ (instancetype)introspectionWithClass: (Class)class
{
	return [[[self alloc] initWithClass: class] autorelease];
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
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







-
-
-
+
+
+










-
+












-
+














-
+











-
+












-
+












-
+









-
-
-
+
+
+










-
-
-
+
+
+






-
+




-
+




-
+


		struct objc_method_list *methodList;
#elif defined(OF_APPLE_RUNTIME)
		Method *methodList;
		Ivar *ivarList;
		unsigned i, count;
#endif

		classMethods = [[OFMutableArray alloc] init];
		instanceMethods = [[OFMutableArray alloc] init];
		instanceVariables = [[OFMutableArray alloc] init];
		_classMethods = [[OFMutableArray alloc] init];
		_instanceMethods = [[OFMutableArray alloc] init];
		_instanceVariables = [[OFMutableArray alloc] init];

#if defined(OF_OBJFW_RUNTIME)
		for (methodList = object_getClass(class)->methodlist;
		    methodList != NULL; methodList = methodList->next) {
			int i;

			for (i = 0; i < methodList->count; i++) {
				void *pool = objc_autoreleasePoolPush();
				OFMethod *method = [[OFMethod alloc]
				    OF_initWithMethod: &methodList->methods[i]];
				[classMethods addObject: [method autorelease]];
				[_classMethods addObject: [method autorelease]];
				objc_autoreleasePoolPop(pool);
			}
		}

		for (methodList = class->methodlist; methodList != NULL;
		    methodList = methodList->next) {
			int i;

			for (i = 0; i < methodList->count; i++) {
				void *pool = objc_autoreleasePoolPush();
				OFMethod *method = [[OFMethod alloc]
				    OF_initWithMethod: &methodList->methods[i]];
				[instanceMethods addObject:
				[_instanceMethods addObject:
				    [method autorelease]];
				objc_autoreleasePoolPop(pool);
			}
		}

		if (class->ivars != NULL) {
			unsigned i;

			for (i = 0; i < class->ivars->count; i++) {
				void *pool = objc_autoreleasePoolPush();
				OFInstanceVariable *ivar;

				ivar = [[OFInstanceVariable alloc]
				    OF_initWithIvar: &class->ivars->ivars[i]];
				[instanceVariables addObject:
				[_instanceVariables addObject:
				    [ivar autorelease]];

				objc_autoreleasePoolPop(pool);
			}
		}
#elif defined(OF_APPLE_RUNTIME)
		methodList = class_copyMethodList(object_getClass(class),
		    &count);
		@try {
			for (i = 0; i < count; i++) {
				void *pool = objc_autoreleasePoolPush();
				[classMethods addObject: [[[OFMethod alloc]
				[_classMethods addObject: [[[OFMethod alloc]
				    OF_initWithMethod: methodList[i]]
				    autorelease]];
				objc_autoreleasePoolPop(pool);
			}
		} @finally {
			free(methodList);
		}

		methodList = class_copyMethodList(class, &count);
		@try {
			for (i = 0; i < count; i++) {
				void *pool = objc_autoreleasePoolPush();
				[instanceMethods addObject: [[[OFMethod alloc]
				[_instanceMethods addObject: [[[OFMethod alloc]
				    OF_initWithMethod: methodList[i]]
				    autorelease]];
				objc_autoreleasePoolPop(pool);
			}
		} @finally {
			free(methodList);
		}

		ivarList = class_copyIvarList(class, &count);
		@try {
			for (i = 0; i < count; i++) {
				void *pool = objc_autoreleasePoolPush();
				[instanceVariables addObject:
				[_instanceVariables addObject:
				    [[[OFInstanceVariable alloc]
				    OF_initWithIvar: ivarList[i]] autorelease]];
				objc_autoreleasePoolPop(pool);
			}
		} @finally {
			free(ivarList);
		}
#endif

		[classMethods makeImmutable];
		[instanceMethods makeImmutable];
		[instanceVariables makeImmutable];
		[_classMethods makeImmutable];
		[_instanceMethods makeImmutable];
		[_instanceVariables makeImmutable];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[classMethods release];
	[instanceMethods release];
	[instanceVariables release];
	[_classMethods release];
	[_instanceMethods release];
	[_instanceVariables release];

	[super dealloc];
}

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

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

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

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

36
37
38
39
40
41
42
43
44
45
46




47
48
49
50
51
52
53
36
37
38
39
40
41
42




43
44
45
46
47
48
49
50
51
52
53







-
-
-
-
+
+
+
+







};

/*!
 * @brief A class which provides easy to use double-linked lists.
 */
@interface OFList: OFObject <OFCopying, OFCollection, OFSerialization>
{
	of_list_object_t *firstListObject;
	of_list_object_t *lastListObject;
	size_t		 count;
	unsigned long	 mutations;
	of_list_object_t *_firstListObject;
	of_list_object_t *_lastListObject;
	size_t		 _count;
	unsigned long	 _mutations;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly) of_list_object_t *firstListObject;
@property (readonly) of_list_object_t *lastListObject;
#endif

158
159
160
161
162
163
164
165
166
167
168




169
170
171
172
173
158
159
160
161
162
163
164




165
166
167
168
169
170
171
172
173







-
-
-
-
+
+
+
+





 * @brief Removes all objects from the list.
 */
- (void)removeAllObjects;
@end

@interface OFListEnumerator: OFEnumerator
{
	OFList		 *list;
	of_list_object_t *current;
	unsigned long	 mutations;
	unsigned long	 *mutationsPtr;
	OFList		 *_list;
	of_list_object_t *_current;
	unsigned long	 _mutations;
	unsigned long	 *_mutationsPtr;
}

-     initWithList: (OFList*)list
  mutationsPointer: (unsigned long*)mutationsPtr;
@end

Modified src/OFList.m from [73617e55da] to [c96b3b33fd].

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







-
+







-
+




-
+









-
+

-
-
+
+

-
-
-
+
+
+

-
-
+
+










-
+


-
-
+
+

-
-
-
+
+
+

-
-
+
+



















-
-
+
+

-
-
+
+



















-
-
+
+

-
-
+
+











-
-
-
-
+
+
+
+

-
-
+
+








-
+




-
+




-
+




-
+





-
+

-
+


-
+





-
+









-
+


-
+










-
+


-
+










-
+

-
+






-
+











-
+






-
-
+
+



-
+








-
+











-
+












-
+




-
+







	return self;
}

- (void)dealloc
{
	of_list_object_t *iter;

	for (iter = firstListObject; iter != NULL; iter = iter->next)
	for (iter = _firstListObject; iter != NULL; iter = iter->next)
		[iter->object release];

	[super dealloc];
}

- (of_list_object_t*)firstListObject
{
	return firstListObject;
	return _firstListObject;
}

- (of_list_object_t*)lastListObject
{
	return lastListObject;
	return _lastListObject;
}

- (of_list_object_t*)appendObject: (id)object
{
	of_list_object_t *listObject;

	listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	listObject->object = [object retain];
	listObject->next = NULL;
	listObject->previous = lastListObject;
	listObject->previous = _lastListObject;

	if (lastListObject != NULL)
		lastListObject->next = listObject;
	if (_lastListObject != NULL)
		_lastListObject->next = listObject;

	lastListObject = listObject;
	if (firstListObject == NULL)
		firstListObject = listObject;
	_lastListObject = listObject;
	if (_firstListObject == NULL)
		_firstListObject = listObject;

	count++;
	mutations++;
	_count++;
	_mutations++;

	return listObject;
}

- (of_list_object_t*)prependObject: (id)object
{
	of_list_object_t *listObject;

	listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	listObject->object = [object retain];
	listObject->next = firstListObject;
	listObject->next = _firstListObject;
	listObject->previous = NULL;

	if (firstListObject != NULL)
		firstListObject->previous = listObject;
	if (_firstListObject != NULL)
		_firstListObject->previous = listObject;

	firstListObject = listObject;
	if (lastListObject == NULL)
		lastListObject = listObject;
	_firstListObject = listObject;
	if (_lastListObject == NULL)
		_lastListObject = listObject;

	count++;
	mutations++;
	_count++;
	_mutations++;

	return listObject;
}

- (of_list_object_t*)insertObject: (id)object
		 beforeListObject: (of_list_object_t*)listObject
{
	of_list_object_t *newListObject;

	newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	newListObject->object = [object retain];
	newListObject->next = listObject;
	newListObject->previous = listObject->previous;

	if (listObject->previous != NULL)
		listObject->previous->next = newListObject;

	listObject->previous = newListObject;

	if (listObject == firstListObject)
		firstListObject = newListObject;
	if (listObject == _firstListObject)
		_firstListObject = newListObject;

	count++;
	mutations++;
	_count++;
	_mutations++;

	return newListObject;
}

- (of_list_object_t*)insertObject: (id)object
		  afterListObject: (of_list_object_t*)listObject
{
	of_list_object_t *newListObject;

	newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	newListObject->object = [object retain];
	newListObject->next = listObject->next;
	newListObject->previous = listObject;

	if (listObject->next != NULL)
		listObject->next->previous = newListObject;

	listObject->next = newListObject;

	if (listObject == lastListObject)
		lastListObject = newListObject;
	if (listObject == _lastListObject)
		_lastListObject = newListObject;

	count++;
	mutations++;
	_count++;
	_mutations++;

	return newListObject;
}

- (void)removeListObject: (of_list_object_t*)listObject
{
	if (listObject->previous != NULL)
		listObject->previous->next = listObject->next;
	if (listObject->next != NULL)
		listObject->next->previous = listObject->previous;

	if (firstListObject == listObject)
		firstListObject = listObject->next;
	if (lastListObject == listObject)
		lastListObject = listObject->previous;
	if (_firstListObject == listObject)
		_firstListObject = listObject->next;
	if (_lastListObject == listObject)
		_lastListObject = listObject->previous;

	count--;
	mutations++;
	_count--;
	_mutations++;

	[listObject->object release];

	[self freeMemory: listObject];
}

- (id)firstObject
{
	return (firstListObject != NULL ? firstListObject->object : nil);
	return (_firstListObject != NULL ? _firstListObject->object : nil);
}

- (id)lastObject
{
	return (lastListObject != NULL ? lastListObject->object : nil);
	return (_lastListObject != NULL ? _lastListObject->object : nil);
}

- (size_t)count
{
	return count;
	return _count;
}

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

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

	otherList = object;
	list = object;

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

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

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

	return YES;
}

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

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

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

	return NO;
}

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

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

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

	return NO;
}

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

	mutations++;
	_mutations++;

	for (iter = firstListObject; iter != NULL; iter = next) {
	for (iter = _firstListObject; iter != NULL; iter = next) {
		next = iter->next;

		[iter->object release];
		[self freeMemory: iter];
	}

	firstListObject = lastListObject = NULL;
	_firstListObject = _lastListObject = NULL;
}

- copy
{
	OFList *copy = [[[self class] alloc] init];
	of_list_object_t *iter, *listObject, *previous;

	listObject = NULL;
	previous = NULL;

	@try {
		for (iter = firstListObject; iter != NULL; iter = iter->next) {
		for (iter = _firstListObject; iter != NULL; iter = iter->next) {
			listObject = [copy allocMemoryWithSize:
			    sizeof(of_list_object_t)];
			listObject->object = [iter->object retain];
			listObject->next = NULL;
			listObject->previous = previous;

			if (copy->firstListObject == NULL)
				copy->firstListObject = listObject;
			if (copy->_firstListObject == NULL)
				copy->_firstListObject = listObject;
			if (previous != NULL)
				previous->next = listObject;

			copy->count++;
			copy->_count++;

			previous = listObject;
		}
	} @catch (id e) {
		[copy release];
		@throw e;
	}

	copy->lastListObject = listObject;
	copy->_lastListObject = listObject;

	return copy;
}

- (uint32_t)hash
{
	of_list_object_t *iter;
	uint32_t hash;

	OF_HASH_INIT(hash);

	for (iter = firstListObject; iter != NULL; iter = iter->next)
	for (iter = _firstListObject; iter != NULL; iter = iter->next)
		OF_HASH_ADD_HASH(hash, [iter->object hash]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

- (OFString*)description
{
	OFMutableString *ret;
	of_list_object_t *iter;

	if (count == 0)
	if (_count == 0)
		return @"[]";

	ret = [OFMutableString stringWithString: @"[\n"];

	for (iter = firstListObject; iter != NULL; iter = iter->next) {
	for (iter = _firstListObject; iter != NULL; iter = iter->next) {
		void *pool = objc_autoreleasePoolPush();

		[ret appendString: [iter->object description]];

		if (iter->next != NULL)
			[ret appendString: @",\n"];

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







-
+












-
+





-
+


-
+



-
+







-
+






-
+




-
-
+
+



-
-
-
-
+
+
+
+






-
+








-
+


-
+

-
+


-
-
+
+






-
+


-
+

-
+


{
	OFXMLElement *element;
	of_list_object_t *iter;

	element = [OFXMLElement elementWithName: [self className]
				      namespace: OF_SERIALIZATION_NS];

	for (iter = firstListObject; iter != NULL; iter = iter->next) {
	for (iter = _firstListObject; iter != NULL; iter = iter->next) {
		void *pool = objc_autoreleasePoolPush();

		[element addChild: [iter->object XMLElementBySerializing]];

		objc_autoreleasePoolPop(pool);
	}

	return element;
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
			     count: (int)count_
			     count: (int)count
{
	of_list_object_t **listObject = (of_list_object_t**)&state->extra[0];
	int i;

	state->itemsPtr = objects;
	state->mutationsPtr = &mutations;
	state->mutationsPtr = &_mutations;

	if (state->state == 0) {
		*listObject = firstListObject;
		*listObject = _firstListObject;
		state->state = 1;
	}

	for (i = 0; i < count_; i++) {
	for (i = 0; i < count; i++) {
		if (*listObject == NULL)
			return i;

		objects[i] = (*listObject)->object;
		*listObject = (*listObject)->next;
	}

	return count_;
	return count;
}

- (OFEnumerator*)objectEnumerator
{
	return [[[OFListEnumerator alloc]
		initWithList: self
	    mutationsPointer: &mutations] autorelease];
	    mutationsPointer: &_mutations] autorelease];
}
@end

@implementation OFListEnumerator
-     initWithList: (OFList*)list_
  mutationsPointer: (unsigned long*)mutationsPtr_
-     initWithList: (OFList*)list
  mutationsPointer: (unsigned long*)mutationsPtr
{
	self = [super init];

	list = [list_ retain];
	current = [list firstListObject];
	mutations = *mutationsPtr_;
	mutationsPtr = mutationsPtr_;
	_list = [list retain];
	_current = [list firstListObject];
	_mutations = *mutationsPtr;
	_mutationsPtr = mutationsPtr;

	return self;
}

- (void)dealloc
{
	[list release];
	[_list release];

	[super dealloc];
}

- (id)nextObject
{
	id ret;

	if (*mutationsPtr != mutations)
	if (*_mutationsPtr != _mutations)
		@throw [OFEnumerationMutationException
		    exceptionWithClass: [self class]
				object: list];
				object: _list];

	if (current == NULL)
	if (_current == NULL)
		return nil;

	ret = current->object;
	current = current->next;
	ret = _current->object;
	_current = _current->next;

	return ret;
}

- (void)reset
{
	if (*mutationsPtr != mutations)
	if (*_mutationsPtr != _mutations)
		@throw [OFEnumerationMutationException
		    exceptionWithClass: [self class]
				object: list];
				object: _list];

	current = [list firstListObject];
	_current = [_list firstListObject];
}
@end

Modified src/OFMD5Hash.h from [8c63eab3b8] to [efbff1e954].

19
20
21
22
23
24
25
26
27


28
29
30
31

32
33
19
20
21
22
23
24
25


26
27
28
29
30

31
32
33







-
-
+
+



-
+


#define OF_MD5_DIGEST_SIZE 16

/*!
 * @brief A class which provides functions to create an MD5 hash.
 */
@interface OFMD5Hash: OFHash
{
	uint32_t buffer[4];
	uint32_t bits[2];
	uint32_t _buffer[4];
	uint32_t _bits[2];
	union {
		uint8_t	u8[64];
		uint32_t u32[16];
	} in;
	} _in;
}
@end

Modified src/OFMD5Hash.m from [b7d6fe40cf] to [f6e92bc9b9].

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







-
-
-
-
+
+
+
+




-
+



-
+




-
+





-
-
+
+

-
-
+
+






-
+




-
+



-
+

-
+

-
+





-
-
-
+
+
+

-
+




-
+





-
+

-
-
+
+


-
+





-
+









-
-
+
+


-
+







-
-
+
+

-
-
+
+

-
+

-
+


	return 64;
}

- init
{
	self = [super init];

	buffer[0] = 0x67452301;
	buffer[1] = 0xEFCDAB89;
	buffer[2] = 0x98BADCFE;
	buffer[3] = 0x10325476;
	_buffer[0] = 0x67452301;
	_buffer[1] = 0xEFCDAB89;
	_buffer[2] = 0x98BADCFE;
	_buffer[3] = 0x10325476;

	return self;
}

- (void)updateWithBuffer: (const void*)buffer__
- (void)updateWithBuffer: (const void*)buffer_
		  length: (size_t)length
{
	uint32_t t;
	const char *buffer_ = buffer__;
	const char *buffer = buffer_;

	if (length == 0)
		return;

	if (calculated)
	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithClass: [self class]
				  hash: self];

	/* Update bitcount */
	t = bits[0];
	if ((bits[0] = t + ((uint32_t)length << 3)) < t)
	t = _bits[0];
	if ((_bits[0] = t + ((uint32_t)length << 3)) < t)
		/* Carry from low to high */
		bits[1]++;
	bits[1] += (uint32_t)length >> 29;
		_bits[1]++;
	_bits[1] += (uint32_t)length >> 29;

	/* Bytes already in shsInfo->data */
	t = (t >> 3) & 0x3F;

	/* Handle any leading odd-sized chunks */
	if (t) {
		uint8_t *p = in.u8 + t;
		uint8_t *p = _in.u8 + t;

		t = 64 - t;

		if (length < t) {
			memcpy(p, buffer_, length);
			memcpy(p, buffer, length);
			return;
		}

		memcpy(p, buffer_, t);
		memcpy(p, buffer, t);
		BSWAP32_VEC_IF_BE(in.u32, 16);
		md5_transform(buffer, in.u32);
		md5_transform(_buffer, _in.u32);

		buffer_ += t;
		buffer += t;
		length -= t;
	}

	/* Process data in 64-byte chunks */
	while (length >= 64) {
		memcpy(in.u8, buffer_, 64);
		BSWAP32_VEC_IF_BE(in.u32, 16);
		md5_transform(buffer, in.u32);
		memcpy(_in.u8, buffer, 64);
		BSWAP32_VEC_IF_BE(_in.u32, 16);
		md5_transform(_buffer, _in.u32);

		buffer_ += 64;
		buffer += 64;
		length -= 64;
	}

	/* Handle any remaining bytes of data. */
	memcpy(in.u8, buffer_, length);
	memcpy(_in.u8, buffer, length);
}

- (uint8_t*)digest
{
	uint8_t	*p;
	size_t	count;
	size_t count;

	if (calculated)
		return (uint8_t*)buffer;
	if (_calculated)
		return (uint8_t*)_buffer;

	/* Compute number of bytes mod 64 */
	count = (bits[0] >> 3) & 0x3F;
	count = (_bits[0] >> 3) & 0x3F;

	/*
	 * Set the first char of padding to 0x80. This is safe since there is
	 * always at least one byte free
	 */
	p = in.u8 + count;
	p = _in.u8 + count;
	*p++ = 0x80;

	/* Bytes of padding needed to make 64 bytes */
	count = 64 - 1 - count;

	/* Pad out to 56 mod 64 */
	if (count < 8) {
		/* Two lots of padding: Pad the first block to 64 bytes */
		memset(p, 0, count);
		BSWAP32_VEC_IF_BE(in.u32, 16);
		md5_transform(buffer, in.u32);
		BSWAP32_VEC_IF_BE(_in.u32, 16);
		md5_transform(_buffer, _in.u32);

		/* Now fill the next block with 56 bytes */
		memset(in.u8, 0, 56);
		memset(_in.u8, 0, 56);
	} else {
		/* Pad block to 56 bytes */
		memset(p, 0, count - 8);
	}
	BSWAP32_VEC_IF_BE(in.u32, 14);

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

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

	calculated = YES;
	_calculated = YES;

	return (uint8_t*)buffer;
	return (uint8_t*)_buffer;
}
@end

Modified src/OFMapTable.h from [7677133529] to [c74d98dfe6].

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





54
55
56
57
58
59
60
42
43
44
45
46
47
48





49
50
51
52
53
54
55
56
57
58
59
60







-
-
-
-
-
+
+
+
+
+








/**
 * @brief A class similar to OFDictionary, but providing more options how keys
 *	  and values should be retained, released, compared and hashed.
 */
@interface OFMapTable: OFObject <OFCopying, OFFastEnumeration>
{
	of_map_table_functions_t keyFunctions, valueFunctions;
	struct of_map_table_bucket **buckets;
	uint32_t minCapacity, capacity, count;
	uint8_t rotate;
	unsigned long mutations;
	of_map_table_functions_t _keyFunctions, _valueFunctions;
	struct of_map_table_bucket **_buckets;
	uint32_t _minCapacity, _capacity, _count;
	uint8_t _rotate;
	unsigned long _mutations;
}

/*!
 * @brief Creates a new OFMapTable with the specified key and value functions.
 *
 * @param keyFunctions A structure of functions for handling keys
 * @param valueFunctions A structure of functions for handling values
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
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







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


-
-
-
-
+
+
+
+

















-
-
+
+






/*!
 * @brief A class which provides methods to enumerate through an OFMapTable's
 *	  keys or values.
 */
@interface OFMapTableEnumerator: OFObject
{
	OFMapTable *mapTable;
	struct of_map_table_bucket **buckets;
	uint32_t capacity;
	unsigned long mutations;
	unsigned long *mutationsPtr;
	uint32_t position;
	OFMapTable *_mapTable;
	struct of_map_table_bucket **_buckets;
	uint32_t _capacity;
	unsigned long _mutations;
	unsigned long *_mutationsPtr;
	uint32_t _position;
}

- OF_initWithMapTable: (OFMapTable*)mapTable_
	      buckets: (struct of_map_table_bucket**)buckets_
	     capacity: (uint32_t)capacity_
     mutationsPointer: (unsigned long*)mutationsPtr_;
- OF_initWithMapTable: (OFMapTable*)mapTable
	      buckets: (struct of_map_table_bucket**)buckets
	     capacity: (uint32_t)capacity
     mutationsPointer: (unsigned long*)mutationsPtr;

/*!
 * @brief Returns the next value.
 *
 * @return The next value
 */
- (void*)nextValue;

/*!
 * @brief Resets the enumerator, so the next call to nextKey returns the first
 *	  key again.
 */
- (void)reset;
@end

@interface OFMapTableEnumeratorWrapper: OFEnumerator
{
	OFMapTableEnumerator *enumerator;
	id object;
	OFMapTableEnumerator *_enumerator;
	id _object;
}

- initWithEnumerator: (OFMapTableEnumerator*)enumerator
	      object: (id)object;
@end

Modified src/OFMapTable.m from [01662f5402] to [212223cd50].

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



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
550
551
552



553
554
555
556
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
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
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
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



550
551
552
553
554
555
556

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







-
-
+
+

-
-
+
+



-
-
-
+
+
+




-
-
+
+





-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+



-
-
-
+
+
+



-
-
-
+
+
+

-
-
+
+

-
+

-
-
+
+

-
+



-
+

-
+

-
+













-
-
-
-
+
+
+
+






-
+




-
+


-
+

-
-
-
+
+
+


-
-
-
+
+
+

-
+











-
-
-
-
+
+
+
+









-
-
-
+
+
+




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





-
+






-
+











-
-
+
+

-
-
+
+


-
-
+
+






-
+

-
-
+
+


-
-
+
+





-
+

-
-
+
+

-
-
+
+


-
+


-
+

-
+



-
+


-
-
+
+

-
-
+
+

-
-
+
+


-
+

-
-
+
+



-
+


-
+




-
+



-
-
-
+
+
+














-
-
+
+

-
-
+
+


-
+





-
+

-
-
+
+


-
+





-
-
+
+


-
+

-
-
+
+

-
-
+
+



-
+

-
-
+
+









-
+






-
+

-
+






-
-
+
+




-
-
-
+
+
+







-
+











-
-
+
+

-
-
+
+


-
-
-
+
+
+

-
-
+
+

-
-
-
+
+
+









-
+

-
-
+
+


-
-
-
+
+
+

-
-
+
+

-
-
-
+
+
+










-
+


-
-
-
+
+
+









-
+


-
-
-
+
+
+









-
-
-
+
+
+






-
-
-
+
+
+




-
+




-
-
-
+
+
+

-
-
+
+







-
+










-
+

-
-
+
+




-
-
+
+







-
+

-
-
+
+




-
+


-
+
+





-
-
-
+
+
+







-
+




-
+
















-
-
-
-
+
+
+
+



-
-
-
-
-
+
+
+
+
+






-
+












-
+

-
-
+
+

-
+






-
+

-
-
+
+

-
-
+
+

-
-
+
+








-
+

-
-
+
+

-
-
+
+

-
-
+
+






-
-
+
+



-
-
+
+






-
-
+
+









-
+


-
-
+
+








-
+


-
-
+
+



		[self release];
		@throw e;
	}

	abort();
}

- initWithKeyFunctions: (of_map_table_functions_t)keyFunctions_
	valueFunctions: (of_map_table_functions_t)valueFunctions_
- initWithKeyFunctions: (of_map_table_functions_t)keyFunctions
	valueFunctions: (of_map_table_functions_t)valueFunctions
{
	return [self initWithKeyFunctions: keyFunctions_
			   valueFunctions: valueFunctions_
	return [self initWithKeyFunctions: keyFunctions
			   valueFunctions: valueFunctions
				 capacity: 0];
}

- initWithKeyFunctions: (of_map_table_functions_t)keyFunctions_
	valueFunctions: (of_map_table_functions_t)valueFunctions_
	      capacity: (size_t)capacity_
- initWithKeyFunctions: (of_map_table_functions_t)keyFunctions
	valueFunctions: (of_map_table_functions_t)valueFunctions
	      capacity: (size_t)capacity
{
	self = [super init];

	@try {
		keyFunctions = keyFunctions_;
		valueFunctions = valueFunctions_;
		_keyFunctions = keyFunctions;
		_valueFunctions = valueFunctions;

#define SET_DEFAULT(var, value) \
	if (var == NULL)	\
		var = value;

		SET_DEFAULT(keyFunctions.retain, default_retain);
		SET_DEFAULT(keyFunctions.release, default_release);
		SET_DEFAULT(keyFunctions.hash, default_hash);
		SET_DEFAULT(keyFunctions.equal, default_equal);
		SET_DEFAULT(_keyFunctions.retain, default_retain);
		SET_DEFAULT(_keyFunctions.release, default_release);
		SET_DEFAULT(_keyFunctions.hash, default_hash);
		SET_DEFAULT(_keyFunctions.equal, default_equal);

		SET_DEFAULT(valueFunctions.retain, default_retain);
		SET_DEFAULT(valueFunctions.release, default_release);
		SET_DEFAULT(valueFunctions.hash, default_hash);
		SET_DEFAULT(valueFunctions.equal, default_equal);
		SET_DEFAULT(_valueFunctions.retain, default_retain);
		SET_DEFAULT(_valueFunctions.release, default_release);
		SET_DEFAULT(_valueFunctions.hash, default_hash);
		SET_DEFAULT(_valueFunctions.equal, default_equal);

#undef SET_DEFAULT

		if (capacity_ > UINT32_MAX ||
		    capacity_ > UINT32_MAX / sizeof(*buckets) ||
		    capacity_ > UINT32_MAX / 8)
		if (capacity > UINT32_MAX ||
		    capacity > UINT32_MAX / sizeof(*_buckets) ||
		    capacity > UINT32_MAX / 8)
			@throw [OFOutOfRangeException
			    exceptionWithClass: [self class]];

		for (capacity = 1; capacity < capacity_; capacity <<= 1);
		if (capacity_ * 8 / capacity >= 6)
			capacity <<= 1;
		for (_capacity = 1; _capacity < capacity; _capacity <<= 1);
		if (capacity * 8 / _capacity >= 6)
			_capacity <<= 1;

		if (capacity < MIN_CAPACITY)
			capacity = MIN_CAPACITY;
		if (_capacity < MIN_CAPACITY)
			_capacity = MIN_CAPACITY;

		minCapacity = capacity;
		_minCapacity = _capacity;

		buckets = [self allocMemoryWithSize: sizeof(*buckets)
					      count: capacity];
		_buckets = [self allocMemoryWithSize: sizeof(*_buckets)
					       count: _capacity];

		memset(buckets, 0, capacity * sizeof(*buckets));
		memset(_buckets, 0, _capacity * sizeof(*_buckets));

		if (of_hash_seed != 0)
#if defined(HAVE_ARC4RANDOM)
			rotate = arc4random() & 31;
			_rotate = arc4random() & 31;
#elif defined(HAVE_RANDOM)
			rotate = random() & 31;
			_rotate = random() & 31;
#else
			rotate = rand() & 31;
			_rotate = rand() & 31;
#endif
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	uint32_t i;

	for (i = 0; i < capacity; i++) {
		if (buckets[i] != NULL && buckets[i] != &deleted) {
			keyFunctions.release(buckets[i]->key);
			valueFunctions.release(buckets[i]->value);
	for (i = 0; i < _capacity; i++) {
		if (_buckets[i] != NULL && _buckets[i] != &deleted) {
			_keyFunctions.release(_buckets[i]->key);
			_valueFunctions.release(_buckets[i]->value);
		}
	}

	[super dealloc];
}

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

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

	mapTable = mapTable_;
	mapTable = object;

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

	for (i = 0; i < capacity; i++) {
		if (buckets[i] != NULL && buckets[i] != &deleted) {
			void *value = [mapTable valueForKey: buckets[i]->key];
	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))
			if (!_valueFunctions.equal(value, _buckets[i]->value))
				return NO;
		}
	}

	return YES;
}

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

	for (i = 0; i < capacity; i++) {
		if (buckets[i] != NULL && buckets[i] != &deleted) {
			hash += OF_ROR(buckets[i]->hash, rotate);
			hash += valueFunctions.hash(buckets[i]->value);
	for (i = 0; i < _capacity; i++) {
		if (_buckets[i] != NULL && _buckets[i] != &deleted) {
			hash += OF_ROR(_buckets[i]->hash, _rotate);
			hash += _valueFunctions.hash(_buckets[i]->value);
		}
	}

	return hash;
}

- (id)copy
{
	OFMapTable *copy = [[OFMapTable alloc]
	    initWithKeyFunctions: keyFunctions
		  valueFunctions: valueFunctions
			capacity: capacity];
	    initWithKeyFunctions: _keyFunctions
		  valueFunctions: _valueFunctions
			capacity: _capacity];

	@try {
		uint32_t i;

		for (i = 0; i < capacity; i++)
			if (buckets[i] != NULL && buckets[i] != &deleted)
				[copy OF_setValue: buckets[i]->value
					   forKey: buckets[i]->key
					     hash: OF_ROR(buckets[i]->hash,
						       rotate)];
		for (i = 0; i < _capacity; i++)
			if (_buckets[i] != NULL && _buckets[i] != &deleted)
				[copy OF_setValue: _buckets[i]->value
					   forKey: _buckets[i]->key
					     hash: OF_ROR(_buckets[i]->hash,
						       _rotate)];
	} @catch (id e) {
		[copy release];
		@throw e;
	}

	copy->minCapacity = MIN_CAPACITY;
	copy->_minCapacity = MIN_CAPACITY;

	return copy;
}

- (size_t)count
{
	return count;
	return _count;
}

- (void*)valueForKey: (void*)key
{
	uint32_t i, hash, last;

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

	hash = OF_ROL(keyFunctions.hash(key), rotate);
	last = capacity;
	hash = OF_ROL(_keyFunctions.hash(key), _rotate);
	last = _capacity;

	for (i = hash & (capacity - 1); i < last && buckets[i] != NULL; i++) {
		if (buckets[i] == &deleted)
	for (i = hash & (_capacity - 1); i < last && _buckets[i] != NULL; i++) {
		if (_buckets[i] == &deleted)
			continue;

		if (keyFunctions.equal(buckets[i]->key, key))
			return buckets[i]->value;
		if (_keyFunctions.equal(_buckets[i]->key, key))
			return _buckets[i]->value;
	}

	if (i < last)
		return nil;

	/* In case the last bucket is already used */
	last = hash & (capacity - 1);
	last = hash & (_capacity - 1);

	for (i = 0; i < last && buckets[i] != NULL; i++) {
		if (buckets[i] == &deleted)
	for (i = 0; i < last && _buckets[i] != NULL; i++) {
		if (_buckets[i] == &deleted)
			continue;

		if (keyFunctions.equal(buckets[i]->key, key))
			return buckets[i]->value;
		if (_keyFunctions.equal(_buckets[i]->key, key))
			return _buckets[i]->value;
	}

	return NULL;
}

- (void)OF_resizeForCount: (uint32_t)newCount
- (void)OF_resizeForCount: (uint32_t)count
{
	uint32_t i, fullness, newCapacity;
	struct of_map_table_bucket **newBuckets;
	uint32_t i, fullness, capacity;
	struct of_map_table_bucket **buckets;

	if (newCount > UINT32_MAX || newCount > UINT32_MAX / sizeof(*buckets) ||
	    newCount > UINT32_MAX / 8)
	if (count > UINT32_MAX || count > UINT32_MAX / sizeof(*_buckets) ||
	    count > UINT32_MAX / 8)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	fullness = newCount * 8 / capacity;
	fullness = count * 8 / _capacity;

	if (fullness >= 6)
		newCapacity = capacity << 1;
		capacity = _capacity << 1;
	else if (fullness <= 1)
		newCapacity = capacity >> 1;
		capacity = _capacity >> 1;
	else
		return;

	if (newCapacity < capacity && newCapacity < minCapacity)
	if (capacity < _capacity && capacity < _minCapacity)
		return;

	newBuckets = [self allocMemoryWithSize: sizeof(*newBuckets)
					 count: newCapacity];
	buckets = [self allocMemoryWithSize: sizeof(*buckets)
				      count: capacity];

	for (i = 0; i < newCapacity; i++)
		newBuckets[i] = NULL;
	for (i = 0; i < capacity; i++)
		buckets[i] = NULL;

	for (i = 0; i < capacity; i++) {
		if (buckets[i] != NULL && buckets[i] != &deleted) {
	for (i = 0; i < _capacity; i++) {
		if (_buckets[i] != NULL && _buckets[i] != &deleted) {
			uint32_t j, last;

			last = newCapacity;
			last = capacity;

			j = buckets[i]->hash & (newCapacity - 1);
			for (; j < last && newBuckets[j] != NULL; j++);
			j = _buckets[i]->hash & (capacity - 1);
			for (; j < last && buckets[j] != NULL; j++);

			/* In case the last bucket is already used */
			if (j >= last) {
				last = buckets[i]->hash & (newCapacity - 1);
				last = _buckets[i]->hash & (capacity - 1);

				for (j = 0; j < last &&
				    newBuckets[j] != NULL; j++);
				    buckets[j] != NULL; j++);
			}

			assert(j < last);

			newBuckets[j] = buckets[i];
			buckets[j] = _buckets[i];
		}
	}

	[self freeMemory: buckets];
	buckets = newBuckets;
	capacity = newCapacity;
	[self freeMemory: _buckets];
	_buckets = buckets;
	_capacity = capacity;
}

- (void)OF_setValue: (void*)value
	     forKey: (void*)key
	       hash: (uint32_t)hash
{
	uint32_t i, last;
	void *old;

	if (key == NULL || value == NULL)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	hash = OF_ROL(hash, rotate);
	last = capacity;
	hash = OF_ROL(hash, _rotate);
	last = _capacity;

	for (i = hash & (capacity - 1); i < last && buckets[i] != NULL; i++) {
		if (buckets[i] == &deleted)
	for (i = hash & (_capacity - 1); i < last && _buckets[i] != NULL; i++) {
		if (_buckets[i] == &deleted)
			continue;

		if (keyFunctions.equal(buckets[i]->key, key))
		if (_keyFunctions.equal(_buckets[i]->key, key))
			break;
	}

	/* In case the last bucket is already used */
	if (i >= last) {
		last = hash & (capacity - 1);
		last = hash & (_capacity - 1);

		for (i = 0; i < last && buckets[i] != NULL; i++) {
			if (buckets[i] == &deleted)
		for (i = 0; i < last && _buckets[i] != NULL; i++) {
			if (_buckets[i] == &deleted)
				continue;

			if (keyFunctions.equal(buckets[i]->key, key))
			if (_keyFunctions.equal(_buckets[i]->key, key))
				break;
		}
	}

	/* Key not in dictionary */
	if (i >= last || buckets[i] == NULL || buckets[i] == &deleted ||
	    !keyFunctions.equal(buckets[i]->key, key)) {
	if (i >= last || _buckets[i] == NULL || _buckets[i] == &deleted ||
	    !_keyFunctions.equal(_buckets[i]->key, key)) {
		struct of_map_table_bucket *bucket;

		[self OF_resizeForCount: count + 1];
		[self OF_resizeForCount: _count + 1];

		mutations++;
		last = capacity;
		_mutations++;
		last = _capacity;

		for (i = hash & (capacity - 1); i < last &&
		    buckets[i] != NULL && buckets[i] != &deleted; i++);
		for (i = hash & (_capacity - 1); i < last &&
		    _buckets[i] != NULL && _buckets[i] != &deleted; i++);

		/* In case the last bucket is already used */
		if (i >= last) {
			last = hash & (capacity - 1);
			last = hash & (_capacity - 1);

			for (i = 0; i < last && buckets[i] != NULL &&
			    buckets[i] != &deleted; i++);
			for (i = 0; i < last && _buckets[i] != NULL &&
			    _buckets[i] != &deleted; i++);
		}

		if (i >= last)
			@throw [OFOutOfRangeException
			    exceptionWithClass: [self class]];

		bucket = [self allocMemoryWithSize: sizeof(*bucket)];

		@try {
			bucket->key = keyFunctions.retain(key);
			bucket->key = _keyFunctions.retain(key);
		} @catch (id e) {
			[self freeMemory: bucket];
			@throw e;
		}

		@try {
			bucket->value = valueFunctions.retain(value);
			bucket->value = _valueFunctions.retain(value);
		} @catch (id e) {
			keyFunctions.release(key);
			_keyFunctions.release(key);
			[self freeMemory: bucket];
			@throw e;
		}

		bucket->hash = hash;

		buckets[i] = bucket;
		count++;
		_buckets[i] = bucket;
		_count++;

		return;
	}

	old = buckets[i]->value;
	buckets[i]->value = valueFunctions.retain(value);
	valueFunctions.release(old);
	old = _buckets[i]->value;
	_buckets[i]->value = _valueFunctions.retain(value);
	_valueFunctions.release(old);
}

- (void)setValue: (void*)value
	  forKey: (void*)key
{
	[self OF_setValue: value
		   forKey: key
		     hash: keyFunctions.hash(key)];
		     hash: _keyFunctions.hash(key)];
}

- (void)removeValueForKey: (void*)key
{
	uint32_t i, hash, last;

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

	hash = OF_ROL(keyFunctions.hash(key), rotate);
	last = capacity;
	hash = OF_ROL(_keyFunctions.hash(key), _rotate);
	last = _capacity;

	for (i = hash & (capacity - 1); i < last && buckets[i] != NULL; i++) {
		if (buckets[i] == &deleted)
	for (i = hash & (_capacity - 1); i < last && _buckets[i] != NULL; i++) {
		if (_buckets[i] == &deleted)
			continue;

		if (keyFunctions.equal(buckets[i]->key, key)) {
			keyFunctions.release(buckets[i]->key);
			valueFunctions.release(buckets[i]->value);
		if (_keyFunctions.equal(_buckets[i]->key, key)) {
			_keyFunctions.release(_buckets[i]->key);
			_valueFunctions.release(_buckets[i]->value);

			[self freeMemory: buckets[i]];
			buckets[i] = &deleted;
			[self freeMemory: _buckets[i]];
			_buckets[i] = &deleted;

			count--;
			mutations++;
			[self OF_resizeForCount: count];
			_count--;
			_mutations++;
			[self OF_resizeForCount: _count];

			return;
		}
	}

	if (i < last)
		return;

	/* In case the last bucket is already used */
	last = hash & (capacity - 1);
	last = hash & (_capacity - 1);

	for (i = 0; i < last && buckets[i] != NULL; i++) {
		if (buckets[i] == &deleted)
	for (i = 0; i < last && _buckets[i] != NULL; i++) {
		if (_buckets[i] == &deleted)
			continue;

		if (keyFunctions.equal(buckets[i]->key, key)) {
			keyFunctions.release(buckets[i]->key);
			valueFunctions.release(buckets[i]->value);
		if (_keyFunctions.equal(_buckets[i]->key, key)) {
			_keyFunctions.release(_buckets[i]->key);
			_valueFunctions.release(_buckets[i]->value);

			[self freeMemory: buckets[i]];
			buckets[i] = &deleted;
			[self freeMemory: _buckets[i]];
			_buckets[i] = &deleted;

			count--;
			mutations++;
			[self OF_resizeForCount: count];
			_count--;
			_mutations++;
			[self OF_resizeForCount: _count];

			return;
		}
	}
}

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

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

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

	return NO;
}

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

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

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

	return NO;
}

- (OFMapTableEnumerator*)keyEnumerator
{
	return [[[OFMapTableKeyEnumerator alloc]
	    OF_initWithMapTable: self
			buckets: buckets
		       capacity: capacity
	       mutationsPointer: &mutations] autorelease];
			buckets: _buckets
		       capacity: _capacity
	       mutationsPointer: &_mutations] autorelease];
}

- (OFMapTableEnumerator*)valueEnumerator
{
	return [[[OFMapTableValueEnumerator alloc]
	    OF_initWithMapTable: self
			buckets: buckets
		       capacity: capacity
	       mutationsPointer: &mutations] autorelease];
			buckets: _buckets
		       capacity: _capacity
	       mutationsPointer: &_mutations] autorelease];
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
			     count: (int)count_
			     count: (int)count
{
	uint32_t j = (uint32_t)state->state;
	int i;

	for (i = 0; i < count_; i++) {
		for (; j < capacity && (buckets[j] == NULL ||
		    buckets[j] == &deleted); j++);
	for (i = 0; i < count; i++) {
		for (; j < _capacity && (_buckets[j] == NULL ||
		    _buckets[j] == &deleted); j++);

		if (j < capacity) {
			objects[i] = buckets[j]->key;
		if (j < _capacity) {
			objects[i] = _buckets[j]->key;
			j++;
		} else
			break;
	}

	state->state = j;
	state->itemsPtr = objects;
	state->mutationsPtr = &mutations;
	state->mutationsPtr = &_mutations;

	return i;
}

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

	for (i = 0; i < capacity && !stop; i++) {
		if (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);
		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;
	unsigned long mutations_ = mutations;
	unsigned long mutations = _mutations;

	for (i = 0; i < capacity && !stop; i++) {
		if (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) {
		if (_buckets[i] != NULL && _buckets[i] != &deleted) {
			void *old, *new;

			new = block(buckets[i]->key, buckets[i]->value, &stop);
			new = block(_buckets[i]->key, _buckets[i]->value,
			    &stop);
			if (new == NULL)
				@throw [OFInvalidArgumentException
				    exceptionWithClass: [self class]
					      selector: _cmd];

			old = buckets[i]->value;
			buckets[i]->value = valueFunctions.retain(new);
			valueFunctions.release(old);
			old = _buckets[i]->value;
			_buckets[i]->value = _valueFunctions.retain(new);
			_valueFunctions.release(old);
		}
	}
}
#endif

- (of_map_table_functions_t)keyFunctions
{
	return keyFunctions;
	return _keyFunctions;
}

- (of_map_table_functions_t)valueFunctions
{
	return valueFunctions;
	return _valueFunctions;
}
@end

@implementation OFMapTableEnumerator
- init
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- OF_initWithMapTable: (OFMapTable*)mapTable_
	      buckets: (struct of_map_table_bucket**)buckets_
	     capacity: (uint32_t)capacity_
     mutationsPointer: (unsigned long*)mutationsPtr_
- OF_initWithMapTable: (OFMapTable*)mapTable
	      buckets: (struct of_map_table_bucket**)buckets
	     capacity: (uint32_t)capacity
     mutationsPointer: (unsigned long*)mutationsPtr
{
	self = [super init];

	mapTable = [mapTable_ retain];
	buckets = buckets_;
	capacity = capacity_;
	mutations = *mutationsPtr_;
	mutationsPtr = mutationsPtr_;
	_mapTable = [mapTable retain];
	_buckets = buckets;
	_capacity = capacity;
	_mutations = *mutationsPtr;
	_mutationsPtr = mutationsPtr;

	return self;
}

- (void)dealloc
{
	[mapTable release];
	[_mapTable release];

	[super dealloc];
}

- (void*)nextValue
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (void)reset
{
	if (*mutationsPtr != mutations)
	if (*_mutationsPtr != _mutations)
		@throw [OFEnumerationMutationException
		    exceptionWithClass: [mapTable class]
				object: mapTable];
		    exceptionWithClass: [_mapTable class]
				object: _mapTable];

	position = 0;
	_position = 0;
}
@end

@implementation OFMapTableKeyEnumerator
- (void*)nextValue
{
	if (*mutationsPtr != mutations)
	if (*_mutationsPtr != _mutations)
		@throw [OFEnumerationMutationException
		    exceptionWithClass: [mapTable class]
				object: mapTable];
		    exceptionWithClass: [_mapTable class]
				object: _mapTable];

	for (; position < capacity && (buckets[position] == NULL ||
	    buckets[position] == &deleted); position++);
	for (; _position < _capacity && (_buckets[_position] == NULL ||
	    _buckets[_position] == &deleted); _position++);

	if (position < capacity)
		return buckets[position++]->key;
	if (_position < _capacity)
		return _buckets[_position++]->key;
	else
		return NULL;
}
@end

@implementation OFMapTableValueEnumerator
- (void*)nextValue
{
	if (*mutationsPtr != mutations)
	if (*_mutationsPtr != _mutations)
		@throw [OFEnumerationMutationException
		    exceptionWithClass: [mapTable class]
				object: mapTable];
		    exceptionWithClass: [_mapTable class]
				object: _mapTable];

	for (; position < capacity && (buckets[position] == NULL ||
	    buckets[position] == &deleted); position++);
	for (; _position < _capacity && (_buckets[_position] == NULL ||
	    _buckets[_position] == &deleted); _position++);

	if (position < capacity)
		return buckets[position++]->value;
	if (_position < _capacity)
		return _buckets[_position++]->value;
	else
		return NULL;
}
@end

@implementation OFMapTableEnumeratorWrapper
- initWithEnumerator: (OFMapTableEnumerator*)enumerator_
	      object: (id)object_
- initWithEnumerator: (OFMapTableEnumerator*)enumerator
	      object: (id)object
{
	self = [super init];

	enumerator = [enumerator_ retain];
	object = [object_ retain];
	_enumerator = [enumerator retain];
	_object = [object retain];

	return self;
}

- (void)dealloc
{
	[enumerator release];
	[object release];
	[_enumerator release];
	[_object release];

	[super dealloc];
}

- (id)nextObject
{
	id ret;

	@try {
		ret = [enumerator nextValue];
		ret = [_enumerator nextValue];
	} @catch (OFEnumerationMutationException *e) {
		@throw [OFEnumerationMutationException
		    exceptionWithClass: [object class]
				object: object];
		    exceptionWithClass: [_object class]
				object: _object];
	}

	return ret;
}

- (void)reset
{
	@try {
		[enumerator reset];
		[_enumerator reset];
	} @catch (OFEnumerationMutationException *e) {
		@throw [OFEnumerationMutationException
		    exceptionWithClass: [object class]
				object: object];
		    exceptionWithClass: [_object class]
				object: _object];
	}
}
@end

Modified src/OFMutableArray_adjacent.h from [9fe27a2082] to [b092493c38].

16
17
18
19
20
21
22
23
24


25
26
16
17
18
19
20
21
22


23
24
25
26







-
-
+
+



#import "OFArray.h"

@class OFDataArray;

@interface OFMutableArray_adjacent: OFMutableArray
{
	OFDataArray   *array;
	unsigned long mutations;
	OFDataArray   *_array;
	unsigned long _mutations;
}
@end

Modified src/OFMutableArray_adjacent.m from [0727c1b670] to [65e0f02167].

35
36
37
38
39
40
41
42

43
44
45

46
47
48
49
50
51
52
53
54
55
56


57
58
59

60
61
62

63
64
65
66


67
68
69
70



71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89


90
91
92
93
94
95
96
35
36
37
38
39
40
41

42
43
44

45
46
47
48
49
50
51
52
53
54


55
56
57
58

59
60
61

62
63
64


65
66
67



68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87


88
89
90
91
92
93
94
95
96







-
+


-
+









-
-
+
+


-
+


-
+


-
-
+
+

-
-
-
+
+
+




-
+












-
-
+
+








- (void)addObject: (id)object
{
	if (object == nil)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]];

	[array addItem: &object];
	[_array addItem: &object];
	[object retain];

	mutations++;
	_mutations++;
}

- (void)insertObject: (id)object
	     atIndex: (size_t)index
{
	if (object == nil)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]];

	[array insertItem: &object
		  atIndex: index];
	[_array insertItem: &object
		   atIndex: index];
	[object retain];

	mutations++;
	_mutations++;
}

- (void)insertObjectsFromArray: (OFArray*)array_
- (void)insertObjectsFromArray: (OFArray*)array
		       atIndex: (size_t)index
{
	id *objects = [array_ objects];
	size_t i, count = [array_ count];
	id *objects = [array objects];
	size_t i, count = [array count];

	[array insertItems: objects
		   atIndex: index
		     count: count];
	[_array insertItems: objects
		    atIndex: index
		      count: count];

	for (i = 0; i < count; i++)
		[objects[i] retain];

	mutations++;
	_mutations++;
}

- (void)replaceObject: (id)oldObject
	   withObject: (id)newObject
{
	id *objects;
	size_t i, count;

	if (oldObject == nil || newObject == nil)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]];

	objects = [array items];
	count = [array count];
	objects = [_array items];
	count = [_array count];

	for (i = 0; i < count; i++) {
		if ([objects[i] isEqual: oldObject]) {
			[newObject retain];
			[objects[i] release];
			objects[i] = newObject;

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







-
+

-
+

















-
-
+
+







	id *objects;
	id oldObject;

	if (object == nil)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]];

	objects = [array items];
	objects = [_array items];

	if (index >= [array count])
	if (index >= [_array count])
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	oldObject = objects[index];
	objects[index] = [object retain];
	[oldObject release];
}

- (void)replaceObjectIdenticalTo: (id)oldObject
		      withObject: (id)newObject
{
	id *objects;
	size_t i, count;

	if (oldObject == nil || newObject == nil)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]];

	objects = [array items];
	count = [array count];
	objects = [_array items];
	count = [_array count];

	for (i = 0; i < count; i++) {
		if (objects[i] == oldObject) {
			[newObject retain];
			[objects[i] release];
			objects[i] = newObject;

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







-
-
+
+





-
-
+
+

















-
-
+
+



-
-
+
+











-
+


-
+




-
-
+
+




-
+




-
-
+
+










-
-
+
+










-
+






-
+


-
+





-
-
+
+












-
-
+
+







	id *objects;
	size_t i, count;

	if (object == nil)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]];

	objects = [array items];
	count = [array count];
	objects = [_array items];
	count = [_array count];

	for (i = 0; i < count; i++) {
		if ([objects[i] isEqual: object]) {
			object = objects[i];

			[array removeItemAtIndex: i];
			mutations++;
			[_array removeItemAtIndex: i];
			_mutations++;

			[object release];

			return;
		}
	}
}

- (void)removeObjectIdenticalTo: (id)object
{
	id *objects;
	size_t i, count;

	if (object == nil)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]];

	objects = [array items];
	count = [array count];
	objects = [_array items];
	count = [_array count];

	for (i = 0; i < count; i++) {
		if (objects[i] == object) {
			[array removeItemAtIndex: i];
			mutations++;
			[_array removeItemAtIndex: i];
			_mutations++;

			[object release];

			return;
		}
	}
}

- (void)removeObjectAtIndex: (size_t)index
{
	id object = [self objectAtIndex: index];
	[array removeItemAtIndex: index];
	[_array removeItemAtIndex: index];
	[object release];

	mutations++;
	_mutations++;
}

- (void)removeAllObjects
{
	id *objects = [array items];
	size_t i, count = [array count];
	id *objects = [_array items];
	size_t i, count = [_array count];

	for (i = 0; i < count; i++)
		[objects[i] release];

	[array removeAllItems];
	[_array removeAllItems];
}

- (void)removeObjectsInRange: (of_range_t)range
{
	id *objects = [array items], *copy;
	size_t i, count = [array count];
	id *objects = [_array items], *copy;
	size_t i, count = [_array count];

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

	copy = [self allocMemoryWithSize: sizeof(*copy)
				   count: range.length];
	memcpy(copy, objects + range.location, range.length * sizeof(id));

	@try {
		[array removeItemsInRange: range];
		mutations++;
		[_array removeItemsInRange: range];
		_mutations++;

		for (i = 0; i < range.length; i++)
			[copy[i] release];
	} @finally {
		[self freeMemory: copy];
	}
}

- (void)removeLastObject
{
	size_t count = [array count];
	size_t count = [_array count];
	id object;

	if (count == 0)
		return;

	object = [self objectAtIndex: count - 1];
	[array removeLastItem];
	[_array removeLastItem];
	[object release];

	mutations++;
	_mutations++;
}

- (void)exchangeObjectAtIndex: (size_t)index1
	    withObjectAtIndex: (size_t)index2
{
	id *objects = [array items];
	size_t count = [array count];
	id *objects = [_array items];
	size_t count = [_array count];
	id tmp;

	if (index1 >= count || index2 >= count)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	tmp = objects[index1];
	objects[index1] = objects[index2];
	objects[index2] = tmp;
}

- (void)reverse
{
	id *objects = [array items];
	size_t i, j, count = [array count];
	id *objects = [_array items];
	size_t i, j, count = [_array count];

	if (count == 0 || count == 1)
		return;

	for (i = 0, j = count - 1; i < j; i++, j--) {
		id tmp = objects[i];
		objects[i] = objects[j];
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
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







-
+








-
+





-
-
+
+

-
+


-
+










-
-
+
+

-
+




-
+







	 * does not reimplement it. As OFArray_adjacent does not reimplement it
	 * either, this is fine.
	 */
	int ret = [super countByEnumeratingWithState: state
					     objects: objects
					       count: count];

	state->mutationsPtr = &mutations;
	state->mutationsPtr = &_mutations;

	return ret;
}

- (OFEnumerator*)objectEnumerator
{
	return [[[OFArrayEnumerator alloc]
	    initWithArray: self
	     mutationsPtr: &mutations] autorelease];
	     mutationsPtr: &_mutations] autorelease];
}

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

	for (i = 0; i < count && !stop; i++) {
		if (mutations != mutations_)
		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];
	id *objects = [_array items];
	size_t i, count = [_array count];
	BOOL stop = NO;
	unsigned long mutations_ = mutations;
	unsigned long mutations = _mutations;

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

		if (mutations != mutations_)
		if (_mutations != mutations)
			@throw [OFEnumerationMutationException
			    exceptionWithClass: [self class]
					object: self];

		newObject = block(objects[i], i, &stop);

		if (newObject == nil)

Modified src/OFMutableDictionary_hashtable.h from [e5615bdea0] to [6850c24dfd].

16
17
18
19
20
21
22
23

24
25
16
17
18
19
20
21
22

23
24
25







-
+



#import "OFDictionary.h"

@class OFMapTable;

@interface OFMutableDictionary_hashtable: OFMutableDictionary
{
	OFMapTable *mapTable;
	OFMapTable *_mapTable;
}
@end

Modified src/OFMutableDictionary_hashtable.m from [612f34358f] to [808b6f21ab].

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







-
-
+
+




-
+






-
+







	if (self == [OFMutableDictionary_hashtable class])
		[self inheritMethodsFromClass: [OFDictionary_hashtable class]];
}

- (void)setObject: (id)object
	   forKey: (id)key
{
	[mapTable setValue: object
		    forKey: key];
	[_mapTable setValue: object
		     forKey: key];
}

- (void)removeObjectForKey: (id)key
{
	[mapTable removeValueForKey: key];
	[_mapTable removeValueForKey: key];
}

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

Modified src/OFMutableSet_hashtable.h from [429d954c17] to [7dc73c5a43].

16
17
18
19
20
21
22
23

24
25
16
17
18
19
20
21
22

23
24
25







-
+



#import "OFMutableSet.h"

@class OFMapTable;

@interface OFMutableSet_hashtable: OFMutableSet
{
	OFMapTable *mapTable;
	OFMapTable *_mapTable;
}
@end

Modified src/OFMutableSet_hashtable.m from [be12d7d85e] to [f03acdef2a].

25
26
27
28
29
30
31
32
33


34
35
36
37
38

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


32
33
34
35
36
37

38
39
40
41
42
43
44
45







-
-
+
+




-
+







{
	if (self == [OFMutableSet_hashtable class])
		[self inheritMethodsFromClass: [OFSet_hashtable class]];
}

- (void)addObject: (id)object
{
	[mapTable setValue: (void*)1
		    forKey: object];
	[_mapTable setValue: (void*)1
		     forKey: object];
}

- (void)removeObject: (id)object
{
	[mapTable removeValueForKey: object];
	[_mapTable removeValueForKey: object];
}

- (void)makeImmutable
{
	object_setClass(self, [OFSet_hashtable class]);
}
@end

Modified src/OFMutableString_UTF8.h from [24f2d8f550] to [7d75f5d24d].

16
17
18
19
20
21
22
23
24


25
26
16
17
18
19
20
21
22


23
24
25
26







-
-
+
+



#import "OFMutableString.h"
#import "OFString_UTF8.h"

@interface OFMutableString_UTF8: OFMutableString
{
@public
	struct of_string_utf8_ivars *restrict s;
	struct of_string_utf8_ivars s_store;
	struct of_string_utf8_ivars *restrict _s;
	struct of_string_utf8_ivars _storage;
}
@end

Modified src/OFMutableString_UTF8.m from [3edda5e667] to [8a8377795b].

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







-
+





-
+

-
+





-
+











-
-
+
+












-
+













-
-
+
+







{
	of_unichar_t *unicodeString;
	size_t unicodeLen, newCStringLength;
	size_t i, j;
	char *newCString;
	BOOL isStart = YES;

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

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

		s->hashed = NO;
		_s->hashed = NO;

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

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

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

		return;
	}

	unicodeLen = [self length];
	unicodeString = [self allocMemoryWithSize: sizeof(of_unichar_t)
					    count: unicodeLen];

	i = j = 0;
	newCStringLength = 0;

	while (i < s->cStringLength) {
	while (i < _s->cStringLength) {
		const of_unichar_t *const *table;
		size_t tableSize;
		of_unichar_t c;
		size_t cLen;

		if (isStart) {
			table = startTable;
			tableSize = middleTableSize;
		} else {
			table = middleTable;
			tableSize = middleTableSize;
		}

		cLen = of_string_utf8_decode(s->cString + i,
		    s->cStringLength - i, &c);
		cLen = of_string_utf8_decode(_s->cString + i,
		    _s->cStringLength - i, &c);

		if (cLen == 0 || c > 0x10FFFF) {
			[self freeMemory: unicodeString];
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];
		}

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







-
-
-
-
+
+
+
+














-
-
-
+
+
+

-
+



-
-
-
+
+
+







-
-
+
+



-
+


-
+

-
-
-
+
+
+

-
-
-
-
+
+
+
+

-
-
-
+
+
+


-
+

-
-
-
-
+
+
+
+

-
-
-
+
+
+


-
-
+
+
+



















-
+






-
-
-
-
-
+
+
+
+
+
+

-
-
+
+














-
+






-
-
-
-
-
+
+
+
+
+

-
-
+
+

-
+







		j += d;
	}

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

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

	/*
	 * Even though cStringLength can change, length cannot, therefore no
	 * need to change it.
	 */
}

- (void)setCharacter: (of_unichar_t)character
	     atIndex: (size_t)index
{
	char buffer[4];
	of_unichar_t c;
	size_t lenNew, lenOld;

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

	if (index > 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->cString[index] = character;
	if (!(character & 0x80) && !(_s->cString[index] & 0x80)) {
		_s->hashed = NO;
		_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)
	if ((lenOld = of_string_utf8_decode(_s->cString + index,
	    _s->cStringLength - index, &c)) == 0)
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];

	s->hashed = NO;
	_s->hashed = NO;

	if (lenNew == lenOld)
		memcpy(s->cString + index, buffer, lenNew);
		memcpy(_s->cString + index, buffer, lenNew);
	else if (lenNew > lenOld) {
		s->cString = [self resizeMemory: s->cString
					   size: s->cStringLength -
						 lenOld + lenNew + 1];
		_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);
		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';
		_s->cStringLength -= lenOld;
		_s->cStringLength += lenNew;
		_s->cString[_s->cStringLength] = '\0';

		if (character & 0x80)
			s->isUTF8 = YES;
			_s->isUTF8 = YES;
	} else if (lenNew < lenOld) {
		memmove(s->cString + index + lenNew,
		    s->cString + index + lenOld,
		    s->cStringLength - index - lenOld);
		memcpy(s->cString + index, buffer, lenNew);
		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';
		_s->cStringLength -= lenOld;
		_s->cStringLength += lenNew;
		_s->cString[_s->cStringLength] = '\0';

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

- (void)appendUTF8String: (const char*)UTF8String
{
	size_t UTF8StringLength = strlen(UTF8String);
	size_t length;

	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 = YES;
		break;
	case -1:
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];
	}

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

	s->cStringLength += UTF8StringLength;
	s->length += length;
	_s->cStringLength += UTF8StringLength;
	_s->length += length;
}

- (void)appendUTF8String: (const char*)UTF8String
		  length: (size_t)UTF8StringLength
{
	size_t length;

	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 = YES;
		break;
	case -1:
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];
	}

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

	s->cStringLength += UTF8StringLength;
	s->length += length;
	_s->cStringLength += UTF8StringLength;
	_s->length += length;

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

- (void)appendCString: (const char*)cString
	     encoding: (of_string_encoding_t)encoding
{
	return [self appendCString: cString
			  encoding: encoding
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
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







-
-
-
-
-
+
+
+
+
+


-
-
+
+

-
+



-
-
+
+

-
+







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

	UTF8StringLength = [string UTF8StringLength];

	s->hashed = NO;
	s->cString = [self resizeMemory: s->cString
				   size: s->cStringLength +
					 UTF8StringLength + 1];
	memcpy(s->cString + s->cStringLength, [string UTF8String],
	_s->hashed = NO;
	_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->cStringLength += UTF8StringLength;
	_s->length += [string length];

	s->cString[s->cStringLength] = 0;
	_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;
		if (((OFString_UTF8*)string)->_s->isUTF8)
			_s->isUTF8 = YES;
	} else
		s->isUTF8 = YES;
		_s->isUTF8 = YES;
}

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

433
434
435
436
437
438
439
440
441
442
443




444
445
446


447
448
449

450
451
452
453
454
455
456
435
436
437
438
439
440
441




442
443
444
445
446


447
448
449
450

451
452
453
454
455
456
457
458







-
-
-
-
+
+
+
+

-
-
+
+


-
+







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

		tmp[j] = '\0';

		s->hashed = NO;
		s->cString = [self resizeMemory: s->cString
					   size: s->cStringLength + j + 1];
		memcpy(s->cString + s->cStringLength, tmp, j + 1);
		_s->hashed = NO;
		_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;
		_s->cStringLength += j;
		_s->length += length;

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

- (void)appendFormat: (OFConstantString*)format
	   arguments: (va_list)arguments
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
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
550
551
552



553
554
555
556
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
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
816




817
818
819
820


821
822
823


824
825
826
827


828
829
830
831
832
833
834
835
836
837
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
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
550
551



552
553
554
555
556
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
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




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







-
+


-
+

-
-
-
+
+
+


-
+


-
+

-
+



-
+




-
-
+
+




-
-
-
-
+
+
+
+






-
-
+
+




-
-
-
-
+
+
+
+






-
-
+
+




-
-
-
-
+
+
+
+

-
-
-
+
+
+
















-
+



-
-
-
+
+
+

-
-
-
-
+
+
+
+

-
-
-
+
+
+

-
+

-
-
+
+



-
-
+
+

-
+







-
+


-
-
-
-
-
+
+
+
+
+


+
-
-
-
-
-
+
+
+
+
+


-
-
+
+












-
+


-
+

-
-
-
-
-
+
+
+
+
+


-
+

-
-
-
+
+
+

-
-
-
+
+
+

-
+

-
-
+
+


















-
-
-
+
+
+

-
-
+
+







-
+



-
+











-
+














-
+




-
-
-
+
+
+


-
-
-
-
-
+
+
+
+
+






-
-
-
-
+
+
+
+


-
-
-
+
+
+

-
-
+
+


-
-
+
+










-
+


-
+








-
-
+
+


-
-
+
+










-
+


-
+








-
-
+
+

-
-
-
-
+
+
+
+


-
-
+
+

-
-
+
+


-
-
+
+










	}
}

- (void)reverse
{
	size_t i, j;

	s->hashed = NO;
	_s->hashed = NO;

	/* We reverse all bytes and restore UTF-8 later, if necessary */
	for (i = 0, j = s->cStringLength - 1; i < s->cStringLength / 2;
	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];
		_s->cString[i] ^= _s->cString[j];
		_s->cString[j] ^= _s->cString[i];
		_s->cString[i] ^= _s->cString[j];
	}

	if (!s->isUTF8)
	if (!_s->isUTF8)
		return;

	for (i = 0; i < s->cStringLength; i++) {
	for (i = 0; i < _s->cStringLength; i++) {
		/* ASCII */
		if OF_LIKELY (!(s->cString[i] & 0x80))
		if OF_LIKELY (!(_s->cString[i] & 0x80))
			continue;

		/* A start byte can't happen first as we reversed everything */
		if OF_UNLIKELY (s->cString[i] & 0x40)
		if OF_UNLIKELY (_s->cString[i] & 0x40)
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];

		/* Next byte must not be ASCII */
		if OF_UNLIKELY (s->cStringLength < i + 1 ||
		    !(s->cString[i + 1] & 0x80))
		if OF_UNLIKELY (_s->cStringLength < i + 1 ||
		    !(_s->cString[i + 1] & 0x80))
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];

		/* Next byte is the start byte */
		if OF_LIKELY (s->cString[i + 1] & 0x40) {
			s->cString[i] ^= s->cString[i + 1];
			s->cString[i + 1] ^= s->cString[i];
			s->cString[i] ^= s->cString[i + 1];
		if OF_LIKELY (_s->cString[i + 1] & 0x40) {
			_s->cString[i] ^= _s->cString[i + 1];
			_s->cString[i + 1] ^= _s->cString[i];
			_s->cString[i] ^= _s->cString[i + 1];

			i++;
			continue;
		}

		/* Second next byte must not be ASCII */
		if OF_UNLIKELY (s->cStringLength < i + 2 ||
		    !(s->cString[i + 2] & 0x80))
		if OF_UNLIKELY (_s->cStringLength < i + 2 ||
		    !(_s->cString[i + 2] & 0x80))
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];

		/* Second next byte is the start byte */
		if OF_LIKELY (s->cString[i + 2] & 0x40) {
			s->cString[i] ^= s->cString[i + 2];
			s->cString[i + 2] ^= s->cString[i];
			s->cString[i] ^= s->cString[i + 2];
		if OF_LIKELY (_s->cString[i + 2] & 0x40) {
			_s->cString[i] ^= _s->cString[i + 2];
			_s->cString[i + 2] ^= _s->cString[i];
			_s->cString[i] ^= _s->cString[i + 2];

			i += 2;
			continue;
		}

		/* Third next byte must not be ASCII */
		if OF_UNLIKELY (s->cStringLength < i + 3 ||
		    !(s->cString[i + 3] & 0x80))
		if OF_UNLIKELY (_s->cStringLength < i + 3 ||
		    !(_s->cString[i + 3] & 0x80))
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];

		/* Third next byte is the start byte */
		if OF_LIKELY (s->cString[i + 3] & 0x40) {
			s->cString[i] ^= s->cString[i + 3];
			s->cString[i + 3] ^= s->cString[i];
			s->cString[i] ^= s->cString[i + 3];
		if OF_LIKELY (_s->cString[i + 3] & 0x40) {
			_s->cString[i] ^= _s->cString[i + 3];
			_s->cString[i + 3] ^= _s->cString[i];
			_s->cString[i] ^= _s->cString[i + 3];

			s->cString[i + 1] ^= s->cString[i + 2];
			s->cString[i + 2] ^= s->cString[i + 1];
			s->cString[i + 1] ^= s->cString[i + 2];
			_s->cString[i + 1] ^= _s->cString[i + 2];
			_s->cString[i + 2] ^= _s->cString[i + 1];
			_s->cString[i + 1] ^= _s->cString[i + 2];

			i += 3;
			continue;
		}

		/* UTF-8 does not allow more than 4 bytes per character */
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];
	}
}

- (void)insertString: (OFString*)string
	     atIndex: (size_t)index
{
	size_t newCStringLength;

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

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

	newCStringLength = s->cStringLength + [string UTF8StringLength];
	s->hashed = NO;
	s->cString = [self resizeMemory: s->cString
				   size: newCStringLength + 1];
	newCStringLength = _s->cStringLength + [string UTF8StringLength];
	_s->hashed = NO;
	_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],
	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->cString[newCStringLength] = '\0';

	s->cStringLength = newCStringLength;
	s->length += [string length];
	_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;
		if (((OFString_UTF8*)string)->_s->isUTF8)
			_s->isUTF8 = YES;
	} else
		s->isUTF8 = YES;
		_s->isUTF8 = YES;
}

- (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)
	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);
	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,
	memmove(s->cString + start, s->cString + end, s->cStringLength - end);
	s->hashed = NO;
	s->length -= range.length;
	s->cStringLength -= end - start;
	s->cString[s->cStringLength] = 0;
	    _s->cStringLength - end);
	_s->hashed = NO;
	_s->length -= range.length;
	_s->cStringLength -= end - start;
	_s->cString[_s->cStringLength] = 0;

	@try {
		s->cString = [self resizeMemory: s->cString
					   size: s->cStringLength + 1];
		_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)replaceCharactersInRange: (of_range_t)range
		      withString: (OFString*)replacement
{
	size_t start = range.location;
	size_t end = range.location + range.length;
	size_t newCStringLength, newLength;

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

	newLength = s->length - range.length + [replacement length];
	newLength = _s->length - range.length + [replacement length];

	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);
	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);
	}

	newCStringLength = s->cStringLength - (end - start) +
	newCStringLength = _s->cStringLength - (end - start) +
	    [replacement UTF8StringLength];
	s->hashed = NO;
	s->cString = [self resizeMemory: s->cString
				   size: newCStringLength + 1];
	_s->hashed = NO;
	_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],
	memmove(_s->cString + start + [replacement UTF8StringLength],
	    _s->cString + end, _s->cStringLength - end);
	memcpy(_s->cString + start, [replacement UTF8String],
	    [replacement UTF8StringLength]);
	s->cString[newCStringLength] = '\0';
	_s->cString[newCStringLength] = '\0';

	s->cStringLength = newCStringLength;
	s->length = newLength;
	_s->cStringLength = newCStringLength;
	_s->length = newLength;
}

- (void)replaceOccurrencesOfString: (OFString*)string
			withString: (OFString*)replacement
			   options: (int)options
			     range: (of_range_t)range
{
	const char *searchString = [string UTF8String];
	const char *replacementString = [replacement UTF8String];
	size_t searchLength = [string UTF8StringLength];
	size_t replacementLength = [replacement UTF8StringLength];
	size_t i, last, newCStringLength, newLength;
	char *newCString;

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

	if (s->isUTF8) {
		range.location = of_string_utf8_get_position(s->cString,
		    range.location, s->cStringLength);
	if (_s->isUTF8) {
		range.location = of_string_utf8_get_position(_s->cString,
		    range.location, _s->cStringLength);
		range.length = of_string_utf8_get_position(
		    s->cString + range.location, range.length,
		    s->cStringLength - range.location);
		    _s->cString + range.location, range.length,
		    _s->cStringLength - range.location);
	}

	if ([string UTF8StringLength] > range.length)
		return;

	newCString = NULL;
	newCStringLength = 0;
	newLength = s->length;
	newLength = _s->length;

	last = 0;
	for (i = range.location; i <= range.length - searchLength; i++) {
		if (memcmp(s->cString + i, searchString, searchLength))
		if (memcmp(_s->cString + i, searchString, searchLength))
			continue;

		@try {
			newCString = [self
			    resizeMemory: newCString
				    size: newCStringLength + i - last +
					  replacementLength + 1];
		} @catch (id e) {
			[self freeMemory: newCString];
			@throw e;
		}
		memcpy(newCString + newCStringLength, s->cString + last,
		memcpy(newCString + newCStringLength, _s->cString + last,
		    i - last);
		memcpy(newCString + newCStringLength + i - last,
		    replacementString, replacementLength);

		newCStringLength += i - last + replacementLength;
		newLength = newLength - [string length] + [replacement length];

		i += searchLength - 1;
		last = i + 1;
	}

	@try {
		newCString = [self resizeMemory: newCString
					   size: newCStringLength +
						 s->cStringLength - last + 1];
						 _s->cStringLength - last + 1];
	} @catch (id e) {
		[self freeMemory: newCString];
		@throw e;
	}
	memcpy(newCString + newCStringLength, s->cString + last,
	    s->cStringLength - last);
	newCStringLength += s->cStringLength - last;
	memcpy(newCString + newCStringLength, _s->cString + last,
	    _s->cStringLength - last);
	newCStringLength += _s->cStringLength - last;
	newCString[newCStringLength] = 0;

	[self freeMemory: s->cString];
	s->hashed = NO;
	s->cString = newCString;
	s->cStringLength = newCStringLength;
	s->length = newLength;
	[self freeMemory: _s->cString];
	_s->hashed = NO;
	_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')
	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->cStringLength -= i;
	s->length -= i;
	_s->hashed = NO;
	_s->cStringLength -= i;
	_s->length -= i;

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

	@try {
		s->cString = [self resizeMemory: s->cString
					   size: s->cStringLength + 1];
		_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 = NO;

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

		*p = '\0';
		d++;
	}

	s->cStringLength -= d;
	s->length -= d;
	_s->cStringLength -= d;
	_s->length -= d;

	@try {
		s->cString = [self resizeMemory: s->cString
					   size: s->cStringLength + 1];
		_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)deleteEnclosingWhitespaces
{
	size_t d, i;
	char *p;

	s->hashed = NO;
	_s->hashed = NO;

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

		*p = '\0';
		d++;
	}

	s->cStringLength -= d;
	s->length -= d;
	_s->cStringLength -= d;
	_s->length -= d;

	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')
	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->cStringLength -= i;
	s->length -= i;
	_s->cStringLength -= i;
	_s->length -= i;

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

	@try {
		s->cString = [self resizeMemory: s->cString
					   size: s->cStringLength + 1];
		_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)makeImmutable
{
	object_setClass(self, [OFString_UTF8 class]);
}
@end

Modified src/OFMutex.h from [241248bc92] to [4850473658].

20
21
22
23
24
25
26
27
28
29



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



27
28
29
30
31
32
33
34
35
36
37
38







-
-
-
+
+
+









#import "threading.h"

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

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

Modified src/OFMutex.m from [03afd45a89] to [d5036265a2].

32
33
34
35
36
37
38
39

40
41
42
43
44
45

46
47
48
49
50
51
52

53
54
55
56
57
58
59

60
61
62
63
64

65
66
67
68
69

70
71

72
73
74
75
76

77
78
79
80
81

82
83
84


85
86
87
88
89
90


91
92
93
94
95

96
97
98
99
32
33
34
35
36
37
38

39
40
41
42
43
44

45
46
47
48
49
50
51

52
53
54
55
56
57
58

59
60
61
62
63

64
65
66
67
68

69
70

71
72
73
74
75

76
77
78
79
80

81
82
83

84
85
86
87
88
89


90
91
92
93
94
95

96
97
98
99
100







-
+





-
+






-
+






-
+




-
+




-
+

-
+




-
+




-
+


-
+
+




-
-
+
+




-
+




	return [[[self alloc] init] autorelease];
}

- init
{
	self = [super init];

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

	initialized = YES;
	_initialized = YES;

	return self;
}

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

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

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

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

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

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

	return [OFString stringWithFormat: @"<%@: %@>", [self className], name];
	return [OFString stringWithFormat: @"<%@: %@>",
					   [self className], _name];
}

- (void)dealloc
{
	if (initialized)
		if (!of_mutex_free(&mutex))
	if (_initialized)
		if (!of_mutex_free(&_mutex))
			@throw [OFStillLockedException
			    exceptionWithClass: [self class]
					  lock: self];

	[name release];
	[_name release];

	[super dealloc];
}
@end

Modified src/OFNumber.h from [c711cafca0] to [b3a58136c1].

92
93
94
95
96
97
98
99
100
101
102




103
104
105
106
107
108
109
92
93
94
95
96
97
98




99
100
101
102
103
104
105
106
107
108
109







-
-
-
-
+
+
+
+







 * @brief Provides a way to store a number in an object.
 */
@interface OFNumber: OFObject <OFCopying, OFComparing, OFSerialization,
    OFJSONRepresentation>
{
	union of_number_value {
		BOOL	       bool_;
		signed char    char_;
		signed short   short_;
		signed int     int_;
		signed long    long_;
		signed char    schar;
		signed short   sshort;
		signed int     sint;
		signed long    slong;
		unsigned char  uchar;
		unsigned short ushort;
		unsigned int   uint;
		unsigned long  ulong;
		int8_t	       int8;
		int16_t	       int16;
		int32_t	       int32;
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
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







-
-
+
+

















-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+







		intmax_t       intmax;
		uintmax_t      uintmax;
		ptrdiff_t      ptrdiff;
		intptr_t       intptr;
		uintptr_t      uintptr;
		float	       float_;
		double	       double_;
	} value;
	of_number_type_t type;
	} _value;
	of_number_type_t _type;
}

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

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

/*!
 * @brief Creates a new OFNumber with the specified signed char.
 *
 * @param char_ A signed char which the OFNumber should contain
 * @param schar A signed char which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithChar: (signed char)char_;
+ (instancetype)numberWithChar: (signed char)schar;

/*!
 * @brief Creates a new OFNumber with the specified signed short.
 *
 * @param short_ A signed short which the OFNumber should contain
 * @param sshort A signed short which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithShort: (signed short)short_;
+ (instancetype)numberWithShort: (signed short)sshort;

/*!
 * @brief Creates a new OFNumber with the specified signed int.
 *
 * @param int_ A signed int which the OFNumber should contain
 * @param sint A signed int which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt: (signed int)int_;
+ (instancetype)numberWithInt: (signed int)sint;

/*!
 * @brief Creates a new OFNumber with the specified signed long.
 *
 * @param long_ A signed long which the OFNumber should contain
 * @param slong A signed long which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithLong: (signed long)long_;
+ (instancetype)numberWithLong: (signed long)slong;

/*!
 * @brief Creates a new OFNumber with the specified unsigned char.
 *
 * @param uchar An unsigned char which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
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
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







-
+


-
+





-
+


-
+





-
+


-
+





-
+


-
+







 */
- initWithBool: (BOOL)bool_;

/*!
 * @brief Initializes an already allocated OFNumber with the specified signed
 *	  char.
 *
 * @param char_ A signed char which the OFNumber should contain
 * @param schar A signed char which the OFNumber should contain
 * @return An initialized OFNumber
 */
- initWithChar: (signed char)char_;
- initWithChar: (signed char)schar;

/*!
 * @brief Initializes an already allocated OFNumber with the specified signed
 *	  short.
 *
 * @param short_ A signed short which the OFNumber should contain
 * @param sshort A signed short which the OFNumber should contain
 * @return An initialized OFNumber
 */
- initWithShort: (signed short)short_;
- initWithShort: (signed short)sshort;

/*!
 * @brief Initializes an already allocated OFNumber with the specified signed
 *	  int.
 *
 * @param int_ A signed int which the OFNumber should contain
 * @param sint A signed int which the OFNumber should contain
 * @return An initialized OFNumber
 */
- initWithInt: (signed int)int_;
- initWithInt: (signed int)sint;

/*!
 * @brief Initializes an already allocated OFNumber with the specified signed
 *	  long.
 *
 * @param long_ A signed long which the OFNumber should contain
 * @param slong A signed long which the OFNumber should contain
 * @return An initialized OFNumber
 */
- initWithLong: (signed long)long_;
- initWithLong: (signed long)slong;

/*!
 * @brief Initializes an already allocated OFNumber with the specified unsigned
 *	  char.
 *
 * @param uchar An unsigned char which the OFNumber should contain
 * @return An initialized OFNumber

Modified src/OFNumber.m from [ae195c0c97] to [df1e685381].

28
29
30
31
32
33
34
35

36
37

38
39

40
41

42
43

44
45

46
47

48
49

50
51

52
53

54
55

56
57

58
59

60
61

62
63

64
65

66
67

68
69

70
71

72
73

74
75

76
77

78
79

80
81

82
83

84
85

86
87

88
89
90
91
92
93

94
95
96

97
98
99

100
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
28
29
30
31
32
33
34

35
36

37
38

39
40

41
42

43
44

45
46

47
48

49
50

51
52

53
54

55
56

57
58

59
60

61
62

63
64

65
66

67
68

69
70

71
72

73
74

75
76

77
78

79
80

81
82

83
84

85
86

87
88
89
90
91
92

93
94
95

96
97
98

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







-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+





-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+





-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+










-
+

-
+

-
+

-
+

-
+

-
+


-
+


-
+

-
+


-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+











-
+

-
+


-
+

-
+


-
+

-
+


-
+

-
+







#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"

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

#define RETURN_AS(t)							\
	switch (type) {							\
	switch (_type) {						\
	case OF_NUMBER_BOOL:						\
		return (t)value.bool_;					\
		return (t)_value.bool_;					\
	case OF_NUMBER_CHAR:						\
		return (t)value.char_;					\
		return (t)_value.schar;					\
	case OF_NUMBER_SHORT:						\
		return (t)value.short_;					\
		return (t)_value.sshort;				\
	case OF_NUMBER_INT:						\
		return (t)value.int_;					\
		return (t)_value.sint;					\
	case OF_NUMBER_LONG:						\
		return (t)value.long_;					\
		return (t)_value.slong;					\
	case OF_NUMBER_UCHAR:						\
		return (t)value.uchar;					\
		return (t)_value.uchar;					\
	case OF_NUMBER_USHORT:						\
		return (t)value.ushort;					\
		return (t)_value.ushort;				\
	case OF_NUMBER_UINT:						\
		return (t)value.uint;					\
		return (t)_value.uint;					\
	case OF_NUMBER_ULONG:						\
		return (t)value.ulong;					\
		return (t)_value.ulong;					\
	case OF_NUMBER_INT8:						\
		return (t)value.int8;					\
		return (t)_value.int8;					\
	case OF_NUMBER_INT16:						\
		return (t)value.int16;					\
		return (t)_value.int16;					\
	case OF_NUMBER_INT32:						\
		return (t)value.int32;					\
		return (t)_value.int32;					\
	case OF_NUMBER_INT64:						\
		return (t)value.int64;					\
		return (t)_value.int64;					\
	case OF_NUMBER_UINT8:						\
		return (t)value.uint8;					\
		return (t)_value.uint8;					\
	case OF_NUMBER_UINT16:						\
		return (t)value.uint16;					\
		return (t)_value.uint16;				\
	case OF_NUMBER_UINT32:						\
		return (t)value.uint32;					\
		return (t)_value.uint32;				\
	case OF_NUMBER_UINT64:						\
		return (t)value.uint64;					\
		return (t)_value.uint64;				\
	case OF_NUMBER_SIZE:						\
		return (t)value.size;					\
		return (t)_value.size;					\
	case OF_NUMBER_SSIZE:						\
		return (t)value.ssize;					\
		return (t)_value.ssize;					\
	case OF_NUMBER_INTMAX:						\
		return (t)value.intmax;					\
		return (t)_value.intmax;				\
	case OF_NUMBER_UINTMAX:						\
		return (t)value.uintmax;				\
		return (t)_value.uintmax;				\
	case OF_NUMBER_PTRDIFF:						\
		return (t)value.ptrdiff;				\
		return (t)_value.ptrdiff;				\
	case OF_NUMBER_INTPTR:						\
		return (t)value.intptr;					\
		return (t)_value.intptr;				\
	case OF_NUMBER_UINTPTR:						\
		return (t)value.uintptr;				\
		return (t)_value.uintptr;				\
	case OF_NUMBER_FLOAT:						\
		return (t)value.float_;					\
		return (t)_value.float_;				\
	case OF_NUMBER_DOUBLE:						\
		return (t)value.double_;				\
		return (t)_value.double_;				\
	default:							\
		@throw [OFInvalidFormatException			\
		    exceptionWithClass: [self class]];			\
	}
#define CALCULATE(o, n)							\
	switch (type) {							\
	switch (_type) {						\
	case OF_NUMBER_BOOL:						\
		return [OFNumber numberWithBool:			\
		    value.bool_ o [n boolValue]];			\
		    _value.bool_ o [n boolValue]];			\
	case OF_NUMBER_CHAR:						\
		return [OFNumber numberWithChar:			\
		    value.char_ o [n charValue]];			\
		    _value.schar o [n charValue]];			\
	case OF_NUMBER_SHORT:						\
		return [OFNumber numberWithShort:			\
		    value.short_ o [n shortValue]];			\
		    _value.sshort o [n shortValue]];			\
	case OF_NUMBER_INT:						\
		return [OFNumber numberWithInt:				\
		    value.int_ o [n intValue]];				\
		    _value.sint o [n intValue]];			\
	case OF_NUMBER_LONG:						\
		return [OFNumber numberWithLong:			\
		    value.long_ o [n longValue]];			\
		    _value.slong o [n longValue]];			\
	case OF_NUMBER_UCHAR:						\
		return [OFNumber numberWithUnsignedChar:		\
		    value.uchar o [n unsignedCharValue]];		\
		    _value.uchar o [n unsignedCharValue]];		\
	case OF_NUMBER_USHORT:						\
		return [OFNumber numberWithUnsignedShort:		\
		    value.ushort o [n unsignedShortValue]];		\
		    _value.ushort o [n unsignedShortValue]];		\
	case OF_NUMBER_UINT:						\
		return [OFNumber numberWithUnsignedInt:			\
		    value.uint o [n unsignedIntValue]];			\
		    _value.uint o [n unsignedIntValue]];		\
	case OF_NUMBER_ULONG:						\
		return [OFNumber numberWithUnsignedLong:		\
		    value.ulong o [n unsignedLongValue]];		\
		    _value.ulong o [n unsignedLongValue]];		\
	case OF_NUMBER_INT8:						\
		return [OFNumber numberWithInt8:			\
		    value.int8 o [n int8Value]];			\
		    _value.int8 o [n int8Value]];			\
	case OF_NUMBER_INT16:						\
		return [OFNumber numberWithInt16:			\
		    value.int16 o [n int16Value]];			\
		    _value.int16 o [n int16Value]];			\
	case OF_NUMBER_INT32:						\
		return [OFNumber numberWithInt32:			\
		    value.int32 o [n int32Value]];			\
		    _value.int32 o [n int32Value]];			\
	case OF_NUMBER_INT64:						\
		return [OFNumber numberWithInt64:			\
		    value.int64 o [n int64Value]];			\
		    _value.int64 o [n int64Value]];			\
	case OF_NUMBER_UINT8:						\
		return [OFNumber numberWithUInt8:			\
		    value.uint8 o [n uInt8Value]];			\
		    _value.uint8 o [n uInt8Value]];			\
	case OF_NUMBER_UINT16:						\
		return [OFNumber numberWithUInt16:			\
		    value.uint16 o [n uInt16Value]];			\
		    _value.uint16 o [n uInt16Value]];			\
	case OF_NUMBER_UINT32:						\
		return [OFNumber numberWithUInt32:			\
		    value.uint32 o [n uInt32Value]];			\
		    _value.uint32 o [n uInt32Value]];			\
	case OF_NUMBER_UINT64:						\
		return [OFNumber numberWithUInt64:			\
		    value.uint64 o [n uInt64Value]];			\
		    _value.uint64 o [n uInt64Value]];			\
	case OF_NUMBER_SIZE:						\
		return [OFNumber numberWithSize:			\
		    value.size o [n sizeValue]];			\
		    _value.size o [n sizeValue]];			\
	case OF_NUMBER_SSIZE:						\
		return [OFNumber numberWithSSize:			\
		    value.ssize o [n sSizeValue]];			\
		    _value.ssize o [n sSizeValue]];			\
	case OF_NUMBER_INTMAX:						\
		return [OFNumber numberWithIntMax:			\
		    value.intmax o [n intMaxValue]];			\
		    _value.intmax o [n intMaxValue]];			\
	case OF_NUMBER_UINTMAX:						\
		return [OFNumber numberWithUIntMax:			\
		    value.uintmax o [n uIntMaxValue]];			\
		    _value.uintmax o [n uIntMaxValue]];			\
	case OF_NUMBER_PTRDIFF:						\
		return [OFNumber numberWithPtrDiff:			\
		    value.ptrdiff o [n ptrDiffValue]];			\
		    _value.ptrdiff o [n ptrDiffValue]];			\
	case OF_NUMBER_INTPTR:						\
		return [OFNumber numberWithIntPtr:			\
		    value.intptr o [n intPtrValue]];			\
		    _value.intptr o [n intPtrValue]];			\
	case OF_NUMBER_UINTPTR:						\
		return [OFNumber numberWithUIntPtr:			\
		    value.uintptr o [n uIntPtrValue]];			\
		    _value.uintptr o [n uIntPtrValue]];			\
	case OF_NUMBER_FLOAT:						\
		return [OFNumber numberWithFloat:			\
		    value.float_ o [n floatValue]];			\
		    _value.float_ o [n floatValue]];			\
	case OF_NUMBER_DOUBLE:						\
		return [OFNumber numberWithDouble:			\
		    value.double_ o [n doubleValue]];			\
		    _value.double_ o [n doubleValue]];			\
	default:							\
		@throw [OFInvalidFormatException			\
		    exceptionWithClass: [self class]];			\
	}
#define CALCULATE2(o, n)						\
	switch (type) {							\
	switch (_type) {						\
	case OF_NUMBER_BOOL:						\
		return [OFNumber numberWithBool:			\
		    value.bool_ o [n boolValue]];			\
		    _value.bool_ o [n boolValue]];			\
	case OF_NUMBER_CHAR:						\
		return [OFNumber numberWithChar:			\
		    value.char_ o [n charValue]];			\
		    _value.schar o [n charValue]];			\
	case OF_NUMBER_SHORT:						\
		return [OFNumber numberWithShort:			\
		    value.short_ o [n shortValue]];			\
		    _value.sshort o [n shortValue]];			\
	case OF_NUMBER_INT:						\
		return [OFNumber numberWithInt:				\
		    value.int_ o [n intValue]];				\
		    _value.sint o [n intValue]];			\
	case OF_NUMBER_LONG:						\
		return [OFNumber numberWithLong:			\
		    value.long_ o [n longValue]];			\
		    _value.slong o [n longValue]];			\
	case OF_NUMBER_UCHAR:						\
		return [OFNumber numberWithUnsignedChar:		\
		    value.uchar o [n unsignedCharValue]];		\
		    _value.uchar o [n unsignedCharValue]];		\
	case OF_NUMBER_USHORT:						\
		return [OFNumber numberWithUnsignedShort:		\
		    value.ushort o [n unsignedShortValue]];		\
		    _value.ushort o [n unsignedShortValue]];		\
	case OF_NUMBER_UINT:						\
		return [OFNumber numberWithUnsignedInt:			\
		    value.uint o [n unsignedIntValue]];			\
		    _value.uint o [n unsignedIntValue]];		\
	case OF_NUMBER_ULONG:						\
		return [OFNumber numberWithUnsignedLong:		\
		    value.ulong o [n unsignedLongValue]];		\
		    _value.ulong o [n unsignedLongValue]];		\
	case OF_NUMBER_INT8:						\
		return [OFNumber numberWithInt8:			\
		    value.int8 o [n int8Value]];			\
		    _value.int8 o [n int8Value]];			\
	case OF_NUMBER_INT16:						\
		return [OFNumber numberWithInt16:			\
		    value.int16 o [n int16Value]];			\
		    _value.int16 o [n int16Value]];			\
	case OF_NUMBER_INT32:						\
		return [OFNumber numberWithInt32:			\
		    value.int32 o [n int32Value]];			\
		    _value.int32 o [n int32Value]];			\
	case OF_NUMBER_INT64:						\
		return [OFNumber numberWithInt64:			\
		    value.int64 o [n int64Value]];			\
		    _value.int64 o [n int64Value]];			\
	case OF_NUMBER_UINT8:						\
		return [OFNumber numberWithUInt8:			\
		    value.uint8 o [n uInt8Value]];			\
		    _value.uint8 o [n uInt8Value]];			\
	case OF_NUMBER_UINT16:						\
		return [OFNumber numberWithUInt16:			\
		    value.uint16 o [n uInt16Value]];			\
		    _value.uint16 o [n uInt16Value]];			\
	case OF_NUMBER_UINT32:						\
		return [OFNumber numberWithUInt32:			\
		    value.uint32 o [n uInt32Value]];			\
		    _value.uint32 o [n uInt32Value]];			\
	case OF_NUMBER_UINT64:						\
		return [OFNumber numberWithUInt64:			\
		    value.uint64 o [n uInt64Value]];			\
		    _value.uint64 o [n uInt64Value]];			\
	case OF_NUMBER_SIZE:						\
		return [OFNumber numberWithSize:			\
		    value.size o [n sizeValue]];			\
		    _value.size o [n sizeValue]];			\
	case OF_NUMBER_SSIZE:						\
		return [OFNumber numberWithSSize:			\
		    value.ssize o [n sSizeValue]];			\
		    _value.ssize o [n sSizeValue]];			\
	case OF_NUMBER_INTMAX:						\
		return [OFNumber numberWithIntMax:			\
		    value.intmax o [n intMaxValue]];			\
		    _value.intmax o [n intMaxValue]];			\
	case OF_NUMBER_UINTMAX:						\
		return [OFNumber numberWithUIntMax:			\
		    value.uintmax o [n uIntMaxValue]];			\
		    _value.uintmax o [n uIntMaxValue]];			\
	case OF_NUMBER_PTRDIFF:						\
		return [OFNumber numberWithPtrDiff:			\
		    value.ptrdiff o [n ptrDiffValue]];			\
		    _value.ptrdiff o [n ptrDiffValue]];			\
	case OF_NUMBER_INTPTR:						\
		return [OFNumber numberWithIntPtr:			\
		    value.intptr o [n intPtrValue]];			\
		    _value.intptr o [n intPtrValue]];			\
	case OF_NUMBER_UINTPTR:						\
		return [OFNumber numberWithUIntPtr:			\
		    value.uintptr o [n uIntPtrValue]];			\
		    _value.uintptr o [n uIntPtrValue]];			\
	case OF_NUMBER_FLOAT:						\
	case OF_NUMBER_DOUBLE:						\
		@throw [OFInvalidArgumentException			\
		    exceptionWithClass: [self class]			\
			      selector: _cmd];				\
	default:							\
		@throw [OFInvalidFormatException			\
		    exceptionWithClass: [self class]];			\
	}
#define CALCULATE3(o)							\
	switch (type) {							\
	switch (_type) {						\
	case OF_NUMBER_BOOL:						\
		return [OFNumber numberWithBool: value.bool_ o];	\
		return [OFNumber numberWithBool: _value.bool_ o];	\
	case OF_NUMBER_CHAR:						\
		return [OFNumber numberWithChar: value.char_ o];	\
		return [OFNumber numberWithChar: _value.schar o];	\
	case OF_NUMBER_SHORT:						\
		return [OFNumber numberWithShort: value.short_ o];	\
		return [OFNumber numberWithShort: _value.sshort o];	\
	case OF_NUMBER_INT:						\
		return [OFNumber numberWithInt: value.int_ o];		\
		return [OFNumber numberWithInt: _value.sint o];		\
	case OF_NUMBER_LONG:						\
		return [OFNumber numberWithLong: value.long_ o];	\
		return [OFNumber numberWithLong: _value.slong o];	\
	case OF_NUMBER_UCHAR:						\
		return [OFNumber numberWithUnsignedChar:		\
		    value.uchar o];					\
		    _value.uchar o];					\
	case OF_NUMBER_USHORT:						\
		return [OFNumber numberWithUnsignedShort:		\
		    value.ushort o];					\
		    _value.ushort o];					\
	case OF_NUMBER_UINT:						\
		return [OFNumber numberWithUnsignedInt: value.uint o];	\
		return [OFNumber numberWithUnsignedInt: _value.uint o];	\
	case OF_NUMBER_ULONG:						\
		return [OFNumber numberWithUnsignedLong:		\
		    value.ulong o];	\
		    _value.ulong o];	\
	case OF_NUMBER_INT8:						\
		return [OFNumber numberWithInt8: value.int8 o];		\
		return [OFNumber numberWithInt8: _value.int8 o];	\
	case OF_NUMBER_INT16:						\
		return [OFNumber numberWithInt16: value.int16 o];	\
		return [OFNumber numberWithInt16: _value.int16 o];	\
	case OF_NUMBER_INT32:						\
		return [OFNumber numberWithInt32: value.int32 o];	\
		return [OFNumber numberWithInt32: _value.int32 o];	\
	case OF_NUMBER_INT64:						\
		return [OFNumber numberWithInt64: value.int64 o];	\
		return [OFNumber numberWithInt64: _value.int64 o];	\
	case OF_NUMBER_UINT8:						\
		return [OFNumber numberWithUInt8: value.uint8 o];	\
		return [OFNumber numberWithUInt8: _value.uint8 o];	\
	case OF_NUMBER_UINT16:						\
		return [OFNumber numberWithUInt16: value.uint16 o];	\
		return [OFNumber numberWithUInt16: _value.uint16 o];	\
	case OF_NUMBER_UINT32:						\
		return [OFNumber numberWithUInt32: value.uint32 o];	\
		return [OFNumber numberWithUInt32: _value.uint32 o];	\
	case OF_NUMBER_UINT64:						\
		return [OFNumber numberWithUInt64: value.uint64 o];	\
		return [OFNumber numberWithUInt64: _value.uint64 o];	\
	case OF_NUMBER_SIZE:						\
		return [OFNumber numberWithSize: value.size o];		\
		return [OFNumber numberWithSize: _value.size o];	\
	case OF_NUMBER_SSIZE:						\
		return [OFNumber numberWithSSize: value.ssize o];	\
		return [OFNumber numberWithSSize: _value.ssize o];	\
	case OF_NUMBER_INTMAX:						\
		return [OFNumber numberWithIntMax: value.intmax o];	\
		return [OFNumber numberWithIntMax: _value.intmax o];	\
	case OF_NUMBER_UINTMAX:						\
		return [OFNumber numberWithUIntMax: value.uintmax o];	\
		return [OFNumber numberWithUIntMax: _value.uintmax o];	\
	case OF_NUMBER_PTRDIFF:						\
		return [OFNumber numberWithPtrDiff: value.ptrdiff o];	\
		return [OFNumber numberWithPtrDiff: _value.ptrdiff o];	\
	case OF_NUMBER_INTPTR:						\
		return [OFNumber numberWithIntPtr: value.intptr o];	\
		return [OFNumber numberWithIntPtr: _value.intptr o];	\
	case OF_NUMBER_UINTPTR:						\
		return [OFNumber numberWithUIntPtr: value.uintptr o];	\
		return [OFNumber numberWithUIntPtr: _value.uintptr o];	\
	case OF_NUMBER_FLOAT:						\
		return [OFNumber numberWithFloat: value.float_ o];	\
		return [OFNumber numberWithFloat: _value.float_ o];	\
	case OF_NUMBER_DOUBLE:						\
		return [OFNumber numberWithDouble: value.double_ o];	\
		return [OFNumber numberWithDouble: _value.double_ o];	\
	default:							\
		@throw [OFInvalidFormatException			\
		    exceptionWithClass: [self class]];			\
	}

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

+ (instancetype)numberWithChar: (signed char)char_
+ (instancetype)numberWithChar: (signed char)schar
{
	return [[[self alloc] initWithChar: char_] autorelease];
	return [[[self alloc] initWithChar: schar] autorelease];
}

+ (instancetype)numberWithShort: (signed short)short_
+ (instancetype)numberWithShort: (signed short)sshort
{
	return [[[self alloc] initWithShort: short_] autorelease];
	return [[[self alloc] initWithShort: sshort] autorelease];
}

+ (instancetype)numberWithInt: (signed int)int_
+ (instancetype)numberWithInt: (signed int)sint
{
	return [[[self alloc] initWithInt: int_] autorelease];
	return [[[self alloc] initWithInt: sint] autorelease];
}

+ (instancetype)numberWithLong: (signed long)long_
+ (instancetype)numberWithLong: (signed long)slong
{
	return [[[self alloc] initWithLong: long_] autorelease];
	return [[[self alloc] initWithLong: slong] autorelease];
}

+ (instancetype)numberWithUnsignedChar: (unsigned char)uchar
{
	return [[[self alloc] initWithUnsignedChar: uchar] autorelease];
}

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


550
551
552
553
554
555
556
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
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
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
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
550
551
552
553
554
555
556
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
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







-
-
+
+




-
+



-
-
+
+




-
+



-
-
+
+




-
+



-
-
+
+




-
+



-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+








-
-
+
+







	abort();
}

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

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

	return self;
}

- initWithChar: (signed char)char_
- initWithChar: (signed char)schar
{
	self = [super init];

	value.char_ = char_;
	type = OF_NUMBER_CHAR;
	_value.schar = schar;
	_type = OF_NUMBER_CHAR;

	return self;
}

- initWithShort: (signed short)short_
- initWithShort: (signed short)sshort
{
	self = [super init];

	value.short_ = short_;
	type = OF_NUMBER_SHORT;
	_value.sshort = sshort;
	_type = OF_NUMBER_SHORT;

	return self;
}

- initWithInt: (signed int)int_
- initWithInt: (signed int)sint
{
	self = [super init];

	value.int_ = int_;
	type = OF_NUMBER_INT;
	_value.sint = sint;
	_type = OF_NUMBER_INT;

	return self;
}

- initWithLong: (signed long)long_
- initWithLong: (signed long)slong
{
	self = [super init];

	value.long_ = long_;
	type = OF_NUMBER_LONG;
	_value.slong = slong;
	_type = OF_NUMBER_LONG;

	return self;
}

- initWithUnsignedChar: (unsigned char)uchar
{
	self = [super init];

	value.uchar = uchar;
	type = OF_NUMBER_UCHAR;
	_value.uchar = uchar;
	_type = OF_NUMBER_UCHAR;

	return self;
}

- initWithUnsignedShort: (unsigned short)ushort
{
	self = [super init];

	value.ushort = ushort;
	type = OF_NUMBER_USHORT;
	_value.ushort = ushort;
	_type = OF_NUMBER_USHORT;

	return self;
}

- initWithUnsignedInt: (unsigned int)uint
{
	self = [super init];

	value.uint = uint;
	type = OF_NUMBER_UINT;
	_value.uint = uint;
	_type = OF_NUMBER_UINT;

	return self;
}

- initWithUnsignedLong: (unsigned long)ulong
{
	self = [super init];

	value.ulong = ulong;
	type = OF_NUMBER_ULONG;
	_value.ulong = ulong;
	_type = OF_NUMBER_ULONG;

	return self;
}

- initWithInt8: (int8_t)int8
{
	self = [super init];

	value.int8 = int8;
	type = OF_NUMBER_INT8;
	_value.int8 = int8;
	_type = OF_NUMBER_INT8;

	return self;
}

- initWithInt16: (int16_t)int16
{
	self = [super init];

	value.int16 = int16;
	type = OF_NUMBER_INT16;
	_value.int16 = int16;
	_type = OF_NUMBER_INT16;

	return self;
}

- initWithInt32: (int32_t)int32
{
	self = [super init];

	value.int32 = int32;
	type = OF_NUMBER_INT32;
	_value.int32 = int32;
	_type = OF_NUMBER_INT32;

	return self;
}

- initWithInt64: (int64_t)int64
{
	self = [super init];

	value.int64 = int64;
	type = OF_NUMBER_INT64;
	_value.int64 = int64;
	_type = OF_NUMBER_INT64;

	return self;
}

- initWithUInt8: (uint8_t)uint8
{
	self = [super init];

	value.uint8 = uint8;
	type = OF_NUMBER_UINT8;
	_value.uint8 = uint8;
	_type = OF_NUMBER_UINT8;

	return self;
}

- initWithUInt16: (uint16_t)uint16
{
	self = [super init];

	value.uint16 = uint16;
	type = OF_NUMBER_UINT16;
	_value.uint16 = uint16;
	_type = OF_NUMBER_UINT16;

	return self;
}

- initWithUInt32: (uint32_t)uint32
{
	self = [super init];

	value.uint32 = uint32;
	type = OF_NUMBER_UINT32;
	_value.uint32 = uint32;
	_type = OF_NUMBER_UINT32;

	return self;
}

- initWithUInt64: (uint64_t)uint64
{
	self = [super init];

	value.uint64 = uint64;
	type = OF_NUMBER_UINT64;
	_value.uint64 = uint64;
	_type = OF_NUMBER_UINT64;

	return self;
}

- initWithSize: (size_t)size
{
	self = [super init];

	value.size = size;
	type = OF_NUMBER_SIZE;
	_value.size = size;
	_type = OF_NUMBER_SIZE;

	return self;
}

- initWithSSize: (ssize_t)ssize
{
	self = [super init];

	value.ssize = ssize;
	type = OF_NUMBER_SSIZE;
	_value.ssize = ssize;
	_type = OF_NUMBER_SSIZE;

	return self;
}

- initWithIntMax: (intmax_t)intmax
{
	self = [super init];

	value.intmax = intmax;
	type = OF_NUMBER_INTMAX;
	_value.intmax = intmax;
	_type = OF_NUMBER_INTMAX;

	return self;
}

- initWithUIntMax: (uintmax_t)uintmax
{
	self = [super init];

	value.uintmax = uintmax;
	type = OF_NUMBER_UINTMAX;
	_value.uintmax = uintmax;
	_type = OF_NUMBER_UINTMAX;

	return self;
}

- initWithPtrDiff: (ptrdiff_t)ptrdiff
{
	self = [super init];

	value.ptrdiff = ptrdiff;
	type = OF_NUMBER_PTRDIFF;
	_value.ptrdiff = ptrdiff;
	_type = OF_NUMBER_PTRDIFF;

	return self;
}

- initWithIntPtr: (intptr_t)intptr
{
	self = [super init];

	value.intptr = intptr;
	type = OF_NUMBER_INTPTR;
	_value.intptr = intptr;
	_type = OF_NUMBER_INTPTR;

	return self;
}

- initWithUIntPtr: (uintptr_t)uintptr
{
	self = [super init];

	value.uintptr = uintptr;
	type = OF_NUMBER_UINTPTR;
	_value.uintptr = uintptr;
	_type = OF_NUMBER_UINTPTR;

	return self;
}

- initWithFloat: (float)float_
{
	self = [super init];

	value.float_ = float_;
	type = OF_NUMBER_FLOAT;
	_value.float_ = float_;
	_type = OF_NUMBER_FLOAT;

	return self;
}

- initWithDouble: (double)double_
{
	self = [super init];

	value.double_ = double_;
	type = OF_NUMBER_DOUBLE;
	_value.double_ = double_;
	_type = OF_NUMBER_DOUBLE;

	return self;
}

- initWithSerialization: (OFXMLElement*)element
{
	self = [super init];
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
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
850

851
852

853
854

855
856
857
858
859
860
861
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

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

850
851

852
853

854
855
856
857
858
859
860
861







-
+


-
+

-
+









-
-
+
+

-
-
+
+








-
-
+
+








-
-
+
+
















-
+




-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+







			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

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

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

			if ([[element stringValue] isEqual: @"YES"])
				value.bool_ = YES;
				_value.bool_ = YES;
			else if ([[element stringValue] isEqual: @"NO"])
				value.bool_ = NO;
				_value.bool_ = NO;
			else
				@throw [OFInvalidArgumentException
				    exceptionWithClass: [self class]
					      selector: _cmd];
		} else if ([typeString isEqual: @"unsigned"]) {
			/*
			 * FIXME: This will fail if the value is bigger than
			 *	  INTMAX_MAX!
			 */
			type = OF_NUMBER_UINTMAX;
			value.uintmax = [element decimalValue];
			_type = OF_NUMBER_UINTMAX;
			_value.uintmax = [element decimalValue];
		} else if ([typeString isEqual: @"signed"]) {
			type = OF_NUMBER_INTMAX;
			value.intmax = [element decimalValue];
			_type = OF_NUMBER_INTMAX;
			_value.intmax = [element decimalValue];
		} else if ([typeString isEqual: @"float"]) {
			union {
				float f;
				uint32_t u;
			} f;

			f.u = (uint32_t)[element hexadecimalValue];

			type = OF_NUMBER_FLOAT;
			value.float_ = f.f;
			_type = OF_NUMBER_FLOAT;
			_value.float_ = f.f;
		} else if ([typeString isEqual: @"double"]) {
			union {
				double d;
				uint64_t u;
			} d;

			d.u = (uint64_t)[element hexadecimalValue];

			type = OF_NUMBER_DOUBLE;
			value.double_ = d.d;
			_type = OF_NUMBER_DOUBLE;
			_value.double_ = d.d;
		} else
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (of_number_type_t)type
{
	return type;
	return _type;
}

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

- (signed char)charValue
988
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
1014
1015

1016
1017
1018
1019
1020
1021
1022
1023
1024

1025

1026
1027
1028
1029
1030
1031
1032
988
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
1014

1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025

1026
1027
1028
1029
1030
1031
1032
1033







-
+


-
+
















-
+









+
-
+







	OFNumber *number;

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

	number = object;

	if (type & OF_NUMBER_FLOAT || number->type & OF_NUMBER_FLOAT)
	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)
	if (_type & OF_NUMBER_SIGNED || number->_type & OF_NUMBER_SIGNED)
		return ([number intMaxValue] == [self intMaxValue]);

	return ([number uIntMaxValue] == [self uIntMaxValue]);
}

- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	OFNumber *number;

	if (![object isKindOfClass: [OFNumber class]])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	number = (OFNumber*)object;

	if (type & OF_NUMBER_FLOAT || number->type & OF_NUMBER_FLOAT) {
	if (_type & OF_NUMBER_FLOAT || number->_type & OF_NUMBER_FLOAT) {
		double double1 = [self doubleValue];
		double double2 = [number doubleValue];

		if (double1 > double2)
			return OF_ORDERED_DESCENDING;
		if (double1 < double2)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
	} else if (_type & OF_NUMBER_SIGNED ||
	} else if (type & OF_NUMBER_SIGNED || number->type & OF_NUMBER_SIGNED) {
	    number->_type & OF_NUMBER_SIGNED) {
		intmax_t int1 = [self intMaxValue];
		intmax_t int2 = [number intMaxValue];

		if (int1 > int2)
			return OF_ORDERED_DESCENDING;
		if (int1 < int2)
			return OF_ORDERED_ASCENDING;
1043
1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055


1056
1057
1058

1059
1060
1061
1062
1063
1064


1065
1066
1067
1068

1069
1070
1071
1072
1073
1074

1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085

1086
1087
1088
1089
1090
1091
1092
1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054


1055
1056
1057
1058

1059
1060
1061
1062
1063


1064
1065
1066
1067
1068

1069
1070
1071
1072
1073
1074

1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085

1086
1087
1088
1089
1090
1091
1092
1093







-
+



-
-
+
+


-
+




-
-
+
+



-
+





-
+










-
+








		return OF_ORDERED_SAME;
	}
}

- (uint32_t)hash
{
	of_number_type_t type_ = type;
	of_number_type_t type = _type;
	uint32_t hash;

	/* Do we really need signed to represent this number? */
	if (type_ & OF_NUMBER_SIGNED && [self intMaxValue] >= 0)
		type_ &= ~OF_NUMBER_SIGNED;
	if (type & OF_NUMBER_SIGNED && [self intMaxValue] >= 0)
		type &= ~OF_NUMBER_SIGNED;

	/* Do we really need floating point to represent this number? */
	if (type_ & OF_NUMBER_FLOAT) {
	if (type & OF_NUMBER_FLOAT) {
		double v = [self doubleValue];

		if (v < 0) {
			if (v == [self intMaxValue]) {
				type_ &= ~OF_NUMBER_FLOAT;
				type_ |= OF_NUMBER_SIGNED;
				type &= ~OF_NUMBER_FLOAT;
				type |= OF_NUMBER_SIGNED;
			}
		} else {
			if (v == [self uIntMaxValue])
				type_ &= ~OF_NUMBER_FLOAT;
				type &= ~OF_NUMBER_FLOAT;
		}
	}

	OF_HASH_INIT(hash);

	if (type_ & OF_NUMBER_FLOAT) {
	if (type & OF_NUMBER_FLOAT) {
		union {
			double d;
			uint8_t b[sizeof(double)];
		} d;
		uint_fast8_t i;

		d.d = OF_BSWAP_DOUBLE_IF_BE([self doubleValue]);

		for (i = 0; i < sizeof(double); i++)
			OF_HASH_ADD(hash, d.b[i]);
	} else if (type_ & OF_NUMBER_SIGNED) {
	} else if (type & OF_NUMBER_SIGNED) {
		intmax_t v = [self intMaxValue] * -1;

		while (v != 0) {
			OF_HASH_ADD(hash, v & 0xFF);
			v >>= 8;
		}

1158
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168

1169
1170
1171

1172
1173
1174

1175
1176


1177
1178
1179

1180
1181
1182

1183
1184
1185

1186
1187
1188

1189
1190
1191

1192
1193
1194

1195
1196
1197

1198
1199
1200

1201
1202
1203

1204
1205
1206

1207
1208
1209

1210
1211
1212

1213
1214
1215

1216
1217
1218

1219
1220
1221

1222
1223
1224

1225
1226
1227

1228
1229
1230

1231
1232
1233

1234
1235
1236

1237
1238
1239


1240
1241
1242

1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258

1259
1260

1261
1262
1263
1264
1265
1266
1267
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168

1169
1170
1171

1172
1173
1174

1175
1176

1177
1178
1179
1180

1181
1182
1183

1184
1185
1186

1187
1188
1189

1190
1191
1192

1193
1194
1195

1196
1197
1198

1199
1200
1201

1202
1203
1204

1205
1206
1207

1208
1209
1210

1211
1212
1213

1214
1215
1216

1217
1218
1219

1220
1221
1222

1223
1224
1225

1226
1227
1228

1229
1230
1231

1232
1233
1234

1235
1236
1237

1238
1239


1240
1241
1242
1243

1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259

1260
1261

1262
1263
1264
1265
1266
1267
1268
1269







-
+


-
+


-
+


-
+

-
+
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+

-
-
+
+


-
+















-
+

-
+







- (OFNumber*)numberByDecreasing
{
	CALCULATE3(- 1)
}

- (OFNumber*)remainderOfDivisionWithNumber: (OFNumber*)number
{
	switch (type) {
	switch (_type) {
	case OF_NUMBER_BOOL:
		return [OFNumber numberWithBool:
		    value.bool_ % [number boolValue]];
		    _value.bool_ % [number boolValue]];
	case OF_NUMBER_CHAR:
		return [OFNumber numberWithChar:
		    value.char_ % [number charValue]];
		    _value.schar % [number charValue]];
	case OF_NUMBER_SHORT:
		return [OFNumber numberWithShort:
		    value.short_ % [number shortValue]];
		    _value.sshort % [number shortValue]];
	case OF_NUMBER_INT:
		return [OFNumber numberWithInt: value.int_ % [number intValue]];
		return [OFNumber numberWithInt:
		    _value.sint % [number intValue]];
	case OF_NUMBER_LONG:
		return [OFNumber numberWithLong:
		    value.long_ % [number longValue]];
		    _value.slong % [number longValue]];
	case OF_NUMBER_UCHAR:
		return [OFNumber numberWithUnsignedChar:
		    value.uchar % [number unsignedCharValue]];
		    _value.uchar % [number unsignedCharValue]];
	case OF_NUMBER_USHORT:
		return [OFNumber numberWithUnsignedShort:
		    value.ushort % [number unsignedShortValue]];
		    _value.ushort % [number unsignedShortValue]];
	case OF_NUMBER_UINT:
		return [OFNumber numberWithUnsignedInt:
		    value.uint % [number unsignedIntValue]];
		    _value.uint % [number unsignedIntValue]];
	case OF_NUMBER_ULONG:
		return [OFNumber numberWithUnsignedLong:
		    value.ulong % [number unsignedLongValue]];
		    _value.ulong % [number unsignedLongValue]];
	case OF_NUMBER_INT8:
		return [OFNumber numberWithInt8:
		    value.int8 % [number int8Value]];
		    _value.int8 % [number int8Value]];
	case OF_NUMBER_INT16:
		return [OFNumber numberWithInt16:
		    value.int16 % [number int16Value]];
		    _value.int16 % [number int16Value]];
	case OF_NUMBER_INT32:
		return [OFNumber numberWithInt32:
		    value.int32 % [number int32Value]];
		    _value.int32 % [number int32Value]];
	case OF_NUMBER_INT64:
		return [OFNumber numberWithInt64:
		    value.int64 % [number int64Value]];
		    _value.int64 % [number int64Value]];
	case OF_NUMBER_UINT8:
		return [OFNumber numberWithUInt8:
		    value.uint8 % [number uInt8Value]];
		    _value.uint8 % [number uInt8Value]];
	case OF_NUMBER_UINT16:
		return [OFNumber numberWithUInt16:
		    value.uint16 % [number uInt16Value]];
		    _value.uint16 % [number uInt16Value]];
	case OF_NUMBER_UINT32:
		return [OFNumber numberWithUInt32:
		    value.uint32 % [number uInt32Value]];
		    _value.uint32 % [number uInt32Value]];
	case OF_NUMBER_UINT64:
		return [OFNumber numberWithUInt64:
		    value.uint64 % [number uInt64Value]];
		    _value.uint64 % [number uInt64Value]];
	case OF_NUMBER_SIZE:
		return [OFNumber numberWithSize:
		    value.size % [number sizeValue]];
		    _value.size % [number sizeValue]];
	case OF_NUMBER_SSIZE:
		return [OFNumber numberWithSSize:
		    value.ssize % [number sSizeValue]];
		    _value.ssize % [number sSizeValue]];
	case OF_NUMBER_INTMAX:
		return [OFNumber numberWithIntMax:
		    value.intmax % [number intMaxValue]];
		    _value.intmax % [number intMaxValue]];
	case OF_NUMBER_UINTMAX:
		return [OFNumber numberWithUIntMax:
		    value.uintmax % [number uIntMaxValue]];
		    _value.uintmax % [number uIntMaxValue]];
	case OF_NUMBER_PTRDIFF:
		return [OFNumber numberWithPtrDiff:
		    value.ptrdiff % [number ptrDiffValue]];
		    _value.ptrdiff % [number ptrDiffValue]];
	case OF_NUMBER_INTPTR:
		return [OFNumber numberWithIntPtr:
		    value.intptr % [number intPtrValue]];
		    _value.intptr % [number intPtrValue]];
	case OF_NUMBER_UINTPTR:
		return [OFNumber numberWithUIntPtr:
		    value.uintptr % [number uIntPtrValue]];
		    _value.uintptr % [number uIntPtrValue]];
	case OF_NUMBER_FLOAT:
		return [OFNumber
		    numberWithFloat: fmodf(value.float_, [number floatValue])];
		return [OFNumber numberWithFloat:
		    fmodf(_value.float_, [number floatValue])];
	case OF_NUMBER_DOUBLE:
		return [OFNumber numberWithDouble:
		    fmod(value.double_, [number doubleValue])];
		    fmod(_value.double_, [number doubleValue])];
	default:
		@throw [OFInvalidFormatException
		    exceptionWithClass: [self class]];
	}
}

- copy
{
	return [self retain];
}

- (OFString*)description
{
	OFMutableString *ret;

	switch (type) {
	switch (_type) {
	case OF_NUMBER_BOOL:
		return (value.bool_ ? @"YES" : @"NO");
		return (_value.bool_ ? @"YES" : @"NO");
	case OF_NUMBER_UCHAR:
	case OF_NUMBER_USHORT:
	case OF_NUMBER_UINT:
	case OF_NUMBER_ULONG:
	case OF_NUMBER_UINT8:
	case OF_NUMBER_UINT16:
	case OF_NUMBER_UINT32:
1280
1281
1282
1283
1284
1285
1286
1287

1288
1289
1290
1291
1292
1293
1294
1295
1296


1297
1298
1299
1300
1301
1302
1303
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296
1297

1298
1299
1300
1301
1302
1303
1304
1305
1306







-
+








-
+
+







	case OF_NUMBER_INT64:
	case OF_NUMBER_SSIZE:
	case OF_NUMBER_INTMAX:
	case OF_NUMBER_PTRDIFF:
	case OF_NUMBER_INTPTR:
		return [OFString stringWithFormat: @"%jd", [self intMaxValue]];
	case OF_NUMBER_FLOAT:
		ret = [OFMutableString stringWithFormat: @"%g", value.float_];
		ret = [OFMutableString stringWithFormat: @"%g", _value.float_];

		if (![ret containsString: @"."])
			[ret appendString: @".0"];

		[ret makeImmutable];

		return ret;
	case OF_NUMBER_DOUBLE:
		ret = [OFMutableString stringWithFormat: @"%lg", value.double_];
		ret = [OFMutableString stringWithFormat: @"%lg",
							 _value.double_];

		if (![ret containsString: @"."])
			[ret appendString: @".0"];

		[ret makeImmutable];

		return ret;
1312
1313
1314
1315
1316
1317
1318
1319

1320
1321
1322
1323
1324
1325
1326
1315
1316
1317
1318
1319
1320
1321

1322
1323
1324
1325
1326
1327
1328
1329







-
+







	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;

	element = [OFXMLElement elementWithName: [self className]
				      namespace: OF_SERIALIZATION_NS
				    stringValue: [self description]];

	switch (type) {
	switch (_type) {
	case OF_NUMBER_BOOL:
		[element addAttributeWithName: @"type"
				  stringValue: @"boolean"];
		break;
	case OF_NUMBER_UCHAR:
	case OF_NUMBER_USHORT:
	case OF_NUMBER_UINT:
1352
1353
1354
1355
1356
1357
1358
1359

1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373

1374
1375
1376
1377
1378
1379
1380
1355
1356
1357
1358
1359
1360
1361

1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375

1376
1377
1378
1379
1380
1381
1382
1383







-
+













-
+







		break;
	case OF_NUMBER_FLOAT:;
		union {
			float f;
			uint32_t u;
		} f;

		f.f = value.float_;
		f.f = _value.float_;

		[element addAttributeWithName: @"type"
				  stringValue: @"float"];
		[element setStringValue:
		    [OFString stringWithFormat: @"%08" PRIx32, f.u]];

		break;
	case OF_NUMBER_DOUBLE:;
		union {
			double d;
			uint64_t u;
		} d;

		d.d = value.double_;
		d.d = _value.double_;

		[element addAttributeWithName: @"type"
				  stringValue: @"double"];
		[element setStringValue:
		    [OFString stringWithFormat: @"%016" PRIx64, d.u]];

		break;
1390
1391
1392
1393
1394
1395
1396
1397
1398


1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1393
1394
1395
1396
1397
1398
1399


1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413







-
-
+
+












	return [element autorelease];
}

- (OFString*)JSONRepresentation
{
	double doubleValue;

	if (type == OF_NUMBER_BOOL)
		return (value.bool_ ? @"true" : @"false");
	if (_type == OF_NUMBER_BOOL)
		return (_value.bool_ ? @"true" : @"false");

	doubleValue = [self doubleValue];
	if (isinf(doubleValue)) {
		if (doubleValue > 0)
			return @"Infinity";
		else
			return @"-Infinity";
	}

	return [self description];
}
@end

Modified src/OFObject.h from [a61f98d08c] to [7e8147f893].

342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
342
343
344
345
346
347
348

349
350
351
352
353
354
355
356







-
+








/*!
 * @brief The root class for all other classes inside ObjFW.
 */
@interface OFObject <OFObject>
{
@public
	Class isa;
	Class _isa;
}

/*!
 * @brief A method which is called once when the class is loaded into the
 *	  runtime.
 *
 * Derived classes can overide this to execute their own code when the class is

Modified src/OFPlugin.h from [00c2e927a6] to [ba7c63f3e9].

26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43







-
+










#endif

/*!
 * @brief Provides a system for loading plugins at runtime.
 */
@interface OFPlugin: OFObject
{
	of_plugin_handle_t handle;
	of_plugin_handle_t _handle;
}

/*!
 * @brief Loads a plugin from a file.
 *
 * @param path Path to the plugin file. The suffix is appended automatically.
 * @return The loaded plugin
 */
+ (id)pluginFromFile: (OFString*)path;
@end

Modified src/OFPlugin.m from [929f009f47] to [ae3dcbbf47].

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







-
+




















-
+






	initPlugin = (OFPlugin*(*)(void))dlsym(handle, "init_plugin");
	if (initPlugin == NULL || (plugin = initPlugin()) == nil) {
		dlclose(handle);
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
	}

	plugin->handle = handle;
	plugin->_handle = handle;
	return plugin;
}

- init
{
	if (object_getClass(self) == [OFPlugin class]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
			abort();
		} @catch (id e) {
			[self release];
			@throw e;
		}
	}

	return [super init];
}

- (void)dealloc
{
	of_plugin_handle_t h = handle;
	of_plugin_handle_t h = _handle;

	[super dealloc];

	dlclose(h);
}
@end

Modified src/OFProcess.h from [4eeb2e3155] to [97b7b3ccc7].

35
36
37
38
39
40
41
42
43


44
45

46
47
48


49
50
51
52
53
54
55
35
36
37
38
39
40
41


42
43
44

45
46


47
48
49
50
51
52
53
54
55







-
-
+
+

-
+

-
-
+
+








/*!
 * @brief A class for stream-like communication with a newly created process.
 */
@interface OFProcess: OFStream
{
#ifndef _WIN32
	pid_t pid;
	int readPipe[2], writePipe[2];
	pid_t _pid;
	int _readPipe[2], _writePipe[2];
#else
	HANDLE process, readPipe[2], writePipe[2];
	HANDLE _process, _readPipe[2], _writePipe[2];
#endif
	int status;
	BOOL atEndOfStream;
	int _status;
	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 [8542470fa0] to [ef90137219].

114
115
116
117
118
119
120
121

122
123
124
125

126
127
128
129
130
131
132
114
115
116
117
118
119
120

121
122
123
124

125
126
127
128
129
130
131
132







-
+



-
+







	arguments: (OFArray*)arguments
      environment: (OFDictionary*)environment
{
	self = [super init];

	@try {
#ifndef _WIN32
		if (pipe(readPipe) != 0 || pipe(writePipe) != 0)
		if (pipe(_readPipe) != 0 || pipe(_writePipe) != 0)
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		switch ((pid = fork())) {
		switch ((_pid = fork())) {
		case 0:;
			OFString **objects = [arguments objects];
			size_t i, count = [arguments count];
			char **argv;

			argv = [self allocMemoryWithSize: sizeof(char*)
						   count: count + 2];
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
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







-
-
-
-
+
+
+
+









-
-
+
+

















+
+
+
-
+
+



-
+



-
-
-
-
-
+
+







-
-
+
+







				    OF_environmentForDictionary: environment];
#else
				environ = [self
				    OF_environmentForDictionary: environment];
#endif
			}

			close(readPipe[0]);
			close(writePipe[1]);
			dup2(writePipe[0], 0);
			dup2(readPipe[1], 1);
			close(_readPipe[0]);
			close(_writePipe[1]);
			dup2(_writePipe[0], 0);
			dup2(_readPipe[1], 1);
			execvp([program cStringWithEncoding:
			    OF_STRING_ENCODING_NATIVE], argv);

			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];
		case -1:
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];
		default:
			close(readPipe[1]);
			close(writePipe[0]);
			close(_readPipe[1]);
			close(_writePipe[0]);
			break;
		}
#else
		SECURITY_ATTRIBUTES sa;
		PROCESS_INFORMATION pi;
		STARTUPINFOW si;
		void *pool;
		OFMutableString *argumentsString;
		OFEnumerator *enumerator;
		OFString *argument;
		uint16_t *argumentsCopy;
		size_t length;

		sa.nLength = sizeof(sa);
		sa.bInheritHandle = TRUE;
		sa.lpSecurityDescriptor = NULL;

		if (!CreatePipe(&_readPipe[0], &_readPipe[1], &sa, 0))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];
		if (!CreatePipe(&readPipe[0], &readPipe[1], &sa, 0))

		if (!SetHandleInformation(_readPipe[0], HANDLE_FLAG_INHERIT, 0))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		if (!SetHandleInformation(readPipe[0], HANDLE_FLAG_INHERIT, 0))
		if (!CreatePipe(&_writePipe[0], &_writePipe[1], &sa, 0))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		if (!CreatePipe(&writePipe[0], &writePipe[1], &sa, 0))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		if (!SetHandleInformation(writePipe[1], HANDLE_FLAG_INHERIT, 0))
		if (!SetHandleInformation(_writePipe[1],
		    HANDLE_FLAG_INHERIT, 0))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		memset(&pi, 0, sizeof(pi));
		memset(&si, 0, sizeof(si));

		si.cb = sizeof(si);
		si.hStdInput = writePipe[0];
		si.hStdOutput = readPipe[1];
		si.hStdInput = _writePipe[0];
		si.hStdOutput = _readPipe[1];
		si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
		si.dwFlags |= STARTF_USESTDHANDLES;

		pool = objc_autoreleasePoolPush();

		argumentsString =
		    [OFMutableString stringWithString: programName];
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
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







-
+


-
-
+
+








+
+
+
+
+
+
+







				    exceptionWithClass: [self class]];
		} @finally {
			[self freeMemory: argumentsCopy];
		}

		objc_autoreleasePoolPop(pool);

		process = pi.hProcess;
		_process = pi.hProcess;
		CloseHandle(pi.hThread);

		CloseHandle(readPipe[1]);
		CloseHandle(writePipe[0]);
		CloseHandle(_readPipe[1]);
		CloseHandle(_writePipe[0]);
#endif
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[self close];

	[super dealloc];
}

#ifndef _WIN32
- (char**)OF_environmentForDictionary: (OFDictionary*)environment
{
	OFEnumerator *keyEnumerator, *objectEnumerator;
	char **envp;
	size_t i, count;
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
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







-
+

-
+



-
+












-
-
+
+

-
-
+
+

-
+










-
+








-
-
+
+



-
-
+
+







-
-
-
-
-
-
-



-
+









-
+









-
-
+
+

-
+

-
-
+
+

-
+






-
-
-
-
+
+
+
+

-
-
-
+
+
+


-
-
-
+
+
+

-
-
-
-
+
+
+
+

-
-
-
+
+
+


-
-
-
+
+
+



	return [env items];
}
#endif

- (BOOL)lowlevelIsAtEndOfStream
{
#ifndef _WIN32
	if (readPipe[0] == -1)
	if (_readPipe[0] == -1)
#else
	if (readPipe[0] == NULL)
	if (_readPipe[0] == NULL)
#endif
		return YES;

	return atEndOfStream;
	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) {
	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 (_readPipe[0] == NULL || _atEndOfStream ||
	    !ReadFile(_readPipe[0], buffer, length, &ret, NULL)) {
		if (GetLastError() == ERROR_BROKEN_PIPE) {
			atEndOfStream = YES;
			_atEndOfStream = YES;
			return 0;
		}

#endif
		@throw [OFReadFailedException exceptionWithClass: [self class]
							  stream: self
						 requestedLength: length];
	}

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

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
		     length: (size_t)length
{
#ifndef _WIN32
	if (writePipe[1] == -1 || atEndOfStream ||
	    write(writePipe[1], buffer, length) < length)
	if (_writePipe[1] == -1 || _atEndOfStream ||
	    write(_writePipe[1], buffer, length) < length)
#else
	DWORD ret;

	if (writePipe[1] == NULL || atEndOfStream ||
	    !WriteFile(writePipe[1], buffer, length, &ret, NULL) ||
	if (_writePipe[1] == NULL || _atEndOfStream ||
	    !WriteFile(_writePipe[1], buffer, length, &ret, NULL) ||
	    ret < length)
#endif
		@throw [OFWriteFailedException exceptionWithClass: [self class]
							   stream: self
						  requestedLength: length];
}

- (void)dealloc
{
	[self close];

	[super dealloc];
}

- (int)fileDescriptorForReading
{
#ifndef _WIN32
	return readPipe[0];
	return _readPipe[0];
#else
	[self doesNotRecognizeSelector: _cmd];
	abort();
#endif
}

- (int)fileDescriptorForWriting
{
#ifndef _WIN32
	return writePipe[1];
	return _writePipe[1];
#else
	[self doesNotRecognizeSelector: _cmd];
	abort();
#endif
}

- (void)closeForWriting
{
#ifndef _WIN32
	if (writePipe[1] != -1)
		close(writePipe[1]);
	if (_writePipe[1] != -1)
		close(_writePipe[1]);

	writePipe[1] = -1;
	_writePipe[1] = -1;
#else
	if (writePipe[1] != NULL)
		CloseHandle(writePipe[1]);
	if (_writePipe[1] != NULL)
		CloseHandle(_writePipe[1]);

	writePipe[1] = NULL;
	_writePipe[1] = NULL;
#endif
}

- (void)close
{
#ifndef _WIN32
	if (readPipe[0] != -1)
		close(readPipe[0]);
	if (writePipe[1] != -1)
		close(writePipe[1]);
	if (_readPipe[0] != -1)
		close(_readPipe[0]);
	if (_writePipe[1] != -1)
		close(_writePipe[1]);

	if (pid != -1) {
		kill(pid, SIGKILL);
		waitpid(pid, &status, WNOHANG);
	if (_pid != -1) {
		kill(_pid, SIGKILL);
		waitpid(_pid, &_status, WNOHANG);
	}

	pid = -1;
	readPipe[0] = -1;
	writePipe[1] = -1;
	_pid = -1;
	_readPipe[0] = -1;
	_writePipe[1] = -1;
#else
	if (readPipe[0] != NULL)
		CloseHandle(readPipe[0]);
	if (writePipe[1] != NULL)
		CloseHandle(writePipe[1]);
	if (_readPipe[0] != NULL)
		CloseHandle(_readPipe[0]);
	if (_writePipe[1] != NULL)
		CloseHandle(_writePipe[1]);

	if (process != INVALID_HANDLE_VALUE) {
		TerminateProcess(process, 0);
		CloseHandle(process);
	if (_process != INVALID_HANDLE_VALUE) {
		TerminateProcess(_process, 0);
		CloseHandle(_process);
	}

	process = INVALID_HANDLE_VALUE;
	readPipe[0] = NULL;
	writePipe[1] = NULL;
	_process = INVALID_HANDLE_VALUE;
	_readPipe[0] = NULL;
	_writePipe[1] = NULL;
#endif
}
@end

Modified src/OFRecursiveMutex.h from [b00b0eb498] to [5b6f8dec9f].

21
22
23
24
25
26
27
28
29
30



31
32
33
34
35
36
37
38
39
21
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;
	OFString *name;
	of_rmutex_t _rmutex;
	BOOL _initialized;
	OFString *_name;
}

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

Modified src/OFRecursiveMutex.m from [216e595238] to [42996d602b].

32
33
34
35
36
37
38
39

40
41
42
43
44
45

46
47
48
49
50
51
52

53
54
55
56
57
58
59

60
61
62
63
64

65
66
67
68
69

70
71

72
73
74
75
76

77
78
79
80
81

82
83
84


85
86
87
88
89
90


91
92
93
94
95

96
97
98
99
32
33
34
35
36
37
38

39
40
41
42
43
44

45
46
47
48
49
50
51

52
53
54
55
56
57
58

59
60
61
62
63

64
65
66
67
68

69
70

71
72
73
74
75

76
77
78
79
80

81
82
83

84
85
86
87
88
89


90
91
92
93
94
95

96
97
98
99
100







-
+





-
+






-
+






-
+




-
+




-
+

-
+




-
+




-
+


-
+
+




-
-
+
+




-
+




	return [[[self alloc] init] autorelease];
}

- init
{
	self = [super init];

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

	initialized = YES;
	_initialized = YES;

	return self;
}

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

- (BOOL)tryLock
{
	return of_rmutex_trylock(&rmutex);
	return of_rmutex_trylock(&_rmutex);
}

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

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

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

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

	return [OFString stringWithFormat: @"<%@: %@>", [self className], name];
	return [OFString stringWithFormat: @"<%@: %@>",
					   [self className], _name];
}

- (void)dealloc
{
	if (initialized)
		if (!of_rmutex_free(&rmutex))
	if (_initialized)
		if (!of_rmutex_free(&_rmutex))
			@throw [OFStillLockedException
			    exceptionWithClass: [self class]
					  lock: self];

	[name release];
	[_name release];

	[super dealloc];
}
@end

Modified src/OFRunLoop.h from [ce454681f1] to [8c2fa8ebb3].

27
28
29
30
31
32
33
34

35
36

37
38
39
40



41
42
43
44
45
46
47
27
28
29
30
31
32
33

34
35

36
37



38
39
40
41
42
43
44
45
46
47







-
+

-
+

-
-
-
+
+
+







@class OFMutableDictionary;

/*!
 * @brief A class providing a run loop for the application and its processes.
 */
@interface OFRunLoop: OFObject
{
	OFSortedList *timersQueue;
	OFSortedList *_timersQueue;
#ifdef OF_HAVE_THREADS
	OFMutex *timersQueueLock;
	OFMutex *_timersQueueLock;
#endif
	OFStreamObserver *streamObserver;
	OFMutableDictionary *readQueues;
	volatile BOOL running;
	OFStreamObserver *_streamObserver;
	OFMutableDictionary *_readQueues;
	volatile BOOL _running;
}

/*!
 * @brief Returns the main run loop.
 *
 * @return The main run loop
 */

Modified src/OFRunLoop.m from [9ee569b5cb] to [d21ff8bef4].

29
30
31
32
33
34
35
36

37
38
39
40
41
42








43
44

45


46
47
48
49

50
51
52
53
54
55
56
57

58


59
60
61
62

63
64
65
66
67
68
69

70

71
72
73
74

75
76
77
78
79
80

81









82
83
84
85

86
87
88
89
90

91
92
93
94

95
96
97

98
99
100
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
29
30
31
32
33
34
35

36
37
38




39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54

55
56
57




58

59
60
61
62
63
64
65

66
67
68



69

70
71
72
73
74
75

76
77
78


79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97



98

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







-
+


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

-
+

+
+



-
+


-
-
-
-

-
+

+
+



-
+


-
-
-

-
+

+



-
+


-
-

-
+

+
+
+
+
+
+
+
+
+




+


-
-
-
+
-



+



+


-
-
-
+
-



+



+


-
-
-
+
-



+



+


-
-
-
+
-



+







#import "OFDate.h"

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

static OFRunLoop *mainRunLoop = nil;

@interface OFRunLoop_ReadQueueItem: OFObject
@interface OFRunLoop_QueueItem: OFObject
{
@public
	void *buffer;
	size_t length;
	id target;
	SEL selector;
	id _target;
	SEL _selector;
}
@end

@interface OFRunLoop_ReadQueueItem: OFRunLoop_QueueItem
{
@public
#ifdef OF_HAVE_BLOCKS
	of_stream_async_read_block_t block;
	of_stream_async_read_block_t _block;
#endif
	void *_buffer;
	size_t _length;
}
@end

@interface OFRunLoop_ExactReadQueueItem: OFObject
@interface OFRunLoop_ExactReadQueueItem: OFRunLoop_QueueItem
{
@public
	void *buffer;
	size_t exactLength, readLength;
	id target;
	SEL selector;
#ifdef OF_HAVE_BLOCKS
	of_stream_async_read_block_t block;
	of_stream_async_read_block_t _block;
#endif
	void *_buffer;
	size_t _exactLength, _readLength;
}
@end

@interface OFRunLoop_ReadLineQueueItem: OFObject
@interface OFRunLoop_ReadLineQueueItem: OFRunLoop_QueueItem
{
@public
	of_string_encoding_t encoding;
	id target;
	SEL selector;
#ifdef OF_HAVE_BLOCKS
	of_stream_async_read_line_block_t block;
	of_stream_async_read_line_block_t _block;
#endif
	of_string_encoding_t _encoding;
}
@end

@interface OFRunLoop_AcceptQueueItem: OFObject
@interface OFRunLoop_AcceptQueueItem: OFRunLoop_QueueItem
{
@public
	id target;
	SEL selector;
#ifdef OF_HAVE_BLOCKS
	of_tcpsocket_async_accept_block_t block;
	of_tcpsocket_async_accept_block_t _block;
#endif
}
@end

@implementation OFRunLoop_QueueItem
- (void)dealloc
{
	[_target release];

	[super dealloc];
}
@end

@implementation OFRunLoop_ReadQueueItem
#ifdef OF_HAVE_BLOCKS
- (void)dealloc
{
	[target release];
#ifdef OF_HAVE_BLOCKS
	[block release];
	[_block release];
#endif

	[super dealloc];
}
#endif
@end

@implementation OFRunLoop_ExactReadQueueItem
#ifdef OF_HAVE_BLOCKS
- (void)dealloc
{
	[target release];
#ifdef OF_HAVE_BLOCKS
	[block release];
	[_block release];
#endif

	[super dealloc];
}
#endif
@end

@implementation OFRunLoop_ReadLineQueueItem
#ifdef OF_HAVE_BLOCKS
- (void)dealloc
{
	[target release];
#ifdef OF_HAVE_BLOCKS
	[block release];
	[_block release];
#endif

	[super dealloc];
}
#endif
@end

@implementation OFRunLoop_AcceptQueueItem
#ifdef OF_HAVE_BLOCKS
- (void)dealloc
{
	[target release];
#ifdef OF_HAVE_BLOCKS
	[block release];
	[_block release];
#endif

	[super dealloc];
}
#endif
@end

@implementation OFRunLoop
+ (OFRunLoop*)mainRunLoop
{
	return [[mainRunLoop retain] autorelease];
}
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
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
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
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







-
+




-
-
+
+



-
+














-
-
-
-
+
+
+
+










-
-
-
-
+
+
+
+









-
-
-
+
+
+








-
-
+
+










+
-
-
+
+
-









+
-
-
+
+
-








-
-
+
+







-
+












-
+


-
-
+
+










-
+

-
+


-
-
+
+

-
+










-
+

-
+

-
-
+
+







-
+


-
+


-
+





-
+





-
+




-
+


-
+





-
+






-
+













-
-
+
+






-
-
+
+




-
+

+
-
+







-
-
+
+

-
-
+
+



-
+

+
-
+













-
-
-
-
+
+
+
+





-
-
+
+


-
-
-
-
+
+
+
+
+




-
+


-
+








-
-
+
+

-
-
-
+
+
+

-
+




-
+


-
+















-
+








-
-
+
+




-
+


-
+








-
-
+
+

-
-
+
+




-
+


-
+







{
	mainRunLoop = [runLoop retain];
}

#define ADD(type, code)							\
	void *pool = objc_autoreleasePoolPush();			\
	OFRunLoop *runLoop = [self currentRunLoop];			\
	OFList *queue = [runLoop->readQueues objectForKey: stream];	\
	OFList *queue = [runLoop->_readQueues objectForKey: stream];	\
	type *queueItem;						\
									\
	if (queue == nil) {						\
		queue = [OFList list];					\
		[runLoop->readQueues setObject: queue			\
					forKey: stream];		\
		[runLoop->_readQueues setObject: queue			\
					 forKey: stream];		\
	}								\
									\
	if ([queue count] == 0)						\
		[runLoop->streamObserver addStreamForReading: stream];	\
		[runLoop->_streamObserver addStreamForReading: stream];	\
									\
	queueItem = [[[type alloc] init] autorelease];			\
	code								\
	[queue appendObject: queueItem];				\
									\
	objc_autoreleasePoolPop(pool);

+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
			  length: (size_t)length
			  target: (id)target
			selector: (SEL)selector
{
	ADD(OFRunLoop_ReadQueueItem, {
		queueItem->buffer = buffer;
		queueItem->length = length;
		queueItem->target = [target retain];
		queueItem->selector = selector;
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
		queueItem->_buffer = buffer;
		queueItem->_length = length;
	})
}

+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
		     exactLength: (size_t)exactLength
			  target: (id)target
			selector: (SEL)selector
{
	ADD(OFRunLoop_ExactReadQueueItem, {
		queueItem->buffer = buffer;
		queueItem->exactLength = exactLength;
		queueItem->target = [target retain];
		queueItem->selector = selector;
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
		queueItem->_buffer = buffer;
		queueItem->_exactLength = exactLength;
	})
}

+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
			    encoding: (of_string_encoding_t)encoding
			      target: (id)target
			    selector: (SEL)selector
{
	ADD(OFRunLoop_ReadLineQueueItem, {
		queueItem->encoding = encoding;
		queueItem->target = [target retain];
		queueItem->selector = selector;
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
		queueItem->_encoding = encoding;
	})
}

+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)stream
			       target: (id)target
			     selector: (SEL)selector
{
	ADD(OFRunLoop_AcceptQueueItem, {
		queueItem->target = [target retain];
		queueItem->selector = selector;
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
	})
}

#ifdef OF_HAVE_BLOCKS
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
			  length: (size_t)length
			   block: (of_stream_async_read_block_t)block
{
	ADD(OFRunLoop_ReadQueueItem, {
		queueItem->_block = [block copy];
		queueItem->buffer = buffer;
		queueItem->length = length;
		queueItem->_buffer = buffer;
		queueItem->_length = length;
		queueItem->block = [block copy];
	})
}

+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
		     exactLength: (size_t)exactLength
			   block: (of_stream_async_read_block_t)block
{
	ADD(OFRunLoop_ExactReadQueueItem, {
		queueItem->_block = [block copy];
		queueItem->buffer = buffer;
		queueItem->exactLength = exactLength;
		queueItem->_buffer = buffer;
		queueItem->_exactLength = exactLength;
		queueItem->block = [block copy];
	})
}

+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
			    encoding: (of_string_encoding_t)encoding
			       block: (of_stream_async_read_line_block_t)block
{
	ADD(OFRunLoop_ReadLineQueueItem, {
		queueItem->encoding = encoding;
		queueItem->block = [block copy];
		queueItem->_block = [block copy];
		queueItem->_encoding = encoding;
	})
}

+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)stream
				block: (of_tcpsocket_async_accept_block_t)block
{
	ADD(OFRunLoop_AcceptQueueItem, {
		queueItem->block = [block copy];
		queueItem->_block = [block copy];
	})
}
#endif

#undef ADD

+ (void)OF_cancelAsyncRequestsForStream: (OFStream*)stream
{
	void *pool = objc_autoreleasePoolPush();
	OFRunLoop *runLoop = [self currentRunLoop];
	OFList *queue;

	if ((queue = [runLoop->readQueues objectForKey: stream]) != nil) {
	if ((queue = [runLoop->_readQueues objectForKey: stream]) != nil) {
		assert([queue count] > 0);

		[runLoop->streamObserver removeStreamForReading: stream];
		[runLoop->readQueues removeObjectForKey: stream];
		[runLoop->_streamObserver removeStreamForReading: stream];
		[runLoop->_readQueues removeObjectForKey: stream];
	}

	objc_autoreleasePoolPop(pool);
}

- init
{
	self = [super init];

	@try {
		timersQueue = [[OFSortedList alloc] init];
		_timersQueue = [[OFSortedList alloc] init];
#ifdef OF_HAVE_THREADS
		timersQueueLock = [[OFMutex alloc] init];
		_timersQueueLock = [[OFMutex alloc] init];
#endif

		streamObserver = [[OFStreamObserver alloc] init];
		[streamObserver setDelegate: self];
		_streamObserver = [[OFStreamObserver alloc] init];
		[_streamObserver setDelegate: self];

		readQueues = [[OFMutableDictionary alloc] init];
		_readQueues = [[OFMutableDictionary alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[timersQueue release];
	[_timersQueue release];
#ifdef OF_HAVE_THREADS
	[timersQueueLock release];
	[_timersQueueLock release];
#endif
	[streamObserver release];
	[readQueues release];
	[_streamObserver release];
	[_readQueues release];

	[super dealloc];
}

- (void)addTimer: (OFTimer*)timer
{
#ifdef OF_HAVE_THREADS
	[timersQueueLock lock];
	[_timersQueueLock lock];
	@try {
#endif
		[timersQueue insertObject: timer];
		[_timersQueue insertObject: timer];
#ifdef OF_HAVE_THREADS
	} @finally {
		[timersQueueLock unlock];
		[_timersQueueLock unlock];
	}
#endif

	[timer OF_setInRunLoop: self];

	[streamObserver cancel];
	[_streamObserver cancel];
}

- (void)OF_removeTimer: (OFTimer*)timer
{
#ifdef OF_HAVE_THREADS
	[timersQueueLock lock];
	[_timersQueueLock lock];
	@try {
#endif
		of_list_object_t *iter;

		for (iter = [timersQueue firstListObject]; iter != NULL;
		for (iter = [_timersQueue firstListObject]; iter != NULL;
		    iter = iter->next) {
			if ([iter->object isEqual: timer]) {
				[timersQueue removeListObject: iter];
				[_timersQueue removeListObject: iter];
				break;
			}
		}
#ifdef OF_HAVE_THREADS
	} @finally {
		[timersQueueLock unlock];
		[_timersQueueLock unlock];
	}
#endif
}

- (void)streamIsReadyForReading: (OFStream*)stream
{
	OFList *queue = [readQueues objectForKey: stream];
	OFList *queue = [_readQueues objectForKey: stream];
	of_list_object_t *listObject;

	OF_ENSURE(queue != nil);

	listObject = [queue firstListObject];

	if ([listObject->object isKindOfClass:
	    [OFRunLoop_ReadQueueItem class]]) {
		OFRunLoop_ReadQueueItem *queueItem = listObject->object;
		size_t length;
		OFException *exception = nil;

		@try {
			length = [stream readIntoBuffer: queueItem->buffer
						 length: queueItem->length];
			length = [stream readIntoBuffer: queueItem->_buffer
						 length: queueItem->_length];
		} @catch (OFException *e) {
			length = 0;
			exception = e;
		}

#ifdef OF_HAVE_BLOCKS
		if (queueItem->block != NULL) {
			if (!queueItem->block(stream, queueItem->buffer,
		if (queueItem->_block != NULL) {
			if (!queueItem->_block(stream, queueItem->_buffer,
			    length, exception)) {
				[queue removeListObject: listObject];

				if ([queue count] == 0) {
					[streamObserver
					[_streamObserver
					    removeStreamForReading: stream];
					[_readQueues
					[readQueues removeObjectForKey: stream];
					    removeObjectForKey: stream];
				}
			}
		} else {
#endif
			BOOL (*func)(id, SEL, OFStream*, void*, size_t,
			    OFException*) = (BOOL(*)(id, SEL, OFStream*, void*,
			    size_t, OFException*))
			    [queueItem->target methodForSelector:
			    queueItem->selector];
			    [queueItem->_target methodForSelector:
			    queueItem->_selector];

			if (!func(queueItem->target, queueItem->selector,
			    stream, queueItem->buffer, length, exception)) {
			if (!func(queueItem->_target, queueItem->_selector,
			    stream, queueItem->_buffer, length, exception)) {
				[queue removeListObject: listObject];

				if ([queue count] == 0) {
					[streamObserver
					[_streamObserver
					    removeStreamForReading: stream];
					[_readQueues
					[readQueues removeObjectForKey: stream];
					    removeObjectForKey: stream];
				}
			}
#ifdef OF_HAVE_BLOCKS
		}
#endif
	} else if ([listObject->object isKindOfClass:
	    [OFRunLoop_ExactReadQueueItem class]]) {
		OFRunLoop_ExactReadQueueItem *queueItem = listObject->object;
		size_t length;
		OFException *exception = nil;

		@try {
			length = [stream
			    readIntoBuffer: (char*)queueItem->buffer +
					    queueItem->readLength
				    length: queueItem->exactLength -
					    queueItem->readLength];
			    readIntoBuffer: (char*)queueItem->_buffer +
					    queueItem->_readLength
				    length: queueItem->_exactLength -
					    queueItem->_readLength];
		} @catch (OFException *e) {
			length = 0;
			exception = e;
		}

		queueItem->readLength += length;
		if (queueItem->readLength == queueItem->exactLength ||
		queueItem->_readLength += length;
		if (queueItem->_readLength == queueItem->_exactLength ||
		    [stream isAtEndOfStream] || exception != nil) {
#ifdef OF_HAVE_BLOCKS
			if (queueItem->block != NULL) {
				if (queueItem->block(stream, queueItem->buffer,
				    queueItem->readLength, exception))
					queueItem->readLength = 0;
			if (queueItem->_block != NULL) {
				if (queueItem->_block(stream,
				    queueItem->_buffer, queueItem->_readLength,
				    exception))
					queueItem->_readLength = 0;
				else {
					[queue removeListObject: listObject];

					if ([queue count] == 0) {
						[streamObserver
						[_streamObserver
						    removeStreamForReading:
						    stream];
						[readQueues
						[_readQueues
						    removeObjectForKey: stream];
					}
				}
			} else {
#endif
				BOOL (*func)(id, SEL, OFStream*, void*,
				    size_t, OFException*) = (BOOL(*)(id, SEL,
				    OFStream*, void*, size_t, OFException*))
				    [queueItem->target
				    methodForSelector: queueItem->selector];
				    [queueItem->_target
				    methodForSelector: queueItem->_selector];

				if (func(queueItem->target,
				    queueItem->selector, stream,
				    queueItem->buffer, queueItem->readLength,
				if (func(queueItem->_target,
				    queueItem->_selector, stream,
				    queueItem->_buffer, queueItem->_readLength,
				    exception))
					queueItem->readLength = 0;
					queueItem->_readLength = 0;
				else {
					[queue removeListObject: listObject];

					if ([queue count] == 0) {
						[streamObserver
						[_streamObserver
						    removeStreamForReading:
						    stream];
						[readQueues
						[_readQueues
						    removeObjectForKey: stream];
					}
				}
#ifdef OF_HAVE_BLOCKS
			}
#endif
		}
	} else if ([listObject->object isKindOfClass:
	    [OFRunLoop_ReadLineQueueItem class]]) {
		OFRunLoop_ReadLineQueueItem *queueItem = listObject->object;
		OFString *line;
		OFException *exception = nil;

		@try {
			line = [stream
			    tryReadLineWithEncoding: queueItem->encoding];
			    tryReadLineWithEncoding: queueItem->_encoding];
		} @catch (OFException *e) {
			line = nil;
			exception = e;
		}

		if (line != nil || [stream isAtEndOfStream] ||
		    exception != nil) {
#ifdef OF_HAVE_BLOCKS
			if (queueItem->block != NULL) {
				if (!queueItem->block(stream, line,
			if (queueItem->_block != NULL) {
				if (!queueItem->_block(stream, line,
				    exception)) {
					[queue removeListObject: listObject];

					if ([queue count] == 0) {
						[streamObserver
						[_streamObserver
						    removeStreamForReading:
						    stream];
						[readQueues
						[_readQueues
						    removeObjectForKey: stream];
					}
				}
			} else {
#endif
				BOOL (*func)(id, SEL, OFStream*, OFString*,
				    OFException*) = (BOOL(*)(id, SEL, OFStream*,
				    OFString*, OFException*))
				    [queueItem->target methodForSelector:
				    queueItem->selector];
				    [queueItem->_target methodForSelector:
				    queueItem->_selector];

				if (!func(queueItem->target,
				    queueItem->selector, stream, line,
				if (!func(queueItem->_target,
				    queueItem->_selector, stream, line,
				    exception)) {
					[queue removeListObject: listObject];

					if ([queue count] == 0) {
						[streamObserver
						[_streamObserver
						    removeStreamForReading:
						    stream];
						[readQueues
						[_readQueues
						    removeObjectForKey: stream];
					}
				}
#ifdef OF_HAVE_BLOCKS
			}
#endif
		}
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
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
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
550
551
552
553
554
555
556


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







-
-
+
+




-
+

+
-
+








-
-
+
+

-
+




-
+

+
-
+











-
+

-
+






-
+



-
+







-
+






-
+







-
+


-
+


-
+








-
+






-
+








-
-
+
+


			newSocket = [(OFTCPSocket*)stream accept];
		} @catch (OFException *e) {
			newSocket = nil;
			exception = e;
		}

#ifdef OF_HAVE_BLOCKS
		if (queueItem->block != NULL) {
			if (!queueItem->block((OFTCPSocket*)stream,
		if (queueItem->_block != NULL) {
			if (!queueItem->_block((OFTCPSocket*)stream,
			    newSocket, exception)) {
				[queue removeListObject: listObject];

				if ([queue count] == 0) {
					[streamObserver
					[_streamObserver
					    removeStreamForReading: stream];
					[_readQueues
					[readQueues removeObjectForKey: stream];
					    removeObjectForKey: stream];
				}
			}
		} else {
#endif
			BOOL (*func)(id, SEL, OFTCPSocket*, OFTCPSocket*,
			    OFException*) =
			    (BOOL(*)(id, SEL, OFTCPSocket*, OFTCPSocket*,
			    OFException*))
			    [queueItem->target methodForSelector:
			    queueItem->selector];
			    [queueItem->_target methodForSelector:
			    queueItem->_selector];

			if (!func(queueItem->target, queueItem->selector,
			if (!func(queueItem->_target, queueItem->_selector,
			    (OFTCPSocket*)stream, newSocket, exception)) {
				[queue removeListObject: listObject];

				if ([queue count] == 0) {
					[streamObserver
					[_streamObserver
					    removeStreamForReading: stream];
					[_readQueues
					[readQueues removeObjectForKey: stream];
					    removeObjectForKey: stream];
				}
			}
#ifdef OF_HAVE_BLOCKS
		}
#endif
	} else
		OF_ENSURE(0);
}

- (void)run
{
	running = YES;
	_running = YES;

	while (running) {
	while (_running) {
		void *pool = objc_autoreleasePoolPush();
		OFDate *now = [OFDate date];
		OFTimer *timer;
		OFDate *nextTimer;

#ifdef OF_HAVE_THREADS
		[timersQueueLock lock];
		[_timersQueueLock lock];
		@try {
#endif
			of_list_object_t *listObject =
			    [timersQueue firstListObject];
			    [_timersQueue firstListObject];

			if (listObject != NULL &&
			    [[listObject->object fireDate] compare: now] !=
			    OF_ORDERED_DESCENDING) {
				timer =
				    [[listObject->object retain] autorelease];

				[timersQueue removeListObject: listObject];
				[_timersQueue removeListObject: listObject];

				[timer OF_setInRunLoop: nil];
			} else
				timer = nil;
#ifdef OF_HAVE_THREADS
		} @finally {
			[timersQueueLock unlock];
			[_timersQueueLock unlock];
		}
#endif

		if ([timer isValid])
			[timer fire];

#ifdef OF_HAVE_THREADS
		[timersQueueLock lock];
		[_timersQueueLock lock];
		@try {
#endif
			nextTimer = [[timersQueue firstObject] fireDate];
			nextTimer = [[_timersQueue firstObject] fireDate];
#ifdef OF_HAVE_THREADS
		} @finally {
			[timersQueueLock unlock];
			[_timersQueueLock unlock];
		}
#endif

		/* Watch for stream events until the next timer is due */
		if (nextTimer != nil) {
			double timeout = [nextTimer timeIntervalSinceNow];

			if (timeout > 0)
				[streamObserver observeWithTimeout: timeout];
				[_streamObserver observeWithTimeout: timeout];
		} else {
			/*
			 * No more timers: Just watch for streams until we get
			 * an event. If a timer is added by another thread, it
			 * cancels the observe.
			 */
			[streamObserver observe];
			[_streamObserver observe];
		}

		objc_autoreleasePoolPop(pool);
	}
}

- (void)stop
{
	running = NO;
	[streamObserver cancel];
	_running = NO;
	[_streamObserver cancel];
}
@end

Modified src/OFSHA1Hash.h from [acb4ce3d19] to [0a2f6efcc5].

19
20
21
22
23
24
25
26
27
28
29




30
31
19
20
21
22
23
24
25




26
27
28
29
30
31







-
-
-
-
+
+
+
+


#define OF_SHA1_DIGEST_SIZE 20

/*!
 * @brief A class which provides functions to create an SHA1 hash.
 */
@interface OFSHA1Hash: OFHash
{
	uint32_t state[5];
	uint64_t count;
	char	 buffer[64];
	uint8_t	 digest[OF_SHA1_DIGEST_SIZE];
	uint32_t _state[5];
	uint64_t _count;
	char	 _buffer[64];
	uint8_t	 _digest[OF_SHA1_DIGEST_SIZE];
}
@end

Modified src/OFSHA1Hash.m from [1e025da8be] to [25afa6488f].

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







-
-
-
-
-
+
+
+
+
+




-
+





-
+




-
+





-
+

-
-
+
+



-
-
+
+

-
-
+
+

-
+


-
+


-
+

-
+


	return 64;
}

- init
{
	self = [super init];

	state[0] = 0x67452301;
	state[1] = 0xEFCDAB89;
	state[2] = 0x98BADCFE;
	state[3] = 0x10325476;
	state[4] = 0xC3D2E1F0;
	_state[0] = 0x67452301;
	_state[1] = 0xEFCDAB89;
	_state[2] = 0x98BADCFE;
	_state[3] = 0x10325476;
	_state[4] = 0xC3D2E1F0;

	return self;
}

- (void)updateWithBuffer: (const void*)buffer_
- (void)updateWithBuffer: (const void*)buffer
		  length: (size_t)length
{
	if (length == 0)
		return;

	if (calculated)
	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithClass: [self class]
				  hash: self];

	sha1_update(state, &count, buffer, buffer_, length);
	sha1_update(_state, &_count, _buffer, buffer, length);
}

- (uint8_t*)digest
{
	size_t i;
	char   finalcount[8];
	char finalcount[8];

	if (calculated)
		return digest;
	if (_calculated)
		return _digest;

	for (i = 0; i < 8; i++)
		/* Endian independent */
		finalcount[i] = (char)((count >> ((7 - (i & 7)) * 8)) & 255);
	sha1_update(state, &count, buffer, "\200", 1);
		finalcount[i] = (char)((_count >> ((7 - (i & 7)) * 8)) & 255);
	sha1_update(_state, &_count, _buffer, "\200", 1);

	while ((count & 504) != 448)
		sha1_update(state, &count, buffer, "\0", 1);
	while ((_count & 504) != 448)
		sha1_update(_state, &_count, _buffer, "\0", 1);
	/* Should cause a sha1_transform() */
	sha1_update(state, &count, buffer, finalcount, 8);
	sha1_update(_state, &_count, _buffer, finalcount, 8);

	for (i = 0; i < OF_SHA1_DIGEST_SIZE; i++)
		digest[i] = (char)((state[i >> 2] >>
		_digest[i] = (char)((_state[i >> 2] >>
		    ((3 - (i & 3)) * 8)) & 255);

	calculated = YES;
	_calculated = YES;

	return digest;
	return _digest;
}
@end

Modified src/OFSeekableStream.m from [52f33aa767] to [b3e35f31cf].

30
31
32
33
34
35
36
37
38
39



40
41
30
31
32
33
34
35
36



37
38
39
40
41







-
-
-
+
+
+



- (void)seekToOffset: (off_t)offset
	      whence: (int)whence
{
	[self lowlevelSeekToOffset: offset
			    whence: whence];

	[self freeMemory: cache];
	cache = NULL;
	cacheLength = 0;
	[self freeMemory: _cache];
	_cache = NULL;
	_cacheLength = 0;
}
@end

Modified src/OFSet_hashtable.h from [d95c52fb45] to [74dd4b8396].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#import "OFSet.h"

@class OFMapTable;

@interface OFSet_hashtable: OFSet
{
	OFMapTable *mapTable;
	OFMapTable *_mapTable;
}

- initWithCapacity: (size_t)capacity;
@end

Modified src/OFSet_hashtable.m from [3deaa65aa1] to [86943d9b76].

68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82







-
+







}

- initWithCapacity: (size_t)capacity
{
	self = [super init];

	@try {
		mapTable = [[OFMapTable alloc]
		_mapTable = [[OFMapTable alloc]
		    initWithKeyFunctions: keyFunctions
			  valueFunctions: valueFunctions
				capacity: capacity];
	} @catch (id e) {
		[self release];
		@throw e;
	}
103
104
105
106
107
108
109
110
111


112
113
114
115
116
117
118
103
104
105
106
107
108
109


110
111
112
113
114
115
116
117
118







-
-
+
+







	@try {
		void *pool = objc_autoreleasePoolPush();
		OFEnumerator *enumerator;
		id object;

		enumerator = [set objectEnumerator];
		while ((object = [enumerator nextObject]) != nil)
			[mapTable setValue: (void*)1
				    forKey: object];
			[_mapTable setValue: (void*)1
				     forKey: object];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

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







-
-
+
+



















-
-
+
+







	@try {
		void *pool = objc_autoreleasePoolPush();
		OFEnumerator *enumerator;
		id object;

		enumerator = [array objectEnumerator];
		while ((object = [enumerator nextObject]) != nil)
			[mapTable setValue: (void*)1
				    forKey: object];
			[_mapTable setValue: (void*)1
				     forKey: object];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		size_t i;

		for (i = 0; i < count; i++)
			[mapTable setValue: (void*)1
				    forKey: objects[i]];
			[_mapTable setValue: (void*)1
				     forKey: objects[i]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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







-
+




-
-
+
+


-
-
+
+







		va_list argumentsCopy;
		size_t count;

		va_copy(argumentsCopy, arguments);

		for (count = 1; va_arg(argumentsCopy, id) != nil; count++);

		mapTable = [[OFMapTable alloc]
		_mapTable = [[OFMapTable alloc]
		    initWithKeyFunctions: keyFunctions
			  valueFunctions: valueFunctions
				capacity: count];

		[mapTable setValue: (void*)1
			    forKey: firstObject];
		[_mapTable setValue: (void*)1
			     forKey: firstObject];

		while ((object = va_arg(arguments, id)) != nil)
			[mapTable setValue: (void*)1
				    forKey: object];
			[_mapTable setValue: (void*)1
				     forKey: object];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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







-
-
+
+















-
+






-
+







-
+




-
+






-
+

-
+





-
+







-
-
-
+
+
+






-
+











				      selector: _cmd];

		enumerator = [[element elementsForNamespace:
		    OF_SERIALIZATION_NS] objectEnumerator];
		while ((child = [enumerator nextObject]) != nil) {
			void *pool2  = objc_autoreleasePoolPush();

			[mapTable setValue: (void*)1
				    forKey: [child objectByDeserializing]];
			[_mapTable setValue: (void*)1
				     forKey: [child objectByDeserializing]];

			objc_autoreleasePoolPop(pool2);
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[mapTable release];
	[_mapTable release];

	[super dealloc];
}

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

- (BOOL)containsObject: (id)object
{
	if (object == nil)
		return NO;

	return ([mapTable valueForKey: object] != nil);
	return ([_mapTable valueForKey: object] != nil);
}

- (BOOL)isEqual: (id)object
{
	OFSet_hashtable *otherSet;
	OFSet_hashtable *set;

	if (![object isKindOfClass: [OFSet_hashtable class]] &&
	    ![object isKindOfClass: [OFMutableSet_hashtable class]] &&
	    ![object isKindOfClass: [OFCountedSet_hashtable class]])
		return [super isEqual: object];

	otherSet = object;
	set = object;

	return [otherSet->mapTable isEqual: mapTable];
	return [set->_mapTable isEqual: _mapTable];
}

- (OFEnumerator*)objectEnumerator
{
	return [[[OFMapTableEnumeratorWrapper alloc]
	    initWithEnumerator: [mapTable keyEnumerator]
	    initWithEnumerator: [_mapTable keyEnumerator]
			object: self] autorelease];
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
			     count: (int)count
{
	return [mapTable countByEnumeratingWithState: state
					     objects: objects
					       count: count];
	return [_mapTable countByEnumeratingWithState: state
					      objects: objects
						count: count];
}

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

Modified src/OFSortedList.m from [153621bbfc] to [0d00948527].

47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62







-
+








	abort();
}

- (of_list_object_t*)insertObject: (id <OFComparing>)object
{
	of_list_object_t *iter;

	for (iter = lastListObject; iter != NULL; iter = iter->previous) {
	for (iter = _lastListObject; iter != NULL; iter = iter->previous) {
		if ([object compare: iter->object] != OF_ORDERED_ASCENDING)
			return [super insertObject: object
				   afterListObject: iter];
	}

	return [super prependObject: object];
}
@end

Modified src/OFStream.h from [6b4f15f3b1] to [57e418e361].

53
54
55
56
57
58
59
60
61
62
63
64





65
66
67
68
69
70
71
53
54
55
56
57
58
59





60
61
62
63
64
65
66
67
68
69
70
71







-
-
-
-
-
+
+
+
+
+







 *	 the methods that do the actual work. OFStream uses those for all other
 *	 methods and does all the caching and other stuff for you. If you
 *	 override these methods without the lowlevel prefix, you *will* break
 *	 caching and get broken results!
 */
@interface OFStream: OFObject <OFCopying>
{
	char   *cache;
	char   *writeBuffer;
	size_t cacheLength, writeBufferLength;
	BOOL   writeBufferEnabled;
	BOOL   blocking, waitingForDelimiter;
	char   *_cache;
	char   *_writeBuffer;
	size_t _cacheLength, _writeBufferLength;
	BOOL   _writeBufferEnabled;
	BOOL   _blocking, _waitingForDelimiter;
}

#ifdef OF_HAVE_PROPERTIES
@property (getter=isWriteBufferEnabled) BOOL writeBufferEnabled;
@property (getter=isBlocking) BOOL blocking;
@property (readonly, getter=isAtEndOfStream) BOOL atEndOfStream;
#endif

Modified src/OFStream.m from [3a3eebc79f] to [0bbf55df10].

64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
64
65
66
67
68
69
70



71
72
73
74
75
76
77
78







-
-
-
+







			[self release];
			@throw e;
		}
	}

	self = [super init];

	cache = NULL;
	writeBuffer = NULL;
	blocking = YES;
	_blocking = YES;

	return self;
}

- (BOOL)lowlevelIsAtEndOfStream
{
	[self doesNotRecognizeSelector: _cmd];
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
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







-
+








-
+



-
-
-
+
+
+

-
-
-
+
+
+



-
-
+
+

-
+

-
-
-
+
+
+







- copy
{
	return [self retain];
}

- (BOOL)isAtEndOfStream
{
	if (cacheLength > 0)
	if (_cacheLength > 0)
		return NO;

	return [self lowlevelIsAtEndOfStream];
}

- (size_t)readIntoBuffer: (void*)buffer
		  length: (size_t)length
{
	if (cacheLength == 0)
	if (_cacheLength == 0)
		return [self lowlevelReadIntoBuffer: buffer
					     length: length];

	if (length >= cacheLength) {
		size_t ret = cacheLength;
		memcpy(buffer, cache, cacheLength);
	if (length >= _cacheLength) {
		size_t ret = _cacheLength;
		memcpy(buffer, _cache, _cacheLength);

		[self freeMemory: cache];
		cache = NULL;
		cacheLength = 0;
		[self freeMemory: _cache];
		_cache = NULL;
		_cacheLength = 0;

		return ret;
	} else {
		char *tmp = [self allocMemoryWithSize: cacheLength - length];
		memcpy(tmp, cache + length, cacheLength - length);
		char *tmp = [self allocMemoryWithSize: _cacheLength - length];
		memcpy(tmp, _cache + length, _cacheLength - length);

		memcpy(buffer, cache, length);
		memcpy(buffer, _cache, length);

		[self freeMemory: cache];
		cache = tmp;
		cacheLength -= length;
		[self freeMemory: _cache];
		_cache = tmp;
		_cacheLength -= length;

		return length;
	}
}

- (void)readIntoBuffer: (void*)buffer
	   exactLength: (size_t)length
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
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
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
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







-
-
-
+
+
+
+


-
+


-
+




-
+

-
-
+
+

-
-
-
+
+
+

-
+











-
-
+
+



-
+

-
+


-
+



-
-
-
+
+
+

-
+










-
+



-
-
-
+
+
+
+


















-
-
-
+
+
+


-
-
+
+


-
+












-
-
-
+
+
+

-
+





-
-
+
+


-
-
+
+

-
-
+
+

-
+




-
+







- (OFString*)tryReadLineWithEncoding: (of_string_encoding_t)encoding
{
	size_t i, pageSize, bufferLength, retLength;
	char *retCString, *buffer, *newCache;
	OFString *ret;

	/* Look if there's a line or \0 in our cache */
	if (!waitingForDelimiter && cache != NULL) {
		for (i = 0; i < cacheLength; i++) {
			if OF_UNLIKELY (cache[i] == '\n' || cache[i] == '\0') {
	if (!_waitingForDelimiter && _cache != NULL) {
		for (i = 0; i < _cacheLength; i++) {
			if OF_UNLIKELY (_cache[i] == '\n' ||
			    _cache[i] == '\0') {
				retLength = i;

				if (i > 0 && cache[i - 1] == '\r')
				if (i > 0 && _cache[i - 1] == '\r')
					retLength--;

				ret = [OFString stringWithCString: cache
				ret = [OFString stringWithCString: _cache
							 encoding: encoding
							   length: retLength];

				newCache = [self
				    allocMemoryWithSize: cacheLength - i - 1];
				    allocMemoryWithSize: _cacheLength - i - 1];
				if (newCache != NULL)
					memcpy(newCache, cache + i + 1,
					    cacheLength - i - 1);
					memcpy(newCache, _cache + i + 1,
					    _cacheLength - i - 1);

				[self freeMemory: cache];
				cache = newCache;
				cacheLength -= i + 1;
				[self freeMemory: _cache];
				_cache = newCache;
				_cacheLength -= i + 1;

				waitingForDelimiter = NO;
				_waitingForDelimiter = NO;
				return ret;
			}
		}
	}

	/* Read and see if we got a newline or \0 */
	pageSize = [OFSystemInfo pageSize];
	buffer = [self allocMemoryWithSize: pageSize];

	@try {
		if ([self lowlevelIsAtEndOfStream]) {
			if (cache == NULL) {
				waitingForDelimiter = NO;
			if (_cache == NULL) {
				_waitingForDelimiter = NO;
				return nil;
			}

			retLength = cacheLength;
			retLength = _cacheLength;

			if (retLength > 0 && cache[retLength - 1] == '\r')
			if (retLength > 0 && _cache[retLength - 1] == '\r')
				retLength--;

			ret = [OFString stringWithCString: cache
			ret = [OFString stringWithCString: _cache
						 encoding: encoding
						   length: retLength];

			[self freeMemory: cache];
			cache = NULL;
			cacheLength = 0;
			[self freeMemory: _cache];
			_cache = NULL;
			_cacheLength = 0;

			waitingForDelimiter = NO;
			_waitingForDelimiter = NO;
			return ret;
		}

		bufferLength = [self lowlevelReadIntoBuffer: buffer
						     length: pageSize];

		/* Look if there's a newline or \0 */
		for (i = 0; i < bufferLength; i++) {
			if OF_UNLIKELY (buffer[i] == '\n' ||
			    buffer[i] == '\0') {
				retLength = cacheLength + i;
				retLength = _cacheLength + i;
				retCString = [self
				    allocMemoryWithSize: retLength];

				if (cache != NULL)
					memcpy(retCString, cache, cacheLength);
				memcpy(retCString + cacheLength, buffer, i);
				if (_cache != NULL)
					memcpy(retCString, _cache,
					    _cacheLength);
				memcpy(retCString + _cacheLength, buffer, i);

				if (retLength > 0 &&
				    retCString[retLength - 1] == '\r')
					retLength--;

				@try {
					char *rcs = retCString;
					size_t rl = retLength;

					ret = [OFString
					    stringWithCString: rcs
						     encoding: encoding
						       length: rl];
				} @catch (id e) {
					/*
					 * Append data to cache to prevent loss
					 * of data due to wrong encoding.
					 */
					cache = [self
					    resizeMemory: cache
						    size: cacheLength +
					_cache = [self
					    resizeMemory: _cache
						    size: _cacheLength +
							  bufferLength];

					if (cache != NULL)
						memcpy(cache + cacheLength,
					if (_cache != NULL)
						memcpy(_cache + _cacheLength,
						    buffer, bufferLength);

					cacheLength += bufferLength;
					_cacheLength += bufferLength;

					@throw e;
				} @finally {
					[self freeMemory: retCString];
				}

				newCache = [self allocMemoryWithSize:
				    bufferLength - i - 1];
				if (newCache != NULL)
					memcpy(newCache, buffer + i + 1,
					    bufferLength - i - 1);

				[self freeMemory: cache];
				cache = newCache;
				cacheLength = bufferLength - i - 1;
				[self freeMemory: _cache];
				_cache = newCache;
				_cacheLength = bufferLength - i - 1;

				waitingForDelimiter = NO;
				_waitingForDelimiter = NO;
				return ret;
			}
		}

		/* There was no newline or \0 */
		cache = [self resizeMemory: cache
				      size: cacheLength + bufferLength];
		_cache = [self resizeMemory: _cache
				       size: _cacheLength + bufferLength];

		/*
		 * It's possible that cacheLen + len is 0 and thus cache was
		 * set to NULL by resizeMemory:size:.
		 * It's possible that _cacheLength + bufferLength is 0 and thus
		 * _cache was set to NULL by resizeMemory:size:.
		 */
		if (cache != NULL)
			memcpy(cache + cacheLength, buffer, bufferLength);
		if (_cache != NULL)
			memcpy(_cache + _cacheLength, buffer, bufferLength);

		cacheLength += bufferLength;
		_cacheLength += bufferLength;
	} @finally {
		[self freeMemory: buffer];
	}

	waitingForDelimiter = YES;
	_waitingForDelimiter = YES;
	return nil;
}

- (OFString*)readLine
{
	return [self readLineWithEncoding: OF_STRING_ENCODING_UTF_8];
}
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
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
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
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
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
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







-
-
-
+
+
+


-
-
+
+



-
+




-
+

-
-
+
+

-
-
-
+
+
+

-
+











-
-
+
+



-
+

-
+

-
-
-
+
+
+

-
+















-
+




-
-
-
-
+
+
+
+
+

-
+




















-
-
-
+
+
+

-
+





-
-
+
+


-
-
+
+

-
+
-
-
+

-
+




-
+








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

	/* Look if there's something in our cache */
	if (!waitingForDelimiter && cache != NULL) {
		for (i = 0; i < cacheLength; i++) {
			if (cache[i] != delimiterCString[j++])
	if (!_waitingForDelimiter && _cache != NULL) {
		for (i = 0; i < _cacheLength; i++) {
			if (_cache[i] != delimiterCString[j++])
				j = 0;

			if (j == delimiterLength || cache[i] == '\0') {
				if (cache[i] == '\0')
			if (j == delimiterLength || _cache[i] == '\0') {
				if (_cache[i] == '\0')
					delimiterLength = 1;

				ret = [OFString
				    stringWithCString: cache
				    stringWithCString: _cache
					     encoding: encoding
					      length: i + 1 - delimiterLength];

				newCache = [self allocMemoryWithSize:
				    cacheLength - i - 1];
				    _cacheLength - i - 1];
				if (newCache != NULL)
					memcpy(newCache, cache + i + 1,
					    cacheLength - i - 1);
					memcpy(newCache, _cache + i + 1,
					    _cacheLength - i - 1);

				[self freeMemory: cache];
				cache = newCache;
				cacheLength -= i + 1;
				[self freeMemory: _cache];
				_cache = newCache;
				_cacheLength -= i + 1;

				waitingForDelimiter = NO;
				_waitingForDelimiter = NO;
				return ret;
			}
		}
	}

	/* Read and see if we got a delimiter or \0 */
	pageSize = [OFSystemInfo pageSize];
	buffer = [self allocMemoryWithSize: pageSize];

	@try {
		if ([self lowlevelIsAtEndOfStream]) {
			if (cache == NULL) {
				waitingForDelimiter = NO;
			if (_cache == NULL) {
				_waitingForDelimiter = NO;
				return nil;
			}

			ret = [OFString stringWithCString: cache
			ret = [OFString stringWithCString: _cache
						 encoding: encoding
						   length: cacheLength];
						   length: _cacheLength];

			[self freeMemory: cache];
			cache = NULL;
			cacheLength = 0;
			[self freeMemory: _cache];
			_cache = NULL;
			_cacheLength = 0;

			waitingForDelimiter = NO;
			_waitingForDelimiter = NO;
			return ret;
		}

		bufferLength = [self lowlevelReadIntoBuffer: buffer
						     length: pageSize];

		/* Look if there's a delimiter or \0 */
		for (i = 0; i < bufferLength; i++) {
			if (buffer[i] != delimiterCString[j++])
				j = 0;

			if (j == delimiterLength || buffer[i] == '\0') {
				if (buffer[i] == '\0')
					delimiterLength = 1;

				retLength = cacheLength + i + 1 -
				retLength = _cacheLength + i + 1 -
				    delimiterLength;
				retCString = [self
				    allocMemoryWithSize: retLength];

				if (cache != NULL && cacheLength <= retLength)
					memcpy(retCString, cache, cacheLength);
				else if (cache != NULL)
					memcpy(retCString, cache, retLength);
				if (_cache != NULL && _cacheLength <= retLength)
					memcpy(retCString, _cache,
					    _cacheLength);
				else if (_cache != NULL)
					memcpy(retCString, _cache, retLength);
				if (i >= delimiterLength)
					memcpy(retCString + cacheLength,
					memcpy(retCString + _cacheLength,
					    buffer, i + 1 - delimiterLength);

				@try {
					char *rcs = retCString;
					size_t rl = retLength;

					ret = [OFString
					    stringWithCString: rcs
						     encoding: encoding
						       length: rl];
				} @finally {
					[self freeMemory: retCString];
				}

				newCache = [self allocMemoryWithSize:
				    bufferLength - i - 1];
				if (newCache != NULL)
					memcpy(newCache, buffer + i + 1,
					    bufferLength - i - 1);

				[self freeMemory: cache];
				cache = newCache;
				cacheLength = bufferLength - i - 1;
				[self freeMemory: _cache];
				_cache = newCache;
				_cacheLength = bufferLength - i - 1;

				waitingForDelimiter = NO;
				_waitingForDelimiter = NO;
				return ret;
			}
		}

		/* Neither the delimiter nor \0 was found */
		cache = [self resizeMemory: cache
				      size: cacheLength + bufferLength];
		_cache = [self resizeMemory: _cache
				       size: _cacheLength + bufferLength];

		/*
		 * It's possible that cacheLen + len is 0 and thus cache was
		 * set to NULL by resizeMemory:size:.
		 * It's possible that _cacheLength + bufferLength is 0 and thus
		 * _cache was set to NULL by resizeMemory:size:.
		 */
		if (cache != NULL)
		if (_cache != NULL)
			memcpy(cache + cacheLength, buffer,
			    bufferLength);
			memcpy(_cache + _cacheLength, buffer, bufferLength);

		cacheLength += bufferLength;
		_cacheLength += bufferLength;
	} @finally {
		[self freeMemory: buffer];
	}

	waitingForDelimiter = YES;
	_waitingForDelimiter = YES;
	return nil;
}


- (OFString*)readTillDelimiter: (OFString*)delimiter
{
	return [self readTillDelimiter: delimiter
935
936
937
938
939
940
941
942

943
944
945
946
947

948
949
950
951
952

953
954
955
956


957
958
959
960



961
962
963
964
965
966

967
968
969
970
971
972
973




974
975
976
977
978
979
980
935
936
937
938
939
940
941

942
943
944
945
946

947
948
949
950
951

952
953
954


955
956
957



958
959
960
961
962
963
964
965

966
967
968
969




970
971
972
973
974
975
976
977
978
979
980







-
+




-
+




-
+


-
-
+
+

-
-
-
+
+
+





-
+



-
-
-
-
+
+
+
+







{
	return [self tryReadTillDelimiter: delimiter
				 encoding: OF_STRING_ENCODING_UTF_8];
}

- (BOOL)isWriteBufferEnabled
{
	return writeBufferEnabled;
	return _writeBufferEnabled;
}

- (void)setWriteBufferEnabled: (BOOL)enable
{
	writeBufferEnabled = enable;
	_writeBufferEnabled = enable;
}

- (void)flushWriteBuffer
{
	if (writeBuffer == NULL)
	if (_writeBuffer == NULL)
		return;

	[self lowlevelWriteBuffer: writeBuffer
			   length: writeBufferLength];
	[self lowlevelWriteBuffer: _writeBuffer
			   length: _writeBufferLength];

	[self freeMemory: writeBuffer];
	writeBuffer = NULL;
	writeBufferLength = 0;
	[self freeMemory: _writeBuffer];
	_writeBuffer = NULL;
	_writeBufferLength = 0;
}

- (void)writeBuffer: (const void*)buffer
	     length: (size_t)length
{
	if (!writeBufferEnabled)
	if (!_writeBufferEnabled)
		[self lowlevelWriteBuffer: buffer
				   length: length];
	else {
		writeBuffer = [self resizeMemory: writeBuffer
					    size: writeBufferLength + length];
		memcpy(writeBuffer + writeBufferLength, buffer, length);
		writeBufferLength += length;
		_writeBuffer = [self resizeMemory: _writeBuffer
					     size: _writeBufferLength + length];
		memcpy(_writeBuffer + _writeBufferLength, buffer, length);
		_writeBufferLength += length;
	}
}

- (void)writeInt8: (uint8_t)int8
{
	[self writeBuffer: (char*)&int8
		   length: 1];
1452
1453
1454
1455
1456
1457
1458
1459

1460
1461
1462
1463
1464

1465
1466
1467
1468
1469
1470
1471
1452
1453
1454
1455
1456
1457
1458

1459
1460
1461
1462
1463

1464
1465
1466
1467
1468
1469
1470
1471







-
+




-
+







	}

	return length;
}

- (size_t)pendingBytes
{
	return cacheLength;
	return _cacheLength;
}

- (BOOL)isBlocking
{
	return blocking;
	return _blocking;
}

- (void)setBlocking: (BOOL)enable
{
#ifndef _WIN32
	BOOL readImplemented = NO, writeImplemented = NO;

1519
1520
1521
1522
1523
1524
1525


1526
1527
1528
1529
1530
1531
1532
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534







+
+







	} @catch (OFNotImplementedException *e) {
	}

	if (!readImplemented && !writeImplemented)
		@throw [OFNotImplementedException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	_blocking = enable;
#else
	[self doesNotRecognizeSelector: _cmd];
	abort();
#endif
}

- (int)fileDescriptorForReading
1550
1551
1552
1553
1554
1555
1556
1557

1558
1559
1552
1553
1554
1555
1556
1557
1558

1559
1560
1561







-
+


{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (BOOL)OF_isWaitingForDelimiter
{
	return waitingForDelimiter;
	return _waitingForDelimiter;
}
@end

Modified src/OFStreamObserver.h from [b07d550270] to [cdfadcf2ee].

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







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

-
+


-
+







/*!
 * @brief A class that can observe multiple streams at once.
 *
 * @note Currently, Win32 can only observe sockets and not files!
 */
@interface OFStreamObserver: OFObject
{
	OFMutableArray *readStreams;
	OFMutableArray *writeStreams;
	__unsafe_unretained OFStream **FDToStream;
	size_t maxFD;
	OFMutableArray *queue;
	OFDataArray *queueInfo, *queueFDs;
	id <OFStreamObserverDelegate> delegate;
	int cancelFD[2];
	OFMutableArray *_readStreams;
	OFMutableArray *_writeStreams;
	__unsafe_unretained OFStream **_FDToStream;
	size_t _maxFD;
	OFMutableArray *_queue;
	OFDataArray *_queueInfo, *_queueFDs;
	id <OFStreamObserverDelegate> _delegate;
	int _cancelFD[2];
#ifdef _WIN32
	struct sockaddr_in cancelAddr;
	struct sockaddr_in _cancelAddr;
#endif
#ifdef OF_HAVE_THREADS
	OFMutex *mutex;
	OFMutex *_mutex;
#endif
}

#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFStreamObserverDelegate> delegate;
#endif

Modified src/OFStreamObserver.m from [b6d33523f1] to [67edca5fb3].

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







-
-
-
-
-
+
+
+
+
+
+


-
+






-
-
+
+

-
-
+
+



-
-
-
-
+
+
+
+

-
-
+
+




-
+

-
+





-
-
-
-
+
+
+
+


-
+











-
-
+
+

-
-
-
-
-
+
+
+
+
+

-
+







-
+


-
+

-
+





-
+





-
-
-
+
+
+


-
+









-
+





-
-
-
+
+
+


-
+









-
+





-
-
-
+
+
+


-
+



-
-
-
-
-
+
-





-
+





-
-
-
+
+
+


-
+



-
-
-
-
-
+
-








	@try {
#ifdef _WIN32
		struct sockaddr_in cancelAddr2;
		socklen_t cancelAddrLen;
#endif

		readStreams = [[OFMutableArray alloc] init];
		writeStreams = [[OFMutableArray alloc] init];
		queue = [[OFMutableArray alloc] init];
		queueInfo = [[OFDataArray alloc] initWithItemSize: sizeof(int)];
		queueFDs = [[OFDataArray alloc] initWithItemSize: sizeof(int)];
		_readStreams = [[OFMutableArray alloc] init];
		_writeStreams = [[OFMutableArray alloc] init];
		_queue = [[OFMutableArray alloc] init];
		_queueInfo = [[OFDataArray alloc]
		    initWithItemSize: sizeof(int)];
		_queueFDs = [[OFDataArray alloc] initWithItemSize: sizeof(int)];

#ifndef _WIN32
		if (pipe(cancelFD))
		if (pipe(_cancelFD))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];
#else
		/* Make sure WSAStartup has been called */
		[OFTCPSocket class];

		cancelFD[0] = socket(AF_INET, SOCK_DGRAM, 0);
		cancelFD[1] = socket(AF_INET, SOCK_DGRAM, 0);
		_cancelFD[0] = socket(AF_INET, SOCK_DGRAM, 0);
		_cancelFD[1] = socket(AF_INET, SOCK_DGRAM, 0);

		if (cancelFD[0] == INVALID_SOCKET ||
		    cancelFD[1] == INVALID_SOCKET)
		if (_cancelFD[0] == INVALID_SOCKET ||
		    _cancelFD[1] == INVALID_SOCKET)
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		cancelAddr.sin_family = AF_INET;
		cancelAddr.sin_port = 0;
		cancelAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
		cancelAddr2 = cancelAddr;
		_cancelAddr.sin_family = AF_INET;
		_cancelAddr.sin_port = 0;
		_cancelAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
		cancelAddr2 = _cancelAddr;

		if (bind(cancelFD[0], (struct sockaddr*)&cancelAddr,
		    sizeof(cancelAddr)) || bind(cancelFD[1],
		if (bind(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
		    sizeof(_cancelAddr)) || bind(_cancelFD[1],
		    (struct sockaddr*)&cancelAddr2, sizeof(cancelAddr2)))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		cancelAddrLen = sizeof(cancelAddr);
		cancelAddrLen = sizeof(_cancelAddr);

		if (getsockname(cancelFD[0], (struct sockaddr*)&cancelAddr,
		if (getsockname(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
		    &cancelAddrLen))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];
#endif

		maxFD = cancelFD[0];
		FDToStream = [self allocMemoryWithSize: sizeof(OFStream*)
						 count: maxFD + 1];
		FDToStream[cancelFD[0]] = nil;
		_maxFD = _cancelFD[0];
		_FDToStream = [self allocMemoryWithSize: sizeof(OFStream*)
						  count: _maxFD + 1];
		_FDToStream[_cancelFD[0]] = nil;

#ifdef OF_HAVE_THREADS
		mutex = [[OFMutex alloc] init];
		_mutex = [[OFMutex alloc] init];
#endif
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	close(cancelFD[0]);
	close(cancelFD[1]);
	close(_cancelFD[0]);
	close(_cancelFD[1]);

	[readStreams release];
	[writeStreams release];
	[queue release];
	[queueInfo release];
	[queueFDs release];
	[_readStreams release];
	[_writeStreams release];
	[_queue release];
	[_queueInfo release];
	[_queueFDs release];
#ifdef OF_HAVE_THREADS
	[mutex release];
	[_mutex release];
#endif

	[super dealloc];
}

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

- (void)setDelegate: (id <OFStreamObserverDelegate>)delegate_
- (void)setDelegate: (id <OFStreamObserverDelegate>)delegate
{
	delegate = delegate_;
	_delegate = delegate;
}

- (void)addStreamForReading: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
	[mutex lock];
	[_mutex lock];
#endif
	@try {
		int qi = QUEUE_ADD | QUEUE_READ;
		int fd = [stream fileDescriptorForReading];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];
		[_queue addObject: stream];
		[_queueInfo addItem: &qi];
		[_queueFDs addItem: &fd];
	} @finally {
#ifdef OF_HAVE_THREADS
		[mutex unlock];
		[_mutex unlock];
#endif
	}

	[self cancel];
}

- (void)addStreamForWriting: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
	[mutex lock];
	[_mutex lock];
#endif
	@try {
		int qi = QUEUE_ADD | QUEUE_WRITE;
		int fd = [stream fileDescriptorForWriting];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];
		[_queue addObject: stream];
		[_queueInfo addItem: &qi];
		[_queueFDs addItem: &fd];
	} @finally {
#ifdef OF_HAVE_THREADS
		[mutex unlock];
		[_mutex unlock];
#endif
	}

	[self cancel];
}

- (void)removeStreamForReading: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
	[mutex lock];
	[_mutex lock];
#endif
	@try {
		int qi = QUEUE_REMOVE | QUEUE_READ;
		int fd = [stream fileDescriptorForReading];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];
		[_queue addObject: stream];
		[_queueInfo addItem: &qi];
		[_queueFDs addItem: &fd];
	} @finally {
#ifdef OF_HAVE_THREADS
		[mutex unlock];
		[_mutex unlock];
#endif
	}

#ifndef _WIN32
	OF_ENSURE(write(cancelFD[1], "", 1) > 0);
#else
	OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr,
	    sizeof(cancelAddr)) > 0);
	[self cancel];
#endif
}

- (void)removeStreamForWriting: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
	[mutex lock];
	[_mutex lock];
#endif
	@try {
		int qi = QUEUE_REMOVE | QUEUE_WRITE;
		int fd = [stream fileDescriptorForWriting];

		[queue addObject: stream];
		[queueInfo addItem: &qi];
		[queueFDs addItem: &fd];
		[_queue addObject: stream];
		[_queueInfo addItem: &qi];
		[_queueFDs addItem: &fd];
	} @finally {
#ifdef OF_HAVE_THREADS
		[mutex unlock];
		[_mutex unlock];
#endif
	}

#ifndef _WIN32
	OF_ENSURE(write(cancelFD[1], "", 1) > 0);
#else
	OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr,
	    sizeof(cancelAddr)) > 0);
	[self cancel];
#endif
}

- (void)OF_addFileDescriptorForReading: (int)fd
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}
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
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







-
+


-
-
-
-
+
+
+
+







-
-
-
-
+
+
+
+

-
+


-
+




-
+




-
+





-
+





-
+





-
+









-
-
-
+
+
+


-
+


















-
+

-
-
+
+





-
-
+
+

-






-
+

-
+







	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (void)OF_processQueue
{
#ifdef OF_HAVE_THREADS
	[mutex lock];
	[_mutex lock];
#endif
	@try {
		OFStream **queueObjects = [queue objects];
		int *queueInfoItems = [queueInfo items];
		int *queueFDsItems = [queueFDs items];
		size_t i, count = [queue count];
		OFStream **queueObjects = [_queue objects];
		int *queueInfoItems = [_queueInfo items];
		int *queueFDsItems = [_queueFDs items];
		size_t i, count = [_queue count];

		for (i = 0; i < count; i++) {
			OFStream *stream = queueObjects[i];
			int action = queueInfoItems[i];
			int fd = queueFDsItems[i];

			if ((action & QUEUE_ACTION) == QUEUE_ADD) {
				if (fd > maxFD) {
					maxFD = fd;
					FDToStream = [self
					    resizeMemory: FDToStream
				if (fd > _maxFD) {
					_maxFD = fd;
					_FDToStream = [self
					    resizeMemory: _FDToStream
						    size: sizeof(OFStream*)
						   count: maxFD + 1];
						   count: _maxFD + 1];
				}

				FDToStream[fd] = stream;
				_FDToStream[fd] = stream;
			}

			if ((action & QUEUE_ACTION) == QUEUE_REMOVE) {
				/* FIXME: Maybe downsize? */
				FDToStream[fd] = nil;
				_FDToStream[fd] = nil;
			}

			switch (action) {
			case QUEUE_ADD | QUEUE_READ:
				[readStreams addObject: stream];
				[_readStreams addObject: stream];

				[self OF_addFileDescriptorForReading: fd];

				break;
			case QUEUE_ADD | QUEUE_WRITE:
				[writeStreams addObject: stream];
				[_writeStreams addObject: stream];

				[self OF_addFileDescriptorForWriting: fd];

				break;
			case QUEUE_REMOVE | QUEUE_READ:
				[readStreams removeObjectIdenticalTo: stream];
				[_readStreams removeObjectIdenticalTo: stream];

				[self OF_removeFileDescriptorForReading: fd];

				break;
			case QUEUE_REMOVE | QUEUE_WRITE:
				[writeStreams removeObjectIdenticalTo: stream];
				[_writeStreams removeObjectIdenticalTo: stream];

				[self OF_removeFileDescriptorForWriting: fd];

				break;
			default:
				assert(0);
			}
		}

		[queue removeAllObjects];
		[queueInfo removeAllItems];
		[queueFDs removeAllItems];
		[_queue removeAllObjects];
		[_queueInfo removeAllItems];
		[_queueFDs removeAllItems];
	} @finally {
#ifdef OF_HAVE_THREADS
		[mutex unlock];
		[_mutex unlock];
#endif
	}
}

- (void)observe
{
	[self observeWithTimeout: -1];
}

- (BOOL)observeWithTimeout: (double)timeout
{
	[self doesNotRecognizeSelector: _cmd];
	abort();
}

- (void)cancel
{
#ifndef _WIN32
	OF_ENSURE(write(cancelFD[1], "", 1) > 0);
	OF_ENSURE(write(_cancelFD[1], "", 1) > 0);
#else
	OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr,
	    sizeof(cancelAddr)) > 0);
	OF_ENSURE(sendto(_cancelFD[1], "", 1, 0, (struct sockaddr*)&_cancelAddr,
	    sizeof(_cancelAddr)) > 0);
#endif
}

- (BOOL)OF_processCache
{
	OFStream **objects = [readStreams objects];
	size_t i, count = [readStreams count];
	OFStream **objects = [_readStreams objects];
	size_t i, count = [_readStreams count];
	BOOL foundInCache = NO;


	for (i = 0; i < count; i++) {
		if ([objects[i] pendingBytes] > 0 &&
		    ![objects[i] OF_isWaitingForDelimiter]) {
			void *pool = objc_autoreleasePoolPush();

			if ([delegate respondsToSelector:
			if ([_delegate respondsToSelector:
			    @selector(streamIsReadyForReading:)])
				[delegate streamIsReadyForReading: objects[i]];
				[_delegate streamIsReadyForReading: objects[i]];

			foundInCache = YES;

			objc_autoreleasePoolPop(pool);
		}
	}

Modified src/OFStreamObserver_kqueue.h from [88b5dfe561] to [5159b313b1].

16
17
18
19
20
21
22
23
24


25
26
16
17
18
19
20
21
22


23
24
25
26







-
-
+
+



#import "OFStreamObserver.h"

@class OFDataArray;

@interface OFStreamObserver_kqueue: OFStreamObserver
{
	int kernelQueue;
	OFDataArray *changeList;
	int _kernelQueue;
	OFDataArray *_changeList;
}
@end

Modified src/OFStreamObserver_kqueue.m from [fe73536f5b] to [fd7c063d3b].

39
40
41
42
43
44
45
46

47
48
49
50

51
52
53

54
55
56
57
58
59
60
61
62
63
64
65


66
67
68
69
70
71
72
73
74

75
76
77
78

79
80
81
82
83
84
85

86
87
88
89

90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
39
40
41
42
43
44
45

46
47
48
49

50
51
52

53
54
55
56
57
58
59
60
61
62
63


64
65
66
67
68
69
70
71
72
73

74
75
76
77

78
79
80
81
82
83
84

85
86
87
88

89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112







-
+



-
+


-
+










-
-
+
+








-
+



-
+






-
+



-
+







-
+







-
+








@implementation OFStreamObserver_kqueue
- init
{
	self = [super init];

	@try {
		if ((kernelQueue = kqueue()) == -1)
		if ((_kernelQueue = kqueue()) == -1)
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		changeList = [[OFDataArray alloc] initWithItemSize:
		_changeList = [[OFDataArray alloc] initWithItemSize:
		    sizeof(struct kevent)];

		[self OF_addFileDescriptorForReading: cancelFD[0]];
		[self OF_addFileDescriptorForReading: _cancelFD[0]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	close(kernelQueue);
	[changeList release];
	close(_kernelQueue);
	[_changeList release];

	[super dealloc];
}

- (void)OF_addFileDescriptorForReading: (int)fd
{
	struct kevent event;

	if ([changeList count] >= INT_MAX)
	if ([_changeList count] >= INT_MAX)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
	[changeList addItem: &event];
	[_changeList addItem: &event];
}

- (void)OF_addFileDescriptorForWriting: (int)fd
{
	struct kevent event;

	if ([changeList count] >= INT_MAX)
	if ([_changeList count] >= INT_MAX)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	EV_SET(&event, fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
	[changeList addItem: &event];
	[_changeList addItem: &event];
}

- (void)OF_removeFileDescriptorForReading: (int)fd
{
	struct kevent event;

	EV_SET(&event, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
	[changeList addItem: &event];
	[_changeList addItem: &event];
}

- (void)OF_removeFileDescriptorForWriting: (int)fd
{
	struct kevent event;

	EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
	[changeList addItem: &event];
	[_changeList addItem: &event];
}

- (BOOL)observeWithTimeout: (double)timeout
{
	void *pool = objc_autoreleasePoolPush();
	struct timespec timespec;
	struct kevent eventList[EVENTLIST_SIZE];
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
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







-
-
+
+





-
+





-
+


-
+









-
+

-
-
+
+







-
+

-
-
+
+


-
+

-
-
+
+







	if ([self OF_processCache]) {
		objc_autoreleasePoolPop(pool);
		return YES;
	}

	objc_autoreleasePoolPop(pool);

	events = kevent(kernelQueue, [changeList items],
	    (int)[changeList count], eventList, EVENTLIST_SIZE,
	events = kevent(_kernelQueue, [_changeList items],
	    (int)[_changeList count], eventList, EVENTLIST_SIZE,
	    (timeout == -1 ? NULL : &timespec));

	if (events < 0)
		return NO;

	[changeList removeAllItems];
	[_changeList removeAllItems];

	if (events == 0)
		return NO;

	for (i = 0; i < events; i++) {
		if (eventList[i].ident == cancelFD[0]) {
		if (eventList[i].ident == _cancelFD[0]) {
			char buffer;

			OF_ENSURE(read(cancelFD[0], &buffer, 1) > 0);
			OF_ENSURE(read(_cancelFD[0], &buffer, 1) > 0);

			continue;
		}

		realEvents++;

		pool = objc_autoreleasePoolPush();

		if (eventList[i].flags & EV_ERROR) {
			if ([delegate respondsToSelector:
			if ([_delegate respondsToSelector:
			    @selector(streamDidReceiveException:)])
				[delegate streamDidReceiveException:
				    FDToStream[eventList[i].ident]];
				[_delegate streamDidReceiveException:
				    _FDToStream[eventList[i].ident]];

			objc_autoreleasePoolPop(pool);
			continue;
		}

		switch (eventList[i].filter) {
		case EVFILT_READ:
			if ([delegate respondsToSelector:
			if ([_delegate respondsToSelector:
			    @selector(streamIsReadyForReading:)])
				[delegate streamIsReadyForReading:
				    FDToStream[eventList[i].ident]];
				[_delegate streamIsReadyForReading:
				    _FDToStream[eventList[i].ident]];
			break;
		case EVFILT_WRITE:
			if ([delegate respondsToSelector:
			if ([_delegate respondsToSelector:
			    @selector(streamIsReadyForWriting:)])
				[delegate streamIsReadyForWriting:
				    FDToStream[eventList[i].ident]];
				[_delegate streamIsReadyForWriting:
				    _FDToStream[eventList[i].ident]];
			break;
		default:
			assert(0);
		}

		objc_autoreleasePoolPop(pool);
	}

Modified src/OFStreamObserver_poll.h from [d8c774bd02] to [a9e9e56b91].

16
17
18
19
20
21
22
23

24
25
16
17
18
19
20
21
22

23
24
25







-
+



#import "OFStreamObserver.h"

@class OFDataArray;

@interface OFStreamObserver_poll: OFStreamObserver
{
	OFDataArray *FDs;
	OFDataArray *_FDs;
}
@end

Modified src/OFStreamObserver_poll.m from [5c8293cbf9] to [1648f30d0f].

33
34
35
36
37
38
39
40

41
42
43
44


45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64


65
66
67
68
69


70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85


86
87
88
89


90
91
92


93
94
95
96
97
98
99
33
34
35
36
37
38
39

40
41
42


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

55
56
57
58
59
60
61
62


63
64
65
66
67


68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83


84
85
86
87


88
89
90


91
92
93
94
95
96
97
98
99







-
+


-
-
+
+










-
+







-
-
+
+



-
-
+
+







-
+






-
-
+
+


-
-
+
+

-
-
+
+







- init
{
	self = [super init];

	@try {
		struct pollfd p = { 0, POLLIN, 0 };

		FDs = [[OFDataArray alloc] initWithItemSize:
		_FDs = [[OFDataArray alloc] initWithItemSize:
		    sizeof(struct pollfd)];

		p.fd = cancelFD[0];
		[FDs addItem: &p];
		p.fd = _cancelFD[0];
		[_FDs addItem: &p];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[FDs release];
	[_FDs release];

	[super dealloc];
}

- (void)OF_addFileDescriptor: (int)fd
		  withEvents: (short)events
{
	struct pollfd *FDs_ = [FDs items];
	size_t i, count = [FDs count];
	struct pollfd *FDs = [_FDs items];
	size_t i, count = [_FDs count];
	BOOL found = NO;

	for (i = 0; i < count; i++) {
		if (FDs_[i].fd == fd) {
			FDs_[i].events |= events;
		if (FDs[i].fd == fd) {
			FDs[i].events |= events;
			found = YES;
			break;
		}
	}

	if (!found) {
		struct pollfd p = { fd, events | POLLERR, 0 };
		[FDs addItem: &p];
		[_FDs addItem: &p];
	}
}

- (void)OF_removeFileDescriptor: (int)fd
		     withEvents: (short)events
{
	struct pollfd *FDs_ = [FDs items];
	size_t i, nFDs = [FDs count];
	struct pollfd *FDs = [_FDs items];
	size_t i, nFDs = [_FDs count];

	for (i = 0; i < nFDs; i++) {
		if (FDs_[i].fd == fd) {
			FDs_[i].events &= ~events;
		if (FDs[i].fd == fd) {
			FDs[i].events &= ~events;

			if ((FDs_[i].events & ~POLLERR) == 0)
				[FDs removeItemAtIndex: i];
			if ((FDs[i].events & ~POLLERR) == 0)
				[_FDs removeItemAtIndex: i];

			break;
		}
	}
}

- (void)OF_addFileDescriptorForReading: (int)fd
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
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







-
+











-
-
+
+






-
+






-
-
+
+


-
-
+
+





-
+

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




-
-
-
-
-
+
+
+
+
+




-
-
-
-
-
-
-
-
-
-
+










	[self OF_removeFileDescriptor: fd
			   withEvents: POLLOUT];
}

- (BOOL)observeWithTimeout: (double)timeout
{
	void *pool = objc_autoreleasePoolPush();
	struct pollfd *FDs_;
	struct pollfd *FDs;
	size_t i, nFDs, realEvents = 0;

	[self OF_processQueue];

	if ([self OF_processCache]) {
		objc_autoreleasePoolPop(pool);
		return YES;
	}

	objc_autoreleasePoolPop(pool);

	FDs_ = [FDs items];
	nFDs = [FDs count];
	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,
	if (poll(FDs, (nfds_t)nFDs,
	    (int)(timeout != -1 ? timeout * 1000 : -1)) < 1)
		return NO;

	for (i = 0; i < nFDs; i++) {
		pool = objc_autoreleasePoolPush();

		if (FDs_[i].revents & POLLIN) {
			if (FDs_[i].fd == cancelFD[0]) {
		if (FDs[i].revents & POLLIN) {
			if (FDs[i].fd == _cancelFD[0]) {
				char buffer;

				OF_ENSURE(read(cancelFD[0], &buffer, 1) > 0);
				FDs_[i].revents = 0;
				OF_ENSURE(read(_cancelFD[0], &buffer, 1) > 0);
				FDs[i].revents = 0;

				objc_autoreleasePoolPop(pool);
				continue;
			}

			if ([delegate respondsToSelector:
			if ([_delegate respondsToSelector:
			    @selector(streamIsReadyForReading:)])
				[delegate streamIsReadyForReading:
				    FDToStream[FDs_[i].fd]];
				[_delegate streamIsReadyForReading:
				    _FDToStream[FDs[i].fd]];

			realEvents++;
		}

		if (FDs[i].revents & POLLOUT) {
			if ([_delegate respondsToSelector:
			    @selector(streamIsReadyForWriting:)])
				[_delegate streamIsReadyForWriting:
				    _FDToStream[FDs[i].fd]];

			realEvents++;
		}

		if (FDs_[i].revents & POLLOUT) {
			if ([delegate respondsToSelector:
			    @selector(streamIsReadyForWriting:)])
				[delegate streamIsReadyForWriting:
				    FDToStream[FDs_[i].fd]];
		if (FDs[i].revents & POLLERR) {
			if ([_delegate respondsToSelector:
			    @selector(streamDidReceiveException:)])
				[_delegate streamDidReceiveException:
				    _FDToStream[FDs[i].fd]];

			realEvents++;
		}

		if (FDs_[i].revents & POLLERR) {
			if ([delegate respondsToSelector:
			    @selector(streamDidReceiveException:)])
				[delegate streamDidReceiveException:
				    FDToStream[FDs_[i].fd]];

			realEvents++;
		}

		FDs_[i].revents = 0;
		FDs[i].revents = 0;

		objc_autoreleasePoolPop(pool);
	}

	if (realEvents == 0)
		return NO;

	return YES;
}
@end

Modified src/OFStreamObserver_select.h from [ef59e082ab] to [bbd983d332].

25
26
27
28
29
30
31
32
33
34

35
36
25
26
27
28
29
30
31



32
33
34







-
-
-
+


# include <sys/select.h>
#endif

#import "OFStreamObserver.h"

@interface OFStreamObserver_select: OFStreamObserver
{
	fd_set readFDs;
	fd_set writeFDs;
	fd_set exceptFDs;
	fd_set _readFDs, _writeFDs, _exceptFDs;
}
@end

Modified src/OFStreamObserver_select.m from [ea4f833523] to [f904878755].

31
32
33
34
35
36
37
38
39


40
41

42
43
44
45
46
47
48
49


50
51
52
53
54
55


56
57
58
59
60

61
62
63


64
65
66
67
68

69
70
71


72
73
74
75
76
77
78
79
80



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96



97
98
99
100



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
31
32
33
34
35
36
37


38
39
40

41
42
43
44
45
46
47


48
49
50
51
52
53


54
55
56
57
58
59

60
61


62
63
64
65
66
67

68
69


70
71
72
73
74
75
76
77



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93



94
95
96
97



98
99
100
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







-
-
+
+

-
+






-
-
+
+




-
-
+
+




-
+

-
-
+
+




-
+

-
-
+
+






-
-
-
+
+
+













-
-
-
+
+
+

-
-
-
+
+
+











-
+



-
+


-
+

-
+
+



-
-
+
+






-
-
+
+

-
+




-
-
+
+

-
+






-
+







-
-
+
+






-
-
+
+

-
+




-
-
+
+

-
+







#import "macros.h"

@implementation OFStreamObserver_select
- init
{
	self = [super init];

	FD_ZERO(&readFDs);
	FD_ZERO(&writeFDs);
	FD_ZERO(&_readFDs);
	FD_ZERO(&_writeFDs);

	FD_SET(cancelFD[0], &readFDs);
	FD_SET(_cancelFD[0], &_readFDs);

	return self;
}

- (void)OF_addFileDescriptorForReading: (int)fd
{
	FD_SET(fd, &readFDs);
	FD_SET(fd, &exceptFDs);
	FD_SET(fd, &_readFDs);
	FD_SET(fd, &_exceptFDs);
}

- (void)OF_addFileDescriptorForWriting: (int)fd
{
	FD_SET(fd, &writeFDs);
	FD_SET(fd, &exceptFDs);
	FD_SET(fd, &_writeFDs);
	FD_SET(fd, &_exceptFDs);
}

- (void)OF_removeFileDescriptorForReading: (int)fd
{
	FD_CLR(fd, &readFDs);
	FD_CLR(fd, &_readFDs);

	if (!FD_ISSET(fd, &writeFDs))
		FD_CLR(fd, &exceptFDs);
	if (!FD_ISSET(fd, &_writeFDs))
		FD_CLR(fd, &_exceptFDs);
}

- (void)OF_removeFileDescriptorForWriting: (int)fd
{
	FD_CLR(fd, &writeFDs);
	FD_CLR(fd, &_writeFDs);

	if (!FD_ISSET(fd, &readFDs))
		FD_CLR(fd, &exceptFDs);
	if (!FD_ISSET(fd, &_readFDs))
		FD_CLR(fd, &_exceptFDs);
}

- (BOOL)observeWithTimeout: (double)timeout
{
	void *pool = objc_autoreleasePoolPush();
	OFStream **objects;
	fd_set readFDs_;
	fd_set writeFDs_;
	fd_set exceptFDs_;
	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;
	}

	objc_autoreleasePoolPop(pool);

#ifdef FD_COPY
	FD_COPY(&readFDs, &readFDs_);
	FD_COPY(&writeFDs, &writeFDs_);
	FD_COPY(&exceptFDs, &exceptFDs_);
	FD_COPY(&_readFDs, &readFDs);
	FD_COPY(&_writeFDs, &writeFDs);
	FD_COPY(&_exceptFDs, &exceptFDs);
#else
	readFDs_ = readFDs;
	writeFDs_ = writeFDs;
	exceptFDs_ = exceptFDs;
	readFDs = _readFDs;
	writeFDs = _writeFDs;
	exceptFDs = _exceptFDs;
#endif

	/*
	 * We cast to int before assigning to tv_usec in order to avoid a
	 * warning with Apple GCC on PPC. POSIX defines this as suseconds_t,
	 * however, this is not available on Win32. As an int should always
	 * 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_,
	if (select((int)_maxFD + 1, &readFDs, &writeFDs, &exceptFDs,
	    (timeout != -1 ? &time : NULL)) < 1)
		return NO;

	if (FD_ISSET(cancelFD[0], &readFDs_)) {
	if (FD_ISSET(_cancelFD[0], &readFDs)) {
		char buffer;
#ifndef _WIN32
		OF_ENSURE(read(cancelFD[0], &buffer, 1) > 0);
		OF_ENSURE(read(_cancelFD[0], &buffer, 1) > 0);
#else
		OF_ENSURE(recvfrom(cancelFD[0], &buffer, 1, 0, NULL, NULL) > 0);
		OF_ENSURE(recvfrom(_cancelFD[0], &buffer, 1, 0, NULL,
		    NULL) > 0);
#endif
	}

	objects = [readStreams objects];
	count = [readStreams count];
	objects = [_readStreams objects];
	count = [_readStreams count];

	for (i = 0; i < count; i++) {
		int fd = [objects[i] fileDescriptorForReading];

		pool = objc_autoreleasePoolPush();

		if (FD_ISSET(fd, &readFDs_)) {
			if ([delegate respondsToSelector:
		if (FD_ISSET(fd, &readFDs)) {
			if ([_delegate respondsToSelector:
			    @selector(streamIsReadyForReading:)])
				[delegate streamIsReadyForReading: objects[i]];
				[_delegate streamIsReadyForReading: objects[i]];

			realEvents++;
		}

		if (FD_ISSET(fd, &exceptFDs_)) {
			if ([delegate respondsToSelector:
		if (FD_ISSET(fd, &exceptFDs)) {
			if ([_delegate respondsToSelector:
			    @selector(streamDidReceiveException:)])
				[delegate streamDidReceiveException:
				[_delegate streamDidReceiveException:
				    objects[i]];

			/*
			 * Prevent calling it twice in case the FD is in both
			 * sets.
			 */
			FD_CLR(fd, &exceptFDs_);
			FD_CLR(fd, &exceptFDs);

			realEvents++;
		}

		objc_autoreleasePoolPop(pool);
	}

	objects = [writeStreams objects];
	count = [writeStreams count];
	objects = [_writeStreams objects];
	count = [_writeStreams count];

	for (i = 0; i < count; i++) {
		int fd = [objects[i] fileDescriptorForWriting];

		pool = objc_autoreleasePoolPush();

		if (FD_ISSET(fd, &writeFDs_)) {
			if ([delegate respondsToSelector:
		if (FD_ISSET(fd, &writeFDs)) {
			if ([_delegate respondsToSelector:
			    @selector(streamIsReadyForWriting:)])
				[delegate streamIsReadyForWriting: objects[i]];
				[_delegate streamIsReadyForWriting: objects[i]];

			realEvents++;
		}

		if (FD_ISSET(fd, &exceptFDs_)) {
			if ([delegate respondsToSelector:
		if (FD_ISSET(fd, &exceptFDs)) {
			if ([_delegate respondsToSelector:
			    @selector(streamDidReceiveException:)])
				[delegate streamDidReceiveException:
				[_delegate streamDidReceiveException:
				    objects[i]];

			realEvents++;
		}

		objc_autoreleasePoolPop(pool);
	}

Modified src/OFStreamSocket.h from [54613b8cfd] to [f3d324a9cc].

24
25
26
27
28
29
30
31
32


33
34
35
36
37
38
39
40
41
24
25
26
27
28
29
30


31
32
33
34
35
36
37
38
39
40
41







-
-
+
+









#endif

/*!
 * @brief A class which provides functions to create and use stream sockets.
 */
@interface OFStreamSocket: OFStream
{
	int  sock;
	BOOL atEndOfStream;
	int  _socket;
	BOOL _atEndOfStream;
}

/*!
 * @brief Returns a new, autoreleased OFTCPSocket.
 *
 * @return A new, autoreleased OFTCPSocket
 */
+ (instancetype)socket;
@end

Modified src/OFStreamSocket.m from [902270c256] to [a7e950a736].

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







-
+







-
+



-
+






-
+

-
+





-
+





-
+







-
+



-
+






-
+

-
+





-
+









-
+

-
+








-
+




-
+




-
+



-
+
+

-
-
+




-
+





+ (instancetype)socket
{
	return [[[self alloc] init] autorelease];
}

- (BOOL)lowlevelIsAtEndOfStream
{
	return atEndOfStream;
	return _atEndOfStream;
}

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

	if (sock == INVALID_SOCKET)
	if (_socket == INVALID_SOCKET)
		@throw [OFNotConnectedException exceptionWithClass: [self class]
							    socket: self];

	if (atEndOfStream) {
	if (_atEndOfStream) {
		OFReadFailedException *e;

		e = [OFReadFailedException exceptionWithClass: [self class]
						       stream: self
					      requestedLength: length];
#ifndef _WIN32
		e->errNo = ENOTCONN;
		e->_errNo = ENOTCONN;
#else
		e->errNo = WSAENOTCONN;
		e->_errNo = WSAENOTCONN;
#endif

		@throw e;
	}

	if ((ret = recv(sock, buffer, length, 0)) < 0)
	if ((ret = recv(_socket, buffer, length, 0)) < 0)
		@throw [OFReadFailedException exceptionWithClass: [self class]
							  stream: self
						 requestedLength: length];

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

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
		     length: (size_t)length
{
	if (sock == INVALID_SOCKET)
	if (_socket == INVALID_SOCKET)
		@throw [OFNotConnectedException exceptionWithClass: [self class]
							    socket: self];

	if (atEndOfStream) {
	if (_atEndOfStream) {
		OFWriteFailedException *e;

		e = [OFWriteFailedException exceptionWithClass: [self class]
							stream: self
					       requestedLength: length];
#ifndef _WIN32
		e->errNo = ENOTCONN;
		e->_errNo = ENOTCONN;
#else
		e->errNo = WSAENOTCONN;
		e->_errNo = WSAENOTCONN;
#endif

		@throw e;
	}

	if (send(sock, buffer, length, 0) < length)
	if (send(_socket, buffer, length, 0) < length)
		@throw [OFWriteFailedException exceptionWithClass: [self class]
							   stream: self
						  requestedLength: length];
}

#ifdef _WIN32
- (void)setBlocking: (BOOL)enable
{
	u_long v = enable;
	blocking = enable;
	_blocking = enable;

	if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR)
	if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR)
		@throw [OFSetOptionFailedException
		    exceptionWithClass: [self class]
				stream: self];
}
#endif

- (int)fileDescriptorForReading
{
	return sock;
	return _socket;
}

- (int)fileDescriptorForWriting
{
	return sock;
	return _socket;
}

- (void)close
{
	if (sock == INVALID_SOCKET)
	if (_socket == INVALID_SOCKET)
		@throw [OFNotConnectedException exceptionWithClass: [self class]
							    socket: self];

	close(sock);
	close(_socket);
	_socket = INVALID_SOCKET;

	sock = INVALID_SOCKET;
	atEndOfStream = NO;
	_atEndOfStream = NO;
}

- (void)dealloc
{
	if (sock != INVALID_SOCKET)
	if (_socket != INVALID_SOCKET)
		[self close];

	[super dealloc];
}
@end

Modified src/OFString_UTF8.h from [9d742edbb7] to [f4f94da890].

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







-
-
-
+
+
+









-
-
+
+








@interface OFString_UTF8: OFString
{
@public
	/*
	 * A pointer to the actual data.
	 *
	 * Since constant strings don't have s_store, they have to malloc it on
	 * the first access. Strings created at runtime just set the pointer to
	 * &s_store.
	 * 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;
		size_t	 length;
		BOOL	 hashed;
		uint32_t hash;
		char	 *freeWhenDone;
	} *restrict s;
	struct of_string_utf8_ivars s_store;
	} *restrict _s;
	struct of_string_utf8_ivars _storage;
}

- OF_initWithUTF8String: (const char*)UTF8String
		 length: (size_t)UTF8StringLength
		storage: (char*)storage;
@end

Modified src/OFString_UTF8.m from [0615761918] to [503640087e].

151
152
153
154
155
156
157
158

159
160
161


162
163
164
165
166
167
168
151
152
153
154
155
156
157

158
159


160
161
162
163
164
165
166
167
168







-
+

-
-
+
+








@implementation OFString_UTF8
- init
{
	self = [super init];

	@try {
		s = &s_store;
		_s = &_storage;

		s->cString = [self allocMemoryWithSize: 1];
		s->cString[0] = '\0';
		_s->cString = [self allocMemoryWithSize: 1];
		_s->cString[0] = '\0';
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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







-
+

-
-
+
+


-
+

-
+






-
-
+
+







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

		s = &s_store;
		_s = &_storage;

		s->cString = storage;
		s->cStringLength = UTF8StringLength;
		_s->cString = storage;
		_s->cStringLength = UTF8StringLength;

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

		memcpy(s->cString, UTF8String, UTF8StringLength);
		s->cString[UTF8StringLength] = 0;
		memcpy(_s->cString, UTF8String, UTF8StringLength);
		_s->cString[UTF8StringLength] = 0;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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







-
+

-
-
+
+




-
+





-
+






-
-
+
+





-
+







-
+



-
+







-
-
-
-
+
+
+
+

-
+



-
+








		if (encoding == OF_STRING_ENCODING_UTF_8 &&
		    cStringLength >= 3 && !memcmp(cString, "\xEF\xBB\xBF", 3)) {
			cString += 3;
			cStringLength -= 3;
		}

		s = &s_store;
		_s = &_storage;

		s->cString = [self allocMemoryWithSize: cStringLength + 1];
		s->cStringLength = cStringLength;
		_s->cString = [self allocMemoryWithSize: cStringLength + 1];
		_s->cStringLength = cStringLength;

		if (encoding == OF_STRING_ENCODING_UTF_8 ||
		    encoding == OF_STRING_ENCODING_ASCII) {
			switch (of_string_utf8_check(cString, cStringLength,
			    &s->length)) {
			    &_s->length)) {
			case 1:
				if (encoding == OF_STRING_ENCODING_ASCII)
					@throw [OFInvalidEncodingException
					    exceptionWithClass: [self class]];

				s->isUTF8 = YES;
				_s->isUTF8 = YES;
				break;
			case -1:
				@throw [OFInvalidEncodingException
				    exceptionWithClass: [self class]];
			}

			memcpy(s->cString, cString, cStringLength);
			s->cString[cStringLength] = 0;
			memcpy(_s->cString, cString, cStringLength);
			_s->cString[cStringLength] = 0;

			return self;
		}

		/* All other encodings we support are single byte encodings */
		s->length = cStringLength;
		_s->length = cStringLength;

		if (encoding == OF_STRING_ENCODING_ISO_8859_1) {
			for (i = j = 0; i < cStringLength; i++) {
				char buffer[4];
				size_t bytes;

				if (!(cString[i] & 0x80)) {
					s->cString[j++] = cString[i];
					_s->cString[j++] = cString[i];
					continue;
				}

				s->isUTF8 = YES;
				_s->isUTF8 = YES;
				bytes = of_string_utf8_encode(
				    (uint8_t)cString[i], buffer);

				if (bytes == 0)
					@throw [OFInvalidEncodingException
					    exceptionWithClass: [self class]];

				s->cStringLength += bytes - 1;
				s->cString = [self
				    resizeMemory: s->cString
					    size: s->cStringLength + 1];
				_s->cStringLength += bytes - 1;
				_s->cString = [self
				    resizeMemory: _s->cString
					    size: _s->cStringLength + 1];

				memcpy(s->cString + j, buffer, bytes);
				memcpy(_s->cString + j, buffer, bytes);
				j += bytes;
			}

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

			return self;
		}

		switch (encoding) {
		case OF_STRING_ENCODING_ISO_8859_15:
			table = of_iso_8859_15;
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
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







-
+









-
+







-
-
-
+
+
+
+

-
+



-
+








		for (i = j = 0; i < cStringLength; i++) {
			char buffer[4];
			of_unichar_t character;
			size_t characterBytes;

			if (!(cString[i] & 0x80)) {
				s->cString[j++] = cString[i];
				_s->cString[j++] = cString[i];
				continue;
			}

			character = table[(uint8_t)cString[i]];

			if (character == 0xFFFD)
				@throw [OFInvalidEncodingException
				    exceptionWithClass: [self class]];

			s->isUTF8 = YES;
			_s->isUTF8 = YES;
			characterBytes = of_string_utf8_encode(character,
			    buffer);

			if (characterBytes == 0)
				@throw [OFInvalidEncodingException
				    exceptionWithClass: [self class]];

			s->cStringLength += characterBytes - 1;
			s->cString = [self resizeMemory: s->cString
						   size: s->cStringLength + 1];
			_s->cStringLength += characterBytes - 1;
			_s->cString = [self
			    resizeMemory: _s->cString
				    size: _s->cStringLength + 1];

			memcpy(s->cString + j, buffer, characterBytes);
			memcpy(_s->cString + j, buffer, characterBytes);
			j += characterBytes;
		}

		s->cString[s->cStringLength] = 0;
		_s->cString[_s->cStringLength] = 0;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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







-
+

-
-
+
+


-
+


-
+

-
+


















-
+

-
+



-
+

-
+

-
+

-
-
+
+
















-
+

-
-
+
+








-
+




-
+

-
+









-
-
+
+


-
-
+
+








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

		s = &s_store;
		_s = &_storage;

		s->cString = (char*)UTF8String;
		s->cStringLength = UTF8StringLength;
		_s->cString = (char*)UTF8String;
		_s->cStringLength = UTF8StringLength;

		if (freeWhenDone)
			s->freeWhenDone = UTF8String;
			_s->freeWhenDone = UTF8String;

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

	return self;
}

- initWithString: (OFString*)string
{
	self = [super init];

	@try {
		s = &s_store;
		_s = &_storage;

		s->cStringLength = [string UTF8StringLength];
		_s->cStringLength = [string UTF8StringLength];

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

		s->length = [string length];
		_s->length = [string length];

		s->cString = [self allocMemoryWithSize: s->cStringLength + 1];
		memcpy(s->cString, [string UTF8String], s->cStringLength + 1);
		_s->cString = [self allocMemoryWithSize: _s->cStringLength + 1];
		memcpy(_s->cString, [string UTF8String], _s->cStringLength + 1);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithCharacters: (const of_unichar_t*)characters
	      length: (size_t)length
{
	self = [super init];

	@try {
		size_t i, j = 0;

		s = &s_store;
		_s = &_storage;

		s->cString = [self allocMemoryWithSize: (length * 4) + 1];
		s->length = length;
		_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(characters[i],
			    buffer);

			switch (len) {
			case 1:
				s->cString[j++] = buffer[0];
				_s->cString[j++] = buffer[0];
				break;
			case 2:
			case 3:
			case 4:
				s->isUTF8 = YES;
				_s->isUTF8 = YES;

				memcpy(s->cString + j, buffer, len);
				memcpy(_s->cString + j, buffer, len);
				j += len;

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

		s->cString[j] = '\0';
		s->cStringLength = j;
		_s->cString[j] = '\0';
		_s->cStringLength = j;

		@try {
			s->cString = [self resizeMemory: s->cString
						   size: j + 1];
			_s->cString = [self resizeMemory: _s->cString
						    size: j + 1];
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only tried to make it smaller */
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}
472
473
474
475
476
477
478
479

480
481
482


483
484
485
486
487
488
489
473
474
475
476
477
478
479

480
481


482
483
484
485
486
487
488
489
490







-
+

-
-
+
+







		} else if (length > 0 && *string == 0xFFFE) {
			swap = YES;
			string++;
			length--;
		} else if (byteOrder != OF_BYTE_ORDER_NATIVE)
			swap = YES;

		s = &s_store;
		_s = &_storage;

		s->cString = [self allocMemoryWithSize: (length * 4) + 1];
		s->length = length;
		_s->cString = [self allocMemoryWithSize: (length * 4) + 1];
		_s->length = length;

		for (i = 0; i < length; i++) {
			char buffer[4];
			of_unichar_t character =
			    (swap ? OF_BSWAP16(string[i]) : string[i]);
			size_t len;

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







-
+






-
+




-
+

-
+









-
-
+
+


-
-
+
+







					@throw [OFInvalidEncodingException
					    exceptionWithClass: [self class]];

				character = (((character & 0x3FF) << 10) |
				    (nextCharacter & 0x3FF)) + 0x10000;

				i++;
				s->length--;
				_s->length--;
			}

			len = of_string_utf8_encode(character, buffer);

			switch (len) {
			case 1:
				s->cString[j++] = buffer[0];
				_s->cString[j++] = buffer[0];
				break;
			case 2:
			case 3:
			case 4:
				s->isUTF8 = YES;
				_s->isUTF8 = YES;

				memcpy(s->cString + j, buffer, len);
				memcpy(_s->cString + j, buffer, len);
				j += len;

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

		s->cString[j] = '\0';
		s->cStringLength = j;
		_s->cString[j] = '\0';
		_s->cStringLength = j;

		@try {
			s->cString = [self resizeMemory: s->cString
						   size: j + 1];
			_s->cString = [self resizeMemory: _s->cString
						    size: j + 1];
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only tried to make it smaller */
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}
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
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







-
+

-
-
+
+









-
+




-
+

-
+









-
-
+
+


-
-
+
+







		} else if (length > 0 && *characters == 0xFFFE0000) {
			swap = YES;
			characters++;
			length--;
		} else if (byteOrder != OF_BYTE_ORDER_NATIVE)
			swap = YES;

		s = &s_store;
		_s = &_storage;

		s->cString = [self allocMemoryWithSize: (length * 4) + 1];
		s->length = length;
		_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];
				_s->cString[j++] = buffer[0];
				break;
			case 2:
			case 3:
			case 4:
				s->isUTF8 = YES;
				_s->isUTF8 = YES;

				memcpy(s->cString + j, buffer, len);
				memcpy(_s->cString + j, buffer, len);
				j += len;

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

		s->cString[j] = '\0';
		s->cStringLength = j;
		_s->cString[j] = '\0';
		_s->cStringLength = j;

		@try {
			s->cString = [self resizeMemory: s->cString
						   size: j + 1];
			_s->cString = [self resizeMemory: _s->cString
						    size: j + 1];
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only tried to make it smaller */
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}
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
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







-
+






-
+



-
+

-
+






-
+

-
+







		int cStringLength;

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

		s = &s_store;
		_s = &_storage;

		if ((cStringLength = of_vasprintf(&tmp, [format UTF8String],
		    arguments)) == -1)
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];

		s->cStringLength = cStringLength;
		_s->cStringLength = cStringLength;

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

			s->cString = [self
			_s->cString = [self
			    allocMemoryWithSize: cStringLength + 1];
			memcpy(s->cString, tmp, cStringLength + 1);
			memcpy(_s->cString, tmp, cStringLength + 1);
		} @finally {
			free(tmp);
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}
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
816
817
818
819
820


821
822
823
824
825
826


827
828
829

830
831
832
833
834
835
836
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
816
817
818
819
820


821
822
823
824
825
826


827
828
829
830

831
832
833
834
835
836
837
838







-
+

-
+




+
-
+

-
+

-
+




-
-
+
+




-
-
+
+

-
+


-
+


-
+





-
-
+
+





-
+










-
-
+
+










-
+




-
+



-
+

-
+











-
+




-
+







-
+




-
+







-
+







-
+














-
-
+
+




-
-
+
+


-
+







	self = [super init];

	@try {
		OFString *component;
		size_t i, cStringLength;
		va_list argumentsCopy;

		s = &s_store;
		_s = &_storage;

		s->cStringLength = [firstComponent UTF8StringLength];
		_s->cStringLength = [firstComponent UTF8StringLength];

		if ([firstComponent isKindOfClass: [OFString_UTF8 class]] ||
		    [firstComponent isKindOfClass:
		    [OFMutableString_UTF8 class]])
			_s->isUTF8 =
			s->isUTF8 = ((OFString_UTF8*)firstComponent)->s->isUTF8;
			    ((OFString_UTF8*)firstComponent)->_s->isUTF8;
		else
			s->isUTF8 = YES;
			_s->isUTF8 = YES;

		s->length = [firstComponent length];
		_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];
			_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;
				_s->isUTF8 =
				    ((OFString_UTF8*)component)->_s->isUTF8;
			else
				s->isUTF8 = YES;
				_s->isUTF8 = YES;
		}

		s->cString = [self allocMemoryWithSize: s->cStringLength + 1];
		_s->cString = [self allocMemoryWithSize: _s->cStringLength + 1];

		cStringLength = [firstComponent UTF8StringLength];
		memcpy(s->cString, [firstComponent UTF8String], cStringLength);
		memcpy(_s->cString, [firstComponent UTF8String], cStringLength);
		i = cStringLength;

		while ((component = va_arg(arguments, OFString*)) != nil) {
			cStringLength = [component UTF8StringLength];

			s->cString[i] = OF_PATH_DELIMITER;
			memcpy(s->cString + i + 1, [component UTF8String],
			_s->cString[i] = OF_PATH_DELIMITER;
			memcpy(_s->cString + i + 1, [component UTF8String],
			    cStringLength);

			i += 1 + cStringLength;
		}

		s->cString[i] = '\0';
		_s->cString[i] = '\0';
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	if (s != NULL && s->freeWhenDone != NULL)
		free(s->freeWhenDone);
	if (_s != NULL && _s->freeWhenDone != NULL)
		free(_s->freeWhenDone);

	[super dealloc];
}

- (size_t)getCString: (char*)cString
	   maxLength: (size_t)maxLength
	    encoding: (of_string_encoding_t)encoding
{
	switch (encoding) {
	case OF_STRING_ENCODING_ASCII:
		if (s->isUTF8)
		if (_s->isUTF8)
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];
		/* intentional fall-through */
	case OF_STRING_ENCODING_UTF_8:
		if (s->cStringLength + 1 > maxLength)
		if (_s->cStringLength + 1 > maxLength)
			@throw [OFOutOfRangeException
			    exceptionWithClass: [self class]];

		memcpy(cString, s->cString, s->cStringLength + 1);
		memcpy(cString, _s->cString, _s->cStringLength + 1);

		return s->cStringLength;
		return _s->cStringLength;
	default:
		return [super getCString: cString
			       maxLength: maxLength
				encoding: encoding];
	}
}

- (const char*)cStringWithEncoding: (of_string_encoding_t)encoding
{
	switch (encoding) {
	case OF_STRING_ENCODING_ASCII:
		if (s->isUTF8)
		if (_s->isUTF8)
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];
		/* intentional fall-through */
	case OF_STRING_ENCODING_UTF_8:
		return s->cString;
		return _s->cString;
	default:
		return [super cStringWithEncoding: encoding];
	}
}

- (const char*)UTF8String
{
	return s->cString;
	return _s->cString;
}

- (size_t)length
{
	return s->length;
	return _s->length;
}

- (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding
{
	switch (encoding) {
	case OF_STRING_ENCODING_UTF_8:
	case OF_STRING_ENCODING_ASCII:
		return s->cStringLength;
		return _s->cStringLength;
	default:
		return [super cStringLengthWithEncoding: encoding];
	}
}

- (size_t)UTF8StringLength
{
	return s->cStringLength;
	return _s->cStringLength;
}

- (BOOL)isEqual: (id)object
{
	OFString_UTF8 *otherString;

	if (object == self)
		return YES;

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

	otherString = object;

	if ([otherString UTF8StringLength] != s->cStringLength ||
	    [otherString length] != s->length)
	if ([otherString UTF8StringLength] != _s->cStringLength ||
	    [otherString length] != _s->length)
		return NO;

	if (([otherString isKindOfClass: [OFString_UTF8 class]] ||
	    [otherString isKindOfClass: [OFMutableString_UTF8 class]]) &&
	    s->hashed && otherString->s->hashed &&
	    s->hash != otherString->s->hash)
	    _s->hashed && otherString->_s->hashed &&
	    _s->hash != otherString->_s->hash)
		return NO;

	if (strcmp(s->cString, [otherString UTF8String]))
	if (strcmp(_s->cString, [otherString UTF8String]))
		return NO;

	return YES;
}

- (of_comparison_result_t)compare: (id <OFComparing>)object
{
844
845
846
847
848
849
850
851
852


853
854

855
856

857
858

859
860
861
862
863
864
865
846
847
848
849
850
851
852


853
854
855

856
857

858
859

860
861
862
863
864
865
866
867







-
-
+
+

-
+

-
+

-
+







	if (![object isKindOfClass: [OFString class]])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	otherString = (OFString*)object;
	otherCStringLength = [otherString UTF8StringLength];
	minimumCStringLength = (s->cStringLength > otherCStringLength
	    ? otherCStringLength : s->cStringLength);
	minimumCStringLength = (_s->cStringLength > otherCStringLength
	    ? otherCStringLength : _s->cStringLength);

	if ((compare = memcmp(s->cString, [otherString UTF8String],
	if ((compare = memcmp(_s->cString, [otherString UTF8String],
	    minimumCStringLength)) == 0) {
		if (s->cStringLength > otherCStringLength)
		if (_s->cStringLength > otherCStringLength)
			return OF_ORDERED_DESCENDING;
		if (s->cStringLength < otherCStringLength)
		if (_s->cStringLength < otherCStringLength)
			return OF_ORDERED_ASCENDING;
		return OF_ORDERED_SAME;
	}

	if (compare > 0)
		return OF_ORDERED_DESCENDING;
	else
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
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







-
-
-
+
+
+

-
+

-
+

-
+












-
+



-
-
+
+







		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	otherCString = [otherString UTF8String];
	otherCStringLength = [otherString UTF8StringLength];

	if (!s->isUTF8) {
		minimumCStringLength = (s->cStringLength > otherCStringLength
		    ? otherCStringLength : s->cStringLength);
	if (!_s->isUTF8) {
		minimumCStringLength = (_s->cStringLength > otherCStringLength
		    ? otherCStringLength : _s->cStringLength);

		if ((compare = memcasecmp(s->cString, otherCString,
		if ((compare = memcasecmp(_s->cString, otherCString,
		    minimumCStringLength)) == 0) {
			if (s->cStringLength > otherCStringLength)
			if (_s->cStringLength > otherCStringLength)
				return OF_ORDERED_DESCENDING;
			if (s->cStringLength < otherCStringLength)
			if (_s->cStringLength < otherCStringLength)
				return OF_ORDERED_ASCENDING;
			return OF_ORDERED_SAME;
		}

		if (compare > 0)
			return OF_ORDERED_DESCENDING;
		else
			return OF_ORDERED_ASCENDING;
	}

	i = j = 0;

	while (i < s->cStringLength && j < otherCStringLength) {
	while (i < _s->cStringLength && j < otherCStringLength) {
		of_unichar_t c1, c2;
		size_t l1, l2;

		l1 = of_string_utf8_decode(s->cString + i,
		    s->cStringLength - i, &c1);
		l1 = of_string_utf8_decode(_s->cString + i,
		    _s->cStringLength - i, &c1);
		l2 = of_string_utf8_decode(otherCString + j,
		    otherCStringLength - j, &c2);

		if (l1 == 0 || l2 == 0 || c1 > 0x10FFFF || c2 > 0x10FFFF)
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];

938
939
940
941
942
943
944
945

946
947

948
949
950
951
952
953
954
955
956
957
958
959


960
961
962
963

964
965
966
967
968


969
970
971
972
973
974
975
976
977
978
979
980
981
982


983
984
985
986
987
988
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
1014
1015
1016

1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034

1035
1036
1037

1038
1039

1040
1041
1042


1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056

1057
1058
1059

1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071

1072
1073
1074

1075
1076
1077
1078
1079
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
1110
1111
1112
1113
1114
1115





1116
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
1160
1161
1162
1163
1164
1165


1166
1167
1168

1169
1170
1171
1172
1173
1174
1175
1176

1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195
1196
1197
1198
1199
1200
1201

1202
1203
1204


1205
1206
1207
1208
1209
1210

1211
1212

1213
1214
1215

1216
1217
1218
1219
1220
1221

1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233

1234
1235
1236
1237
1238
1239
1240

1241
1242
1243


1244
1245
1246
1247
1248
1249

1250
1251

1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265

1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277

1278
1279
1280


1281
1282
1283
1284
1285

1286
1287
1288
1289
1290

1291
1292

1293
1294

1295
1296
1297
1298

1299
1300

1301
1302

1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315

1316
1317
1318
1319

1320
1321
1322
1323
1324


1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344

1345
1346
1347
1348

1349
1350
1351
1352
1353


1354
1355
1356
1357
1358
1359
1360
940
941
942
943
944
945
946

947
948

949
950
951
952
953
954
955
956
957
958
959


960
961
962
963
964

965
966
967
968


969
970
971
972
973
974
975
976
977
978
979
980
981
982


983
984
985
986
987
988
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
1014
1015
1016
1017

1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035

1036
1037
1038

1039
1040

1041
1042


1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057

1058
1059
1060

1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072

1073
1074
1075

1076
1077
1078
1079
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

1110
1111
1112





1113
1114
1115
1116
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
1160
1161
1162
1163
1164
1165


1166
1167
1168
1169

1170
1171
1172
1173
1174
1175
1176
1177

1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192

1193
1194
1195
1196
1197
1198
1199
1200
1201
1202

1203
1204


1205
1206
1207
1208
1209
1210
1211

1212
1213

1214
1215
1216

1217
1218
1219
1220
1221
1222

1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234

1235
1236
1237
1238
1239
1240
1241

1242
1243


1244
1245
1246
1247
1248
1249
1250

1251
1252

1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272

1273
1274
1275
1276
1277
1278

1279
1280


1281
1282
1283
1284
1285
1286

1287
1288
1289
1290
1291

1292
1293

1294
1295

1296
1297
1298
1299

1300
1301

1302
1303

1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316

1317
1318
1319
1320

1321
1322
1323
1324


1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345

1346
1347
1348
1349

1350
1351
1352
1353


1354
1355
1356
1357
1358
1359
1360
1361
1362







-
+

-
+










-
-
+
+



-
+



-
-
+
+












-
-
+
+








-
+


-
-
+
+

-
-
+
+

-
-
+
+














-
+

















-
+


-
+

-
+

-
-
+
+













-
+


-
+











-
+


-
+


















-
+


-
-
+
+










-
+


-
-
-
-
-
+
+
+
+
+


-
+







-
+


-
+






-
+


-
+

















-
+






-
-
+
+


-
+







-
+














-
+









-
+

-
-
+
+





-
+

-
+


-
+





-
+











-
+






-
+

-
-
+
+





-
+

-
+













-
+





-
+





-
+

-
-
+
+




-
+




-
+

-
+

-
+



-
+

-
+

-
+












-
+



-
+



-
-
+
+



















-
+



-
+



-
-
+
+







		if (c1 < c2)
			return OF_ORDERED_ASCENDING;

		i += l1;
		j += l2;
	}

	if (s->cStringLength - i > otherCStringLength - j)
	if (_s->cStringLength - i > otherCStringLength - j)
		return OF_ORDERED_DESCENDING;
	else if (s->cStringLength - i < otherCStringLength - j)
	else if (_s->cStringLength - i < otherCStringLength - j)
		return OF_ORDERED_ASCENDING;

	return OF_ORDERED_SAME;
}

- (uint32_t)hash
{
	size_t i;
	uint32_t hash;

	if (s->hashed)
		return s->hash;
	if (_s->hashed)
		return _s->hash;

	OF_HASH_INIT(hash);

	for (i = 0; i < s->cStringLength; i++) {
	for (i = 0; i < _s->cStringLength; i++) {
		of_unichar_t c;
		size_t length;

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

		OF_HASH_ADD(hash, (c & 0xFF0000) >> 16);
		OF_HASH_ADD(hash, (c & 0x00FF00) >>  8);
		OF_HASH_ADD(hash,  c & 0x0000FF);

		i += length - 1;
	}

	OF_HASH_FINALIZE(hash);

	s->hash = hash;
	s->hashed = YES;
	_s->hash = hash;
	_s->hashed = YES;

	return hash;
}

- (of_unichar_t)characterAtIndex: (size_t)index
{
	of_unichar_t character;

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

	if (!s->isUTF8)
		return s->cString[index];
	if (!_s->isUTF8)
		return _s->cString[index];

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

	if (!of_string_utf8_decode(s->cString + index, s->cStringLength - index,
	    &character))
	if (!of_string_utf8_decode(_s->cString + index,
	    _s->cStringLength - index, &character))
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];

	return character;
}

- (void)getCharacters: (of_unichar_t*)buffer
	      inRange: (of_range_t)range
{
	/* TODO: Could be slightly optimized */
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];

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

	memcpy(buffer, characters + range.location,
	    range.length * sizeof(of_unichar_t));

	objc_autoreleasePoolPop(pool);
}

- (of_range_t)rangeOfString: (OFString*)string
		    options: (int)options
		      range: (of_range_t)range
{
	const char *cString = [string UTF8String];
	size_t i, cStringLength = [string UTF8StringLength];
	size_t rangeLocation, rangeLength;

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

	if (s->isUTF8) {
	if (_s->isUTF8) {
		rangeLocation = of_string_utf8_get_position(
		    s->cString, range.location, s->cStringLength);
		    _s->cString, range.location, _s->cStringLength);
		rangeLength = of_string_utf8_get_position(
		    s->cString + rangeLocation, range.length,
		    s->cStringLength - rangeLocation);
		    _s->cString + rangeLocation, range.length,
		    _s->cStringLength - rangeLocation);
	} else {
		rangeLocation = range.location;
		rangeLength = range.length;
	}

	if (cStringLength == 0)
		return of_range(0, 0);

	if (cStringLength > rangeLength)
		return of_range(OF_NOT_FOUND, 0);

	if (options & OF_STRING_SEARCH_BACKWARDS) {
		for (i = rangeLength - cStringLength;; i--) {
			if (!memcmp(s->cString + rangeLocation + i, cString,
			if (!memcmp(_s->cString + rangeLocation + i, cString,
			    cStringLength)) {
				range.location += of_string_utf8_get_index(
				    s->cString + rangeLocation, i);
				    _s->cString + rangeLocation, i);
				range.length = [string length];

				return range;
			}

			/* Did not match and we're at the last char */
			if (i == 0)
				return of_range(OF_NOT_FOUND, 0);
		}
	} else {
		for (i = 0; i <= rangeLength - cStringLength; i++) {
			if (!memcmp(s->cString + rangeLocation + i, cString,
			if (!memcmp(_s->cString + rangeLocation + i, cString,
			    cStringLength)) {
				range.location += of_string_utf8_get_index(
				    s->cString + rangeLocation, i);
				    _s->cString + rangeLocation, i);
				range.length = [string length];

				return range;
			}
		}
	}

	return of_range(OF_NOT_FOUND, 0);
}

- (BOOL)containsString: (OFString*)string
{
	const char *cString = [string UTF8String];
	size_t i, cStringLength = [string UTF8StringLength];

	if (cStringLength == 0)
		return YES;

	if (cStringLength > s->cStringLength)
	if (cStringLength > _s->cStringLength)
		return NO;

	for (i = 0; i <= s->cStringLength - cStringLength; i++)
		if (!memcmp(s->cString + i, cString, cStringLength))
	for (i = 0; i <= _s->cStringLength - cStringLength; i++)
		if (!memcmp(_s->cString + i, cString, cStringLength))
			return YES;

	return NO;
}

- (OFString*)substringWithRange: (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)
	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);
	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);
	}

	return [OFString stringWithUTF8String: s->cString + start
	return [OFString stringWithUTF8String: _s->cString + start
				       length: end - start];
}

- (BOOL)hasPrefix: (OFString*)prefix
{
	size_t cStringLength = [prefix UTF8StringLength];

	if (cStringLength > s->cStringLength)
	if (cStringLength > _s->cStringLength)
		return NO;

	return !memcmp(s->cString, [prefix UTF8String], cStringLength);
	return !memcmp(_s->cString, [prefix UTF8String], cStringLength);
}

- (BOOL)hasSuffix: (OFString*)suffix
{
	size_t cStringLength = [suffix UTF8StringLength];

	if (cStringLength > s->cStringLength)
	if (cStringLength > _s->cStringLength)
		return NO;

	return !memcmp(s->cString + (s->cStringLength - cStringLength),
	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);
	size_t i, last;
	OFString *component;

	array = [OFMutableArray array];
	pool = objc_autoreleasePoolPush();

	if (cStringLength > s->cStringLength) {
	if (cStringLength > _s->cStringLength) {
		[array addObject: [[self copy] autorelease]];
		objc_autoreleasePoolPop(pool);

		return array;
	}

	for (i = 0, last = 0; i <= s->cStringLength - cStringLength; i++) {
		if (memcmp(s->cString + i, cString, cStringLength))
	for (i = 0, last = 0; i <= _s->cStringLength - cStringLength; i++) {
		if (memcmp(_s->cString + i, cString, cStringLength))
			continue;

		component = [OFString stringWithUTF8String: s->cString + last
		component = [OFString stringWithUTF8String: _s->cString + last
						    length: i - last];
		if (!skipEmpty || [component length] > 0)
			[array addObject: component];

		i += cStringLength - 1;
		last = i + 1;
	}
	component = [OFString stringWithUTF8String: s->cString + last];
	component = [OFString stringWithUTF8String: _s->cString + last];
	if (!skipEmpty || [component length] > 0)
		[array addObject: component];

	[array makeImmutable];

	objc_autoreleasePoolPop(pool);

	return array;
}

- (OFArray*)pathComponents
{
	OFMutableArray *ret;
	void *pool;
	size_t i, last = 0, pathCStringLength = s->cStringLength;
	size_t i, last = 0, pathCStringLength = _s->cStringLength;

	ret = [OFMutableArray array];

	if (pathCStringLength == 0)
		return ret;

	pool = objc_autoreleasePoolPush();

#ifndef _WIN32
	if (s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
	if (_s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
#else
	if (s->cString[pathCStringLength - 1] == '/' ||
	    s->cString[pathCStringLength - 1] == '\\')
	if (_s->cString[pathCStringLength - 1] == '/' ||
	    _s->cString[pathCStringLength - 1] == '\\')
#endif
		pathCStringLength--;

	for (i = 0; i < pathCStringLength; i++) {
#ifndef _WIN32
		if (s->cString[i] == OF_PATH_DELIMITER) {
		if (_s->cString[i] == OF_PATH_DELIMITER) {
#else
		if (s->cString[i] == '/' || s->cString[i] == '\\') {
		if (_s->cString[i] == '/' || _s->cString[i] == '\\') {
#endif
			[ret addObject:
			    [OFString stringWithUTF8String: s->cString + last
			    [OFString stringWithUTF8String: _s->cString + last
						    length: i - last]];
			last = i + 1;
		}
	}

	[ret addObject: [OFString stringWithUTF8String: s->cString + last
	[ret addObject: [OFString stringWithUTF8String: _s->cString + last
						length: i - last]];

	[ret makeImmutable];

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (OFString*)lastPathComponent
{
	size_t pathCStringLength = s->cStringLength;
	size_t pathCStringLength = _s->cStringLength;
	ssize_t i;

	if (pathCStringLength == 0)
		return @"";

#ifndef _WIN32
	if (s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
	if (_s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
#else
	if (s->cString[pathCStringLength - 1] == '/' ||
	    s->cString[pathCStringLength - 1] == '\\')
	if (_s->cString[pathCStringLength - 1] == '/' ||
	    _s->cString[pathCStringLength - 1] == '\\')
#endif
		pathCStringLength--;

	for (i = pathCStringLength - 1; i >= 0; i--) {
#ifndef _WIN32
		if (s->cString[i] == OF_PATH_DELIMITER) {
		if (_s->cString[i] == OF_PATH_DELIMITER) {
#else
		if (s->cString[i] == '/' || s->cString[i] == '\\') {
		if (_s->cString[i] == '/' || _s->cString[i] == '\\') {
#endif
			i++;
			break;
		}
	}

	/*
	 * Only one component, but the trailing delimiter might have been
	 * removed, so return a new string anyway.
	 */
	if (i < 0)
		i = 0;

	return [OFString stringWithUTF8String: s->cString + i
	return [OFString stringWithUTF8String: _s->cString + i
				       length: pathCStringLength - i];
}

- (OFString*)stringByDeletingLastPathComponent
{
	size_t i, pathCStringLength = s->cStringLength;
	size_t i, pathCStringLength = _s->cStringLength;

	if (pathCStringLength == 0)
		return @"";

#ifndef _WIN32
	if (s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
	if (_s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
#else
	if (s->cString[pathCStringLength - 1] == '/' ||
	    s->cString[pathCStringLength - 1] == '\\')
	if (_s->cString[pathCStringLength - 1] == '/' ||
	    _s->cString[pathCStringLength - 1] == '\\')
#endif
		pathCStringLength--;

	if (pathCStringLength == 0)
		return [OFString stringWithUTF8String: s->cString
		return [OFString stringWithUTF8String: _s->cString
					       length: 1];

	for (i = pathCStringLength - 1; i >= 1; i--)
#ifndef _WIN32
		if (s->cString[i] == OF_PATH_DELIMITER)
		if (_s->cString[i] == OF_PATH_DELIMITER)
#else
		if (s->cString[i] == '/' || s->cString[i] == '\\')
		if (_s->cString[i] == '/' || _s->cString[i] == '\\')
#endif
			return [OFString stringWithUTF8String: s->cString
			return [OFString stringWithUTF8String: _s->cString
						       length: i];

#ifndef _WIN32
	if (s->cString[0] == OF_PATH_DELIMITER)
	if (_s->cString[0] == OF_PATH_DELIMITER)
#else
	if (s->cString[0] == '/' || s->cString[0] == '\\')
	if (_s->cString[0] == '/' || _s->cString[0] == '\\')
#endif
		return [OFString stringWithUTF8String: s->cString
		return [OFString stringWithUTF8String: _s->cString
					       length: 1];

	return @".";
}

- (const of_unichar_t*)characters
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	of_unichar_t *ret;
	size_t i, j;

	ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
				    count: s->length];
				    count: _s->length];

	i = j = 0;

	while (i < s->cStringLength) {
	while (i < _s->cStringLength) {
		of_unichar_t c;
		size_t cLen;

		cLen = of_string_utf8_decode(s->cString + i,
		    s->cStringLength - i, &c);
		cLen = of_string_utf8_decode(_s->cString + i,
		    _s->cStringLength - i, &c);

		if (cLen == 0 || c > 0x10FFFF)
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];

		ret[j++] = c;
		i += cLen;
	}

	return ret;
}

- (const of_char32_t*)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	of_char32_t *ret;
	size_t i, j;

	ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
				    count: s->length + 1];
				    count: _s->length + 1];

	i = j = 0;

	while (i < s->cStringLength) {
	while (i < _s->cStringLength) {
		of_unichar_t c;
		size_t cLen;

		cLen = of_string_utf8_decode(s->cString + i,
		    s->cStringLength - i, &c);
		cLen = of_string_utf8_decode(_s->cString + i,
		    _s->cStringLength - i, &c);

		if (cLen == 0 || c > 0x10FFFF)
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];

		if (byteOrder != OF_BYTE_ORDER_NATIVE)
			ret[j++] = OF_BSWAP32(c);
1368
1369
1370
1371
1372
1373
1374
1375

1376
1377
1378
1379
1380
1381
1382
1370
1371
1372
1373
1374
1375
1376

1377
1378
1379
1380
1381
1382
1383
1384







-
+







	return ret;
}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block
{
	void *pool;
	const char *cString = s->cString;
	const char *cString = _s->cString;
	const char *last = cString;
	BOOL stop = NO, lastCarriageReturn = NO;

	while (!stop && *cString != 0) {
		if (lastCarriageReturn && *cString == '\n') {
			lastCarriageReturn = NO;

Modified src/OFTCPSocket.h from [80ab9c568a] to [99ba0b78fd].

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







-
-
-
-
-
+
+
+
+
+











-
+
+

-
+











-
+

-
+







 * @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;
	struct sockaddr_storage	*sockAddr;
	socklen_t		sockAddrLen;
	OFString		*SOCKS5Host;
	uint16_t		SOCKS5Port;
	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 (copy) OFString *SOCKS5Host;
@property uint16_t SOCKS5Port;
#endif

/*!
 * @brief Sets the global SOCKS5 proxy host to use when creating a new socket
 *
 * @param host The host to use as a SOCKS5 proxy when creating a new socket
 * @param SOCKS5Host The host to use as a SOCKS5 proxy when creating a new
 *		     socket
 */
+ (void)setSOCKS5Host: (OFString*)host;
+ (void)setSOCKS5Host: (OFString*)SOCKS5Host;

/*!
 * @brief Returns the host to use as a SOCKS5 proxy when creating a new socket
 *
 * @return The host to use as a SOCKS5 proxy when creating a new socket
 */
+ (OFString*)SOCKS5Host;

/*!
 * @brief Sets the global SOCKS5 proxy port to use when creating a new socket
 *
 * @param port The port to use as a SOCKS5 proxy when creating a new socket
 * @param SOCKS5Port The port to use as a SOCKS5 proxy when creating a new socket
 */
+ (void)setSOCKS5Port: (uint16_t)port;
+ (void)setSOCKS5Port: (uint16_t)SOCKS5Port;

/*!
 * @brief Returns the port to use as a SOCKS5 proxy when creating a new socket
 *
 * @return The port to use as a SOCKS5 proxy when creating a new socket
 */
+ (uint16_t)SOCKS5Port;

Modified src/OFTCPSocket.m from [e3f567d132] to [742dd6ce2f].

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







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

-
+

-
+


















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




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









-
-
-
-
-
+
+
+
+
+




-
-
-
-
-
+
+
+
+
+











-
-
-
-
+
+
+
+

-
+

-
+









-
-
+
+



-
-
+
+

-
+










-
-
+
+

-
+



-
+








static OFString *defaultSOCKS5Host = nil;
static uint16_t defaultSOCKS5Port = 1080;

#ifdef OF_HAVE_THREADS
@interface OFTCPSocket_ConnectThread: OFThread
{
	OFThread *sourceThread;
	OFTCPSocket *sock;
	OFString *host;
	uint16_t port;
	id target;
	SEL selector;
	OFThread *_sourceThread;
	OFTCPSocket *_socket;
	OFString *_host;
	uint16_t _port;
	id _target;
	SEL _selector;
# ifdef OF_HAVE_BLOCKS
	of_tcpsocket_async_connect_block_t connectBlock;
	of_tcpsocket_async_connect_block_t _connectBlock;
# endif
	OFException *exception;
	OFException *_exception;
}

- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
		  port: (uint16_t)port
		target: (id)target
	      selector: (SEL)selector;
# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
		  port: (uint16_t)port
		 block: (of_tcpsocket_async_connect_block_t)block;
# endif
@end

@implementation OFTCPSocket_ConnectThread
- initWithSourceThread: (OFThread*)sourceThread_
		socket: (OFTCPSocket*)sock_
		  host: (OFString*)host_
		  port: (uint16_t)port_
		target: (id)target_
	      selector: (SEL)selector_
- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
		  port: (uint16_t)port
		target: (id)target
	      selector: (SEL)selector
{
	self = [super init];

	@try {
		sourceThread = [sourceThread_ retain];
		sock = [sock_ retain];
		host = [host_ copy];
		port = port_;
		target = [target_ retain];
		selector = selector_;
		_sourceThread = [sourceThread retain];
		_socket = [socket retain];
		_host = [host copy];
		_port = port;
		_target = [target retain];
		_selector = selector;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread_
		socket: (OFTCPSocket*)sock_
		  host: (OFString*)host_
		  port: (uint16_t)port_
		 block: (of_tcpsocket_async_connect_block_t)block_
- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
		  port: (uint16_t)port
		 block: (of_tcpsocket_async_connect_block_t)block
{
	self = [super init];

	@try {
		sourceThread = [sourceThread_ retain];
		sock = [sock_ retain];
		host = [host_ copy];
		port = port_;
		connectBlock = [block_ copy];
		_sourceThread = [sourceThread retain];
		_socket = [socket retain];
		_host = [host copy];
		_port = port;
		_connectBlock = [block copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
# endif

- (void)dealloc
{
	[sourceThread release];
	[sock release];
	[host release];
	[target release];
	[_sourceThread release];
	[_socket release];
	[_host release];
	[_target release];
# ifdef OF_HAVE_BLOCKS
	[connectBlock release];
	[_connectBlock release];
# endif
	[exception release];
	[_exception release];

	[super dealloc];
}

- (void)didConnect
{
	[self join];

# ifdef OF_HAVE_BLOCKS
	if (connectBlock != NULL)
		connectBlock(sock, exception);
	if (_connectBlock != NULL)
		_connectBlock(_socket, _exception);
	else {
# endif
		void (*func)(id, SEL, OFTCPSocket*, OFException*) =
		    (void(*)(id, SEL, OFTCPSocket*, OFException*))[target
		    methodForSelector: selector];
		    (void(*)(id, SEL, OFTCPSocket*, OFException*))[_target
		    methodForSelector: _selector];

		func(target, selector, sock, exception);
		func(_target, _selector, _socket, _exception);
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

- (id)main
{
	void *pool = objc_autoreleasePoolPush();

	@try {
		[sock connectToHost: host
			       port: port];
		[_socket connectToHost: _host
				  port: _port];
	} @catch (OFException *e) {
		exception = [[e retain] autorelease];
		_exception = [[e retain] autorelease];
	}

	[self performSelector: @selector(didConnect)
		     onThread: sourceThread
		     onThread: _sourceThread
		waitUntilDone: NO];

	objc_autoreleasePoolPop(pool);

	return nil;
}
@end
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
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







-
-
-
-
+
+
+
+










-
+




-
+

-
+




-
+


-
+

-
+




-
+








-
+




-
+

-
-
+
+




















-
+



-
-
-
+
+
+







}

- init
{
	self = [super init];

	@try {
		sock = INVALID_SOCKET;
		sockAddr = NULL;
		SOCKS5Host = [defaultSOCKS5Host copy];
		SOCKS5Port = defaultSOCKS5Port;
		_socket = INVALID_SOCKET;
		_sockAddr = NULL;
		_SOCKS5Host = [defaultSOCKS5Host copy];
		_SOCKS5Port = defaultSOCKS5Port;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[SOCKS5Host release];
	[_SOCKS5Host release];

	[super dealloc];
}

- (void)setSOCKS5Host: (OFString*)host
- (void)setSOCKS5Host: (OFString*)SOCKS5Host
{
	OF_SETTER(SOCKS5Host, host, YES, 1)
	OF_SETTER(_SOCKS5Host, SOCKS5Host, YES, 1)
}

- (OFString*)SOCKS5Host
{
	OF_GETTER(SOCKS5Host, YES)
	OF_GETTER(_SOCKS5Host, YES)
}

- (void)setSOCKS5Port: (uint16_t)port
- (void)setSOCKS5Port: (uint16_t)SOCKS5Port
{
	SOCKS5Port = port;
	_SOCKS5Port = SOCKS5Port;
}

- (uint16_t)SOCKS5Port
{
	return SOCKS5Port;
	return _SOCKS5Port;
}

- (void)connectToHost: (OFString*)host
		 port: (uint16_t)port
{
	OFString *destinationHost = host;
	uint16_t destinationPort = port;

	if (sock != INVALID_SOCKET)
	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException
		    exceptionWithClass: [self class]
				socket: self];

	if (SOCKS5Host != nil) {
	if (_SOCKS5Host != nil) {
		/* Connect to the SOCKS5 proxy instead */
		host = SOCKS5Host;
		port = SOCKS5Port;
		host = _SOCKS5Host;
		port = _SOCKS5Port;
	}

#ifdef HAVE_THREADSAFE_GETADDRINFO
	struct addrinfo hints, *res, *res0;
	char portCString[7];

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_NUMERICSERV;
	snprintf(portCString, 7, "%" PRIu16, port);

	if (getaddrinfo([host cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    portCString, &hints, &res0))
		@throw [OFAddressTranslationFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host];

	for (res = res0; res != NULL; res = res->ai_next) {
		if ((sock = socket(res->ai_family, res->ai_socktype,
		if ((_socket = socket(res->ai_family, res->ai_socktype,
		    res->ai_protocol)) == INVALID_SOCKET)
			continue;

		if (connect(sock, res->ai_addr, res->ai_addrlen) == -1) {
			close(sock);
			sock = INVALID_SOCKET;
		if (connect(_socket, res->ai_addr, res->ai_addrlen) == -1) {
			close(_socket);
			_socket = INVALID_SOCKET;
			continue;
		}

		break;
	}

	freeaddrinfo(res0);
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
389


390
391
392
393
394
395
396
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387


388
389
390
391
392
393
394
395
396







-
+







-
-
+
+







	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = OF_BSWAP16_IF_LE(port);

	if (he->h_addrtype != AF_INET ||
	    (sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
	    (_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
# ifdef OF_HAVE_THREADS
		[addrlist release];
		[mutex unlock];
# endif
		@throw [OFConnectionFailedException
		    exceptionWithClass: [self class]
				socket: self
								  host: host
								  port: port];
				  host: host
				  port: port];
	}

# ifdef OF_HAVE_THREADS
	@try {
		for (ip = he->h_addr_list; *ip != NULL; ip++)
			[addrlist addItem: ip];

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







+
-
+











-
-
+
+



-
+






-
+








	for (ip = [addrlist items]; *ip != NULL; ip++) {
# else
	for (ip = he->h_addr_list; *ip != NULL; ip++) {
# endif
		memcpy(&addr.sin_addr.s_addr, *ip, he->h_length);

		if (connect(_socket, (struct sockaddr*)&addr,
		if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
		    sizeof(addr)) == -1)
			continue;

		connected = YES;
		break;
	}

# ifdef OF_HAVE_THREADS
	[addrlist release];
# endif

	if (!connected) {
		close(sock);
		sock = INVALID_SOCKET;
		close(_socket);
		_socket = INVALID_SOCKET;
	}
#endif

	if (sock == INVALID_SOCKET)
	if (_socket == INVALID_SOCKET)
		@throw [OFConnectionFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host
				  port: port];

	if (SOCKS5Host != nil)
	if (_SOCKS5Host != nil)
		[self OF_SOCKS5ConnectToHost: destinationHost
					port: destinationPort];
}

#ifdef OF_HAVE_THREADS
- (void)asyncConnectToHost: (OFString*)host
		      port: (uint16_t)port
483
484
485
486
487
488
489
490

491
492
493
494
495

496
497
498
499
500
501
502
484
485
486
487
488
489
490

491
492
493
494
495

496
497
498
499
500
501
502
503







-
+




-
+







	union {
		struct sockaddr_storage storage;
		struct sockaddr_in in;
		struct sockaddr_in6 in6;
	} addr;
	socklen_t addrLen;

	if (sock != INVALID_SOCKET)
	if (_socket != INVALID_SOCKET)
		@throw [OFAlreadyConnectedException
		    exceptionWithClass: [self class]
				socket: self];

	if (SOCKS5Host != nil)
	if (_SOCKS5Host != nil)
		@throw [OFNotImplementedException
		    exceptionWithClass: [self class]
			      selector: _cmd];

#ifdef HAVE_THREADSAFE_GETADDRINFO
	struct addrinfo hints, *res;
	char portCString[7];
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
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







-
+
+





-
+





-
+

-
-
+
+







	if (getaddrinfo([host cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    portCString, &hints, &res))
		@throw [OFAddressTranslationFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host];

	if ((sock = socket(res->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
	if ((_socket = socket(res->ai_family, SOCK_STREAM,
	    0)) == INVALID_SOCKET)
		@throw [OFBindFailedException exceptionWithClass: [self class]
							  socket: self
							    host: host
							    port: port];

	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&one,
	if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one,
	    sizeof(one)))
		@throw [OFSetOptionFailedException
		    exceptionWithClass: [self class]
				stream: self];

	if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
	if (bind(_socket, res->ai_addr, res->ai_addrlen) == -1) {
		freeaddrinfo(res);
		close(sock);
		sock = INVALID_SOCKET;
		close(_socket);
		_socket = INVALID_SOCKET;
		@throw [OFBindFailedException exceptionWithClass: [self class]
							  socket: self
							    host: host
							    port: port];
	}

	freeaddrinfo(res);
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
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
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
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







-
+





-
+





-
-
-
+
+
+











-
-
-
+
+
+











-
-
+
+








-
+



-
+




-
+









-
+


-
+

-
+

-
+

-
+




-
-
-
+
+
+

-
+







	}

	memcpy(&addr.in.sin_addr.s_addr, he->h_addr_list[0], he->h_length);

# ifdef OF_HAVE_THREADS
	[mutex unlock];
# endif
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
	if ((_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
		@throw [OFBindFailedException exceptionWithClass: [self class]
							  socket: self
							    host: host
							    port: port];

	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&one,
	if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one,
	    sizeof(one)))
		@throw [OFSetOptionFailedException
		    exceptionWithClass: [self class]
				stream: self];

	if (bind(sock, (struct sockaddr*)&addr.in, sizeof(addr.in)) == -1) {
		close(sock);
		sock = INVALID_SOCKET;
	if (bind(_socket, (struct sockaddr*)&addr.in, sizeof(addr.in)) == -1) {
		close(_socket);
		_socket = INVALID_SOCKET;
		@throw [OFBindFailedException exceptionWithClass: [self class]
							  socket: self
							    host: host
							    port: port];
	}
#endif

	if (port > 0)
		return port;

	addrLen = sizeof(addr.storage);
	if (getsockname(sock, (struct sockaddr*)&addr, &addrLen)) {
		close(sock);
		sock = INVALID_SOCKET;
	if (getsockname(_socket, (struct sockaddr*)&addr, &addrLen)) {
		close(_socket);
		_socket = INVALID_SOCKET;
		@throw [OFBindFailedException exceptionWithClass: [self class]
							  socket: self
							    host: host
							    port: port];
	}

	if (addr.storage.ss_family == AF_INET)
		return OF_BSWAP16_IF_LE(addr.in.sin_port);
	if (addr.storage.ss_family == AF_INET6)
		return OF_BSWAP16_IF_LE(addr.in6.sin6_port);

	close(sock);
	sock = INVALID_SOCKET;
	close(_socket);
	_socket = INVALID_SOCKET;
	@throw [OFBindFailedException exceptionWithClass: [self class]
						  socket: self
						    host: host
						    port: port];
}

- (void)listenWithBackLog: (int)backLog
{
	if (sock == INVALID_SOCKET)
	if (_socket == INVALID_SOCKET)
		@throw [OFNotConnectedException exceptionWithClass: [self class]
							    socket: self];

	if (listen(sock, backLog) == -1)
	if (listen(_socket, backLog) == -1)
		@throw [OFListenFailedException exceptionWithClass: [self class]
							    socket: self
							   backLog: backLog];

	listening = YES;
	_listening = YES;
}

- (void)listen
{
	[self listenWithBackLog: SOMAXCONN];
}

- (OFTCPSocket*)accept
{
	OFTCPSocket *newSocket;
	OFTCPSocket *client;
	struct sockaddr_storage *addr;
	socklen_t addrLen;
	int newSock;
	int socket;

	newSocket = [[[[self class] alloc] init] autorelease];
	client = [[[[self class] alloc] init] autorelease];
	addrLen = sizeof(*addr);
	addr = [newSocket allocMemoryWithSize: addrLen];
	addr = [client allocMemoryWithSize: addrLen];

	if ((newSock = accept(sock, (struct sockaddr*)addr,
	if ((socket = accept(_socket, (struct sockaddr*)addr,
	    &addrLen)) == INVALID_SOCKET)
		@throw [OFAcceptFailedException exceptionWithClass: [self class]
							    socket: self];

	newSocket->sock = newSock;
	newSocket->sockAddr = addr;
	newSocket->sockAddrLen = addrLen;
	client->_socket = socket;
	client->_sockAddr = addr;
	client->_sockAddrLen = addrLen;

	return newSocket;
	return client;
}

- (void)asyncAcceptWithTarget: (id)target
		     selector: (SEL)selector
{
	[OFRunLoop OF_addAsyncAcceptForTCPSocket: self
					  target: target
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
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







-
+









-
+








-
+















-
+




















-
+






-
-
-
-
+
+
+
+


}
#endif

- (void)setKeepAlivesEnabled: (BOOL)enable
{
	int v = enable;

	if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&v, sizeof(v)))
	if (setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&v, sizeof(v)))
		@throw [OFSetOptionFailedException
		    exceptionWithClass: [self class]
				stream: self];
}

- (OFString*)remoteAddress
{
	char *host;

	if (sockAddr == NULL || sockAddrLen == 0)
	if (_sockAddr == NULL || _sockAddrLen == 0)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

#ifdef HAVE_THREADSAFE_GETADDRINFO
	host = [self allocMemoryWithSize: NI_MAXHOST];

	@try {
		if (getnameinfo((struct sockaddr*)sockAddr, sockAddrLen, host,
		if (getnameinfo((struct sockaddr*)_sockAddr, _sockAddrLen, host,
		    NI_MAXHOST, NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV))
			@throw [OFAddressTranslationFailedException
			    exceptionWithClass: [self class]];

		return [OFString stringWithCString: host
					  encoding: OF_STRING_ENCODING_NATIVE];
	} @finally {
		[self freeMemory: host];
	}
#else
# ifdef OF_HAVE_THREADS
	[mutex lock];

	@try {
# endif
		host = inet_ntoa(((struct sockaddr_in*)sockAddr)->sin_addr);
		host = inet_ntoa(((struct sockaddr_in*)_sockAddr)->sin_addr);

		if (host == NULL)
			@throw [OFAddressTranslationFailedException
			    exceptionWithClass: [self class]];

		return [OFString stringWithCString: host
					  encoding: OF_STRING_ENCODING_NATIVE];
# ifdef OF_HAVE_THREADS
	} @finally {
		[mutex unlock];
	}
# endif
#endif

	/* Get rid of a warning, never reached anyway */
	assert(0);
}

- (BOOL)isListening
{
	return listening;
	return _listening;
}

- (void)close
{
	[super close];

	listening = NO;
	[self freeMemory: sockAddr];
	sockAddr = NULL;
	sockAddrLen = 0;
	_listening = NO;
	[self freeMemory: _sockAddr];
	_sockAddr = NULL;
	_sockAddrLen = 0;
}
@end

Modified src/OFTLSKey.h from [e53bfd8cf7] to [9ad9a41960].

26
27
28
29
30
31
32
33

34
35
36
37



38
39
40
41
42
43
44
26
27
28
29
30
31
32

33
34



35
36
37
38
39
40
41
42
43
44







-
+

-
-
-
+
+
+








/*!
 * @brief A class for Thread Local Storage keys.
 */
@interface OFTLSKey: OFObject
{
@public
	of_tlskey_t key;
	of_tlskey_t _key;
@protected
	void (*destructor)(id);
	of_list_object_t *listObject;
	BOOL initialized;
	void (*_destructor)(id);
	of_list_object_t *_listObject;
	BOOL _initialized;
}

/*!
 * @brief Creates a new Thread Local Storage key
 *
 * @return A new, autoreleased Thread Local Storage key
 */

Modified src/OFTLSKey.m from [a1e7ea9f8c] to [90e1fd67d0].

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







-
-
+
+









-
+



-
+


-
+









-
+



-
+






+
-
-
+
+

-
-
-
+
+
+

-
+

-
+






	of_list_object_t *iter;

	@synchronized (TLSKeys) {
		for (iter = [TLSKeys firstListObject]; iter != NULL;
		    iter = iter->next) {
			OFTLSKey *key = (OFTLSKey*)iter->object;

			if (key->destructor != NULL)
				key->destructor(iter->object);
			if (key->_destructor != NULL)
				key->_destructor(iter->object);
		}
	}
}

- init
{
	self = [super init];

	@try {
		if (!of_tlskey_new(&key))
		if (!of_tlskey_new(&_key))
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		initialized = YES;
		_initialized = YES;

		@synchronized (TLSKeys) {
			listObject = [TLSKeys appendObject: self];
			_listObject = [TLSKeys appendObject: self];
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithDestructor: (void(*)(id))destructor_
- initWithDestructor: (void(*)(id))destructor
{
	self = [self init];

	destructor = destructor_;
	_destructor = destructor;

	return self;
}

- (void)dealloc
{
	if (_initialized) {
	if (destructor != NULL)
		destructor(self);
		if (_destructor != NULL)
			_destructor(self);

	if (initialized)
		of_tlskey_free(key);

		of_tlskey_free(_key);
	}

	/* In case we called [self release] in init */
	if (listObject != NULL) {
	if (_listObject != NULL) {
		@synchronized (TLSKeys) {
			[TLSKeys removeListObject: listObject];
			[TLSKeys removeListObject: _listObject];
		}
	}

	[super dealloc];
}
@end

Modified src/OFThread.h from [daf9be21c3] to [abb9dc92a6].

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







-
+




-
+

-
+

-
-
-
+
+
+







@interface OFThread: OFObject <OFCopying>
{
#ifdef OF_THREAD_M
@public
#else
@private
#endif
	of_thread_t thread;
	of_thread_t _thread;
	enum {
		OF_THREAD_NOT_RUNNING,
		OF_THREAD_RUNNING,
		OF_THREAD_WAITING_FOR_JOIN
	} running;
	} _running;
#ifdef OF_HAVE_BLOCKS
	of_thread_block_t block;
	of_thread_block_t _block;
#endif
	id returnValue;
	OFRunLoop *runLoop;
	OFString *name;
	id _returnValue;
	OFRunLoop *_runLoop;
	OFString *_name;
}

#ifdef OF_HAVE_PROPERTIES
# ifdef OF_HAVE_BLOCKS
@property (copy) of_thread_block_t block;
# endif
@property (copy) OFString *name;

Modified src/OFThread.m from [750512444c] to [d1deb64582].

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







-
-
+
+


-
+



-
+




















-
+










-
+







	objc_autoreleasePoolPush();

	/*
	 * Nasty workaround for thread implementations which can't return a
	 * value on join.
	 */
#ifdef OF_HAVE_BLOCKS
	if (thread->block != NULL)
		thread->returnValue = [thread->block() retain];
	if (thread->_block != NULL)
		thread->_returnValue = [thread->_block() retain];
	else
#endif
		thread->returnValue = [[thread main] retain];
		thread->_returnValue = [[thread main] retain];

	[thread handleTermination];

	thread->running = OF_THREAD_WAITING_FOR_JOIN;
	thread->_running = OF_THREAD_WAITING_FOR_JOIN;

	[OFTLSKey OF_callAllDestructors];
#ifdef OF_OBJFW_RUNTIME
	/*
	 * As the values returned by objc_autoreleasePoolPush() in the ObjFW
	 * runtime are not actually pointers, but sequential numbers, 0 means
	 * we pop everything.
	 */
	objc_autoreleasePoolPop(0);
#endif

	[thread release];

	return 0;
}

static void
set_thread_name(OFThread *thread)
{
#ifdef __HAIKU__
	OFString *name = thread->name;
	OFString *name = thread->_name;

	if (name == nil)
		name = [thread className];

	rename_thread(get_pthread_thread_id(thread->thread), [name UTF8String]);
#endif
}

@implementation OFThread
#if defined(OF_HAVE_PROPERTIES) && defined(OF_HAVE_BLOCKS)
@synthesize block;
@synthesize block = _block;
#endif

+ (void)initialize
{
	if (self != [OFThread class])
		return;

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







-
+

-
+








-
+







	return [[[self alloc] initWithBlock: block] autorelease];
}
#endif

+ (void)setObject: (id)object
	forTLSKey: (OFTLSKey*)key
{
	id oldObject = of_tlskey_get(key->key);
	id oldObject = of_tlskey_get(key->_key);

	if (!of_tlskey_set(key->key, [object retain]))
	if (!of_tlskey_set(key->_key, [object retain]))
		@throw [OFInvalidArgumentException exceptionWithClass: self
							     selector: _cmd];

	[oldObject release];
}

+ (id)objectForTLSKey: (OFTLSKey*)key
{
	return [[(id)of_tlskey_get(key->key) retain] autorelease];
	return [[(id)of_tlskey_get(key->_key) retain] autorelease];
}

+ (OFThread*)currentThread
{
	return [[(id)of_tlskey_get(threadSelfKey) retain] autorelease];
}

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







-
+



-
+




















-
+







-
+




-
+


















-
-
+
+





-
+




-
-
-
+
+
+




-
+

-
+











-
+




-
+

-
+










-
+


-
+




-
-
+
+



-
+




-
+


-
+

-
+

-
+





-
+








-
-
+
+

-
-
+
+




}

+ (void)terminateWithObject: (id)object
{
	OFThread *thread = of_tlskey_get(threadSelfKey);

	if (thread != nil) {
		thread->returnValue = [object retain];
		thread->_returnValue = [object retain];

		[thread handleTermination];

		thread->running = OF_THREAD_WAITING_FOR_JOIN;
		thread->_running = OF_THREAD_WAITING_FOR_JOIN;
	}

	[OFTLSKey OF_callAllDestructors];
#ifdef OF_OBJFW_RUNTIME
	/*
	 * As the values returned by objc_autoreleasePoolPush() in the ObjFW
	 * runtime are not actually pointers, but sequential numbers, 0 means
	 * we pop everything.
	 */
	objc_autoreleasePoolPop(0);
#endif

	[thread release];

	of_thread_exit();
}

+ (void)OF_createMainThread
{
	mainThread = [[OFThread alloc] init];
	mainThread->thread = of_thread_current();
	mainThread->_thread = of_thread_current();

	if (!of_tlskey_set(threadSelfKey, mainThread))
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}

#ifdef OF_HAVE_BLOCKS
- initWithBlock: (of_thread_block_t)block_
- initWithBlock: (of_thread_block_t)block
{
	self = [super init];

	@try {
		block = [block_ copy];
		_block = [block copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
#endif

- (id)main
{
	[[OFRunLoop currentRunLoop] run];

	return nil;
}

- (void)handleTermination
{
	OFRunLoop *oldRunLoop = runLoop;
	runLoop = nil;
	OFRunLoop *oldRunLoop = _runLoop;
	_runLoop = nil;
	[oldRunLoop release];
}

- (void)start
{
	if (running == OF_THREAD_RUNNING)
	if (_running == OF_THREAD_RUNNING)
		@throw [OFThreadStillRunningException
		    exceptionWithClass: [self class]
				thread: self];

	if (running == OF_THREAD_WAITING_FOR_JOIN) {
		of_thread_detach(thread);
		[returnValue release];
	if (_running == OF_THREAD_WAITING_FOR_JOIN) {
		of_thread_detach(_thread);
		[_returnValue release];
	}

	[self retain];

	running = OF_THREAD_RUNNING;
	_running = OF_THREAD_RUNNING;

	if (!of_thread_new(&thread, call_main, self)) {
	if (!of_thread_new(&_thread, call_main, self)) {
		[self release];
		@throw [OFThreadStartFailedException
		    exceptionWithClass: [self class]
				thread: self];
	}

	set_thread_name(self);
}

- (id)join
{
	if (running == OF_THREAD_NOT_RUNNING || !of_thread_join(thread))
	if (_running == OF_THREAD_NOT_RUNNING || !of_thread_join(_thread))
		@throw [OFThreadJoinFailedException
		    exceptionWithClass: [self class]
				thread: self];

	running = OF_THREAD_NOT_RUNNING;
	_running = OF_THREAD_NOT_RUNNING;

	return returnValue;
	return _returnValue;
}

- copy
{
	return [self retain];
}

- (OFRunLoop*)runLoop
{
#ifdef OF_HAVE_ATOMIC_OPS
	if (runLoop == nil) {
	if (_runLoop == nil) {
		OFRunLoop *tmp = [[OFRunLoop alloc] init];

		if (!of_atomic_cmpswap_ptr((void**)&runLoop, nil, tmp))
		if (!of_atomic_cmpswap_ptr((void**)&_runLoop, nil, tmp))
			[tmp release];
	}
#else
	@synchronized (self) {
		if (runLoop == nil)
			runLoop = [[OFRunLoop alloc] init];
		if (_runLoop == nil)
			_runLoop = [[OFRunLoop alloc] init];
	}
#endif

	return [[runLoop retain] autorelease];
	return [[_runLoop retain] autorelease];
}

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

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

	if (running == OF_THREAD_RUNNING)
	if (_running == OF_THREAD_RUNNING)
		set_thread_name(self);
}

- (void)dealloc
{
	if (running == OF_THREAD_RUNNING)
	if (_running == OF_THREAD_RUNNING)
		@throw [OFThreadStillRunningException
		    exceptionWithClass: [self class]
				thread: self];

	/*
	 * We should not be running anymore, but call detach in order to free
	 * the resources.
	 */
	if (running == OF_THREAD_WAITING_FOR_JOIN)
		of_thread_detach(thread);
	if (_running == OF_THREAD_WAITING_FOR_JOIN)
		of_thread_detach(_thread);

	[returnValue release];
	[runLoop release];
	[_returnValue release];
	[_runLoop release];

	[super dealloc];
}
@end

Modified src/OFThreadPool.h from [646e84b6f4] to [0db8d807f8].

29
30
31
32
33
34
35
36
37
38



39
40
41
42
43




44
45
46
47
48
49
50
29
30
31
32
33
34
35



36
37
38
39




40
41
42
43
44
45
46
47
48
49
50







-
-
-
+
+
+

-
-
-
-
+
+
+
+







 * @brief A class providing a pool of reusable threads.
 *
 * @note When the thread pool is released, all threads will terminate after
 *	 they finish the job they are currently processing.
 */
@interface OFThreadPool: OFObject
{
	size_t size;
	OFMutableArray *threads;
	volatile int count;
	size_t _size;
	OFMutableArray *_threads;
	volatile int _count;
@public
	OFList *queue;
	OFCondition *queueCondition;
	volatile int doneCount;
	OFCondition *countCondition;
	OFList *_queue;
	OFCondition *_queueCondition;
	volatile int _doneCount;
	OFCondition *_countCondition;
}

/*!
 * @brief Returns a new thread pool with one thread for each core in the system.
 *
 * @warning If for some reason the number of cores in the system could not be
 *	    determined, the pool will only have one thread!

Modified src/OFThreadPool.m from [b48920db5d] to [75625ed3ab].

23
24
25
26
27
28
29
30
31
32



33
34

35
36
37
38
39
40
41
23
24
25
26
27
28
29



30
31
32
33

34
35
36
37
38
39
40
41







-
-
-
+
+
+

-
+







#import "OFCondition.h"
#import "OFSystemInfo.h"

#import "autorelease.h"

@interface OFThreadPoolJob: OFObject
{
	id target;
	SEL selector;
	id object;
	id _target;
	SEL _selector;
	id _object;
#ifdef OF_HAVE_BLOCKS
	of_thread_pool_block_t block;
	of_thread_pool_block_t _block;
#endif
}

+ (instancetype)jobWithTarget: (id)target
		     selector: (SEL)selector
		       object: (id)object;
#ifdef OF_HAVE_BLOCKS
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
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







-
-
-
+
+
+




-
-
-
+
+
+









-
+




-
+











-
-
+
+

-
+








-
-
+
+


-
-
+
+





-
-
+
+

-
-
+
+

















-
-
-
-
+
+
+
+










-
-
-
+
+
+








-
+







-
+



-
+




-
+


-
+

-
+




-
+



-
+

-
+


-
+






-
+







-
+

-
+




-
+

-
+

-
+







+ (instancetype)jobWithBlock: (of_thread_pool_block_t)block
{
	return [[(OFThreadPoolJob*)[self alloc]
	    initWithBlock: block] autorelease];
}
#endif

- initWithTarget: (id)target_
	selector: (SEL)selector_
	  object: (id)object_
- initWithTarget: (id)target
	selector: (SEL)selector
	  object: (id)object
{
	self = [super init];

	@try {
		target = [target_ retain];
		selector = selector_;
		object = [object_ retain];
		_target = [target retain];
		_selector = selector;
		_object = [object retain];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

#ifdef OF_HAVE_BLOCKS
- initWithBlock: (of_thread_pool_block_t)block_
- initWithBlock: (of_thread_pool_block_t)block
{
	self = [super init];

	@try {
		block = [block_ copy];
		_block = [block copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
#endif

- (void)dealloc
{
	[target release];
	[object release];
	[_target release];
	[_object release];
#ifdef OF_HAVE_BLOCKS
	[block release];
	[_block release];
#endif

	[super dealloc];
}

- (void)perform
{
#ifdef OF_HAVE_BLOCKS
	if (block != NULL)
		block();
	if (_block != NULL)
		_block();
	else
#endif
		[object performSelector: selector
			     withObject: object];
		[_target performSelector: _selector
			      withObject: _object];
}
@end

@interface OFThreadPoolThread: OFThread
{
	OFList *queue;
	OFCondition *queueCondition, *countCondition;
	OFList *_queue;
	OFCondition *_queueCondition, *_countCondition;
@public
	volatile BOOL terminate;
	volatile int *doneCount;
	volatile BOOL _terminate;
	volatile int *_doneCount;
}

+ (instancetype)threadWithThreadPool: (OFThreadPool*)threadPool;
- initWithThreadPool: (OFThreadPool*)threadPool;
@end

@implementation OFThreadPoolThread
+ (instancetype)threadWithThreadPool: (OFThreadPool*)threadPool
{
	return [[[self alloc] initWithThreadPool: threadPool] autorelease];
}

- initWithThreadPool: (OFThreadPool*)threadPool
{
	self = [super init];

	@try {
		queue = [threadPool->queue retain];
		queueCondition = [threadPool->queueCondition retain];
		countCondition = [threadPool->countCondition retain];
		doneCount = &threadPool->doneCount;
		_queue = [threadPool->_queue retain];
		_queueCondition = [threadPool->_queueCondition retain];
		_countCondition = [threadPool->_countCondition retain];
		_doneCount = &threadPool->_doneCount;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[queue release];
	[queueCondition release];
	[countCondition release];
	[_queue release];
	[_queueCondition release];
	[_countCondition release];

	[super dealloc];
}

- (id)main
{
	void *pool;

	if (terminate)
	if (_terminate)
		return nil;

	pool = objc_autoreleasePoolPush();

	for (;;) {
		OFThreadPoolJob *job;

		[queueCondition lock];
		[_queueCondition lock];
		@try {
			of_list_object_t *listObject;

			if (terminate) {
			if (_terminate) {
				objc_autoreleasePoolPop(pool);
				return nil;
			}

			listObject = [queue firstListObject];
			listObject = [_queue firstListObject];

			while (listObject == NULL) {
				[queueCondition wait];
				[_queueCondition wait];

				if (terminate) {
				if (_terminate) {
					objc_autoreleasePoolPop(pool);
					return nil;
				}

				listObject = [queue firstListObject];
				listObject = [_queue firstListObject];
			}

			job = [[listObject->object retain] autorelease];
			[queue removeListObject: listObject];
			[_queue removeListObject: listObject];
		} @finally {
			[queueCondition unlock];
			[_queueCondition unlock];
		}

		if (terminate) {
		if (_terminate) {
			objc_autoreleasePoolPop(pool);
			return nil;
		}

		[job perform];

		if (terminate) {
		if (_terminate) {
			objc_autoreleasePoolPop(pool);
			return nil;
		}

		objc_autoreleasePoolPop(pool);
		pool = objc_autoreleasePoolPush();

		[countCondition lock];
		[_countCondition lock];
		@try {
			if (terminate) {
			if (_terminate) {
				objc_autoreleasePoolPop(pool);
				return nil;
			}

			(*doneCount)++;
			(*_doneCount)++;

			[countCondition signal];
			[_countCondition signal];
		} @finally {
			[countCondition unlock];
			[_countCondition unlock];
		}
	}
}
@end

@implementation OFThreadPool
+ (instancetype)threadPool
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
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







-
+






-
-
-
-
-
+
+
+
+
+







-
+








-
-
+
+
-
-
-











-
+

-
+

-
+



-
+

-
+


-
+

-
+



-
-
-
-
+
+
+
+






-
-
-
+
+
+

-
+

-
-
+
+

-
+






-
+

-
+


-
+

-
+







}

- init
{
	return [self initWithSize: [OFSystemInfo numberOfCPUs]];
}

- initWithSize: (size_t)size_
- initWithSize: (size_t)size
{
	self = [super init];

	@try {
		size_t i;

		size = size_;
		threads = [[OFMutableArray alloc] init];
		queue = [[OFList alloc] init];
		queueCondition = [[OFCondition alloc] init];
		countCondition = [[OFCondition alloc] init];
		_size = size;
		_threads = [[OFMutableArray alloc] init];
		_queue = [[OFList alloc] init];
		_queueCondition = [[OFCondition alloc] init];
		_countCondition = [[OFCondition alloc] init];

		for (i = 0; i < size; i++) {
			void *pool = objc_autoreleasePoolPush();

			OFThreadPoolThread *thread =
			    [OFThreadPoolThread threadWithThreadPool: self];

			[threads addObject: thread];
			[_threads addObject: thread];

			objc_autoreleasePoolPop(pool);
		}

		/*
		 * We need to start the threads in a separate loop to make sure
		 * threads is not modified anymore to prevent a race condition.
		 */
		for (i = 0; i < size; i++) {
			OFThreadPoolThread *thread = [threads objectAtIndex: i];
		for (i = 0; i < size; i++)
			[[_threads objectAtIndex: i] start];

			[thread start];
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	void *pool = objc_autoreleasePoolPush();
	[queueCondition lock];
	[_queueCondition lock];
	@try {
		[countCondition lock];
		[_countCondition lock];
		@try {
			OFEnumerator *enumerator = [threads objectEnumerator];
			OFEnumerator *enumerator = [_threads objectEnumerator];
			OFThreadPoolThread *thread;

			while ((thread = [enumerator nextObject]) != nil)
				thread->terminate = YES;
				thread->_terminate = YES;
		} @finally {
			[countCondition unlock];
			[_countCondition unlock];
		}

		[queueCondition broadcast];
		[_queueCondition broadcast];
	} @finally {
		[queueCondition unlock];
		[_queueCondition unlock];
	}
	objc_autoreleasePoolPop(pool);

	[threads release];
	[queue release];
	[queueCondition release];
	[countCondition release];
	[_threads release];
	[_queue release];
	[_queueCondition release];
	[_countCondition release];

	[super dealloc];
}

- (void)OF_dispatchJob: (OFThreadPoolJob*)job
{
	[countCondition lock];
	count++;
	[countCondition unlock];
	[_countCondition lock];
	_count++;
	[_countCondition unlock];

	[queueCondition lock];
	[_queueCondition lock];
	@try {
		[queue appendObject: job];
		[queueCondition signal];
		[_queue appendObject: job];
		[_queueCondition signal];
	} @finally {
		[queueCondition unlock];
		[_queueCondition unlock];
	}
}

- (void)waitUntilDone
{
	for (;;) {
		[countCondition lock];
		[_countCondition lock];
		@try {
			if (doneCount == count)
			if (_doneCount == _count)
				return;

			[countCondition wait];
			[_countCondition wait];
		} @finally {
			[countCondition unlock];
			[_countCondition unlock];
		}
	}
}

- (void)dispatchWithTarget: (id)target
		  selector: (SEL)selector
		    object: (id)object
373
374
375
376
377
378
379
380

381
382
370
371
372
373
374
375
376

377
378
379







-
+


{
	[self OF_dispatchJob: [OFThreadPoolJob jobWithBlock: block]];
}
#endif

- (size_t)size
{
	return size;
	return _size;
}
@end

Modified src/OFTimer.h from [b48acf13c1] to [06b74b5159].

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







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

-
+

-
+

-
-
+
+

-
+







#endif

/*!
 * @brief A class for creating and firing timers.
 */
@interface OFTimer: OFObject <OFComparing>
{
	OFDate *fireDate;
	double interval;
	id target, object1, object2;
	SEL selector;
	uint8_t arguments;
	BOOL repeats;
	OFDate *_fireDate;
	double _interval;
	id _target, _object1, _object2;
	SEL _selector;
	uint8_t _arguments;
	BOOL _repeats;
#ifdef OF_HAVE_BLOCKS
	of_timer_block_t block;
	of_timer_block_t _block;
#endif
	BOOL isValid;
	BOOL _valid;
#ifdef OF_HAVE_THREADS
	OFCondition *condition;
	BOOL done;
	OFCondition *_condition;
	BOOL _done;
#endif
	OFRunLoop *inRunLoop;
	OFRunLoop *_inRunLoop;
}

#ifdef OF_HAVE_PROPERTIES
@property (retain) OFDate *fireDate;
#endif

/*!

Modified src/OFTimer.m from [937b3c80f0] to [f650b3c206].

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







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




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

-
+









-
-
-
-
-
+
+
+
+
+

-
-
-
-
+
+
+
+



-
+


-
-
-
-
+
+
+
+

-
+

-
-
-
-
+
+
+
+



-
+


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

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

-
+



-
-
-
-
+
+
+
+




-
-
-
-
-
+
+
+
+
+

-
+
















-
+

-
-
-
-
+
+
+
+

-
+


-
+





-
+

-
+

-
+




-
+

-
+




-
+


-
-
+
+


-
+

-
+


-
-
+
+


-
-
-
+
+
+







-
+

-
-
+
+

-
+



-
-
-
-
+
+
+
+









-
+


-
+




-
+

-
+

-
+








-
+




-
+

-
-
+
+




-
+





-
+

-
-
+
+



-
+

-
+




-
+

-
+


		[self release];
		@throw e;
	}

	abort();
}

- 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_
- 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
{
	self = [super init];

	@try {
		fireDate = [fireDate_ retain];
		interval = interval_;
		target = [target_ retain];
		selector = selector_;
		object1 = [object1_ retain];
		object2 = [object2_ retain];
		arguments = arguments_;
		repeats = repeats_;
		isValid = YES;
		_fireDate = [fireDate retain];
		_interval = interval;
		_target = [target retain];
		_selector = selector;
		_object1 = [object1 retain];
		_object2 = [object2 retain];
		_arguments = arguments;
		_repeats = repeats;
		_valid = YES;
#ifdef OF_HAVE_THREADS
		condition = [[OFCondition alloc] init];
		_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_
- initWithFireDate: (OFDate*)fireDate
	  interval: (double)interval
	    target: (id)target
	  selector: (SEL)selector
	   repeats: (BOOL)repeats
{
	return [self OF_initWithFireDate: fireDate_
				interval: interval_
				  target: target_
				selector: selector_
	return [self OF_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: nil
				  object: nil
			       arguments: 0
				 repeats: repeats_];
				 repeats: repeats];
}

- initWithFireDate: (OFDate*)fireDate_
	  interval: (double)interval_
	    target: (id)target_
	  selector: (SEL)selector_
- 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_
	return [self OF_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object
				  object: nil
			       arguments: 1
				 repeats: repeats_];
				 repeats: repeats];
}

- initWithFireDate: (OFDate*)fireDate_
	  interval: (double)interval_
	    target: (id)target_
	  selector: (SEL)selector_
	    object: (id)object1_
	    object: (id)object2_
	   repeats: (BOOL)repeats_
- initWithFireDate: (OFDate*)fireDate
	  interval: (double)interval
	    target: (id)target
	  selector: (SEL)selector
	    object: (id)object1
	    object: (id)object2
	   repeats: (BOOL)repeats
{
	return [self OF_initWithFireDate: fireDate_
				interval: interval_
				  target: target_
				selector: selector_
				  object: object1_
				  object: object2_
	return [self OF_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object1
				  object: object2
			       arguments: 2
				 repeats: repeats_];
				 repeats: repeats];
}

#ifdef OF_HAVE_BLOCKS
- initWithFireDate: (OFDate*)fireDate_
	   interval: (double)interval_
	    repeats: (BOOL)repeats_
	      block: (of_timer_block_t)block_
- initWithFireDate: (OFDate*)fireDate
	   interval: (double)interval
	    repeats: (BOOL)repeats
	      block: (of_timer_block_t)block
{
	self = [super init];

	@try {
		fireDate = [fireDate_ retain];
		interval = interval_;
		repeats = repeats_;
		block = [block_ copy];
		isValid = YES;
		_fireDate = [fireDate retain];
		_interval = interval;
		_repeats = repeats;
		_block = [block copy];
		_valid = YES;
# ifdef OF_HAVE_THREADS
		condition = [[OFCondition alloc] init];
		_condition = [[OFCondition alloc] init];
# endif
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
#endif

- (void)dealloc
{
	/*
	 * The run loop references the timer, so it should never be deallocated
	 * if it is still in a run loop.
	 */
	assert(inRunLoop == nil);
	assert(_inRunLoop == nil);

	[fireDate release];
	[target release];
	[object1 release];
	[object2 release];
	[_fireDate release];
	[_target release];
	[_object1 release];
	[_object2 release];
#ifdef OF_HAVE_BLOCKS
	[block release];
	[_block release];
#endif
#ifdef OF_HAVE_THREADS
	[condition release];
	[_condition release];
#endif

	[super dealloc];
}

- (of_comparison_result_t)compare: (id <OFComparing>)object_
- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	OFTimer *otherTimer;
	OFTimer *timer;

	if (![object_ isKindOfClass: [OFTimer class]])
	if (![object isKindOfClass: [OFTimer class]])
		@throw[OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	otherTimer = (OFTimer*)object_;
	timer = (OFTimer*)object;

	return [fireDate compare: otherTimer->fireDate];
	return [_fireDate compare: timer->_fireDate];
}

- (void)fire
{
	OF_ENSURE(arguments <= 2);
	OF_ENSURE(_arguments <= 2);

#ifdef OF_HAVE_BLOCKS
	if (block != NULL)
		block(self);
	if (_block != NULL)
		_block(self);
	else {
#endif
		switch (arguments) {
		switch (_arguments) {
		case 0:
			[target performSelector: selector];
			[_target performSelector: _selector];
			break;
		case 1:
			[target performSelector: selector
				     withObject: object1];
			[_target performSelector: _selector
				      withObject: _object1];
			break;
		case 2:
			[target performSelector: selector
				     withObject: object1
				     withObject: object2];
			[_target performSelector: _selector
				      withObject: _object1
				      withObject: _object2];
			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif

#ifdef OF_HAVE_THREADS
	[condition lock];
	[_condition lock];
	@try {
		done = YES;
		[condition signal];
		_done = YES;
		[_condition signal];
	} @finally {
		[condition unlock];
		[_condition unlock];
	}
#endif

	if (repeats && isValid) {
		OFDate *old = fireDate;
		fireDate = [[OFDate alloc]
		    initWithTimeIntervalSinceNow: interval];
	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, YES)
}

- (void)setFireDate: (OFDate*)fireDate_
- (void)setFireDate: (OFDate*)fireDate
{
	[self retain];
	@try {
		@synchronized (self) {
			[inRunLoop OF_removeTimer: self];
			[_inRunLoop OF_removeTimer: self];

			OF_SETTER(fireDate, fireDate_, YES, 0)
			OF_SETTER(_fireDate, fireDate, YES, 0)

			[inRunLoop addTimer: self];
			[_inRunLoop addTimer: self];
		}
	} @finally {
		[self release];
	}
}

- (double)timeInterval
{
	return interval;
	return _interval;
}

- (void)invalidate
{
	isValid = NO;
	_valid = NO;

	[target release];
	target = nil;
	[_target release];
	_target = nil;
}

- (BOOL)isValid
{
	return isValid;
	return _valid;
}

#ifdef OF_HAVE_THREADS
- (void)waitUntilDone
{
	[condition lock];
	[_condition lock];
	@try {
		if (done) {
			done = NO;
		if (_done) {
			_done = NO;
			return;
		}

		[condition wait];
		[_condition wait];
	} @finally {
		[condition unlock];
		[_condition unlock];
	}
}
#endif

- (void)OF_setInRunLoop: (OFRunLoop*)inRunLoop_
- (void)OF_setInRunLoop: (OFRunLoop*)inRunLoop
{
	OF_SETTER(inRunLoop, inRunLoop_, YES, 0)
	OF_SETTER(_inRunLoop, inRunLoop, YES, 0)
}
@end

Modified src/OFURL.h from [74eb4f4df2] to [17bbc676ef].

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







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







@class OFString;

/*!
 * @brief A class for parsing URLs and accessing parts of it.
 */
@interface OFURL: OFObject <OFCopying, OFSerialization>
{
	OFString *scheme;
	OFString *host;
	uint16_t port;
	OFString *user;
	OFString *_scheme, *_host;
	uint16_t _port;
	OFString *_user, *_password, *_path, *_parameters, *_query, *_fragment;
	OFString *password;
	OFString *path;
	OFString *parameters;
	OFString *query;
	OFString *fragment;
}

#ifdef OF_HAVE_PROPERTIES
@property (copy) OFString *scheme;
@property (copy) OFString *host;
@property uint16_t port;
@property (copy) OFString *user;

Modified src/OFURL.m from [2267fdd898] to [fcf898c186].

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







-
-
+
+



-
+


-
+




















-
+

-
+


-
+












-
+









-
+

-
-
+
+



-
+


-
-
-
-
+
+
+
+








-
+






-
+






-
+



-
-
+
+

-
+







			@throw [OFOutOfMemoryException
			     exceptionWithClass: [self class]
				  requestedSize: [string UTF8StringLength]];

		UTF8String = UTF8String2;

		if (!strncmp(UTF8String, "file://", 7)) {
			scheme = @"file";
			path = [[OFString alloc]
			_scheme = @"file";
			_path = [[OFString alloc]
			    initWithUTF8String: UTF8String + 7];
			return self;
		} else if (!strncmp(UTF8String, "http://", 7)) {
			scheme = @"http";
			_scheme = @"http";
			UTF8String += 7;
		} else if (!strncmp(UTF8String, "https://", 8)) {
			scheme = @"https";
			_scheme = @"https";
			UTF8String += 8;
		} else
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];

		if ((tmp = strchr(UTF8String, '/')) != NULL) {
			*tmp = '\0';
			tmp++;
		}

		if ((tmp2 = strchr(UTF8String, '@')) != NULL) {
			char *tmp3;

			*tmp2 = '\0';
			tmp2++;

			if ((tmp3 = strchr(UTF8String, ':')) != NULL) {
				*tmp3 = '\0';
				tmp3++;

				user = [[OFString alloc]
				_user = [[OFString alloc]
				    initWithUTF8String: UTF8String];
				password = [[OFString alloc]
				_password = [[OFString alloc]
				    initWithUTF8String: tmp3];
			} else
				user = [[OFString alloc]
				_user = [[OFString alloc]
				    initWithUTF8String: UTF8String];

			UTF8String = tmp2;
		}

		if ((tmp2 = strchr(UTF8String, ':')) != NULL) {
			void *pool;
			OFString *portString;

			*tmp2 = '\0';
			tmp2++;

			host = [[OFString alloc]
			_host = [[OFString alloc]
			    initWithUTF8String: UTF8String];

			pool = objc_autoreleasePoolPush();
			portString = [OFString stringWithUTF8String: tmp2];

			if ([portString decimalValue] > 65535)
				@throw [OFInvalidFormatException
				    exceptionWithClass: [self class]];

			port = [portString decimalValue];
			_port = [portString decimalValue];

			if (port == 0)
				port = 80;
			if (_port == 0)
				_port = 80;

			objc_autoreleasePoolPop(pool);
		} else {
			host = [[OFString alloc]
			_host = [[OFString alloc]
			    initWithUTF8String: UTF8String];

			if ([scheme isEqual: @"http"])
				port = 80;
			else if ([scheme isEqual: @"https"])
				port = 443;
			if ([_scheme isEqual: @"http"])
				_port = 80;
			else if ([_scheme isEqual: @"https"])
				_port = 443;
			else
				assert(0);
		}

		if ((UTF8String = tmp) != NULL) {
			if ((tmp = strchr(UTF8String, '#')) != NULL) {
				*tmp = '\0';

				fragment = [[OFString alloc]
				_fragment = [[OFString alloc]
				    initWithUTF8String: tmp + 1];
			}

			if ((tmp = strchr(UTF8String, '?')) != NULL) {
				*tmp = '\0';

				query = [[OFString alloc]
				_query = [[OFString alloc]
				    initWithUTF8String: tmp + 1];
			}

			if ((tmp = strchr(UTF8String, ';')) != NULL) {
				*tmp = '\0';

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

			path = [[OFString alloc] initWithFormat: @"/%s",
								 UTF8String];
			_path = [[OFString alloc] initWithFormat: @"/%s",
								  UTF8String];
		} else
			path = @"";
			_path = @"";
	} @catch (id e) {
		[self release];
		@throw e;
	} @finally {
		free(UTF8String2);
	}

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







-
-
-
-
-
+
+
+
+
+










-
+





-
+




-
+




-
+







-
+

-
+



-
+


-
+







		return [self initWithString: string];

	self = [super init];

	@try {
		char *tmp;

		scheme = [URL->scheme copy];
		host = [URL->host copy];
		port = URL->port;
		user = [URL->user copy];
		password = [URL->password copy];
		_scheme = [URL->_scheme copy];
		_host = [URL->_host copy];
		_port = URL->_port;
		_user = [URL->_user copy];
		_password = [URL->_password copy];

		if ((UTF8String2 = strdup([string UTF8String])) == NULL)
			@throw [OFOutOfMemoryException
			     exceptionWithClass: [self class]
				  requestedSize: [string UTF8StringLength]];

		UTF8String = UTF8String2;

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

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

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

		if (*UTF8String == '/')
			path = [[OFString alloc]
			_path = [[OFString alloc]
			    initWithUTF8String: UTF8String];
		else {
			void *pool;
			OFString *s;

			pool = objc_autoreleasePoolPush();

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

			path = [[s stringByStandardizingURLPath] copy];
			_path = [[s stringByStandardizingURLPath] copy];

			objc_autoreleasePoolPop(pool);
		}
	} @catch (id e) {
		[self release];
		@throw e;
	} @finally {
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
494


495
496
497
498

499
500
501


502
503
504


505
506
507


508
509
510


511
512
513
514
515
516
517
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




494
495


496
497
498


499
500
501


502
503
504


505
506
507
508
509
510
511
512
513







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






-
+




-
+

-
+

-
+

-
+

-
+

-
-
+
+

-
+

-
-
+
+

-
-
+
+

-
-
+
+











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











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










-
+


-
+

-
+




-
+




-
+


-
+

-
+




-
+


-
+

-
+




-
+


-
+

-
+




-
+


-
+

-
+




-
+


-
+

-
-
+
+




-
+




-
+


-
+

-
+




-
+


-
+

-
+




-
+


-
+

-
+





-
+
-

-
-
-
+
+
+




-
-
-
-
+
+
+
+

-
-
+
+

-
-
+
+
-
-
-
-
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+







	}

	return self;
}

- (void)dealloc
{
	[scheme release];
	[host release];
	[user release];
	[password release];
	[path release];
	[parameters release];
	[query release];
	[fragment release];
	[_scheme release];
	[_host release];
	[_user release];
	[_password release];
	[_path release];
	[_parameters release];
	[_query release];
	[_fragment release];

	[super dealloc];
}

- (BOOL)isEqual: (id)object
{
	OFURL *otherURL;
	OFURL *URL;

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

	otherURL = object;
	URL = object;

	if (![otherURL->scheme isEqual: scheme])
	if (![URL->_scheme isEqual: _scheme])
		return NO;
	if (![otherURL->host isEqual: host])
	if (![URL->_host isEqual: _host])
		return NO;
	if (otherURL->port != port)
	if (URL->_port != _port)
		return NO;
	if (otherURL->user != user && ![otherURL->user isEqual: user])
	if (URL->_user != _user && ![URL->_user isEqual: _user])
		return NO;
	if (otherURL->password != password &&
	    ![otherURL->password isEqual: password])
	if (URL->_password != _password &&
	    ![URL->_password isEqual: _password])
		return NO;
	if (![otherURL->path isEqual: path])
	if (![URL->_path isEqual: _path])
		return NO;
	if (otherURL->parameters != parameters &&
	    ![otherURL->parameters isEqual: parameters])
	if (URL->_parameters != _parameters &&
	    ![URL->_parameters isEqual: _parameters])
		return NO;
	if (otherURL->query != query &&
	    ![otherURL->query isEqual: query])
	if (URL->_query != _query &&
	    ![URL->_query isEqual: _query])
		return NO;
	if (otherURL->fragment != fragment &&
	    ![otherURL->fragment isEqual: fragment])
	if (URL->_fragment != _fragment &&
	    ![URL->_fragment isEqual: _fragment])
		return NO;

	return YES;
}

- (uint32_t)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, [scheme hash]);
	OF_HASH_ADD_HASH(hash, [host hash]);
	OF_HASH_ADD(hash, (port & 0xFF00) >> 8);
	OF_HASH_ADD(hash, port & 0xFF);
	OF_HASH_ADD_HASH(hash, [user hash]);
	OF_HASH_ADD_HASH(hash, [password hash]);
	OF_HASH_ADD_HASH(hash, [path hash]);
	OF_HASH_ADD_HASH(hash, [parameters hash]);
	OF_HASH_ADD_HASH(hash, [query hash]);
	OF_HASH_ADD_HASH(hash, [fragment hash]);
	OF_HASH_ADD_HASH(hash, [_scheme hash]);
	OF_HASH_ADD_HASH(hash, [_host hash]);
	OF_HASH_ADD(hash, (_port & 0xFF00) >> 8);
	OF_HASH_ADD(hash, _port & 0xFF);
	OF_HASH_ADD_HASH(hash, [_user hash]);
	OF_HASH_ADD_HASH(hash, [_password hash]);
	OF_HASH_ADD_HASH(hash, [_path hash]);
	OF_HASH_ADD_HASH(hash, [_parameters hash]);
	OF_HASH_ADD_HASH(hash, [_query hash]);
	OF_HASH_ADD_HASH(hash, [_fragment hash]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

- copy
{
	OFURL *copy = [[[self class] alloc] init];

	@try {
		copy->scheme = [scheme copy];
		copy->host = [host copy];
		copy->port = port;
		copy->user = [user copy];
		copy->password = [password copy];
		copy->path = [path copy];
		copy->parameters = [parameters copy];
		copy->query = [query copy];
		copy->fragment = [fragment copy];
		copy->_scheme = [_scheme copy];
		copy->_host = [_host copy];
		copy->_port = _port;
		copy->_user = [_user copy];
		copy->_password = [_password copy];
		copy->_path = [_path copy];
		copy->_parameters = [_parameters copy];
		copy->_query = [_query copy];
		copy->_fragment = [_fragment copy];
	} @catch (id e) {
		[copy release];
		@throw e;
	}

	return copy;
}

- (OFString*)scheme
{
	OF_GETTER(scheme, YES)
	OF_GETTER(_scheme, YES)
}

- (void)setScheme: (OFString*)scheme_
- (void)setScheme: (OFString*)scheme
{
	if (![scheme_ isEqual: @"http"] && ![scheme_ isEqual: @"https"])
	if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	OF_SETTER(scheme, scheme_, YES, 1)
	OF_SETTER(_scheme, scheme, YES, 1)
}

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

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

- (uint16_t)port
{
	return port;
	return _port;
}

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

- (OFString*)user
{
	OF_GETTER(user, YES)
	OF_GETTER(_user, YES)
}

- (void)setUser: (OFString*)user_
- (void)setUser: (OFString*)user
{
	OF_SETTER(user, user_, YES, 1)
	OF_SETTER(_user, user, YES, 1)
}

- (OFString*)password
{
	OF_GETTER(password, YES)
	OF_GETTER(_password, YES)
}

- (void)setPassword: (OFString*)password_
- (void)setPassword: (OFString*)password
{
	OF_SETTER(password, password_, YES, 1)
	OF_SETTER(_password, password, YES, 1)
}

- (OFString*)path
{
	OF_GETTER(path, YES)
	OF_GETTER(_path, YES)
}

- (void)setPath: (OFString*)path_
- (void)setPath: (OFString*)path
{
	if (([scheme isEqual: @"http"] || [scheme isEqual: @"https"]) &&
	    ![path_ hasPrefix: @"/"])
	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, YES, 1)
}

- (OFString*)parameters
{
	OF_GETTER(parameters, YES)
	OF_GETTER(_parameters, YES)
}

- (void)setParameters: (OFString*)parameters_
- (void)setParameters: (OFString*)parameters
{
	OF_SETTER(parameters, parameters_, YES, 1)
	OF_SETTER(_parameters, parameters, YES, 1)
}

- (OFString*)query
{
	OF_GETTER(query, YES)
	OF_GETTER(_query, YES)
}

- (void)setQuery: (OFString*)query_
- (void)setQuery: (OFString*)query
{
	OF_SETTER(query, query_, YES, 1)
	OF_SETTER(_query, query, YES, 1)
}

- (OFString*)fragment
{
	OF_GETTER(fragment, YES)
	OF_GETTER(_fragment, YES)
}

- (void)setFragment: (OFString*)fragment_
- (void)setFragment: (OFString*)fragment
{
	OF_SETTER(fragment, fragment_, YES, 1)
	OF_SETTER(_fragment, fragment, YES, 1)
}

- (OFString*)string
{
	OFMutableString *ret = [OFMutableString stringWithFormat: @"%@://",
								  scheme];
								  _scheme];
	BOOL needPort = YES;

	if ([scheme isEqual: @"file"]) {
		if (path != nil)
			[ret appendString: path];
	if ([_scheme isEqual: @"file"]) {
		if (_path != nil)
			[ret appendString: _path];

		return ret;
	}

	if (user != nil && password != nil)
		[ret appendFormat: @"%@:%@@", user, password];
	else if (user != nil)
		[ret appendFormat: @"%@@", user];
	if (_user != nil && _password != nil)
		[ret appendFormat: @"%@:%@@", _user, _password];
	else if (_user != nil)
		[ret appendFormat: @"%@@", _user];

	if (host != nil)
		[ret appendString: host];
	if (_host != nil)
		[ret appendString: _host];

	if (([scheme isEqual: @"http"] && port == 80) ||
	    ([scheme isEqual: @"https"] && port == 443))
	if (([_scheme isEqual: @"http"] && _port != 80) ||
	    ([_scheme isEqual: @"https"] && _port != 443))
		needPort = NO;

	if (needPort)
		[ret appendFormat: @":%d", port];
		[ret appendFormat: @":%u", _port];

	if (path != nil)
		[ret appendString: path];
	if (_path != nil)
		[ret appendString: _path];

	if (parameters != nil)
		[ret appendFormat: @";%@", parameters];
	if (_parameters != nil)
		[ret appendFormat: @";%@", _parameters];

	if (query != nil)
		[ret appendFormat: @"?%@", query];
	if (_query != nil)
		[ret appendFormat: @"?%@", _query];

	if (fragment != nil)
		[ret appendFormat: @"#%@", fragment];
	if (_fragment != nil)
		[ret appendFormat: @"#%@", _fragment];

	[ret makeImmutable];

	return ret;
}

- (OFString*)description

Modified src/OFXMLAttribute.h from [86af9b92f4] to [45b1e6b315].

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







-
-
+
-



-
+
-
-
















-
+




-
+
















-
+




-
+








/*!
 * @brief A representation of an attribute of an XML element as an object.
 */
@interface OFXMLAttribute: OFXMLNode
{
@public
	OFString *name;
	OFString *ns;
	OFString *_name, *_namespace, *_stringValue;
	OFString *stringValue;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy) OFString *name;
@property (readonly, copy) OFString *name, *namespace, *stringValue;
@property (readonly, copy, getter=namespace) OFString *ns;
@property (readonly, copy) OFString *stringValue;
#endif

/*!
 * @brief Creates a new XML attribute.
 *
 * @param name The name of the attribute
 * @param stringValue The string value of the attribute
 * @return A new autoreleased OFXMLAttribute with the specified parameters
 */
+ (instancetype)attributeWithName: (OFString*)name
		      stringValue: (OFString*)stringValue;

/*!
 * @brief Creates a new XML attribute.
 *
 * @param name The name of the attribute
 * @param ns The namespace of the attribute
 * @param namespace_ The namespace of the attribute
 * @param stringValue The string value of the attribute
 * @return A new autoreleased OFXMLAttribute with the specified parameters
 */
+ (instancetype)attributeWithName: (OFString*)name
			namespace: (OFString*)ns
			namespace: (OFString*)namespace_
		      stringValue: (OFString*)stringValue;

/*!
 * @brief Initializes an already allocated OFXMLAttribute.
 *
 * @param name The name of the attribute
 * @param stringValue The string value of the attribute
 * @return An initialized OFXMLAttribute with the specified parameters
 */
- initWithName: (OFString*)name
   stringValue: (OFString*)stringValue;

/*!
 * @brief Initializes an already allocated OFXMLAttribute.
 *
 * @param name The name of the attribute
 * @param ns The namespace of the attribute
 * @param namespace_ The namespace of the attribute
 * @param stringValue The string value of the attribute
 * @return An initialized OFXMLAttribute with the specified parameters
 */
- initWithName: (OFString*)name
     namespace: (OFString*)ns
     namespace: (OFString*)namespace_
   stringValue: (OFString*)stringValue;

/*!
 * @brief Returns the name of the attribute as an autoreleased OFString.
 *
 * @return The name of the attribute as an autoreleased OFString
 */

Modified src/OFXMLAttribute.m from [39e877686b] to [a242f67939].

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







-
+



-
+










-
-
+
+

-
+

-
+


-
-
-
+
+
+




-
-
-
+
+
+







#import "OFInvalidArgumentException.h"

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

@implementation OFXMLAttribute
+ (instancetype)attributeWithName: (OFString*)name
			namespace: (OFString*)ns
			namespace: (OFString*)namespace
		      stringValue: (OFString*)stringValue
{
	return [[[self alloc] initWithName: name
				 namespace: ns
				 namespace: namespace
			       stringValue: stringValue] autorelease];
}

+ (instancetype)attributeWithName: (OFString*)name
		      stringValue: (OFString*)stringValue
{
	return [[[self alloc] initWithName: name
			       stringValue: stringValue] autorelease];
}

- initWithName: (OFString*)name_
   stringValue: (OFString*)stringValue_
- initWithName: (OFString*)name
   stringValue: (OFString*)stringValue
{
	return [self initWithName: name_
	return [self initWithName: name
			namespace: nil
		      stringValue: stringValue_];
		      stringValue: stringValue];
}

- initWithName: (OFString*)name_
     namespace: (OFString*)ns_
   stringValue: (OFString*)stringValue_
- initWithName: (OFString*)name
     namespace: (OFString*)namespace
   stringValue: (OFString*)stringValue
{
	self = [super init];

	@try {
		name = [name_ copy];
		ns = [ns_ copy];
		stringValue = [stringValue_ copy];
		_name = [name copy];
		_namespace = [namespace copy];
		_stringValue = [stringValue copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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







-
-
-
-
-
+
+
+
+
+













-
-
-
+
+
+






-
+




-
+




-
+




-
+




-
+

-
+

-
+
+

-
+











-
-
-
+
+
+















-
+

-
+

-
+


-
+












-
+



		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

		name = [[[element attributeForName: @"name"] stringValue]
		    copy];
		ns = [[[element attributeForName: @"namespace"] stringValue]
		    copy];
		stringValue = [[[element attributeForName: @"stringValue"]
		_name = [[[element attributeForName: @"name"]
		    stringValue] copy];
		_namespace = [[[element attributeForName: @"namespace"]
		    stringValue] copy];
		_stringValue = [[[element attributeForName: @"stringValue"]
		    stringValue] copy];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[name release];
	[ns release];
	[stringValue release];
	[_name release];
	[_namespace release];
	[_stringValue release];

	[super dealloc];
}

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

- (OFString*)namespace
{
	OF_GETTER(ns, YES)
	OF_GETTER(_namespace, YES)
}

- (OFString*)stringValue
{
	OF_GETTER(stringValue, YES)
	OF_GETTER(_stringValue, YES)
}

- (BOOL)isEqual: (id)object
{
	OFXMLAttribute *otherAttribute;
	OFXMLAttribute *attribute;

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

	otherAttribute = object;
	attribute = object;

	if (![otherAttribute->name isEqual: name])
	if (![attribute->_name isEqual: _name])
		return NO;
	if (otherAttribute->ns != ns && ![otherAttribute->ns isEqual: ns])
	if (attribute->_namespace != _namespace &&
	    ![attribute->_namespace isEqual: _namespace])
		return NO;
	if (![otherAttribute->stringValue isEqual: stringValue])
	if (![attribute->_stringValue isEqual: _stringValue])
		return NO;

	return YES;
}

- (uint32_t)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, [name hash]);
	OF_HASH_ADD_HASH(hash, [ns hash]);
	OF_HASH_ADD_HASH(hash, [stringValue hash]);
	OF_HASH_ADD_HASH(hash, [_name hash]);
	OF_HASH_ADD_HASH(hash, [_namespace hash]);
	OF_HASH_ADD_HASH(hash, [_stringValue hash]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

- (OFXMLElement*)XMLElementBySerializing
{
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;

	element = [OFXMLElement elementWithName: [self className]
				      namespace: OF_SERIALIZATION_NS];

	[element addAttributeWithName: @"name"
			  stringValue: name];
			  stringValue: _name];

	if (ns != nil)
	if (_namespace != nil)
		[element addAttributeWithName: @"namespace"
				  stringValue: ns];
				  stringValue: _namespace];

	[element addAttributeWithName: @"stringValue"
			  stringValue: stringValue];
			  stringValue: _stringValue];

	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (OFString*)description
{
	return [OFString stringWithFormat: @"<OFXMLAttribute, name=%@, "
					   @"namespace=%@, stringValue=%@>",
					   name, ns, stringValue];
					   _name, _namespace, _stringValue];
}
@end

Modified src/OFXMLCDATA.h from [9531b00aa3] to [948e1d4299].

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 "OFXMLNode.h"

/*!
 * @brief A class representing XML CDATA.
 */
@interface OFXMLCDATA: OFXMLNode
{
	OFString *CDATA;
	OFString *_CDATA;
}

/*!
 * @brief Creates a new OFXMLCDATA with the specified string.
 *
 * @param string The string value for the CDATA
 * @return A new OFXMLCDATA

Modified src/OFXMLCDATA.m from [80501e221c] to [3a90c3abbf].

31
32
33
34
35
36
37
38

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

38
39
40
41
42
43
44
45







-
+







}

- initWithString: (OFString*)string
{
	self = [super init];

	@try {
		CDATA = [string copy];
		_CDATA = [string copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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

101
102
103
104
105
106

107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
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

101
102
103
104
105
106

107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124







-
+












-
+




-
+

-
+




-
+




-
+




+
-
+




-
+





-
+




-
+













		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

		CDATA = [[element stringValue] copy];
		_CDATA = [[element stringValue] copy];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (BOOL)isEqual: (id)object
{
	OFXMLCDATA *otherCDATA;
	OFXMLCDATA *CDATA;

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

	otherCDATA = object;
	CDATA = object;

	return ([otherCDATA->CDATA isEqual: CDATA]);
	return ([CDATA->_CDATA isEqual: _CDATA]);
}

- (uint32_t)hash
{
	return [CDATA hash];
	return [_CDATA hash];
}

- (OFString*)stringValue
{
	return [[CDATA copy] autorelease];
	return [[_CDATA copy] autorelease];
}

- (OFString*)XMLString
{
	/* FIXME: What to do about ]]>? */
	return [OFString stringWithFormat: @"<![CDATA[%@]]>", CDATA];
	return [OFString stringWithFormat: @"<![CDATA[%@]]>", _CDATA];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
	return [OFString stringWithFormat: @"<![CDATA[%@]]>", CDATA];
	return [self XMLString];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
				level: (unsigned int)level
{
	return [OFString stringWithFormat: @"<![CDATA[%@]]>", CDATA];
	return [self XMLString];
}

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

- (OFXMLElement*)XMLElementBySerializing
{
	OFXMLElement *element =
	    [OFXMLElement elementWithName: [self className]
				namespace: OF_SERIALIZATION_NS];
	[element addChild: self];

	return element;
}
@end

Modified src/OFXMLCharacters.h from [bad21294e1] to [5d04d761e9].

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 "OFXMLNode.h"

/*!
 * @brief A class representing XML characters.
 */
@interface OFXMLCharacters: OFXMLNode
{
	OFString *characters;
	OFString *_characters;
}

/*!
 * @brief Creates a new OFXMLCharacters with the specified string.
 *
 * @param string The string value for the characters
 * @return A new OFXMLCharacters

Modified src/OFXMLCharacters.m from [d1e25b4850] to [872a1be8d0].

31
32
33
34
35
36
37
38

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

38
39
40
41
42
43
44
45







-
+







}

- initWithString: (OFString*)string
{
	self = [super init];

	@try {
		characters = [string copy];
		_characters = [string copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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

101
102
103
104
105
106

107
108
109
110
111

112
113
114
115
116
117
118

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

106
107
108
109
110

111
112
113
114
115
116
117

118
119
120







-
+












-
+




-
+

-
+




-
+




-
+




-
+




-
+





-
+




-
+






-
+



		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

		characters = [[element stringValue] copy];
		_characters = [[element stringValue] copy];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (BOOL)isEqual: (id)object
{
	OFXMLCharacters *otherCharacters;
	OFXMLCharacters *characters;

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

	otherCharacters = object;
	characters = object;

	return ([otherCharacters->characters isEqual: characters]);
	return ([characters->_characters isEqual: _characters]);
}

- (uint32_t)hash
{
	return [characters hash];
	return [_characters hash];
}

- (OFString*)stringValue
{
	return [[characters copy] autorelease];
	return [[_characters copy] autorelease];
}

- (OFString*)XMLString
{
	return [characters stringByXMLEscaping];
	return [_characters stringByXMLEscaping];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
	return [characters stringByXMLEscaping];
	return [_characters stringByXMLEscaping];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
				level: (unsigned int)level
{
	return [characters stringByXMLEscaping];
	return [_characters stringByXMLEscaping];
}

- (OFString*)description
{
	return [characters stringByXMLEscaping];
	return [_characters stringByXMLEscaping];
}

- (OFXMLElement*)XMLElementBySerializing
{
	return [OFXMLElement elementWithName: [self className]
				   namespace: OF_SERIALIZATION_NS
				 stringValue: characters];
				 stringValue: _characters];
}
@end

Modified src/OFXMLComment.h from [8e29ccb3e9] to [11e800d409].

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 "OFXMLNode.h"

/*!
 * @brief A class for representing XML comments.
 */
@interface OFXMLComment: OFXMLNode
{
	OFString *comment;
	OFString *_comment;
}

/*!
 * @brief Creates a new OFXMLComment with the specified string.
 *
 * @param string The string for the comment
 * @return A new OFXMLComment

Modified src/OFXMLComment.m from [4a37d9f4a6] to [4d978dda45].

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







-
+







}

- initWithString: (OFString*)string
{
	self = [super init];

	@try {
		comment = [string copy];
		_comment = [string copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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
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
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







-
+












-
+




-
+

-
+




-
+









-
+




-
+
















-
+




-
+






-
+






-
+



		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

		comment = [[element stringValue] copy];
		_comment = [[element stringValue] copy];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (BOOL)isEqual: (id)object
{
	OFXMLComment *otherComment;
	OFXMLComment *comment;

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

	otherComment = object;
	comment = object;

	return ([otherComment->comment isEqual: comment]);
	return ([comment->_comment isEqual: _comment]);
}

- (uint32_t)hash
{
	return [comment hash];
	return [_comment hash];
}

- (OFString*)stringValue
{
	return @"";
}

- (OFString*)XMLString
{
	return [OFString stringWithFormat: @"<!--%@-->", comment];
	return [OFString stringWithFormat: @"<!--%@-->", _comment];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
	return [OFString stringWithFormat: @"<!--%@-->", comment];
	return [OFString stringWithFormat: @"<!--%@-->", _comment];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
				level: (unsigned int)level
{
	OFString *ret;

	if (indentation > 0 && level > 0) {
		char *whitespaces = [self allocMemoryWithSize:
		    (level * indentation) + 1];
		memset(whitespaces, ' ', level * indentation);
		whitespaces[level * indentation] = 0;

		@try {
			ret = [OFString stringWithFormat: @"%s<!--%@-->",
							  whitespaces,
							  comment];
							  _comment];
		} @finally {
			[self freeMemory: whitespaces];
		}
	} else
		ret = [OFString stringWithFormat: @"<!--%@-->", comment];
		ret = [OFString stringWithFormat: @"<!--%@-->", _comment];

	return ret;
}

- (OFString*)description
{
	return [OFString stringWithFormat: @"<!--%@-->", comment];
	return [OFString stringWithFormat: @"<!--%@-->", _comment];
}

- (OFXMLElement*)XMLElementBySerializing
{
	return [OFXMLElement elementWithName: [self className]
				   namespace: OF_SERIALIZATION_NS
				 stringValue: comment];
				 stringValue: _comment];
}
@end

Modified src/OFXMLElement+Serialization.m from [ccf852396a] to [4b7b970c65].

31
32
33
34
35
36
37
38

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

38
39
40
41
42
43
44
45







-
+







@implementation OFXMLElement (Serialization)
- (id)objectByDeserializing
{
	void *pool = objc_autoreleasePoolPush();
	Class class;
	id object;

	if ((class = objc_getClass([name cStringWithEncoding:
	if ((class = objc_getClass([_name cStringWithEncoding:
	    OF_STRING_ENCODING_ASCII])) == Nil)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]];

	if (![class conformsToProtocol: @protocol(OFSerialization)])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]];

Modified src/OFXMLElement.h from [d1aca2d059] to [ea560ddced].

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
24
25
26
27
28
29
30


31




32
33
34
35
36
37

38


39

40
41
42
43
44
45
46
47







-
-
+
-
-
-
-
+
+
+



-
+
-
-

-
+







@class OFXMLAttribute;

/*!
 * @brief A class which stores an XML element.
 */
@interface OFXMLElement: OFXMLNode
{
	OFString *name;
	OFString *ns;
	OFString *_name, *_namespace, *_defaultNamespace;
	OFString *defaultNamespace;
	OFMutableArray *attributes;
	OFMutableDictionary *namespaces;
	OFMutableArray *children;
	OFMutableArray *_attributes;
	OFMutableDictionary *_namespaces;
	OFMutableArray *_children;
}

#ifdef OF_HAVE_PROPERTIES
@property (copy) OFString *name;
@property (copy) OFString *name, *namespace, *defaultNamespace;
@property (copy, getter=namespace, setter=setNamespace:) OFString *ns;
@property (copy) OFString *defaultNamespace;
@property (readonly, copy) OFArray *attributes;
@property (readonly, copy) OFArray *children;
@property (copy) OFArray *children;
#endif

/*!
 * @brief Creates a new XML element with the specified name.
 *
 * @param name The name for the element
 * @return A new autoreleased OFXMLElement with the specified element name
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
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







-
+




-
+






-
+





-
+







+ (instancetype)elementWithName: (OFString*)name
		    stringValue: (OFString*)stringValue;

/*!
 * @brief Creates a new XML element with the specified name and namespace.
 *
 * @param name The name for the element
 * @param ns The namespace for the element
 * @param namespace The namespace for the element
 * @return A new autoreleased OFXMLElement with the specified element name and
 *	   namespace
 */
+ (instancetype)elementWithName: (OFString*)name
		      namespace: (OFString*)ns;
		      namespace: (OFString*)namespace;

/*!
 * @brief Creates a new XML element with the specified name, namespace and
 * 	  string value.
 *
 * @param name The name for the element
 * @param ns The namespace for the element
 * @param namespace The namespace for the element
 * @param stringValue The value for the element
 * @return A new autoreleased OFXMLElement with the specified element name,
 *	   namespace and value
 */
+ (instancetype)elementWithName: (OFString*)name
		      namespace: (OFString*)ns
		      namespace: (OFString*)namespace
		    stringValue: (OFString*)stringValue;

/*!
 * @brief Creates a new element with the specified element.
 *
 * @param element An OFXMLElement to initialize the OFXMLElement with
 * @return A new autoreleased OFXMLElement with the contents of the specified
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
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







-
+




-
+






-
+





-
+







   stringValue: (OFString*)stringValue;

/*!
 * @brief Initializes an already allocated OFXMLElement with the specified name
 *	  and namespace.
 *
 * @param name The name for the element
 * @param ns The namespace for the element
 * @param namespace The namespace for the element
 * @return An initialized OFXMLElement with the specified element name and
 *	   namespace
 */
- initWithName: (OFString*)name
     namespace: (OFString*)ns;
     namespace: (OFString*)namespace;

/*!
 * @brief Initializes an already allocated OFXMLElement with the specified name,
 *	  namespace and value.
 *
 * @param name The name for the element
 * @param ns The namespace for the element
 * @param namespace The namespace for the element
 * @param stringValue The value for the element
 * @return An initialized OFXMLElement with the specified element name,
 *	   namespace and value
 */
- initWithName: (OFString*)name
     namespace: (OFString*)ns
     namespace: (OFString*)namespace
   stringValue: (OFString*)stringValue;

/*!
 * @brief Initializes an already allocated OFXMLElement with the specified
 *	  element.
 *
 * @param element An OFXMLElement to initialize the OFXMLElement with
201
202
203
204
205
206
207
208

209
210

211
212
213
214
215
216
217
197
198
199
200
201
202
203

204
205

206
207
208
209
210
211
212
213







-
+

-
+







 * @return The name of the element
 */
- (OFString*)name;

/*!
 * @brief Sets the namespace of the element.
 *
 * @param ns The new namespace
 * @param namespace The new namespace
 */
- (void)setNamespace: (OFString*)ns;
- (void)setNamespace: (OFString*)namespace;

/*!
 * @brief Returns the namespace of the element.
 *
 * @return The namespace of the element
 */
- (OFString*)namespace;
271
272
273
274
275
276
277
278

279
280
281
282

283
284
285
286
287
288
289
267
268
269
270
271
272
273

274
275
276
277

278
279
280
281
282
283
284
285







-
+



-
+







 * @brief Adds the specified attribute with the specified namespace and string
 *	  value.
 *
 * If an attribute with the same name and namespace already exists, it is not
 * added.
 *
 * @param name The name of the attribute
 * @param ns The namespace of the attribute
 * @param namespace The namespace of the attribute
 * @param stringValue The value of the attribute
 */
- (void)addAttributeWithName: (OFString*)name
		   namespace: (OFString*)ns
		   namespace: (OFString*)namespace
		 stringValue: (OFString*)stringValue;

/*!
 * @brief Returns the attribute with the specified name.
 *
 * @param attributeName The name of the attribute
 * @return The attribute with the specified name
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
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







-
+


-
+





-
+


-
+





-
+

-
+







- (void)removeAttributeForName: (OFString*)attributeName
		     namespace: (OFString*)attributeNS;

/*!
 * @brief Sets a prefix for a namespace.
 *
 * @param prefix The prefix for the namespace
 * @param ns The namespace for which the prefix is set
 * @param namespace The namespace for which the prefix is set
 */
- (void)setPrefix: (OFString*)prefix
     forNamespace: (OFString*)ns;
     forNamespace: (OFString*)namespace;

/*!
 * @brief Binds a prefix for a namespace.
 *
 * @param prefix The prefix for the namespace
 * @param ns The namespace for which the prefix is bound
 * @param namespace The namespace for which the prefix is bound
 */
- (void)bindPrefix: (OFString*)prefix
      forNamespace: (OFString*)ns;
      forNamespace: (OFString*)namespace;

/*!
 * @brief Sets the default namespace for the element to be used if there is no
 *	  parent.
 *
 * @param ns The default namespace for the element
 * @param defaultNamespace The default namespace for the element
 */
- (void)setDefaultNamespace: (OFString*)ns;
- (void)setDefaultNamespace: (OFString*)defaultNamespace;

/*!
 * @brief Adds a child to the OFXMLElement.
 *
 * @param child An OFXMLNode which is added as a child
 */
- (void)addChild: (OFXMLNode*)child;

Modified src/OFXMLElement.m from [5e664c8a15] to [177671f0ee].

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







-
+





-
+

-
-
+
+




-
+








static Class charactersClass = Nil;
static Class CDATAClass = Nil;

@interface OFXMLElement_OFXMLElementBuilderDelegate: OFObject
{
@public
	OFXMLElement *element;
	OFXMLElement *_element;
}
@end

@implementation OFXMLElement_OFXMLElementBuilderDelegate
- (void)elementBuilder: (OFXMLElementBuilder*)builder
       didBuildElement: (OFXMLElement*)element_
       didBuildElement: (OFXMLElement*)element
{
	if (element == nil)
		element = [element_ retain];
	if (_element == nil)
		_element = [element retain];
}

- (void)dealloc
{
	[element release];
	[_element release];

	[super dealloc];
}
@end

@implementation OFXMLElement
+ (void)initialize
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
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







-
+

-
+




-
+


-
+




-
-
+
+

-
-
+
+



-
-
+
+





-
+




-
-
+
+

-
+







		[self release];
		@throw e;
	}

	abort();
}

- initWithName: (OFString*)name_
- initWithName: (OFString*)name
{
	return [self initWithName: name_
	return [self initWithName: name
			namespace: nil
		      stringValue: nil];
}

- initWithName: (OFString*)name_
- initWithName: (OFString*)name
   stringValue: (OFString*)stringValue
{
	return [self initWithName: name_
	return [self initWithName: name
			namespace: nil
		      stringValue: stringValue];
}

- initWithName: (OFString*)name_
     namespace: (OFString*)ns_
- initWithName: (OFString*)name
     namespace: (OFString*)namespace
{
	return [self initWithName: name_
			namespace: ns_
	return [self initWithName: name
			namespace: namespace
		      stringValue: nil];
}

- initWithName: (OFString*)name_
     namespace: (OFString*)ns_
- initWithName: (OFString*)name
     namespace: (OFString*)namespace
   stringValue: (OFString*)stringValue
{
	self = [super init];

	@try {
		if (name_ == nil)
		if (name == nil)
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

		name = [name_ copy];
		ns = [ns_ copy];
		_name = [name copy];
		_namespace = [namespace copy];

		namespaces = [[OFMutableDictionary alloc]
		_namespaces = [[OFMutableDictionary alloc]
		    initWithKeysAndObjects:
		    @"http://www.w3.org/XML/1998/namespace", @"xml",
		    @"http://www.w3.org/2000/xmlns/", @"xmlns", nil];

		if (stringValue != nil)
			[self setStringValue: stringValue];
	} @catch (id e) {
195
196
197
198
199
200
201
202
203
204
205
206
207






208
209
210
211
212
213
214
195
196
197
198
199
200
201






202
203
204
205
206
207
208
209
210
211
212
213
214







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








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

		name = [element->name copy];
		ns = [element->ns copy];
		defaultNamespace = [element->defaultNamespace copy];
		attributes = [element->attributes mutableCopy];
		namespaces = [element->namespaces mutableCopy];
		children = [element->children mutableCopy];
		_name = [element->_name copy];
		_namespace = [element->_namespace copy];
		_defaultNamespace = [element->_defaultNamespace copy];
		_attributes = [element->_attributes mutableCopy];
		_namespaces = [element->_namespaces mutableCopy];
		_children = [element->_children mutableCopy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254







-
+








	[parser parseString: string];

	if (![parser finishedParsing])
		@throw [OFMalformedXMLException exceptionWithClass: c
							    parser: parser];

	self = [delegate->element retain];
	self = [delegate->_element retain];

	objc_autoreleasePoolPop(pool);

	return self;
}

- initWithFile: (OFString*)path
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288







-
+








	[parser parseFile: path];

	if (![parser finishedParsing])
		@throw [OFMalformedXMLException exceptionWithClass: c
							    parser: parser];

	self = [delegate->element retain];
	self = [delegate->_element retain];

	objc_autoreleasePoolPop(pool);

	return self;
}

- initWithSerialization: (OFXMLElement*)element
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
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







-
-
-
-
+
+
+
+
+















-
+

-
+

-
+



-
+
-
-
-
-
-
+
+
+
+




-
+






-
-
+
+








-
+






-
-
+
+

+
-
-
-
-
+
+
+
+

-
+













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

-
+




-
+




-
+


-
+

-
+




-
+




-
+


-
+

-
+




-
+
















-
+





-
+








		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

		name = [[[element attributeForName: @"name"] stringValue] copy];
		ns = [[[element attributeForName: @"namespace"] stringValue]
		    copy];
		defaultNamespace = [[[element attributeForName:
		_name = [[[element attributeForName: @"name"]
		    stringValue] copy];
		_namespace = [[[element attributeForName: @"namespace"]
		    stringValue] copy];
		_defaultNamespace = [[[element attributeForName:
		    @"defaultNamespace"] stringValue] copy];

		attributesElement = [[[element
		    elementForName: @"attributes"
			 namespace: OF_SERIALIZATION_NS] elementsForNamespace:
		    OF_SERIALIZATION_NS] firstObject];
		namespacesElement = [[[element
		    elementForName: @"namespaces"
			 namespace: OF_SERIALIZATION_NS] elementsForNamespace:
		    OF_SERIALIZATION_NS] firstObject];
		childrenElement = [[[element
		    elementForName: @"children"
			 namespace: OF_SERIALIZATION_NS] elementsForNamespace:
		    OF_SERIALIZATION_NS] firstObject];

		attributes = [[attributesElement objectByDeserializing]
		_attributes = [[attributesElement objectByDeserializing]
		    mutableCopy];
		namespaces = [[namespacesElement objectByDeserializing]
		_namespaces = [[namespacesElement objectByDeserializing]
		    mutableCopy];
		children = [[childrenElement objectByDeserializing]
		_children = [[childrenElement objectByDeserializing]
		    mutableCopy];

		/* Sanity checks */
		if ((attributes != nil &&
		if ((_attributes != nil && ![_attributes isKindOfClass:
		    ![attributes isKindOfClass: [OFMutableArray class]]) ||
		    (namespaces != nil &&
		    ![namespaces isKindOfClass: [OFMutableDictionary class]]) ||
		    (children != nil &&
		    ![children isKindOfClass: [OFMutableArray class]]))
		    [OFMutableArray class]]) || (_namespaces != nil &&
		    ![_namespaces isKindOfClass:
		    [OFMutableDictionary class]]) || (_children != nil &&
		    ![_children isKindOfClass: [OFMutableArray class]]))
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

		objectEnumerator = [attributes objectEnumerator];
		objectEnumerator = [_attributes objectEnumerator];
		while ((object = [objectEnumerator nextObject]) != nil)
			if (![object isKindOfClass: [OFXMLAttribute class]])
				@throw [OFInvalidArgumentException
				    exceptionWithClass: [self class]
					      selector: _cmd];

		keyEnumerator = [namespaces keyEnumerator];
		objectEnumerator = [namespaces objectEnumerator];
		keyEnumerator = [_namespaces keyEnumerator];
		objectEnumerator = [_namespaces objectEnumerator];
		while ((key = [keyEnumerator nextObject]) != nil &&
		    (object = [objectEnumerator nextObject]) != nil)
			if (![key isKindOfClass: [OFString class]] ||
			    ![object isKindOfClass: [OFString class]])
				@throw [OFInvalidArgumentException
				    exceptionWithClass: [self class]
					      selector: _cmd];

		objectEnumerator = [children objectEnumerator];
		objectEnumerator = [_children objectEnumerator];
		while ((object = [objectEnumerator nextObject]) != nil)
			if (![object isKindOfClass: [OFXMLNode class]])
				@throw [OFInvalidArgumentException
				    exceptionWithClass: [self class]
					      selector: _cmd];

		if (namespaces == nil)
			namespaces = [[OFMutableDictionary alloc] init];
		if (_namespaces == nil)
			_namespaces = [[OFMutableDictionary alloc] init];

		[_namespaces
		[namespaces setObject: @"xml"
			       forKey: @"http://www.w3.org/XML/1998/namespace"];
		[namespaces setObject: @"xmlns"
			       forKey: @"http://www.w3.org/2000/xmlns/"];
		    setObject: @"xml"
		       forKey: @"http://www.w3.org/XML/1998/namespace"];
		[_namespaces setObject: @"xmlns"
				forKey: @"http://www.w3.org/2000/xmlns/"];

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

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_name release];
	[_namespace release];
	[_defaultNamespace release];
	[_attributes release];
	[_namespaces release];
	[_children release];

	[super dealloc];
}

- (void)setName: (OFString*)name_
- (void)setName: (OFString*)name
{
	if (name_ == nil)
	if (name == nil)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	OF_SETTER(name, name_, YES, 1)
	OF_SETTER(_name, name, YES, 1)
}

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

- (void)setNamespace: (OFString*)ns_
- (void)setNamespace: (OFString*)namespace
{
	OF_SETTER(ns, ns_, YES, 1)
	OF_SETTER(_namespace, namespace, YES, 1)
}

- (OFString*)namespace
{
	OF_GETTER(ns, YES)
	OF_GETTER(_namespace, YES)
}

- (OFArray*)attributes
{
	OF_GETTER(attributes, YES)
	OF_GETTER(_attributes, YES)
}

- (void)setChildren: (OFArray*)children_
- (void)setChildren: (OFArray*)children
{
	OF_SETTER(children, children_, YES, 2)
	OF_SETTER(_children, children, YES, 2)
}

- (OFArray*)children
{
	OF_GETTER(children, YES)
	OF_GETTER(_children, YES)
}

- (void)setStringValue: (OFString*)stringValue
{
	void *pool = objc_autoreleasePoolPush();

	[self setChildren: [OFArray arrayWithObject:
	    [OFXMLCharacters charactersWithString: stringValue]]];

	objc_autoreleasePoolPop(pool);
}

- (OFString*)stringValue
{
	OFMutableString *ret;
	OFXMLElement **objects;
	size_t i, count = [children count];
	size_t i, count = [_children count];

	if (count == 0)
		return @"";

	ret = [OFMutableString string];
	objects = [children objects];
	objects = [_children objects];

	for (i = 0; i < count; i++) {
		void *pool = objc_autoreleasePoolPush();

		[ret appendString: [objects[i] stringValue]];

		objc_autoreleasePoolPop(pool);
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




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

552
553


554
555
556
557
558
559


560
561
562
563
564
565
566
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

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
573


574
575
576
577
578
579
580
581
582







-
+
+



-
-
+
+












-
+


-
+

-
-
-
-
+
+
+
+

-
+


-
+








-
+















-
-
+
+


-
-
-
+
+
+
+










+
-
-
+
+




-
-
+
+







	OFXMLAttribute **attributesObjects;
	OFString *ret;
	OFString *defaultNS;

	pool = objc_autoreleasePoolPush();

	parentPrefix = [allNamespaces objectForKey:
	    (parent != nil && parent->ns != nil ? parent->ns : (OFString*)@"")];
	    (parent != nil && parent->_namespace != nil
	    ? parent->_namespace : (OFString*)@"")];

	/* Add the namespaces of the current element */
	if (allNamespaces != nil) {
		OFEnumerator *keyEnumerator = [namespaces keyEnumerator];
		OFEnumerator *objectEnumerator = [namespaces objectEnumerator];
		OFEnumerator *keyEnumerator = [_namespaces keyEnumerator];
		OFEnumerator *objectEnumerator = [_namespaces objectEnumerator];
		OFMutableDictionary *tmp;
		id key, object;

		tmp = [[allNamespaces mutableCopy] autorelease];

		while ((key = [keyEnumerator nextObject]) != nil &&
		    (object = [objectEnumerator nextObject]) != nil)
			[tmp setObject: object
				forKey: key];

		allNamespaces = tmp;
	} else
		allNamespaces = namespaces;
		allNamespaces = _namespaces;

	prefix = [allNamespaces objectForKey:
	    (ns != nil ? ns : (OFString*)@"")];
	    (_namespace != nil ? _namespace : (OFString*)@"")];

	if (parent != nil && parent->ns != nil && parentPrefix == nil)
		defaultNS = parent->ns;
	else if (parent != nil && parent->defaultNamespace != nil)
		defaultNS = parent->defaultNamespace;
	if (parent != nil && parent->_namespace != nil && parentPrefix == nil)
		defaultNS = parent->_namespace;
	else if (parent != nil && parent->_defaultNamespace != nil)
		defaultNS = parent->_defaultNamespace;
	else
		defaultNS = defaultNamespace;
		defaultNS = _defaultNamespace;

	i = 0;
	length = [name UTF8StringLength] + 3 + (level * indentation);
	length = [_name UTF8StringLength] + 3 + (level * indentation);
	cString = [self allocMemoryWithSize: length];

	memset(cString + i, ' ', level * indentation);
	i += level * indentation;

	/* Start of tag */
	cString[i++] = '<';

	if (prefix != nil && ![ns isEqual: defaultNS]) {
	if (prefix != nil && ![_namespace isEqual: defaultNS]) {
		length += [prefix UTF8StringLength] + 1;
		@try {
			cString = [self resizeMemory: cString
						size: length];
		} @catch (id e) {
			[self freeMemory: cString];
			@throw e;
		}

		memcpy(cString + i, [prefix UTF8String],
		    [prefix UTF8StringLength]);
		i += [prefix UTF8StringLength];
		cString[i++] = ':';
	}

	memcpy(cString + i, [name UTF8String], [name UTF8StringLength]);
	i += [name UTF8StringLength];
	memcpy(cString + i, [_name UTF8String], [_name UTF8StringLength]);
	i += [_name UTF8StringLength];

	/* xmlns if necessary */
	if (prefix == nil && ((ns != nil && ![ns isEqual: defaultNS]) ||
	    (ns == nil && defaultNS != nil))) {
		length += [ns UTF8StringLength] + 9;
	if (prefix == nil && ((_namespace != nil &&
	    ![_namespace isEqual: defaultNS]) ||
	    (_namespace == nil && defaultNS != nil))) {
		length += [_namespace UTF8StringLength] + 9;
		@try {
			cString = [self resizeMemory: cString
						size: length];
		} @catch (id e) {
			[self freeMemory: cString];
			@throw e;
		}

		memcpy(cString + i, " xmlns='", 8);
		i += 8;
		memcpy(cString + i, [_namespace UTF8String],
		memcpy(cString + i, [ns UTF8String], [ns UTF8StringLength]);
		i += [ns UTF8StringLength];
		    [_namespace UTF8StringLength]);
		i += [_namespace UTF8StringLength];
		cString[i++] = '\'';
	}

	/* Attributes */
	attributesObjects = [attributes objects];
	attributesCount = [attributes count];
	attributesObjects = [_attributes objects];
	attributesCount = [_attributes count];

	for (j = 0; j < attributesCount; j++) {
		void *pool2 = objc_autoreleasePoolPush();
		OFString *attributeName = [attributesObjects[j] name];
		OFString *attributePrefix = nil;
		OFString *tmp =
		    [[attributesObjects[j] stringValue] stringByXMLEscaping];
602
603
604
605
606
607
608
609
610
611



612
613
614
615
616
617
618
618
619
620
621
622
623
624



625
626
627
628
629
630
631
632
633
634







-
-
-
+
+
+







		i += [tmp UTF8StringLength];
		cString[i++] = '\'';

		objc_autoreleasePoolPop(pool2);
	}

	/* Childen */
	if (children != nil) {
		OFXMLElement **childrenObjects = [children objects];
		size_t childrenCount = [children count];
	if (_children != nil) {
		OFXMLElement **childrenObjects = [_children objects];
		size_t childrenCount = [_children count];
		OFDataArray *tmp = [OFDataArray dataArray];
		BOOL indent;

		if (indentation > 0) {
			indent = YES;

			for (j = 0; j < childrenCount; j++) {
648
649
650
651
652
653
654
655

656
657
658
659
660
661
662
664
665
666
667
668
669
670

671
672
673
674
675
676
677
678







-
+







			[tmp addItems: [child UTF8String]
				count: [child UTF8StringLength]];
		}

		if (indent)
			[tmp addItem: "\n"];

		length += [tmp count] + [name UTF8StringLength] + 2 +
		length += [tmp count] + [_name UTF8StringLength] + 2 +
		    (indent ? level * indentation : 0);
		@try {
			cString = [self resizeMemory: cString
						size: length];
		} @catch (id e) {
			[self freeMemory: cString];
			@throw e;
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







-
-
+
+
+







			}

			memcpy(cString + i, [prefix UTF8String],
			    [prefix UTF8StringLength]);
			i += [prefix UTF8StringLength];
			cString[i++] = ':';
		}
		memcpy(cString + i, [name UTF8String], [name UTF8StringLength]);
		i += [name UTF8StringLength];
		memcpy(cString + i, [_name UTF8String],
		    [_name UTF8StringLength]);
		i += [_name UTF8StringLength];
	} else
		cString[i++] = '/';

	cString[i++] = '>';
	assert(i == length);

	objc_autoreleasePoolPop(pool);
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
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
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
924
925

926
927
928
929
930

931
932
933

934
935

936
937
938
939
940
941
942
943
944
945
946


947
948

949
950
951
952
953
954
955
956
957
958
959
960


961
962
963


964
965
966

967
968
969
970

971
972
973
974
975
976
977
978
979
980


981
982
983
984
985
986
987
988
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
1014
1015
1016
1017
1018
1019
1020
1021
1022


1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041


1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056


1057
1058
1059
1060
1061


1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073


1074
1075
1076
1077
1078


1079
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
1110
1111
1112
1113

1114
1115
1116
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
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
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
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
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
924
925
926
927


928
929
930


931
932
933
934
935

936
937
938

939
940
941

942
943
944
945
946

947
948
949

950
951

952
953
954
955
956
957
958
959
960
961


962
963
964

965
966
967
968
969
970
971
972
973
974
975


976
977
978


979
980
981
982

983
984
985
986

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

1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025


1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037


1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056


1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071


1072
1073
1074
1075
1076


1077
1078
1079
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
1110
1111
1112
1113


1114
1115
1116
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
1160
1161
1162
1163






1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179












1180







-
+

-
+

-
+

-
+

-
+

-
+

-
+






-
+



-
+


-
+
















-
+





-
+












-
-
+
+

-
-
-
+
+
+


-
+


-
+




-
-
+
+




-
-
+
+







-
-
+
+


-
-
+
+














-
-
+
+


-
-
+
+







-
-
+
+


-
-
-
+
+
+















-
-
+
+


-
-
-
+
+
+






-
+





-
-
+
+

-
-
+
+



-
+


-
+


-
+




-
+


-
+

-
+









-
-
+
+

-
+










-
-
+
+

-
-
+
+


-
+



-
+








-
-
+
+











-
+




-
+











-
-
+
+










-
-
+
+

















-
-
+
+













-
-
+
+



-
-
+
+










-
-
+
+



-
-
+
+


















-
-
+
+



-
-
+
+









-
+




-
+

-
+

+
-
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+











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










-
-
-
-
-
-
-
-
-
-
-
-

{
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;

	element = [OFXMLElement elementWithName: [self className]
				      namespace: OF_SERIALIZATION_NS];

	if (name != nil)
	if (_name != nil)
		[element addAttributeWithName: @"name"
				  stringValue: name];
				  stringValue: _name];

	if (ns != nil)
	if (_namespace != nil)
		[element addAttributeWithName: @"namespace"
				  stringValue: ns];
				  stringValue: _namespace];

	if (defaultNamespace != nil)
	if (_defaultNamespace != nil)
		[element addAttributeWithName: @"defaultNamespace"
				  stringValue: defaultNamespace];
				  stringValue: _defaultNamespace];

	if (attributes != nil) {
	if (_attributes != nil) {
		OFXMLElement *attributesElement;

		attributesElement =
		    [OFXMLElement elementWithName: @"attributes"
					namespace: OF_SERIALIZATION_NS];
		[attributesElement addChild:
		    [attributes XMLElementBySerializing]];
		    [_attributes XMLElementBySerializing]];
		[element addChild: attributesElement];
	}

	if (namespaces != nil) {
	if (_namespaces != nil) {
		OFXMLElement *namespacesElement;
		OFMutableDictionary *namespacesCopy =
		    [[namespaces mutableCopy] autorelease];
		    [[_namespaces mutableCopy] autorelease];

		[namespacesCopy removeObjectForKey:
		    @"http://www.w3.org/XML/1998/namespace"];
		[namespacesCopy removeObjectForKey:
		    @"http://www.w3.org/2000/xmlns/"];

		if ([namespacesCopy count] > 0) {
			namespacesElement =
			    [OFXMLElement elementWithName: @"namespaces"
						namespace: OF_SERIALIZATION_NS];
			[namespacesElement addChild:
			    [namespacesCopy XMLElementBySerializing]];
			[element addChild: namespacesElement];
		}
	}

	if (children != nil) {
	if (_children != nil) {
		OFXMLElement *childrenElement;

		childrenElement =
		    [OFXMLElement elementWithName: @"children"
					namespace: OF_SERIALIZATION_NS];
		[childrenElement addChild: [children XMLElementBySerializing]];
		[childrenElement addChild: [_children XMLElementBySerializing]];
		[element addChild: childrenElement];
	}

	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (void)addAttribute: (OFXMLAttribute*)attribute
{
	if (attributes == nil)
		attributes = [[OFMutableArray alloc] init];
	if (_attributes == nil)
		_attributes = [[OFMutableArray alloc] init];

	if ([self attributeForName: attribute->name
			 namespace: attribute->ns] == nil)
		[attributes addObject: attribute];
	if ([self attributeForName: attribute->_name
			 namespace: attribute->_namespace] == nil)
		[_attributes addObject: attribute];
}

- (void)addAttributeWithName: (OFString*)name_
- (void)addAttributeWithName: (OFString*)name
		 stringValue: (OFString*)stringValue
{
	[self addAttributeWithName: name_
	[self addAttributeWithName: name
			 namespace: nil
		       stringValue: stringValue];
}

- (void)addAttributeWithName: (OFString*)name_
		   namespace: (OFString*)ns_
- (void)addAttributeWithName: (OFString*)name
		   namespace: (OFString*)namespace
		 stringValue: (OFString*)stringValue
{
	void *pool = objc_autoreleasePoolPush();

	[self addAttribute: [OFXMLAttribute attributeWithName: name_
						    namespace: ns_
	[self addAttribute: [OFXMLAttribute attributeWithName: name
						    namespace: namespace
						  stringValue: stringValue]];

	objc_autoreleasePoolPop(pool);
}

- (OFXMLAttribute*)attributeForName: (OFString*)attributeName
{
	OFXMLAttribute **objects = [attributes objects];
	size_t i, count = [attributes count];
	OFXMLAttribute **objects = [_attributes objects];
	size_t i, count = [_attributes count];

	for (i = 0; i < count; i++)
		if (objects[i]->ns == nil &&
		    [objects[i]->name isEqual: attributeName])
		if (objects[i]->_namespace == nil &&
		    [objects[i]->_name isEqual: attributeName])
			return [[objects[i] retain] autorelease];

	return nil;
}

- (OFXMLAttribute*)attributeForName: (OFString*)attributeName
			  namespace: (OFString*)attributeNS
{
	OFXMLAttribute **objects;
	size_t i, count;

	if (attributeNS == nil)
		return [self attributeForName: attributeName];

	objects = [attributes objects];
	count = [attributes count];
	objects = [_attributes objects];
	count = [_attributes count];

	for (i = 0; i < count; i++)
		if ([objects[i]->ns isEqual: attributeNS] &&
		    [objects[i]->name isEqual: attributeName])
		if ([objects[i]->_namespace isEqual: attributeNS] &&
		    [objects[i]->_name isEqual: attributeName])
			return [[objects[i] retain] autorelease];

	return nil;
}

- (void)removeAttributeForName: (OFString*)attributeName
{
	OFXMLAttribute **objects = [attributes objects];
	size_t i, count = [attributes count];
	OFXMLAttribute **objects = [_attributes objects];
	size_t i, count = [_attributes count];

	for (i = 0; i < count; i++) {
		if (objects[i]->ns == nil &&
		    [objects[i]->name isEqual: attributeName]) {
			[attributes removeObjectAtIndex: i];
		if (objects[i]->_namespace == nil &&
		    [objects[i]->_name isEqual: attributeName]) {
			[_attributes removeObjectAtIndex: i];

			return;
		}
	}
}

- (void)removeAttributeForName: (OFString*)attributeName
		     namespace: (OFString*)attributeNS
{
	OFXMLAttribute **objects;
	size_t i, count;

	if (attributeNS == nil)
		return [self removeAttributeForName: attributeName];

	objects = [attributes objects];
	count = [attributes count];
	objects = [_attributes objects];
	count = [_attributes count];

	for (i = 0; i < count; i++) {
		if ([objects[i]->ns isEqual: attributeNS] &&
		    [objects[i]->name isEqual: attributeName]) {
			[attributes removeObjectAtIndex: i];
		if ([objects[i]->_namespace isEqual: attributeNS] &&
		    [objects[i]->_name isEqual: attributeName]) {
			[_attributes removeObjectAtIndex: i];
				return;
		}
	}
}

- (void)setPrefix: (OFString*)prefix
     forNamespace: (OFString*)ns_
     forNamespace: (OFString*)namespace
{
	if ([prefix length] == 0)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];
	if (ns_ == nil)
		ns_ = @"";
	if (namespace == nil)
		namespace = @"";

	[namespaces setObject: prefix
		       forKey: ns_];
	[_namespaces setObject: prefix
			forKey: namespace];
}

- (void)bindPrefix: (OFString*)prefix
      forNamespace: (OFString*)ns_
      forNamespace: (OFString*)namespace
{
	[self setPrefix: prefix
	   forNamespace: ns_];
	   forNamespace: namespace];
	[self addAttributeWithName: prefix
			 namespace: @"http://www.w3.org/2000/xmlns/"
		       stringValue: ns_];
		       stringValue: namespace];
}

- (OFString*)defaultNamespace
{
	OF_GETTER(defaultNamespace, YES)
	OF_GETTER(_defaultNamespace, YES)
}

- (void)setDefaultNamespace: (OFString*)ns_
- (void)setDefaultNamespace: (OFString*)defaultNamespace
{
	OF_SETTER(defaultNamespace, ns_, YES, 1)
	OF_SETTER(_defaultNamespace, defaultNamespace, YES, 1)
}

- (void)addChild: (OFXMLNode*)child
{
	if ([child isKindOfClass: [OFXMLAttribute class]])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	if (children == nil)
		children = [[OFMutableArray alloc] init];
	if (_children == nil)
		_children = [[OFMutableArray alloc] init];

	[children addObject: child];
	[_children addObject: child];
}

- (void)insertChild: (OFXMLNode*)child
	    atIndex: (size_t)index
{
	if ([child isKindOfClass: [OFXMLAttribute class]])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	if (children == nil)
		children = [[OFMutableArray alloc] init];
	if (_children == nil)
		_children = [[OFMutableArray alloc] init];

	[children insertObject: child
		       atIndex: index];
	[_children insertObject: child
			atIndex: index];
}

- (void)insertChildren: (OFArray*)children_
- (void)insertChildren: (OFArray*)children
	       atIndex: (size_t)index
{
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator = [children_ objectEnumerator];
	OFEnumerator *enumerator = [children objectEnumerator];
	OFXMLNode *node;

	while ((node = [enumerator nextObject]) != nil)
		if ([node isKindOfClass: [OFXMLAttribute class]])
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

	[children insertObjectsFromArray: children_
				 atIndex: index];
	[_children insertObjectsFromArray: children
				  atIndex: index];

	objc_autoreleasePoolPop(pool);
}

- (void)removeChild: (OFXMLNode*)child
{
	if ([child isKindOfClass: [OFXMLAttribute class]])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	[children removeObject: child];
	[_children removeObject: child];
}

- (void)removeChildAtIndex: (size_t)index
{
	[children removeObjectAtIndex: index];
	[_children removeObjectAtIndex: index];
}

- (void)replaceChild: (OFXMLNode*)child
	    withNode: (OFXMLNode*)node
{
	if ([node isKindOfClass: [OFXMLAttribute class]] ||
	    [child isKindOfClass: [OFXMLAttribute class]])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	[children replaceObject: child
		     withObject: node];
	[_children replaceObject: child
		      withObject: node];
}

- (void)replaceChildAtIndex: (size_t)index
		   withNode: (OFXMLNode*)node
{
	if ([node isKindOfClass: [OFXMLAttribute class]])
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	[children replaceObjectAtIndex: index
			    withObject: node];
	[_children replaceObjectAtIndex: index
			     withObject: node];
}

- (OFXMLElement*)elementForName: (OFString*)elementName
{
	return [[self elementsForName: elementName] firstObject];
}

- (OFXMLElement*)elementForName: (OFString*)elementName
		      namespace: (OFString*)elementNS
{
	return [[self elementsForName: elementName
			    namespace: elementNS] firstObject];
}

- (OFArray*)elements
{
	OFMutableArray *ret = [OFMutableArray array];
	OFXMLElement **objects = [children objects];
	size_t i, count = [children count];
	OFXMLElement **objects = [_children objects];
	size_t i, count = [_children count];

	for (i = 0; i < count; i++)
		if ([objects[i] isKindOfClass: [OFXMLElement class]])
			[ret addObject: objects[i]];

	[ret makeImmutable];

	return ret;
}

- (OFArray*)elementsForName: (OFString*)elementName
{
	OFMutableArray *ret = [OFMutableArray array];
	OFXMLElement **objects = [children objects];
	size_t i, count = [children count];
	OFXMLElement **objects = [_children objects];
	size_t i, count = [_children count];

	for (i = 0; i < count; i++)
		if ([objects[i] isKindOfClass: [OFXMLElement class]] &&
		    objects[i]->ns == nil &&
		    [objects[i]->name isEqual: elementName])
		    objects[i]->_namespace == nil &&
		    [objects[i]->_name isEqual: elementName])
			[ret addObject: objects[i]];

	[ret makeImmutable];

	return ret;
}

- (OFArray*)elementsForNamespace: (OFString*)elementNS
{
	OFMutableArray *ret = [OFMutableArray array];
	OFXMLElement **objects = [children objects];
	size_t i, count = [children count];
	OFXMLElement **objects = [_children objects];
	size_t i, count = [_children count];

	for (i = 0; i < count; i++)
		if ([objects[i] isKindOfClass: [OFXMLElement class]] &&
		    objects[i]->name != nil &&
		    [objects[i]->ns isEqual: elementNS])
		    objects[i]->_name != nil &&
		    [objects[i]->_namespace isEqual: elementNS])
			[ret addObject: objects[i]];

	[ret makeImmutable];

	return ret;
}

- (OFArray*)elementsForName: (OFString*)elementName
		  namespace: (OFString*)elementNS
{
	OFMutableArray *ret;
	OFXMLElement **objects;
	size_t i, count;

	if (elementNS == nil)
		return [self elementsForName: elementName];

	ret = [OFMutableArray array];
	objects = [children objects];
	count = [children count];
	objects = [_children objects];
	count = [_children count];

	for (i = 0; i < count; i++)
		if ([objects[i] isKindOfClass: [OFXMLElement class]] &&
		    [objects[i]->ns isEqual: elementNS] &&
		    [objects[i]->name isEqual: elementName])
		    [objects[i]->_namespace isEqual: elementNS] &&
		    [objects[i]->_name isEqual: elementName])
			[ret addObject: objects[i]];

	[ret makeImmutable];

	return ret;
}

- (BOOL)isEqual: (id)object
{
	OFXMLElement *otherElement;
	OFXMLElement *element;

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

	otherElement = object;
	element = object;

	if (otherElement->name != name && ![otherElement->name isEqual: name])
	if (element->_name != _name && ![element->_name isEqual: _name])
		return NO;
	if (element->_namespace != _namespace &&
	if (otherElement->ns != ns && ![otherElement->ns isEqual: ns])
	    ![element->_namespace isEqual: _namespace])
		return NO;
	if (otherElement->defaultNamespace != defaultNamespace &&
	    ![otherElement->defaultNamespace isEqual: defaultNamespace])
	if (element->_defaultNamespace != _defaultNamespace &&
	    ![element->_defaultNamespace isEqual: _defaultNamespace])
		return NO;
	if (otherElement->attributes != attributes &&
	    ![otherElement->attributes isEqual: attributes])
	if (element->_attributes != _attributes &&
	    ![element->_attributes isEqual: _attributes])
		return NO;
	if (otherElement->namespaces != namespaces &&
	    ![otherElement->namespaces isEqual: namespaces])
	if (element->_namespaces != _namespaces &&
	    ![element->_namespaces isEqual: _namespaces])
		return NO;
	if (otherElement->children != children &&
	    ![otherElement->children isEqual: children])
	if (element->_children != _children &&
	    ![element->_children isEqual: _children])
		return NO;

	return YES;
}

- (uint32_t)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, [name hash]);
	OF_HASH_ADD_HASH(hash, [ns hash]);
	OF_HASH_ADD_HASH(hash, [defaultNamespace hash]);
	OF_HASH_ADD_HASH(hash, [attributes hash]);
	OF_HASH_ADD_HASH(hash, [namespaces hash]);
	OF_HASH_ADD_HASH(hash, [children hash]);
	OF_HASH_ADD_HASH(hash, [_name hash]);
	OF_HASH_ADD_HASH(hash, [_namespace hash]);
	OF_HASH_ADD_HASH(hash, [_defaultNamespace hash]);
	OF_HASH_ADD_HASH(hash, [_attributes hash]);
	OF_HASH_ADD_HASH(hash, [_namespaces hash]);
	OF_HASH_ADD_HASH(hash, [_children hash]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

- copy
{
	return [[[self class] alloc] initWithElement: self];
}

- (void)dealloc
{
	[name release];
	[ns release];
	[defaultNamespace release];
	[attributes release];
	[namespaces release];
	[children release];

	[super dealloc];
}
@end

Modified src/OFXMLElementBuilder.h from [25d77e9e49] to [2639811347].

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







-
+




-
+







 *
 * If this method is not implemented in the delegate, the default is to throw
 * an OFMalformedXMLException.
 *
 * @param builder The builder which did not expect the close tag
 * @param name The name of the close tag
 * @param prefix The prefix of the close tag
 * @param ns The namespace of the close tag
 * @param namespace The namespace of the close tag
 */
- (void)elementBuilder: (OFXMLElementBuilder*)builder
  didNotExpectCloseTag: (OFString*)name
		prefix: (OFString*)prefix
	     namespace: (OFString*)ns;
	     namespace: (OFString*)namespace;

/*!
 * @brief This callback is called when the XML parser for the element builder
 *	  found an unknown entity.
 *
 * @param builder The element builder which found an unknown entity
 * @param entity The name of the entity
97
98
99
100
101
102
103
104
105


106
107
108
109
110
111
112
97
98
99
100
101
102
103


104
105
106
107
108
109
110
111
112







-
-
+
+







 *
 * It can also be used to build OFXMLElements from parts of the document by
 * first parsing stuff using the OFXMLParser with another delegate and then
 * setting the OFXMLElementBuilder as delegate for the parser.
 */
@interface OFXMLElementBuilder: OFObject <OFXMLParserDelegate>
{
	OFMutableArray *stack;
	id <OFXMLElementBuilderDelegate> delegate;
	OFMutableArray *_stack;
	id <OFXMLElementBuilderDelegate> _delegate;
}

#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFXMLElementBuilderDelegate> delegate;
#endif

/*!

Modified src/OFXMLElementBuilder.m from [eab873b1b6] to [13da6c9002].

37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62

63
64
65

66
67

68
69
70
71
72
73
74
75

76
77
78
79

80
81
82


83
84
85
86
87
88

89
90
91
92
93
94
95
96

97
98
99
100
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
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61

62
63
64

65
66

67
68
69
70
71
72
73
74

75
76
77
78

79
80


81
82
83
84
85
86
87

88
89
90
91
92
93
94
95

96
97
98
99
100
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







-
+










-
+






-
+


-
+

-
+







-
+



-
+

-
-
+
+





-
+







-
+

















-
-
+
+





-
+

-
+

-
+

-
-
-
-
+
+
+
+






-
-
+
+



-
+









-
+



-
+

-
+







-
+



-
+

-
-
+
+






-
+



-
+

-
-
+
+





-
+

-
-
+
+




}

- init
{
	self = [super init];

	@try {
		stack = [[OFMutableArray alloc] init];
		_stack = [[OFMutableArray alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[stack release];
	[_stack release];

	[super dealloc];
}

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

- (void)setDelegate: (id <OFXMLElementBuilderDelegate>)delegate_
- (void)setDelegate: (id <OFXMLElementBuilderDelegate>)delegate
{
	delegate = delegate_;
	_delegate = delegate;
}

-		 (void)parser: (OFXMLParser*)parser
  foundProcessingInstructions: (OFString*)pi
{
	OFXMLProcessingInstructions *node = [OFXMLProcessingInstructions
	    processingInstructionsWithString: pi];
	OFXMLElement *parent = [stack lastObject];
	OFXMLElement *parent = [_stack lastObject];

	if (parent != nil)
		[parent addChild: node];
	else if ([delegate respondsToSelector:
	else if ([_delegate respondsToSelector:
	    @selector(elementBuilder:didBuildParentlessNode:)])
		[delegate   elementBuilder: self
		    didBuildParentlessNode: node];
		[_delegate elementBuilder: self
		   didBuildParentlessNode: node];
}

-    (void)parser: (OFXMLParser*)parser
  didStartElement: (OFString*)name
	   prefix: (OFString*)prefix
	namespace: (OFString*)ns
	namespace: (OFString*)namespace
       attributes: (OFArray*)attributes
{
	OFXMLElement *element;
	OFXMLAttribute **objects;
	size_t i, count;

	element = [OFXMLElement elementWithName: name
				      namespace: ns];
				      namespace: namespace];

	objects = [attributes objects];
	count = [attributes count];

	for (i = 0; i < count; i++) {
		if ([objects[i] namespace] == nil &&
		    [[objects[i] name] isEqual: @"xmlns"])
			continue;

		if ([[objects[i] namespace]
		    isEqual: @"http://www.w3.org/2000/xmlns/"])
			[element setPrefix: [objects[i] name]
			      forNamespace: [objects[i] stringValue]];

		[element addAttribute: objects[i]];
	}

	[[stack lastObject] addChild: element];
	[stack addObject: element];
	[[_stack lastObject] addChild: element];
	[_stack addObject: element];
}

-  (void)parser: (OFXMLParser*)parser
  didEndElement: (OFString*)name
	 prefix: (OFString*)prefix
      namespace: (OFString*)ns
      namespace: (OFString*)namespace
{
	switch ([stack count]) {
	switch ([_stack count]) {
	case 0:
		if ([delegate respondsToSelector: @selector(elementBuilder:
		if ([_delegate respondsToSelector: @selector(elementBuilder:
		    didNotExpectCloseTag:prefix:namespace:)])
			[delegate elementBuilder: self
			    didNotExpectCloseTag: name
					  prefix: prefix
				       namespace: ns];
			[_delegate elementBuilder: self
			     didNotExpectCloseTag: name
					   prefix: prefix
					namespace: namespace];
		else
			@throw [OFMalformedXMLException
			    exceptionWithClass: [self class]];

		return;
	case 1:
		[delegate elementBuilder: self
			 didBuildElement: [stack firstObject]];
		[_delegate elementBuilder: self
			  didBuildElement: [_stack firstObject]];
		break;
	}

	[stack removeLastObject];
	[_stack removeLastObject];
}

-    (void)parser: (OFXMLParser*)parser
  foundCharacters: (OFString*)characters
{
	OFXMLCharacters *node;
	OFXMLElement *parent;

	node = [OFXMLCharacters charactersWithString: characters];
	parent = [stack lastObject];
	parent = [_stack lastObject];

	if (parent != nil)
		[parent addChild: node];
	else if ([delegate respondsToSelector:
	else if ([_delegate respondsToSelector:
	    @selector(elementBuilder:didBuildParentlessNode:)])
		[delegate   elementBuilder: self
		[_delegate  elementBuilder: self
		    didBuildParentlessNode: node];
}

- (void)parser: (OFXMLParser*)parser
    foundCDATA: (OFString*)CDATA
{
	OFXMLCDATA *node = [OFXMLCDATA CDATAWithString: CDATA];
	OFXMLElement *parent = [stack lastObject];
	OFXMLElement *parent = [_stack lastObject];

	if (parent != nil)
		[parent addChild: node];
	else if ([delegate respondsToSelector:
	else if ([_delegate respondsToSelector:
	    @selector(elementBuilder:didBuildParentlessNode:)])
		[delegate   elementBuilder: self
		    didBuildParentlessNode: node];
		[_delegate elementBuilder: self
		   didBuildParentlessNode: node];
}

- (void)parser: (OFXMLParser*)parser
  foundComment: (OFString*)comment
{
	OFXMLComment *node = [OFXMLComment commentWithString: comment];
	OFXMLElement *parent = [stack lastObject];
	OFXMLElement *parent = [_stack lastObject];

	if (parent != nil)
		[parent addChild: node];
	else if ([delegate respondsToSelector:
	else if ([_delegate respondsToSelector:
	    @selector(elementBuilder:didBuildParentlessNode:)])
		[delegate   elementBuilder: self
		    didBuildParentlessNode: node];
		[_delegate elementBuilder: self
		   didBuildParentlessNode: node];
}

-	(OFString*)parser: (OFXMLParser*)parser
  foundUnknownEntityNamed: (OFString*)entity
{
	if ([delegate respondsToSelector:
	if ([_delegate respondsToSelector:
	    @selector(elementBuilder:foundUnknownEntityNamed:)])
		return [delegate elementBuilder: self
			foundUnknownEntityNamed: entity];
		return [_delegate elementBuilder: self
			 foundUnknownEntityNamed: entity];

	return nil;
}
@end

Modified src/OFXMLParser.h from [e7c5a2a327] to [3c72bea853].

121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135







-
+







 * @brief An event-based XML parser.
 *
 * OFXMLParser is an event-based XML parser which calls the delegate's callbacks
 * as soon asit finds something, thus suitable for streams as well.
 */
@interface OFXMLParser: OFObject <OFStringXMLUnescapingDelegate>
{
	id <OFXMLParserDelegate> delegate;
	id <OFXMLParserDelegate> _delegate;
	enum {
		OF_XMLPARSER_OUTSIDE_TAG,
		OF_XMLPARSER_TAG_OPENED,
		OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS,
		OF_XMLPARSER_IN_TAG_NAME,
		OF_XMLPARSER_IN_CLOSE_TAG_NAME,
		OF_XMLPARSER_IN_TAG,
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
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







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







		OF_XMLPARSER_IN_CDATA_1,
		OF_XMLPARSER_IN_CDATA_2,
		OF_XMLPARSER_IN_COMMENT_OPENING,
		OF_XMLPARSER_IN_COMMENT_1,
		OF_XMLPARSER_IN_COMMENT_2,
		OF_XMLPARSER_IN_DOCTYPE,
		OF_XMLPARSER_NUM_STATES
	} state;
	OFDataArray *cache;
	OFString *name;
	} _state;
	OFDataArray *_cache;
	OFString *_name, *_prefix;
	OFString *prefix;
	OFMutableArray *namespaces;
	OFMutableArray *_namespaces, *_attributes;
	OFMutableArray *attributes;
	OFString *attributeName;
	OFString *_attributeName, *_attributePrefix;
	OFString *attributePrefix;
	char delimiter;
	OFMutableArray *previous;
	size_t level;
	BOOL acceptProlog;
	size_t lineNumber;
	BOOL lastCarriageReturn;
	char _delimiter;
	OFMutableArray *_previous;
	size_t _level;
	BOOL _acceptProlog;
	size_t _lineNumber;
	BOOL _lastCarriageReturn, _finishedParsing;
	BOOL finishedParsing;
	of_string_encoding_t encoding;
	size_t depthLimit;
	of_string_encoding_t _encoding;
	size_t _depthLimit;
}

#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFXMLParserDelegate> delegate;
@property size_t depthLimit;
#endif

Modified src/OFXMLParser.m from [b0c5452c32] to [ca4fab60df].

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







-
+











-
-
+
+







}

static OF_INLINE void
resolve_attribute_namespace(OFXMLAttribute *attribute, OFArray *namespaces,
    OFXMLParser *self)
{
	OFString *attributeNS;
	OFString *attributePrefix = attribute->ns;
	OFString *attributePrefix = attribute->_namespace;

	if (attributePrefix == nil)
		return;

	attributeNS = namespace_for_prefix(attributePrefix, namespaces);

	if ((attributePrefix != nil && attributeNS == nil))
		@throw [OFUnboundNamespaceException
		    exceptionWithClass: [self class]
				prefix: attributePrefix];

	[attribute->ns release];
	attribute->ns = [attributeNS retain];
	[attribute->_namespace release];
	attribute->_namespace = [attributeNS retain];
}

@implementation OFXMLParser
+ (void)initialize
{
	size_t i;

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







-
-
-
-
+
+
+
+





-
+

-
-
-
-
+
+
+
+












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






-
+


-
+

-
+




-
+


-
+

-
+










-
+






-
-
+
+

-
+



-
-
+
+







{
	self = [super init];

	@try {
		void *pool;
		OFMutableDictionary *dict;

		cache = [[OFBigDataArray alloc] init];
		previous = [[OFMutableArray alloc] init];
		namespaces = [[OFMutableArray alloc] init];
		attributes = [[OFMutableArray alloc] init];
		_cache = [[OFBigDataArray alloc] init];
		_previous = [[OFMutableArray alloc] init];
		_namespaces = [[OFMutableArray alloc] init];
		_attributes = [[OFMutableArray alloc] init];

		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];
		[_namespaces addObject: dict];

		acceptProlog = YES;
		lineNumber = 1;
		encoding = OF_STRING_ENCODING_UTF_8;
		depthLimit = 32;
		_acceptProlog = YES;
		_lineNumber = 1;
		_encoding = OF_STRING_ENCODING_UTF_8;
		_depthLimit = 32;

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[cache release];
	[name release];
	[prefix release];
	[namespaces release];
	[attributes release];
	[attributeName release];
	[attributePrefix release];
	[previous release];
	[_cache release];
	[_name release];
	[_prefix release];
	[_namespaces release];
	[_attributes release];
	[_attributeName release];
	[_attributePrefix release];
	[_previous release];

	[super dealloc];
}

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

- (void)setDelegate: (id <OFXMLParserDelegate>)delegate_
- (void)setDelegate: (id <OFXMLParserDelegate>)delegate
{
	delegate = delegate_;
	_delegate = delegate;
}

- (size_t)depthLimit
{
	return depthLimit;
	return _depthLimit;
}

- (void)setDepthLimit: (size_t)depthLimit_
- (void)setDepthLimit: (size_t)depthLimit
{
	depthLimit = depthLimit_;
	_depthLimit = depthLimit;
}

- (void)parseBuffer: (const char*)buffer
	     length: (size_t)length
{
	size_t i, last = 0;

	for (i = 0; i < length; i++) {
		size_t j = i;

		lookupTable[state](self, selectors[state], buffer, &i, &last);
		lookupTable[_state](self, selectors[_state], buffer, &i, &last);

		/* Ensure we don't count this character twice */
		if (i != j)
			continue;

		if (buffer[i] == '\r' || (buffer[i] == '\n' &&
		    !lastCarriageReturn))
			lineNumber++;
		    !_lastCarriageReturn))
			_lineNumber++;

		lastCarriageReturn = (buffer[i] == '\r');
		_lastCarriageReturn = (buffer[i] == '\r');
	}

	/* In OF_XMLPARSER_IN_TAG, there can be only spaces */
	if (length - last > 0 && state != OF_XMLPARSER_IN_TAG)
		cache_append(cache, buffer + last, encoding, length - last);
	if (length - last > 0 && _state != OF_XMLPARSER_IN_TAG)
		cache_append(_cache, buffer + last, _encoding, length - last);
}

- (void)parseString: (OFString*)string
{
	[self parseBuffer: [string UTF8String]
		   length: [string UTF8StringLength]];
}
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


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

552
553
554
555
556


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

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






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

924
925
926
927
928
929



930
931
932
933
934
935
936
937
938
939
940

941
942

943
944
945


946
947
948
949
950
951
952
953
954
955
956
957


958
959
960
961
962
963
964
965


966
967
968
969



970
971
972
973

974
975
976

977
978
979
980
981
982
983
984
985
986
987
988
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
1014
1015
1016
1017
1018
1019
1020


1021
1022
1023
1024



1025
1026
1027
1028

1029
1030
1031

1032
1033
1034
1035
1036
1037
1038
1039
1040


1041
1042
1043
1044
1045
1046


1047
1048
1049
1050


1051
1052

1053
1054
1055
1056
1057
1058
1059
1060

1061
1062
1063
1064
1065

1066
1067
1068
1069
1070
1071

1072
1073
1074


1075
1076
1077
1078
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
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
550

551
552
553
554


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



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



926
927
928
929
930
931
932
933
934
935
936
937
938

939
940

941
942


943
944
945
946
947
948
949
950
951
952
953
954


955
956
957
958
959
960
961
962


963
964
965



966
967
968
969
970
971

972
973
974

975
976
977
978
979
980
981
982
983
984
985
986
987


988
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
1014
1015
1016
1017


1018
1019
1020



1021
1022
1023
1024
1025
1026

1027
1028
1029

1030
1031
1032
1033
1034
1035
1036
1037


1038
1039
1040
1041
1042
1043


1044
1045
1046
1047


1048
1049
1050

1051
1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063

1064
1065
1066
1067
1068
1069

1070
1071


1072
1073
1074
1075
1076
1077







-
+









-
+

-
+

-
+

-
+

-
-
+
+




-
+


-
+







-
+






-
-
+
+



-
-
+
+



-
-
+
+


-
+




-
-
+
+










-
+




-
+


-
+








-
+






-
+











-
+








-
+


















-
+

-
+


-
+


-
+






-
+





-
+











-
-
+
+

-
+

-
-
+
+

-
-
-
-
+
+
+
+




-
+

-
-
+
+



-
+


-
+

-
+

















-
+



-
-
+
+




-
+


-
+



-
-
+
+



-
+

-
+

-
+


-
+

-
+

-
-
-
-
-
+
+
+
+
+


-
+

-
-
-
-
+
+
+
+

-
-
+
+

-
+

-
-
-
+
+
+

-
+



-
+


-
+



-
+











-
+
-






-
+



-
-
+
+




-
+


-
+



-
-
+
+


-
+



-
+

-
+

-
-
+
+


-
+

-
+

-
-
-
-
+
+
+
+



-
-
-
-
+
+
+
+


-
+



-
-
+
+








-
+







-
+






-
-
+
+

-
+

-
+


-
+


-
+




-
+

-
-
-
-
-
+
+
+
+
+


-
+

-
-
-
-
+
+
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
+



-
-
-
-
+
+
+
+


-
+


















-
+



-
-
+
+








-
+


-
+



-
-
+
+




-
+


-
+

















-
-
+
+











-
+



-
+


-
+

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

-
-
-
+
+
+




-
-
-
-
+
+
+
+


-
+









-
+












-
+











-
+




-
+

-
-
+
+

-
-
+
+












-
+



-
-
-
+
+
+










-
+

-
+

-
-
+
+










-
-
+
+






-
-
+
+

-
-
-
+
+
+



-
+


-
+












-
-
+
+







-
+

-
+

-
-
+
+















-
-
+
+

-
-
-
+
+
+



-
+


-
+







-
-
+
+




-
-
+
+


-
-
+
+

-
+







-
+




-
+





-
+

-
-
+
+




/* Not in a tag */
- (void)OF_parseOutsideTagWithBuffer: (const char*)buffer
				   i: (size_t*)i
				last: (size_t*)last
{
	size_t length;

	if ((finishedParsing || [previous count] < 1) && buffer[*i] != ' ' &&
	if ((_finishedParsing || [_previous count] < 1) && buffer[*i] != ' ' &&
	    buffer[*i] != '\t' && buffer[*i] != '\n' && buffer[*i] != '\r' &&
	    buffer[*i] != '<')
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	if (buffer[*i] != '<')
		return;

	if ((length = *i - *last) > 0)
		cache_append(cache, buffer + *last, encoding, length);
		cache_append(_cache, buffer + *last, _encoding, length);

	if ([cache count] > 0) {
	if ([_cache count] > 0) {
		void *pool = objc_autoreleasePoolPush();
		OFString *characters = transform_string(cache, 0, YES, self);
		OFString *characters = transform_string(_cache, 0, YES, self);

		if ([delegate respondsToSelector:
		if ([_delegate respondsToSelector:
		    @selector(parser:foundCharacters:)])
			[delegate    parser: self
			    foundCharacters: characters];
			[_delegate parser: self
			  foundCharacters: characters];

		objc_autoreleasePoolPop(pool);
	}

	[cache removeAllItems];
	[_cache removeAllItems];

	*last = *i + 1;
	state = OF_XMLPARSER_TAG_OPENED;
	_state = OF_XMLPARSER_TAG_OPENED;
}

/* Tag was just opened */
- (void)OF_parseTagOpenedWithBuffer: (const char*)buffer
				  i: (size_t*)i
			       last: (size_t*)last
{
	if (finishedParsing && buffer[*i] != '!' && buffer[*i] != '?')
	if (_finishedParsing && buffer[*i] != '!' && buffer[*i] != '?')
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	switch (buffer[*i]) {
	case '?':
		*last = *i + 1;
		state = OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS;
		level = 0;
		_state = OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS;
		_level = 0;
		break;
	case '/':
		*last = *i + 1;
		state = OF_XMLPARSER_IN_CLOSE_TAG_NAME;
		acceptProlog = NO;
		_state = OF_XMLPARSER_IN_CLOSE_TAG_NAME;
		_acceptProlog = NO;
		break;
	case '!':
		*last = *i + 1;
		state = OF_XMLPARSER_IN_EXCLAMATIONMARK;
		acceptProlog = NO;
		_state = OF_XMLPARSER_IN_EXCLAMATIONMARK;
		_acceptProlog = NO;
		break;
	default:
		if (depthLimit > 0 && [previous count] >= depthLimit)
		if (_depthLimit > 0 && [_previous count] >= _depthLimit)
			@throw [OFMalformedXMLException
			    exceptionWithClass: [self class]
					parser: self];

		state = OF_XMLPARSER_IN_TAG_NAME;
		acceptProlog = NO;
		_state = OF_XMLPARSER_IN_TAG_NAME;
		_acceptProlog = NO;
		(*i)--;
		break;
	}
}

/* <?xml […]?> */
- (BOOL)OF_parseXMLProcessingInstructions: (OFString*)pi
{
	const char *cString;
	size_t i, last, length;
	int piState = 0;
	int PIState = 0;
	OFString *attribute = nil;
	OFMutableString *value = nil;
	char piDelimiter = 0;

	if (!acceptProlog)
	if (!_acceptProlog)
		return NO;

	acceptProlog = NO;
	_acceptProlog = NO;

	pi = [pi substringWithRange: of_range(3, [pi length] - 3)];
	pi = [pi stringByDeletingEnclosingWhitespaces];

	cString = [pi UTF8String];
	length = [pi UTF8StringLength];

	for (i = last = 0; i < length; i++) {
		switch (piState) {
		switch (PIState) {
		case 0:
			if (cString[i] == ' ' || cString[i] == '\t' ||
			    cString[i] == '\r' || cString[i] == '\n')
				continue;

			last = i;
			piState = 1;
			PIState = 1;
			i--;

			break;
		case 1:
			if (cString[i] != '=')
				continue;

			attribute = [OFString
			    stringWithUTF8String: cString + last
					  length: i - last];
			last = i + 1;
			piState = 2;
			PIState = 2;

			break;
		case 2:
			if (cString[i] != '\'' && cString[i] != '"')
				return NO;

			piDelimiter = cString[i];
			last = i + 1;
			piState = 3;
			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;

			if ([attribute isEqual: @"encoding"]) {
				[value lowercase];

				if ([value isEqual: @"utf-8"])
					encoding = OF_STRING_ENCODING_UTF_8;
					_encoding = OF_STRING_ENCODING_UTF_8;
				else if ([value isEqual: @"iso-8859-1"])
					encoding =
					_encoding =
					    OF_STRING_ENCODING_ISO_8859_1;
				else if ([value isEqual: @"iso-8859-15"])
					encoding =
					_encoding =
					    OF_STRING_ENCODING_ISO_8859_15;
				else if ([value isEqual: @"windows-1252"])
					encoding =
					_encoding =
					    OF_STRING_ENCODING_WINDOWS_1252;
				else
					return NO;
			}

			last = i + 1;
			piState = 0;
			PIState = 0;

			break;
		}
	}

	if (piState != 0)
	if (PIState != 0)
		return NO;

	return YES;
}

/* 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] == '>') {
		_level = 1;
	else if (_level == 1 && buffer[*i] == '>') {
		void *pool = objc_autoreleasePoolPush();
		OFString *pi;
		OFString *PI;

		cache_append(cache, buffer + *last, encoding, *i - *last);
		pi = transform_string(cache, 1, NO, nil);
		cache_append(_cache, buffer + *last, _encoding, *i - *last);
		PI = transform_string(_cache, 1, NO, 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])
		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]
						parser: self];

		if ([delegate respondsToSelector:
		if ([_delegate respondsToSelector:
		    @selector(parser:foundProcessingInstructions:)])
			[delegate		 parser: self
			    foundProcessingInstructions: pi];
			[_delegate		 parser: self
			    foundProcessingInstructions: PI];

		objc_autoreleasePoolPop(pool);

		[cache removeAllItems];
		[_cache removeAllItems];

		*last = *i + 1;
		state = OF_XMLPARSER_OUTSIDE_TAG;
		_state = OF_XMLPARSER_OUTSIDE_TAG;
	} else
		level = 0;
		_level = 0;
}

/* Inside a tag, no name yet */
- (void)OF_parseInTagNameWithBuffer: (const char*)buffer
				  i: (size_t*)i
			       last: (size_t*)last
{
	void *pool;
	const char *cacheCString, *tmp;
	size_t length, cacheLength;
	OFString *cacheString;

	if (buffer[*i] != ' ' && buffer[*i] != '\t' && buffer[*i] != '\n' &&
	    buffer[*i] != '\r' && buffer[*i] != '>' && buffer[*i] != '/')
		return;

	if ((length = *i - *last) > 0)
		cache_append(cache, buffer + *last, encoding, length);
		cache_append(_cache, buffer + *last, _encoding, length);

	pool = objc_autoreleasePoolPush();

	cacheCString = [cache items];
	cacheLength = [cache count];
	cacheCString = [_cache items];
	cacheLength = [_cache count];
	cacheString = [OFString stringWithUTF8String: cacheCString
					      length: cacheLength];

	if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) {
		name = [[OFString alloc]
		_name = [[OFString alloc]
		    initWithUTF8String: tmp + 1
				length: cacheLength - (tmp - cacheCString) - 1];
		prefix = [[OFString alloc]
		_prefix = [[OFString alloc]
		    initWithUTF8String: cacheCString
				length: tmp - cacheCString];
	} else {
		name = [cacheString copy];
		prefix = nil;
		_name = [cacheString copy];
		_prefix = nil;
	}

	if (buffer[*i] == '>' || buffer[*i] == '/') {
		OFString *ns;
		OFString *namespace;

		ns = namespace_for_prefix(prefix, namespaces);
		namespace = namespace_for_prefix(_prefix, _namespaces);

		if (prefix != nil && ns == nil)
		if (_prefix != nil && namespace == nil)
			@throw [OFUnboundNamespaceException
			    exceptionWithClass: [self class]
					prefix: prefix];
					prefix: _prefix];

		if ([delegate respondsToSelector: @selector(parser:
		if ([_delegate respondsToSelector: @selector(parser:
		    didStartElement:prefix:namespace:attributes:)])
			[delegate    parser: self
			    didStartElement: name
				     prefix: prefix
				  namespace: ns
				 attributes: nil];
			[_delegate parser: self
			  didStartElement: _name
				   prefix: _prefix
				namespace: namespace
			       attributes: nil];

		if (buffer[*i] == '/') {
			if ([delegate respondsToSelector:
			if ([_delegate respondsToSelector:
			    @selector(parser:didEndElement:prefix:namespace:)])
				[delegate  parser: self
				    didEndElement: name
					   prefix: prefix
					namespace: ns];
				[_delegate parser: self
				    didEndElement: _name
					   prefix: _prefix
					namespace: namespace];

			if ([previous count] == 0)
				finishedParsing = YES;
			if ([_previous count] == 0)
				_finishedParsing = YES;
		} else
			[previous addObject: cacheString];
			[_previous addObject: cacheString];

		[name release];
		[prefix release];
		name = prefix = nil;
		[_name release];
		[_prefix release];
		_name = _prefix = nil;

		state = (buffer[*i] == '/'
		_state = (buffer[*i] == '/'
		    ? OF_XMLPARSER_EXPECT_CLOSE
		    : OF_XMLPARSER_OUTSIDE_TAG);
	} else
		state = OF_XMLPARSER_IN_TAG;
		_state = OF_XMLPARSER_IN_TAG;

	if (buffer[*i] != '/')
		[namespaces addObject: [OFMutableDictionary dictionary]];
		[_namespaces addObject: [OFMutableDictionary dictionary]];

	objc_autoreleasePoolPop(pool);

	[cache removeAllItems];
	[_cache removeAllItems];
	*last = *i + 1;
}

/* Inside a close tag, no name yet */
- (void)OF_parseInCloseTagNameWithBuffer: (const char*)buffer
				       i: (size_t*)i
				    last: (size_t*)last
{
	void *pool;
	const char *cacheCString, *tmp;
	size_t length, cacheLength;
	OFString *cacheString;
	OFString *cacheString, *namespace;
	OFString *ns;

	if (buffer[*i] != ' ' && buffer[*i] != '\t' && buffer[*i] != '\n' &&
	    buffer[*i] != '\r' && buffer[*i] != '>')
		return;

	if ((length = *i - *last) > 0)
		cache_append(cache, buffer + *last, encoding, length);
		cache_append(_cache, buffer + *last, _encoding, length);

	pool = objc_autoreleasePoolPush();

	cacheCString = [cache items];
	cacheLength = [cache count];
	cacheCString = [_cache items];
	cacheLength = [_cache count];
	cacheString = [OFString stringWithUTF8String: cacheCString
					      length: cacheLength];

	if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) {
		name = [[OFString alloc]
		_name = [[OFString alloc]
		    initWithUTF8String: tmp + 1
				length: cacheLength - (tmp - cacheCString) - 1];
		prefix = [[OFString alloc]
		_prefix = [[OFString alloc]
		    initWithUTF8String: cacheCString
				length: tmp - cacheCString];
	} else {
		name = [cacheString copy];
		prefix = nil;
		_name = [cacheString copy];
		_prefix = nil;
	}

	if (![[previous lastObject] isEqual: cacheString])
	if (![[_previous lastObject] isEqual: cacheString])
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	[previous removeLastObject];
	[_previous removeLastObject];

	[cache removeAllItems];
	[_cache removeAllItems];

	ns = namespace_for_prefix(prefix, namespaces);
	if (prefix != nil && ns == nil)
	namespace = namespace_for_prefix(_prefix, _namespaces);
	if (_prefix != nil && namespace == nil)
		@throw [OFUnboundNamespaceException
		    exceptionWithClass: [self class]
				prefix: prefix];
				prefix: _prefix];

	if ([delegate respondsToSelector:
	if ([_delegate respondsToSelector:
	    @selector(parser:didEndElement:prefix:namespace:)])
		[delegate  parser: self
		    didEndElement: name
			   prefix: prefix
			namespace: ns];
		[_delegate parser: self
		    didEndElement: _name
			   prefix: _prefix
			namespace: namespace];

	objc_autoreleasePoolPop(pool);

	[namespaces removeLastObject];
	[name release];
	[prefix release];
	name = prefix = nil;
	[_namespaces removeLastObject];
	[_name release];
	[_prefix release];
	_name = _prefix = nil;

	*last = *i + 1;
	state = (buffer[*i] == '>'
	_state = (buffer[*i] == '>'
	    ? OF_XMLPARSER_OUTSIDE_TAG
	    : OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE);

	if ([previous count] == 0)
		finishedParsing = YES;
	if ([_previous count] == 0)
		_finishedParsing = YES;
}

/* Inside a tag, name found */
- (void)OF_parseInTagWithBuffer: (const char*)buffer
			      i: (size_t*)i
			   last: (size_t*)last
{
	void *pool;
	OFString *ns;
	OFString *namespace;
	OFXMLAttribute **attributesObjects;
	size_t j, attributesCount;

	if (buffer[*i] != '>' && buffer[*i] != '/') {
		if (buffer[*i] != ' ' && buffer[*i] != '\t' &&
		    buffer[*i] != '\n' && buffer[*i] != '\r') {
			*last = *i;
			state = OF_XMLPARSER_IN_ATTR_NAME;
			_state = OF_XMLPARSER_IN_ATTR_NAME;
			(*i)--;
		}

		return;
	}

	attributesObjects = [attributes objects];
	attributesCount = [attributes count];
	attributesObjects = [_attributes objects];
	attributesCount = [_attributes count];

	ns = namespace_for_prefix(prefix, namespaces);
	namespace = namespace_for_prefix(_prefix, _namespaces);

	if (prefix != nil && ns == nil)
	if (_prefix != nil && namespace == nil)
		@throw [OFUnboundNamespaceException
		    exceptionWithClass: [self class]
				prefix: prefix];
				prefix: _prefix];

	for (j = 0; j < attributesCount; j++)
		resolve_attribute_namespace(attributesObjects[j], namespaces,
		resolve_attribute_namespace(attributesObjects[j], _namespaces,
		    self);

	pool = objc_autoreleasePoolPush();

	if ([delegate respondsToSelector:
	if ([_delegate respondsToSelector:
	    @selector(parser:didStartElement:prefix:namespace:attributes:)])
		[delegate    parser: self
		    didStartElement: name
			     prefix: prefix
			  namespace: ns
			 attributes: attributes];
		[_delegate parser: self
		  didStartElement: _name
			   prefix: _prefix
			namespace: namespace
		       attributes: _attributes];

	if (buffer[*i] == '/') {
		if ([delegate respondsToSelector:
		if ([_delegate respondsToSelector:
		    @selector(parser:didEndElement:prefix:namespace:)])
			[delegate  parser: self
			    didEndElement: name
				   prefix: prefix
				namespace: ns];
			[_delegate parser: self
			    didEndElement: _name
				   prefix: _prefix
				namespace: namespace];

		if ([previous count] == 0)
			finishedParsing = YES;
		if ([_previous count] == 0)
			_finishedParsing = YES;

		[namespaces removeLastObject];
	} else if (prefix != nil) {
		[_namespaces removeLastObject];
	} else if (_prefix != nil) {
		OFString *str = [OFString stringWithFormat: @"%@:%@",
							    prefix, name];
		[previous addObject: str];
							    _prefix, _name];
		[_previous addObject: str];
	} else
		[previous addObject: name];
		[_previous addObject: _name];

	objc_autoreleasePoolPop(pool);

	[name release];
	[prefix release];
	[attributes removeAllObjects];
	name = prefix = nil;
	[_name release];
	[_prefix release];
	[_attributes removeAllObjects];
	_name = _prefix = nil;

	*last = *i + 1;
	state = (buffer[*i] == '/'
	_state = (buffer[*i] == '/'
	    ? OF_XMLPARSER_EXPECT_CLOSE
	    : OF_XMLPARSER_OUTSIDE_TAG);
}

/* Looking for attribute name */
- (void)OF_parseInAttributeNameWithBuffer: (const char*)buffer
					i: (size_t*)i
				     last: (size_t*)last
{
	void *pool;
	OFMutableString *cacheString;
	const char *cacheCString, *tmp;
	size_t length, cacheLength;

	if (buffer[*i] != '=')
		return;

	if ((length = *i - *last) > 0)
		cache_append(cache, buffer + *last, encoding, length);
		cache_append(_cache, buffer + *last, _encoding, length);

	pool = objc_autoreleasePoolPush();

	cacheString = [OFMutableString stringWithUTF8String: [cache items]
						     length: [cache count]];
	cacheString = [OFMutableString stringWithUTF8String: [_cache items]
						     length: [_cache count]];
	[cacheString deleteEnclosingWhitespaces];
	/* Prevent a useless copy later */
	[cacheString makeImmutable];

	cacheCString = [cacheString UTF8String];
	cacheLength = [cacheString UTF8StringLength];

	if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) {
		attributeName = [[OFString alloc]
		_attributeName = [[OFString alloc]
		    initWithUTF8String: tmp + 1
				length: cacheLength - (tmp - cacheCString) - 1];
		attributePrefix = [[OFString alloc]
		_attributePrefix = [[OFString alloc]
		    initWithUTF8String: cacheCString
				length: tmp - cacheCString];
	} else {
		attributeName = [cacheString copy];
		attributePrefix = nil;
		_attributeName = [cacheString copy];
		_attributePrefix = nil;
	}

	objc_autoreleasePoolPop(pool);

	[cache removeAllItems];
	[_cache removeAllItems];

	*last = *i + 1;
	state = OF_XMLPARSER_EXPECT_DELIM;
	_state = OF_XMLPARSER_EXPECT_DELIM;
}

/* Expecting delimiter */
- (void)OF_parseExpectDelimiterWithBuffer: (const char*)buffer
					i: (size_t*)i
				     last: (size_t*)last
{
	*last = *i + 1;

	if (buffer[*i] == ' ' || buffer[*i] == '\t' || buffer[*i] == '\n' ||
	    buffer[*i] == '\r')
		return;

	if (buffer[*i] != '\'' && buffer[*i] != '"')
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	delimiter = buffer[*i];
	state = OF_XMLPARSER_IN_ATTR_VALUE;
	_delimiter = buffer[*i];
	_state = OF_XMLPARSER_IN_ATTR_VALUE;
}

/* Looking for attribute value */
- (void)OF_parseInAttributeValueWithBuffer: (const char*)buffer
					 i: (size_t*)i
				      last: (size_t*)last
{
	void *pool;
	OFString *attributeValue;
	size_t length;

	if (buffer[*i] != delimiter)
	if (buffer[*i] != _delimiter)
		return;

	if ((length = *i - *last) > 0)
		cache_append(cache, buffer + *last, encoding, length);
		cache_append(_cache, buffer + *last, _encoding, length);

	pool = objc_autoreleasePoolPush();
	attributeValue = transform_string(cache, 0, YES, self);
	attributeValue = transform_string(_cache, 0, YES, self);

	if (attributePrefix == nil && [attributeName isEqual: @"xmlns"])
		[[namespaces lastObject] setObject: attributeValue
					    forKey: @""];
	if ([attributePrefix isEqual: @"xmlns"])
		[[namespaces lastObject] setObject: attributeValue
					    forKey: attributeName];
	if (_attributePrefix == nil && [_attributeName isEqual: @"xmlns"])
		[[_namespaces lastObject] setObject: attributeValue
					     forKey: @""];
	if ([_attributePrefix isEqual: @"xmlns"])
		[[_namespaces lastObject] setObject: attributeValue
					     forKey: _attributeName];

	[attributes addObject:
	    [OFXMLAttribute attributeWithName: attributeName
				    namespace: attributePrefix
	[_attributes addObject:
	    [OFXMLAttribute attributeWithName: _attributeName
				    namespace: _attributePrefix
				  stringValue: attributeValue]];

	objc_autoreleasePoolPop(pool);

	[cache removeAllItems];
	[attributeName release];
	[attributePrefix release];
	attributeName = attributePrefix = nil;
	[_cache removeAllItems];
	[_attributeName release];
	[_attributePrefix release];
	_attributeName = _attributePrefix = nil;

	*last = *i + 1;
	state = OF_XMLPARSER_IN_TAG;
	_state = OF_XMLPARSER_IN_TAG;
}

/* Expecting closing '>' */
- (void)OF_parseExpectCloseWithBuffer: (const char*)buffer
				    i: (size_t*)i
				 last: (size_t*)last
{
	if (buffer[*i] == '>') {
		*last = *i + 1;
		state = OF_XMLPARSER_OUTSIDE_TAG;
		_state = OF_XMLPARSER_OUTSIDE_TAG;
	} else
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];
}

/* Expecting closing '>' or space */
- (void)OF_parseExpectSpaceOrCloseWithBuffer: (const char*)buffer
					   i: (size_t*)i
					last: (size_t*)last
{
	if (buffer[*i] == '>') {
		*last = *i + 1;
		state = OF_XMLPARSER_OUTSIDE_TAG;
		_state = OF_XMLPARSER_OUTSIDE_TAG;
	} else if (buffer[*i] != ' ' && buffer[*i] != '\t' &&
	    buffer[*i] != '\n' && buffer[*i] != '\r')
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];
}

/* In <! */
- (void)OF_parseInExclamationMarkWithBuffer: (const char*)buffer
					  i: (size_t*)i
				       last: (size_t*)last
{
	if (finishedParsing && buffer[*i] != '-')
	if (_finishedParsing && buffer[*i] != '-')
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	if (buffer[*i] == '-')
		state = OF_XMLPARSER_IN_COMMENT_OPENING;
		_state = OF_XMLPARSER_IN_COMMENT_OPENING;
	else if (buffer[*i] == '[') {
		state = OF_XMLPARSER_IN_CDATA_OPENING;
		level = 0;
		_state = OF_XMLPARSER_IN_CDATA_OPENING;
		_level = 0;
	} else if (buffer[*i] == 'D') {
		state = OF_XMLPARSER_IN_DOCTYPE;
		level = 0;
		_state = OF_XMLPARSER_IN_DOCTYPE;
		_level = 0;
	} else
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	*last = *i + 1;
}

/* CDATA */
- (void)OF_parseInCDATAOpeningWithBuffer: (const char*)buffer
				       i: (size_t*)i
				    last: (size_t*)last
{
	if (buffer[*i] != "CDATA["[level])
	if (buffer[*i] != "CDATA["[_level])
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	if (++level == 6) {
		state = OF_XMLPARSER_IN_CDATA_1;
		level = 0;
	if (++_level == 6) {
		_state = OF_XMLPARSER_IN_CDATA_1;
		_level = 0;
	}

	*last = *i + 1;
}

- (void)OF_parseInCDATA1WithBuffer: (const char*)buffer
				 i: (size_t*)i
			      last: (size_t*)last
{
	if (buffer[*i] == ']')
		level++;
		_level++;
	else
		level = 0;
		_level = 0;

	if (level == 2)
		state = OF_XMLPARSER_IN_CDATA_2;
	if (_level == 2)
		_state = OF_XMLPARSER_IN_CDATA_2;
}

- (void)OF_parseInCDATA2WithBuffer: (const char*)buffer
				 i: (size_t*)i
			      last: (size_t*)last
{
	void *pool;
	OFString *CDATA;

	if (buffer[*i] != '>') {
		state = OF_XMLPARSER_IN_CDATA_1;
		level = (buffer[*i] == ']' ? 1 : 0);
		_state = OF_XMLPARSER_IN_CDATA_1;
		_level = (buffer[*i] == ']' ? 1 : 0);

		return;
	}

	pool = objc_autoreleasePoolPush();

	cache_append(cache, buffer + *last, encoding, *i - *last);
	CDATA = transform_string(cache, 2, NO, nil);
	cache_append(_cache, buffer + *last, _encoding, *i - *last);
	CDATA = transform_string(_cache, 2, NO, nil);

	if ([delegate respondsToSelector: @selector(parser:foundCDATA:)])
		[delegate parser: self
		      foundCDATA: CDATA];
	if ([_delegate respondsToSelector: @selector(parser:foundCDATA:)])
		[_delegate parser: self
		       foundCDATA: CDATA];

	objc_autoreleasePoolPop(pool);

	[cache removeAllItems];
	[_cache removeAllItems];

	*last = *i + 1;
	state = OF_XMLPARSER_OUTSIDE_TAG;
	_state = OF_XMLPARSER_OUTSIDE_TAG;
}

/* Comment */
- (void)OF_parseInCommentOpeningWithBuffer: (const char*)buffer
					 i: (size_t*)i
				      last: (size_t*)last
{
	if (buffer[*i] != '-')
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	*last = *i + 1;
	state = OF_XMLPARSER_IN_COMMENT_1;
	level = 0;
	_state = OF_XMLPARSER_IN_COMMENT_1;
	_level = 0;
}

- (void)OF_parseInComment1WithBuffer: (const char*)buffer
				   i: (size_t*)i
				last: (size_t*)last
{
	if (buffer[*i] == '-')
		level++;
		_level++;
	else
		level = 0;
		_level = 0;

	if (level == 2)
		state = OF_XMLPARSER_IN_COMMENT_2;
	if (_level == 2)
		_state = OF_XMLPARSER_IN_COMMENT_2;
}

- (void)OF_parseInComment2WithBuffer: (const char*)buffer
				   i: (size_t*)i
				last: (size_t*)last
{
	void *pool;
	OFString *comment;

	if (buffer[*i] != '>')
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	pool = objc_autoreleasePoolPush();

	cache_append(cache, buffer + *last, encoding, *i - *last);
	comment = transform_string(cache, 2, NO, nil);
	cache_append(_cache, buffer + *last, _encoding, *i - *last);
	comment = transform_string(_cache, 2, NO, nil);

	if ([delegate respondsToSelector: @selector(parser:foundComment:)])
		[delegate parser: self
		    foundComment: comment];
	if ([_delegate respondsToSelector: @selector(parser:foundComment:)])
		[_delegate parser: self
		     foundComment: comment];

	objc_autoreleasePoolPop(pool);

	[cache removeAllItems];
	[_cache removeAllItems];

	*last = *i + 1;
	state = OF_XMLPARSER_OUTSIDE_TAG;
	_state = OF_XMLPARSER_OUTSIDE_TAG;
}

/* In <!DOCTYPE ...> */
- (void)OF_parseInDoctypeWithBuffer: (const char*)buffer
				  i: (size_t*)i
			       last: (size_t*)last
{
	if ((level < 6 && buffer[*i] != "OCTYPE"[level]) ||
	    (level == 6 && buffer[*i] != ' ' && buffer[*i] != '\t' &&
	if ((_level < 6 && buffer[*i] != "OCTYPE"[_level]) ||
	    (_level == 6 && buffer[*i] != ' ' && buffer[*i] != '\t' &&
	    buffer[*i] != '\n' && buffer[*i] != '\r'))
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	if (level < 7 || buffer[*i] == '<')
		level++;
	if (_level < 7 || buffer[*i] == '<')
		_level++;

	if (buffer[*i] == '>') {
		if (level == 7)
			state = OF_XMLPARSER_OUTSIDE_TAG;
		if (_level == 7)
			_state = OF_XMLPARSER_OUTSIDE_TAG;
		else
			level--;
			_level--;
	}

	*last = *i + 1;
}

- (size_t)lineNumber
{
	return lineNumber;
	return _lineNumber;
}

- (BOOL)finishedParsing
{
	return finishedParsing;
	return _finishedParsing;
}

-	   (OFString*)string: (OFString*)string
  containsUnknownEntityNamed: (OFString*)entity
{
	if ([delegate respondsToSelector:
	if ([_delegate respondsToSelector:
	    @selector(parser:foundUnknownEntityNamed:)])
		return [delegate     parser: self
		    foundUnknownEntityNamed: entity];
		return [_delegate parser: self
		 foundUnknownEntityNamed: entity];

	return nil;
}
@end

Modified src/OFXMLProcessingInstructions.h from [855fc8a6f5] to [03f62c6277].

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 "OFXMLNode.h"

/*!
 * @brief A class for representing XML processing instructions.
 */
@interface OFXMLProcessingInstructions: OFXMLNode
{
	OFString *processingInstructions;
	OFString *_processingInstructions;
}

/*!
 * @brief Creates a new OFXMLProcessingInstructions with the specified string.
 *
 * @param string The string for the processing instructions
 * @return A new OFXMLProcessingInstructions

Modified src/OFXMLProcessingInstructions.m from [1362f58459] to [ba4e0fdeba].

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







-
+







}

- initWithString: (OFString*)string
{
	self = [super init];

	@try {
		processingInstructions = [string copy];
		_processingInstructions = [string copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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
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
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







-
+












-
+




-
+

-
-
+
+




-
+









-
+




-
+















-
-
-
+





-
+






-
+






-
+



		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

		processingInstructions = [[element stringValue] copy];
		_processingInstructions = [[element stringValue] copy];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (BOOL)isEqual: (id)object
{
	OFXMLProcessingInstructions *otherProcessingInstructions;
	OFXMLProcessingInstructions *processingInstructions;

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

	otherProcessingInstructions = object;
	processingInstructions = object;

	return ([otherProcessingInstructions->processingInstructions
	    isEqual: processingInstructions]);
	return ([processingInstructions->_processingInstructions
	    isEqual: _processingInstructions]);
}

- (uint32_t)hash
{
	return [processingInstructions hash];
	return [_processingInstructions hash];
}

- (OFString*)stringValue
{
	return @"";
}

- (OFString*)XMLString
{
	return [OFString stringWithFormat: @"<?%@?>", processingInstructions];
	return [OFString stringWithFormat: @"<?%@?>", _processingInstructions];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
	return [OFString stringWithFormat: @"<?%@?>", processingInstructions];
	return [OFString stringWithFormat: @"<?%@?>", _processingInstructions];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
				level: (unsigned int)level
{
	OFString *ret;

	if (indentation > 0 && level > 0) {
		char *whitespaces = [self allocMemoryWithSize:
		    (level * indentation) + 1];
		memset(whitespaces, ' ', level * indentation);
		whitespaces[level * indentation] = 0;

		@try {
			ret = [OFString stringWithFormat:
			    @"%s<?%@?>",
			    whitespaces,
			    processingInstructions];
			    @"%s<?%@?>", whitespaces, _processingInstructions];
		} @finally {
			[self freeMemory: whitespaces];
		}
	} else
		ret = [OFString stringWithFormat: @"<?%@?>",
						  processingInstructions];
						  _processingInstructions];

	return ret;
}

- (OFString*)description
{
	return [OFString stringWithFormat: @"<?%@?>", processingInstructions];
	return [OFString stringWithFormat: @"<?%@?>", _processingInstructions];
}

- (OFXMLElement*)XMLElementBySerializing
{
	return [OFXMLElement elementWithName: [self className]
				   namespace: OF_SERIALIZATION_NS
				 stringValue: processingInstructions];
				 stringValue: _processingInstructions];
}
@end

Modified src/bridge/NSArray_OFArray.h from [64cda1af47] to [0ab5200b4a].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#import <Foundation/NSArray.h>

@class OFArray;

@interface NSArray_OFArray: NSArray
{
	OFArray *array;
	OFArray *_array;
}

- initWithOFArray: (OFArray*)array;
@end

Modified src/bridge/NSArray_OFArray.m from [61bec25775] to [434089e7ff].

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







-
+



-
+










-
+









-
+







#import "NSArray_OFArray.h"
#import "OFArray.h"
#import "OFBridging.h"

#import "OFOutOfRangeException.h"

@implementation NSArray_OFArray
- initWithOFArray: (OFArray*)array_
- initWithOFArray: (OFArray*)array
{
	if ((self = [super init]) != nil) {
		@try {
			array = [array_ retain];
			_array = [array retain];
		} @catch (id e) {
			return nil;
		}
	}

	return self;
}

- (id)objectAtIndex: (NSUInteger)index
{
	id object = [array objectAtIndex: index];
	id object = [_array objectAtIndex: index];

	if ([object conformsToProtocol: @protocol(OFBridging)])
		return [object NSObject];

	return object;
}

- (NSUInteger)count
{
	size_t count = [array count];
	size_t count = [_array count];

	if (count > NSUIntegerMax)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	return (NSUInteger)count;
}
@end

Modified src/bridge/NSDictionary_OFDictionary.h from [ed07628feb] to [6e0ce58f25].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#import <Foundation/NSDictionary.h>

@class OFDictionary;

@interface NSDictionary_OFDictionary: NSDictionary
{
	OFDictionary *dictionary;
	OFDictionary *_dictionary;
}

- initWithOFDictionary: (OFDictionary*)dictionary;
@end

Modified src/bridge/NSDictionary_OFDictionary.m from [8b0d7ded32] to [f733fe8d7e].

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







-
+



-
+















-
+









-
+








#import "NSBridging.h"
#import "OFBridging.h"

#import "OFOutOfRangeException.h"

@implementation NSDictionary_OFDictionary
- initWithOFDictionary: (OFDictionary*)dictionary_
- initWithOFDictionary: (OFDictionary*)dictionary
{
	if ((self = [super init]) != nil) {
		@try {
			dictionary = [dictionary_ retain];
			_dictionary = [dictionary retain];
		} @catch (id e) {
			return nil;
		}
	}

	return self;
}

- (id)objectForKey: (id)key
{
	id object;

	if ([key conformsToProtocol: @protocol(NSBridging)])
		key = [key OFObject];

	object = [dictionary objectForKey: key];
	object = [_dictionary objectForKey: key];

	if ([object conformsToProtocol: @protocol(OFBridging)])
		return [object NSObject];

	return object;
}

- (NSUInteger)count
{
	size_t count = [dictionary count];
	size_t count = [_dictionary count];

	if (count > NSUIntegerMax)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	return (NSUInteger)count;
}
@end

Modified src/bridge/OFArray_NSArray.h from [7886c58cee] to [02bad917af].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#import "OFArray.h"

@class NSArray;

@interface OFArray_NSArray: OFArray
{
	NSArray *array;
	NSArray *_array;
}

- initWithNSArray: (NSArray*)array;
@end

Modified src/bridge/OFArray_NSArray.m from [ed89b3631c] to [550babc622].

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







-
+




-
-


-
+
+
+















-
+









-
+


#import "OFArray_NSArray.h"
#import "NSBridging.h"

#import "OFInitializationFailedException.h"
#import "OFOutOfRangeException.h"

@implementation OFArray_NSArray
- initWithNSArray: (NSArray*)array_
- initWithNSArray: (NSArray*)array
{
	self = [super init];

	@try {
		array = [array_ retain];

		if (array == nil)
			@throw [OFInitializationFailedException
			    exceptionWithClass: isa];
			    exceptionWithClass: [self class]];

		_array = [array retain];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (id)objectAtIndex: (size_t)index
{
	id object;

	if (index > NSUIntegerMax)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	object = [array objectAtIndex: index];
	object = [_array objectAtIndex: index];

	if ([object conformsToProtocol: @protocol(NSBridging)])
		return [object OFObject];

	return object;
}

- (size_t)count
{
	return [array count];
	return [_array count];
}
@end

Modified src/bridge/OFDictionary_NSDictionary.h from [7826d59e94] to [f68f3a5712].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#import "OFDictionary.h"

@class NSDictionary;

@interface OFDictionary_NSDictionary: OFDictionary
{
	NSDictionary *dictionary;
	NSDictionary *_dictionary;
}

- initWithNSDictionary: (NSDictionary*)dictionary;
@end

Modified src/bridge/OFDictionary_NSDictionary.m from [9a66c6414d] to [cb3b31f5ab].

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







-
+




-
-


-
+
+
+















-
+









-
+



#import "NSBridging.h"
#import "OFBridging.h"

#import "OFInitializationFailedException.h"

@implementation OFDictionary_NSDictionary
- initWithNSDictionary: (NSDictionary*)dictionary_
- initWithNSDictionary: (NSDictionary*)dictionary
{
	self = [super init];

	@try {
		dictionary = [dictionary_ retain];

		if (dictionary == nil)
			@throw [OFInitializationFailedException
			    exceptionWithClass: isa];
			    exceptionWithClass: [self class]];

		_dictionary = [dictionary retain];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (id)objectForKey: (id)key
{
	id object;

	if ([key conformsToProtocol: @protocol(OFBridging)])
		key = [key NSObject];

	object = [dictionary objectForKey: key];
	object = [_dictionary objectForKey: key];

	if ([object conformsToProtocol: @protocol(NSBridging)])
		return [object OFObject];

	return object;
}

- (size_t)count
{
	return [dictionary count];
	return [_dictionary count];
}
@end

Modified src/exceptions/OFAcceptFailedException.h from [be9ae8cbf9] to [f828728a28].

19
20
21
22
23
24
25
26
27


28
29
30
31
32
33
34
19
20
21
22
23
24
25


26
27
28
29
30
31
32
33
34







-
-
+
+







@class OFTCPSocket;

/*!
 * @brief An exception indicating that accepting a connection failed.
 */
@interface OFAcceptFailedException: OFException
{
	OFTCPSocket *socket;
	int errNo;
	OFTCPSocket *_socket;
	int _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly) int errNo;
#endif

Modified src/exceptions/OFAcceptFailedException.m from [69a04b661c] to [13c27ee54c].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
-
+
+






-
+






-
-
+
+

-
+

-
+

-
+




-
+




-
+


#import "OFAcceptFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"

#import "common.h"

@implementation OFAcceptFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    socket: (OFTCPSocket*)socket
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     socket: socket] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 socket: (OFTCPSocket*)socket_
- initWithClass: (Class)class
	 socket: (OFTCPSocket*)socket
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	socket = [socket_ retain];
	errNo = GET_SOCK_ERRNO;
	_socket = [socket retain];
	_errNo = GET_SOCK_ERRNO;

	return self;
}

- (void)dealloc
{
	[socket release];
	[_socket release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to accept connection in socket of type %@! " ERRFMT,
	    inClass, ERRPARAM];
	    _inClass, ERRPARAM];

	return description;
	return _description;
}

- (OFTCPSocket*)socket
{
	OF_GETTER(socket, NO)
	OF_GETTER(_socket, NO)
}

- (int)errNo
{
	return errNo;
	return _errNo;
}
@end

Modified src/exceptions/OFAddressTranslationFailedException.h from [ca60b34b9f] to [9eb5a36411].

19
20
21
22
23
24
25
26
27
28



29
30
31
32
33
34
35
19
20
21
22
23
24
25



26
27
28
29
30
31
32
33
34
35







-
-
-
+
+
+







@class OFTCPSocket;

/*!
 * @brief An exception indicating the translation of an address failed.
 */
@interface OFAddressTranslationFailedException: OFException
{
	OFTCPSocket *socket;
	OFString    *host;
	int	    errNo;
	OFTCPSocket *_socket;
	OFString    *_host;
	int	    _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly, copy, nonatomic) OFString *host;
@property (readonly) int errNo;
#endif

Modified src/exceptions/OFAddressTranslationFailedException.m from [967ab0fcff] to [1441dd45a6].

19
20
21
22
23
24
25
26

27
28
29
30

31
32
33
34
35

36
37

38
39

40
41
42
43
44
45
46



47
48

49
50
51
52
53



54
55
56
57
58
59
60
61
62
63
64
65


66
67
68
69
70
71
72
73


74
75
76


77
78
79
80
81

82
83

84
85

86
87

88
89
90
91
92

93
94
95
96
97

98
99
100
101
102

103
104
19
20
21
22
23
24
25

26
27
28
29

30
31
32
33
34

35
36

37
38

39
40
41
42
43



44
45
46
47

48
49
50



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


64
65
66
67
68
69
70
71


72
73
74


75
76
77
78
79
80

81
82

83
84

85
86

87
88
89
90
91

92
93
94
95
96

97
98
99
100
101

102
103
104







-
+



-
+




-
+

-
+

-
+




-
-
-
+
+
+

-
+


-
-
-
+
+
+










-
-
+
+






-
-
+
+

-
-
+
+




-
+

-
+

-
+

-
+




-
+




-
+




-
+


#import "OFAddressTranslationFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"

#import "common.h"

@implementation OFAddressTranslationFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    socket: (OFTCPSocket*)socket
			      host: (OFString*)host
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     socket: socket
				       host: host] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	errNo = GET_AT_ERRNO;
	_errNo = GET_AT_ERRNO;

	return self;
}

- initWithClass: (Class)class_
	 socket: (OFTCPSocket*)socket_
	   host: (OFString*)host_
- initWithClass: (Class)class
	 socket: (OFTCPSocket*)socket
	   host: (OFString*)host
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		socket = [socket_ retain];
		host   = [host_ copy];
		errNo  = GET_AT_ERRNO;
		_socket = [socket retain];
		_host   = [host copy];
		_errNo  = GET_AT_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[socket release];
	[host release];
	[_socket release];
	[_host release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	if (host != nil)
		description = [[OFString alloc] initWithFormat:
	if (_host != nil)
		_description = [[OFString alloc] initWithFormat:
		    @"The host %@ could not be translated to an address in "
		    @"class %@. This means that either the host was not found, "
		    @"there was a problem with the name server, there was a "
		    @"problem with your network connection or you specified an "
		    @"invalid host. " ERRFMT, host, inClass, AT_ERRPARAM];
		    @"invalid host. " ERRFMT, _host, _inClass, AT_ERRPARAM];
	else
		description = [[OFString alloc] initWithFormat:
		_description = [[OFString alloc] initWithFormat:
		    @"An address translation failed in class %@! " ERRFMT,
		    inClass, AT_ERRPARAM];
		    _inClass, AT_ERRPARAM];

	return description;
	return _description;
}

- (OFTCPSocket*)socket
{
	OF_GETTER(socket, NO)
	OF_GETTER(_socket, NO)
}

- (OFString*)host
{
	return host;
	OF_GETTER(_host, NO)
}

- (int)errNo
{
	return errNo;
	return _errNo;
}
@end

Modified src/exceptions/OFAlreadyConnectedException.h from [8c89edc113] to [5e96c85485].

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34







-
+








/*!
 * @brief An exception indicating an attempt to connect or bind an already
 *        connected or bound socket.
 */
@interface OFAlreadyConnectedException: OFException
{
	OFTCPSocket *socket;
	OFTCPSocket *_socket;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
#endif

/*!

Modified src/exceptions/OFAlreadyConnectedException.m from [539ea0a982] to [8b35209312].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
+

-
+

-
+




-
+


#import "OFAlreadyConnectedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"

#import "common.h"

@implementation OFAlreadyConnectedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    socket: (OFTCPSocket*)socket
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     socket: socket] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 socket: (OFTCPSocket*)socket_
- initWithClass: (Class)class
	 socket: (OFTCPSocket*)socket
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	socket = [socket_ retain];
	_socket = [socket retain];

	return self;
}

- (void)dealloc
{
	[socket release];
	[_socket release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"The socket of type %@ is already connected or bound and thus "
	    @"can't be connected or bound again!", inClass];
	    @"can't be connected or bound again!", _inClass];

	return description;
	return _description;
}

- (OFTCPSocket*)socket
{
	OF_GETTER(socket, NO)
	OF_GETTER(_socket, NO)
}
@end

Modified src/exceptions/OFBindFailedException.h from [9ba16ce080] to [3324f93c42].

19
20
21
22
23
24
25
26
27
28
29




30
31
32
33
34
35
36
19
20
21
22
23
24
25




26
27
28
29
30
31
32
33
34
35
36







-
-
-
-
+
+
+
+







@class OFTCPSocket;

/*!
 * @brief An exception indicating that binding a socket failed.
 */
@interface OFBindFailedException: OFException
{
	OFTCPSocket *socket;
	OFString    *host;
	uint16_t    port;
	int	    errNo;
	OFTCPSocket *_socket;
	OFString    *_host;
	uint16_t    _port;
	int	    _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly, copy, nonatomic) OFString *host;
@property (readonly) uint16_t port;
@property (readonly) int errNo;

Modified src/exceptions/OFBindFailedException.m from [4d941c04f6] to [04bd4c8eb2].

21
22
23
24
25
26
27
28

29
30
31
32
33

34
35
36
37
38
39

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




55
56

57
58
59
60
61
62




63
64
65
66
67
68
69
70
71
72
73
74


75
76
77
78
79
80
81
82


83
84

85
86

87
88

89
90
91
92
93

94
95
96
97
98

99
100
101
102
103

104
105
106
107
108

109
110
21
22
23
24
25
26
27

28
29
30
31
32

33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50




51
52
53
54
55

56
57
58




59
60
61
62
63
64
65
66
67
68
69
70
71
72


73
74
75
76
77
78
79
80


81
82
83

84
85

86
87

88
89
90
91
92

93
94
95
96
97

98
99
100
101
102

103
104
105
106
107

108
109
110







-
+




-
+





-
+











-
-
-
-
+
+
+
+

-
+


-
-
-
-
+
+
+
+










-
-
+
+






-
-
+
+

-
+

-
+

-
+




-
+




-
+




-
+




-
+


#import "OFBindFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"

#import "common.h"

@implementation OFBindFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    socket: (OFTCPSocket*)socket
			      host: (OFString*)host
			      port: (uint16_t)port
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     socket: socket
				       host: host
				       port: port] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 socket: (OFTCPSocket*)socket_
	   host: (OFString*)host_
	   port: (uint16_t)port_
- initWithClass: (Class)class
	 socket: (OFTCPSocket*)socket
	   host: (OFString*)host
	   port: (uint16_t)port
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		socket = [socket_ retain];
		host   = [host_ copy];
		port   = port_;
		errNo  = GET_SOCK_ERRNO;
		_socket = [socket retain];
		_host   = [host copy];
		_port   = port;
		_errNo  = GET_SOCK_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[socket release];
	[host release];
	[_socket release];
	[_host release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Binding to port %" @PRIu16 @" on host %@ failed in class %@! "
	    ERRFMT, port, host, inClass, ERRPARAM];
	    ERRFMT, _port, _host, _inClass, ERRPARAM];

	return description;
	return _description;
}

- (OFTCPSocket*)socket
{
	OF_GETTER(socket, NO)
	OF_GETTER(_socket, NO)
}

- (OFString*)host
{
	OF_GETTER(host, NO)
	OF_GETTER(_host, NO)
}

- (uint16_t)port
{
	return port;
	return _port;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}
@end

Modified src/exceptions/OFChangeDirectoryFailedException.h from [e713af3485] to [4e7164768a].

17
18
19
20
21
22
23
24
25


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


24
25
26
27
28
29
30
31
32







-
-
+
+







#import "OFException.h"

/*!
 * @brief An exception indicating changing to a directory failed
 */
@interface OFChangeDirectoryFailedException: OFException
{
	OFString *path;
	int errNo;
	OFString *_path;
	int _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif

Modified src/exceptions/OFChangeDirectoryFailedException.m from [ba07871883] to [a9860585f3].

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







-
-
+
+

-
-
+
+


-
+











-
-
+
+

-
+


-
-
+
+










-
+






-
-
+
+

-
-
-
+
+
+

-
+




-
+




-
+



#import "OFChangeDirectoryFailedException.h"
#import "OFString.h"

#import "common.h"

@implementation OFChangeDirectoryFailedException
+ (instancetype)exceptionWithClass: (Class)class_
			      path: (OFString*)path_
+ (instancetype)exceptionWithClass: (Class)class
			      path: (OFString*)path
{
	return [[[self alloc] initWithClass: class_
				       path: path_] autorelease];
	return [[[self alloc] initWithClass: class
				       path: path] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	   path: (OFString*)path_
- initWithClass: (Class)class
	   path: (OFString*)path
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		path  = [path_ copy];
		errNo = GET_ERRNO;
		_path  = [path copy];
		_errNo = GET_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[path release];
	[_path release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Failed to change to directory %@ in class %@! " ERRFMT, path,
	    inClass, ERRPARAM];
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to change to directory %@ in class %@! " ERRFMT, _path,
	    _inClass, ERRPARAM];

	return description;
	return _description;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(path, NO)
	OF_GETTER(_path, NO)
}
@end

Modified src/exceptions/OFChangeFileModeFailedException.h from [c2c327670a] to [ff2f6d8da0].

19
20
21
22
23
24
25
26
27
28



29
30
31
32
33
34
35
19
20
21
22
23
24
25



26
27
28
29
30
31
32
33
34
35







-
-
-
+
+
+







#import "OFException.h"

/*!
 * @brief An exception indicating that changing the mode of a file failed.
 */
@interface OFChangeFileModeFailedException: OFException
{
	OFString *path;
	mode_t mode;
	int errNo;
	OFString *_path;
	mode_t _mode;
	int _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) mode_t mode;
@property (readonly) int errNo;
#endif

Modified src/exceptions/OFChangeFileModeFailedException.m from [a59ee4c2b7] to [319db3107f].

20
21
22
23
24
25
26
27

28
29
30
31

32
33
34
35
36

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



51
52

53
54
55
56
57



58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76


77
78

79
80

81
82

83
84
85
86
87

88
89
90
91
92

93
94
95
96
97

98
99
20
21
22
23
24
25
26

27
28
29
30

31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47



48
49
50
51

52
53
54



55
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74


75
76
77

78
79

80
81

82
83
84
85
86

87
88
89
90
91

92
93
94
95
96

97
98
99







-
+



-
+




-
+











-
-
-
+
+
+

-
+


-
-
-
+
+
+










-
+






-
-
+
+

-
+

-
+

-
+




-
+




-
+




-
+



#import "OFChangeFileModeFailedException.h"
#import "OFString.h"

#import "common.h"

@implementation OFChangeFileModeFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			      path: (OFString*)path
			      mode: (mode_t)mode
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				       path: path
				       mode: mode] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	   path: (OFString*)path_
	   mode: (mode_t)mode_
- initWithClass: (Class)class
	   path: (OFString*)path
	   mode: (mode_t)mode
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		path  = [path_ copy];
		mode  = mode_;
		errNo = GET_ERRNO;
		_path  = [path copy];
		_mode  = mode;
		_errNo = GET_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[path release];
	[_path release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to change mode for file %@ to %d in class %@! " ERRFMT,
	    path, mode, inClass, ERRPARAM];
	    _path, _mode, _inClass, ERRPARAM];

	return description;
	return _description;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(path, NO)
	OF_GETTER(_path, NO)
}

- (mode_t)mode
{
	return mode;
	return _mode;
}
@end

Modified src/exceptions/OFChangeFileOwnerFailedException.h from [ac5a1c7a55] to [c53d35405c].

18
19
20
21
22
23
24
25

26
27
28

29
30
31
32

33
34
35
36
37
38
39
40
41
18
19
20
21
22
23
24

25



26
27
28
29

30


31
32
33
34
35
36
37







-
+
-
-
-
+



-
+
-
-








#ifndef _WIN32
/*!
 * @brief An exception indicating that changing the owner of a file failed.
 */
@interface OFChangeFileOwnerFailedException: OFException
{
	OFString *path;
	OFString *_path, *_owner, *_group;
	OFString *owner;
	OFString *group;
	int errNo;
	int _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly, copy, nonatomic) OFString *path, *owner, *group;
@property (readonly, copy, nonatomic) OFString *owner;
@property (readonly, copy, nonatomic) OFString *group;
@property (readonly) int errNo;
#endif

/*!
 * @brief Creates a new, autoreleased change file owner failed exception.
 *
 * @param class_ The class of the object which caused the exception

Modified src/exceptions/OFChangeFileOwnerFailedException.m from [7ba6b6f15a] to [0b00f53cf5].

21
22
23
24
25
26
27
28

29
30
31
32
33

34
35
36
37
38
39

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




55
56

57
58
59
60
61
62




63
64
65
66
67
68
69
70
71
72
73
74
75



76
77
78
79
80
81
82
83


84
85
86


87
88
89
90



91
92

93
94

95
96

97
98

99
100
101
102
103

104
105
106
107
108

109
110
111
112
113

114
115
116
117
118

119
120
121
21
22
23
24
25
26
27

28
29
30
31
32

33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50




51
52
53
54
55

56
57
58




59
60
61
62
63
64
65
66
67
68
69
70
71
72



73
74
75
76
77
78
79
80
81


82
83
84


85
86
87



88
89
90
91

92
93

94
95

96
97

98
99
100
101
102

103
104
105
106
107

108
109
110
111
112

113
114
115
116
117

118
119
120
121







-
+




-
+





-
+











-
-
-
-
+
+
+
+

-
+


-
-
-
-
+
+
+
+










-
-
-
+
+
+






-
-
+
+

-
-
+
+

-
-
-
+
+
+

-
+

-
+

-
+

-
+




-
+




-
+




-
+




-
+



#import "OFChangeFileOwnerFailedException.h"
#import "OFString.h"

#import "common.h"

#ifndef _WIN32
@implementation OFChangeFileOwnerFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			      path: (OFString*)path
			     owner: (OFString*)owner
			     group: (OFString*)group
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				       path: path
				      owner: owner
				      group: group] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	   path: (OFString*)path_
	  owner: (OFString*)owner_
	  group: (OFString*)group_
- initWithClass: (Class)class
	   path: (OFString*)path
	  owner: (OFString*)owner
	  group: (OFString*)group
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		path  = [path_ copy];
		owner = [owner_ copy];
		group = [group_ copy];
		errNo = GET_ERRNO;
		_path  = [path copy];
		_owner = [owner copy];
		_group = [group copy];
		_errNo = GET_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[path release];
	[owner release];
	[group release];
	[_path release];
	[_owner release];
	[_group release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	if (group == nil)
		description = [[OFString alloc] initWithFormat:
	if (_group == nil)
		_description = [[OFString alloc] initWithFormat:
		    @"Failed to change owner for file %@ to %@ in class %@! "
		    ERRFMT, path, owner, inClass, ERRPARAM];
	else if (owner == nil)
		description = [[OFString alloc] initWithFormat:
		    ERRFMT, _path, _owner, _inClass, ERRPARAM];
	else if (_owner == nil)
		_description = [[OFString alloc] initWithFormat:
		    @"Failed to change group for file %@ to %@ in class %@! "
		    ERRFMT, path, group, inClass, ERRPARAM];
		    ERRFMT, _path, _group, _inClass, ERRPARAM];
	else
		description = [[OFString alloc] initWithFormat:
		_description = [[OFString alloc] initWithFormat:
		    @"Failed to change owner for file %@ to %@:%@ in class %@! "
		    ERRFMT, path, owner, group, inClass, ERRPARAM];
		    ERRFMT, _path, _owner, _group, _inClass, ERRPARAM];

	return description;
	return _description;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(path, NO)
	OF_GETTER(_path, NO)
}

- (OFString*)owner
{
	OF_GETTER(owner, NO)
	OF_GETTER(_owner, NO)
}

- (OFString*)group
{
	OF_GETTER(group, NO)
	OF_GETTER(_group, NO)
}
@end
#endif

Modified src/exceptions/OFConditionBroadcastFailedException.h from [37863f05fb] to [8280acbac2].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







@class OFCondition;

/*!
 * @brief An exception indicating broadcasting a condition failed.
 */
@interface OFConditionBroadcastFailedException: OFException
{
	OFCondition *condition;
	OFCondition *_condition;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif

/*!

Modified src/exceptions/OFConditionBroadcastFailedException.m from [239bfd4ef8] to [cc9bbab33a].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
-
+
+

-
+




-
+


#include <stdlib.h>

#import "OFConditionBroadcastFailedException.h"
#import "OFString.h"
#import "OFCondition.h"

@implementation OFConditionBroadcastFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			 condition: (OFCondition*)condition
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				  condition: condition] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
      condition: (OFCondition*)condition_
- initWithClass: (Class)class
      condition: (OFCondition*)condition
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	condition = [condition_ retain];
	_condition = [condition retain];

	return self;
}

- (void)dealloc
{
	[condition release];
	[_condition release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Broadcasting a condition of type %@ failed!", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"Broadcasting a condition of type %@ failed!", _inClass];

	return description;
	return _description;
}

- (OFCondition*)condition
{
	OF_GETTER(condition, NO)
	OF_GETTER(_condition, NO)
}
@end

Modified src/exceptions/OFConditionSignalFailedException.h from [1882a0cdda] to [ce8cf52835].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







@class OFCondition;

/*!
 * @brief An exception indicating signaling a condition failed.
 */
@interface OFConditionSignalFailedException: OFException
{
	OFCondition *condition;
	OFCondition *_condition;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif

/*!

Modified src/exceptions/OFConditionSignalFailedException.m from [e9f398f7d6] to [3da88ce5d9].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
-
+
+

-
+




-
+


#include <stdlib.h>

#import "OFConditionSignalFailedException.h"
#import "OFString.h"
#import "OFCondition.h"

@implementation OFConditionSignalFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			 condition: (OFCondition*)condition
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				  condition: condition] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
      condition: (OFCondition*)condition_
- initWithClass: (Class)class
      condition: (OFCondition*)condition
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	condition = [condition_ retain];
	_condition = [condition retain];

	return self;
}

- (void)dealloc
{
	[condition release];
	[_condition release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Signaling a condition of type %@ failed!", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"Signaling a condition of type %@ failed!", _inClass];

	return description;
	return _description;
}

- (OFCondition*)condition
{
	OF_GETTER(condition, NO)
	OF_GETTER(_condition, NO)
}
@end

Modified src/exceptions/OFConditionStillWaitingException.h from [0abdd32fbd] to [fdfddc2862].

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34







-
+








/*!
 * @brief An exception indicating that a thread is still waiting for a
 *	  condition.
 */
@interface OFConditionStillWaitingException: OFException
{
	OFCondition *condition;
	OFCondition *_condition;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif

/*!

Modified src/exceptions/OFConditionStillWaitingException.m from [c432acb363] to [ccf984394c].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
+

-
+

-
+




-
+


#include <stdlib.h>

#import "OFConditionStillWaitingException.h"
#import "OFString.h"
#import "OFCondition.h"

@implementation OFConditionStillWaitingException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			 condition: (OFCondition*)condition
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				  condition: condition] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
      condition: (OFCondition*)condition_
- initWithClass: (Class)class
      condition: (OFCondition*)condition
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	condition = [condition_ retain];
	_condition = [condition retain];

	return self;
}

- (void)dealloc
{
	[condition release];
	[_condition release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Deallocation of a condition of type %@ was tried, even though a "
	    @"thread was still waiting for it!", inClass];
	    @"thread was still waiting for it!", _inClass];

	return description;
	return _description;
}

- (OFCondition*)condition
{
	OF_GETTER(condition, NO)
	OF_GETTER(_condition, NO)
}
@end

Modified src/exceptions/OFConditionWaitFailedException.h from [1446fc3245] to [c95a31d0d6].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







@class OFCondition;

/*!
 * @brief An exception indicating waiting for a condition failed.
 */
@interface OFConditionWaitFailedException: OFException
{
	OFCondition *condition;
	OFCondition *_condition;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif

/*!

Modified src/exceptions/OFConditionWaitFailedException.m from [1c3c12a3c1] to [8bbc25a706].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
-
+
+

-
+




-
+


#include <stdlib.h>

#import "OFConditionWaitFailedException.h"
#import "OFString.h"
#import "OFCondition.h"

@implementation OFConditionWaitFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			 condition: (OFCondition*)condition
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				  condition: condition] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
      condition: (OFCondition*)condition_
- initWithClass: (Class)class
      condition: (OFCondition*)condition
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	condition = [condition_ retain];
	_condition = [condition retain];

	return self;
}

- (void)dealloc
{
	[condition release];
	[_condition release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Waiting for a condition of type %@ failed!", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"Waiting for a condition of type %@ failed!", _inClass];

	return description;
	return _description;
}

- (OFCondition*)condition
{
	OF_GETTER(condition, NO)
	OF_GETTER(_condition, NO)
}
@end

Modified src/exceptions/OFConnectionFailedException.h from [98696826d6] to [6e0a8c3716].

19
20
21
22
23
24
25
26
27
28
29




30
31
32
33
34
35
36
19
20
21
22
23
24
25




26
27
28
29
30
31
32
33
34
35
36







-
-
-
-
+
+
+
+







@class OFTCPSocket;

/*!
 * @brief An exception indicating that a connection could not be established.
 */
@interface OFConnectionFailedException: OFException
{
	OFTCPSocket *socket;
	OFString    *host;
	uint16_t    port;
	int	    errNo;
	OFTCPSocket *_socket;
	OFString    *_host;
	uint16_t    _port;
	int	    _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly, copy, nonatomic) OFString *host;
@property (readonly) uint16_t port;
@property (readonly) int errNo;

Modified src/exceptions/OFConnectionFailedException.m from [122bf660e2] to [ed77afb6a3].

21
22
23
24
25
26
27
28

29
30
31
32
33

34
35
36
37
38
39

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




55
56

57
58
59
60
61
62




63
64
65
66
67
68
69
70
71
72
73
74


75
76
77
78
79
80
81
82


83
84

85
86


87
88

89
90
91
92
93

94
95
96
97
98

99
100
101
102
103

104
105
106
107
108

109
110
21
22
23
24
25
26
27

28
29
30
31
32

33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50




51
52
53
54
55

56
57
58




59
60
61
62
63
64
65
66
67
68
69
70
71
72


73
74
75
76
77
78
79
80


81
82
83

84
85

86
87
88

89
90
91
92
93

94
95
96
97
98

99
100
101
102
103

104
105
106
107
108

109
110
111







-
+




-
+





-
+











-
-
-
-
+
+
+
+

-
+


-
-
-
-
+
+
+
+










-
-
+
+






-
-
+
+

-
+

-
+
+

-
+




-
+




-
+




-
+




-
+


#import "OFConnectionFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"

#import "common.h"

@implementation OFConnectionFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    socket: (OFTCPSocket*)socket
			      host: (OFString*)host
			      port: (uint16_t)port
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     socket: socket
				       host: host
				       port: port] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 socket: (OFTCPSocket*)socket_
	   host: (OFString*)host_
	   port: (uint16_t)port_
- initWithClass: (Class)class
	 socket: (OFTCPSocket*)socket
	   host: (OFString*)host
	   port: (uint16_t)port
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		socket = [socket_ retain];
		host   = [host_ copy];
		port   = port_;
		errNo  = GET_SOCK_ERRNO;
		_socket = [socket retain];
		_host   = [host copy];
		_port   = port;
		_errNo  = GET_SOCK_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[socket release];
	[host release];
	[_socket release];
	[_host release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"A connection to %@ on port %" @PRIu16 @" could not be "
	    @"established in class %@! " ERRFMT, host, port, inClass, ERRPARAM];
	    @"established in class %@! " ERRFMT, _host, _port, _inClass,
	    ERRPARAM];

	return description;
	return _description;
}

- (OFTCPSocket*)socket
{
	OF_GETTER(socket, NO)
	OF_GETTER(_socket, NO)
}

- (OFString*)host
{
	OF_GETTER(host, NO)
	OF_GETTER(_host, NO)
}

- (uint16_t)port
{
	return port;
	return _port;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}
@end

Modified src/exceptions/OFCopyFileFailedException.h from [999eac0ccf] to [8e2325479f].

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
57


58
59
60
61
62
63
64
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
57
58
59
60
61
62
63







-
-
-
+
+












-
-
+
+



-
-
+
+





-
-
+
+



-
-
+
+







#import "OFException.h"

/*!
 * @brief An exception indicating that copying a file failed.
 */
@interface OFCopyFileFailedException: OFException
{
	OFString *sourcePath;
	OFString *destinationPath;
	int errNo;
	OFString *_sourcePath, *_destinationPath;
	int _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath;
@property (readonly, copy, nonatomic) OFString *destinationPath;
@property (readonly) int errNo;
#endif

/*!
 * @brief Creates a new, autoreleased copy file failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param source The original path
 * @param destination The new path
 * @param sourcePath The original path
 * @param destinationPath The new path
 * @return A new, autoreleased copy file failed exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
			sourcePath: (OFString*)source
		   destinationPath: (OFString*)destination;
			sourcePath: (OFString*)sourcePath
		   destinationPath: (OFString*)destinationPath;

/*!
 * @brief Initializes an already allocated copy file failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param source The original path
 * @param destination The new path
 * @param sourcePath The original path
 * @param destinationPath The new path
 * @return An initialized copy file failed exception
 */
-   initWithClass: (Class)class_
       sourcePath: (OFString*)source
  destinationPath: (OFString*)destination;
       sourcePath: (OFString*)sourcePath
  destinationPath: (OFString*)destinationPath;

/*!
 * @brief Returns the errno from when the exception was created.
 *
 * @return The errno from when the exception was created
 */
- (int)errNo;

Modified src/exceptions/OFCopyFileFailedException.m from [c7d13f40bb] to [c8f8b1a133].

20
21
22
23
24
25
26
27
28
29



30
31
32
33



34
35
36

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



51
52

53
54
55
56
57



58
59
60
61
62
63
64
65
66
67
68
69


70
71
72
73
74
75
76
77


78
79

80
81

82
83

84
85
86
87
88

89
90
91
92
93

94
95
96
97
98

99
100
20
21
22
23
24
25
26



27
28
29
30



31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47



48
49
50
51

52
53
54



55
56
57
58
59
60
61
62
63
64
65
66
67


68
69
70
71
72
73
74
75


76
77
78

79
80

81
82

83
84
85
86
87

88
89
90
91
92

93
94
95
96
97

98
99
100







-
-
-
+
+
+

-
-
-
+
+
+


-
+











-
-
-
+
+
+

-
+


-
-
-
+
+
+










-
-
+
+






-
-
+
+

-
+

-
+

-
+




-
+




-
+




-
+



#import "OFCopyFileFailedException.h"
#import "OFString.h"

#import "common.h"

@implementation OFCopyFileFailedException
+ (instancetype)exceptionWithClass: (Class)class_
			sourcePath: (OFString*)source
		   destinationPath: (OFString*)destination
+ (instancetype)exceptionWithClass: (Class)class
			sourcePath: (OFString*)sourcePath
		   destinationPath: (OFString*)destinationPath
{
	return [[[self alloc] initWithClass: class_
				 sourcePath: source
			    destinationPath: destination] autorelease];
	return [[[self alloc] initWithClass: class
				 sourcePath: sourcePath
			    destinationPath: destinationPath] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

-   initWithClass: (Class)class_
       sourcePath: (OFString*)source
  destinationPath: (OFString*)destination
-   initWithClass: (Class)class
       sourcePath: (OFString*)sourcePath
  destinationPath: (OFString*)destinationPath
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		sourcePath = [source copy];
		destinationPath = [destination copy];
		errNo = GET_ERRNO;
		_sourcePath = [sourcePath copy];
		_destinationPath = [destinationPath copy];
		_errNo = GET_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[sourcePath release];
	[destinationPath release];
	[_sourcePath release];
	[_destinationPath release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to copy file %@ to %@ in class %@! " ERRFMT,
	    sourcePath, destinationPath, inClass, ERRPARAM];
	    _sourcePath, _destinationPath, _inClass, ERRPARAM];

	return description;
	return _description;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}

- (OFString*)sourcePath
{
	OF_GETTER(sourcePath, NO)
	OF_GETTER(_sourcePath, NO)
}

- (OFString*)destinationPath
{
	OF_GETTER(destinationPath, NO)
	OF_GETTER(_destinationPath, NO)
}
@end

Modified src/exceptions/OFCreateDirectoryFailedException.h from [a59eadf735] to [34b0a07f1e].

17
18
19
20
21
22
23
24
25


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


24
25
26
27
28
29
30
31
32







-
-
+
+







#import "OFException.h"

/*!
 * @brief An exception indicating a directory couldn't be created.
 */
@interface OFCreateDirectoryFailedException: OFException
{
	OFString *path;
	int errNo;
	OFString *_path;
	int _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif

Modified src/exceptions/OFCreateDirectoryFailedException.m from [2a62eb5d8d] to [029fb950d4].

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







-
-
+
+

-
-
+
+


-
+











-
-
+
+

-
+


-
-
+
+










-
+






-
-
+
+

-
-
-
+
+
+

-
+




-
+




-
+



#import "OFCreateDirectoryFailedException.h"
#import "OFString.h"

#import "common.h"

@implementation OFCreateDirectoryFailedException
+ (instancetype)exceptionWithClass: (Class)class_
			      path: (OFString*)path_
+ (instancetype)exceptionWithClass: (Class)class
			      path: (OFString*)path
{
	return [[[self alloc] initWithClass: class_
				       path: path_] autorelease];
	return [[[self alloc] initWithClass: class
				       path: path] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	   path: (OFString*)path_
- initWithClass: (Class)class
	   path: (OFString*)path
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		path  = [path_ copy];
		errNo = GET_ERRNO;
		_path  = [path copy];
		_errNo = GET_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[path release];
	[_path release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Failed to create directory %@ in class %@! " ERRFMT, path,
	    inClass, ERRPARAM];
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to create directory %@ in class %@! " ERRFMT, _path,
	    _inClass, ERRPARAM];

	return description;
	return _description;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(path, NO)
	OF_GETTER(_path, NO)
}
@end

Modified src/exceptions/OFDeleteDirectoryFailedException.h from [ecc67ea15b] to [9ce6ca0f5f].

17
18
19
20
21
22
23
24
25


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


24
25
26
27
28
29
30
31
32







-
-
+
+







#import "OFException.h"

/*!
 * @brief An exception indicating that deleting a directory failed.
 */
@interface OFDeleteDirectoryFailedException: OFException
{
	OFString *path;
	int errNo;
	OFString *_path;
	int _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif

Modified src/exceptions/OFDeleteDirectoryFailedException.m from [c0c7391dfd] to [55773e30a9].

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







-
+


-
+



-
+











-
-
+
+

-
+


-
-
+
+










-
+






-
-
+
+

-
-
-
+
+
+

-
+




-
+




-
+



#import "OFDeleteDirectoryFailedException.h"
#import "OFString.h"

#import "common.h"

@implementation OFDeleteDirectoryFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			      path: (OFString*)path_
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				       path: path_] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	   path: (OFString*)path_
- initWithClass: (Class)class
	   path: (OFString*)path
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		path  = [path_ copy];
		errNo = GET_ERRNO;
		_path  = [path copy];
		_errNo = GET_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[path release];
	[_path release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Failed to delete directory %@ in class %@! " ERRFMT, path,
	    inClass, ERRPARAM];
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to delete directory %@ in class %@! " ERRFMT, _path,
	    _inClass, ERRPARAM];

	return description;
	return _description;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(path, NO)
	OF_GETTER(_path, NO)
}
@end

Modified src/exceptions/OFDeleteFileFailedException.h from [e97aa02e0b] to [ed836376b8].

17
18
19
20
21
22
23
24
25


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


24
25
26
27
28
29
30
31
32







-
-
+
+







#import "OFException.h"

/*!
 * @brief An exception indicating that deleting a file failed.
 */
@interface OFDeleteFileFailedException: OFException
{
	OFString *path;
	int errNo;
	OFString *_path;
	int _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif

Modified src/exceptions/OFDeleteFileFailedException.m from [688b15cb7d] to [65143331f2].

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







-
-
+
+

-
-
+
+


-
+











-
-
+
+

-
+


-
-
+
+










-
+






-
-
+
+

-
-
+
+


-
+




-
+




-
+



#import "OFDeleteFileFailedException.h"
#import "OFString.h"

#import "common.h"

@implementation OFDeleteFileFailedException
+ (instancetype)exceptionWithClass: (Class)class_
			      path: (OFString*)path_
+ (instancetype)exceptionWithClass: (Class)class
			      path: (OFString*)path
{
	return [[[self alloc] initWithClass: class_
				       path: path_] autorelease];
	return [[[self alloc] initWithClass: class
				       path: path] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	   path: (OFString*)path_
- initWithClass: (Class)class
	   path: (OFString*)path
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		path  = [path_ copy];
		errNo = GET_ERRNO;
		_path  = [path copy];
		_errNo = GET_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[path release];
	[_path release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Failed to delete file %@ in class %@! " ERRFMT, path, inClass,
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to delete file %@ in class %@! " ERRFMT, _path, _inClass,
	    ERRPARAM];

	return description;
	return _description;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(path, NO)
	OF_GETTER(_path, NO)
}
@end

Modified src/exceptions/OFEnumerationMutationException.h from [7938f605d2] to [878a08d7a2].

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 An exception indicating that a mutation was detected during
 *        enumeration.
 */
@interface OFEnumerationMutationException: OFException
{
	id object;
	id _object;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id object;
#endif

/*!

Modified src/exceptions/OFEnumerationMutationException.m from [1d37cda0c7] to [d10005f035].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
-
+
+

-
+




-
+



#import "OFEnumerationMutationException.h"
#import "OFString.h"

#import "common.h"

@implementation OFEnumerationMutationException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    object: (id)object
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     object: object] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 object: (id)object_
- initWithClass: (Class)class
	 object: (id)object
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	object = [object_ retain];
	_object = [object retain];

	return self;
}

- (void)dealloc
{
	[object release];
	[_object release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Object of class %@ was mutated during enumeration!", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"Object of class %@ was mutated during enumeration!", _inClass];

	return description;
	return _description;
}

- (id)object
{
	OF_GETTER(object, NO)
	OF_GETTER(_object, NO)
}
@end

Modified src/exceptions/OFException.h from [93f8f3dd32] to [0e7a48ed31].

22
23
24
25
26
27
28
29
30


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


29
30
31
32
33
34
35
36
37







-
-
+
+







 * @brief The base class for all exceptions in ObjFW
 *
 * The OFException class is the base class for all exceptions in ObjFW, except
 * the OFAllocFailedException.
 */
@interface OFException: OFObject
{
	Class inClass;
	OFString *description;
	Class _inClass;
	OFString *_description;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly) Class inClass;
#endif

/*!

Modified src/exceptions/OFException.m from [17d551971c] to [0dacb298b3].

18
19
20
21
22
23
24
25

26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46

47
48
49
50
51
52
53

54
55
56
57
58
59
60

61
62
63
64
65
66


67
68

69
70

71
72

73
74
18
19
20
21
22
23
24

25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45

46
47
48
49
50
51
52

53
54
55
56
57
58
59

60
61
62
63
64


65
66
67

68
69

70
71

72
73
74







-
+

-
+














-
+



-
+






-
+






-
+




-
-
+
+

-
+

-
+

-
+



#include <stdlib.h>

#import "OFException.h"
#import "OFString.h"

@implementation OFException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
{
	return [[[self alloc] initWithClass: class_] autorelease];
	return [[[self alloc] initWithClass: class] autorelease];
}

- init
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	self = [super init];

	inClass = class_;
	_inClass = class;

	return self;
}

- (void)dealloc
{
	[description release];
	[_description release];

	[super dealloc];
}

- (Class)inClass
{
	return inClass;
	return _inClass;
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"An exception of class %@ occurred in class %@!",
	    object_getClass(self), inClass];
	    object_getClass(self), _inClass];

	return description;
	return _description;
}
@end

Modified src/exceptions/OFHTTPRequestFailedException.h from [5db7e230ae] to [e63622a3c6].

20
21
22
23
24
25
26
27
28


29
30
31
32
33
34
35
20
21
22
23
24
25
26


27
28
29
30
31
32
33
34
35







-
-
+
+







@class OFHTTPRequestReply;

/*!
 * @brief An exception indicating that a HTTP request failed.
 */
@interface OFHTTPRequestFailedException: OFException
{
	OFHTTPRequest *request;
	OFHTTPRequestReply *reply;
	OFHTTPRequest *_request;
	OFHTTPRequestReply *_reply;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFHTTPRequest *request;
@property (readonly, retain, nonatomic) OFHTTPRequestReply *reply;
#endif

Modified src/exceptions/OFHTTPRequestFailedException.m from [c529841d84] to [6a16e70139].

23
24
25
26
27
28
29
30

31
32
33
34

35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51
52
53



54
55

56
57
58


59
60
61
62
63
64
65
66


67
68
69
70
71
72
73
74
75
76
77


78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93

94
95

96
97
98
99

100
101
102
103
104

105
106
107
108
109

110
111
23
24
25
26
27
28
29

30
31
32
33

34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50



51
52
53
54

55
56


57
58
59
60
61
62
63
64


65
66
67
68
69
70
71
72
73
74
75


76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94

95
96
97
98

99
100
101
102
103

104
105
106
107
108

109
110
111







-
+



-
+




-
+











-
-
-
+
+
+

-
+

-
-
+
+






-
-
+
+









-
-
+
+

-
+













-
+

-
+



-
+




-
+




-
+


#import "OFHTTPRequest.h"
#import "OFHTTPRequestReply.h"

#import "autorelease.h"
#import "common.h"

@implementation OFHTTPRequestFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			   request: (OFHTTPRequest*)request
			     reply: (OFHTTPRequestReply*)reply
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				    request: request
				      reply: reply] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	request: (OFHTTPRequest*)request_
	  reply: (OFHTTPRequestReply*)reply_
- initWithClass: (Class)class
	request: (OFHTTPRequest*)request
	  reply: (OFHTTPRequestReply*)reply
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	request = [request_ retain];
	reply = [reply_ retain];
	_request = [request retain];
	_reply = [reply retain];

	return self;
}

- (void)dealloc
{
	[request release];
	[reply release];
	[_request release];
	[_reply release];

	[super dealloc];
}

- (OFString*)description
{
	void *pool;
	const char *type = "(unknown)";

	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	switch ([request requestType]) {
	switch ([_request requestType]) {
	case OF_HTTP_REQUEST_TYPE_GET:
		type = "GET";
		break;
	case OF_HTTP_REQUEST_TYPE_HEAD:
		type = "HEAD";
		break;
	case OF_HTTP_REQUEST_TYPE_POST:
		type = "POST";
		break;
	}

	pool = objc_autoreleasePoolPush();

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"A HTTP %s request in class %@ with URL %@ failed with code %d",
	    type, inClass, [request URL], [reply statusCode]];
	    type, _inClass, [_request URL], [_reply statusCode]];

	objc_autoreleasePoolPop(pool);

	return description;
	return _description;
}

- (OFHTTPRequest*)request
{
	OF_GETTER(request, NO)
	OF_GETTER(_request, NO)
}

- (OFHTTPRequestReply*)reply
{
	OF_GETTER(reply, NO)
	OF_GETTER(_reply, NO)
}
@end

Modified src/exceptions/OFHashAlreadyCalculatedException.h from [9afa896f63] to [3c8cb83bb8].

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







-
+










-
+



-
+





-
+



-
+








@class OFHash;

/*!
 * @brief An exception indicating that the hash has already been calculated.
 */
@interface OFHashAlreadyCalculatedException: OFException
{
	OFHash *hashObject;
	OFHash *_hashObject;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFHash *hashObject;
#endif

/*!
 * @brief Creates a new, autoreleased hash already calculated exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param hash The hash which has already been calculated
 * @param hashObject The hash which has already been calculated
 * @return A new, autoreleased hash already calculated exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
			      hash: (OFHash*)hash;
			      hash: (OFHash*)hashObject;

/*!
 * @brief Initializes an already allocated hash already calculated exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param hash The hash which has already been calculated
 * @param hashObject The hash which has already been calculated
 * @return An initialized hash already calculated exception
 */
- initWithClass: (Class)class_
	   hash: (OFHash*)hash;
	   hash: (OFHash*)hashObject;

/*!
 * @brief Returns the hash which has already been calculated.
 *
 * @return The hash which has already been calculated
 */
- (OFHash*)hashObject;
@end

Modified src/exceptions/OFHashAlreadyCalculatedException.m from [45da32b1b3] to [1c6147719c].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
+

-
+

-
+




-
+


#import "OFHashAlreadyCalculatedException.h"
#import "OFString.h"
#import "OFHash.h"

#import "common.h"

@implementation OFHashAlreadyCalculatedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			      hash: (OFHash*)hash
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				       hash: hash] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	   hash: (OFHash*)hash
- initWithClass: (Class)class
	   hash: (OFHash*)hashObject
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	hashObject = [hash retain];
	_hashObject = [hashObject retain];

	return self;
}

- (void)dealloc
{
	[hashObject release];
	[_hashObject release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"The hash has already been calculated in class %@ and thus no new "
	    @"data can be added", inClass];
	    @"data can be added", _inClass];

	return description;
	return _description;
}

- (OFHash*)hashObject
{
	OF_GETTER(hashObject, NO)
	OF_GETTER(_hashObject, NO)
}
@end

Modified src/exceptions/OFInitializationFailedException.m from [c6c6b9a8bb] to [5f9ac7b48a].

18
19
20
21
22
23
24
25
26


27
28
29


30
31

32
33
18
19
20
21
22
23
24


25
26
27


28
29
30

31
32
33







-
-
+
+

-
-
+
+

-
+



#import "OFInitializationFailedException.h"
#import "OFString.h"

@implementation OFInitializationFailedException
- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Initialization failed for or in class %@!", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"Initialization failed for or in class %@!", _inClass];

	return description;
	return _description;
}
@end

Modified src/exceptions/OFInvalidArgumentException.h from [aeaa01bea3] to [6c06e4e596].

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 "OFException.h"

/*!
 * @brief An exception indicating that the argument is invalid for this method.
 */
@interface OFInvalidArgumentException: OFException
{
	SEL selector;
	SEL _selector;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly) SEL selector;
#endif

/*!

Modified src/exceptions/OFInvalidArgumentException.m from [378595486c] to [98b7296261].

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







-
-
+
+

-
-
+
+


-
+











-
-
+
+

-
+

-
+






-
-
+
+

-
+

-
+

-
+




-
+



#import "OFInvalidArgumentException.h"
#import "OFString.h"

#import "common.h"

@implementation OFInvalidArgumentException
+ (instancetype)exceptionWithClass: (Class)class_
			  selector: (SEL)selector_
+ (instancetype)exceptionWithClass: (Class)class
			  selector: (SEL)selector
{
	return [[[self alloc] initWithClass: class_
				   selector: selector_] autorelease];
	return [[[self alloc] initWithClass: class
				   selector: selector] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
       selector: (SEL)selector_
- initWithClass: (Class)class
       selector: (SEL)selector
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	selector = selector_;
	_selector = selector;

	return self;
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"The argument or receiver for method %s of class %@ is invalid!",
	    sel_getName(selector), inClass];
	    sel_getName(_selector), _inClass];

	return description;
	return _description;
}

- (SEL)selector
{
	return selector;
	return _selector;
}
@end

Modified src/exceptions/OFInvalidEncodingException.m from [65d6f47aba] to [890bb48a2b].

18
19
20
21
22
23
24
25
26


27
28
29


30
31

32
33
18
19
20
21
22
23
24


25
26
27


28
29
30

31
32
33







-
-
+
+

-
-
+
+

-
+



#import "OFInvalidEncodingException.h"
#import "OFString.h"

@implementation OFInvalidEncodingException
- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"The encoding is invalid for class %@!", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"The encoding is invalid for class %@!", _inClass];

	return description;
	return _description;
}
@end

Modified src/exceptions/OFInvalidFormatException.m from [01a1973b97] to [7b073a6102].

18
19
20
21
22
23
24
25
26


27
28
29


30
31

32
33
18
19
20
21
22
23
24


25
26
27


28
29
30

31
32
33







-
-
+
+

-
-
+
+

-
+



#import "OFInvalidFormatException.h"
#import "OFString.h"

@implementation OFInvalidFormatException
- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"The format is invalid for class %@!", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"The format is invalid for class %@!", _inClass];

	return description;
	return _description;
}
@end

Modified src/exceptions/OFInvalidJSONException.h from [15c9f96f98] to [e45d7a3ec9].

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 "OFException.h"

/*!
 * @brief An exception indicating a JSON representation is invalid.
 */
@interface OFInvalidJSONException: OFException
{
	size_t line;
	size_t _line;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly) size_t line;
#endif

/*!

Modified src/exceptions/OFInvalidJSONException.m from [c2b4bc6b4c] to [477577db36].

18
19
20
21
22
23
24
25

26
27
28

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


46
47

48
49

50
51
52
53
54
55
56
57


58
59

60
61

62
63

64
65
66
67
68

69
70
18
19
20
21
22
23
24

25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43


44
45
46

47
48

49
50
51
52
53
54
55


56
57
58

59
60

61
62

63
64
65
66
67

68
69
70







-
+


-
+















-
-
+
+

-
+

-
+






-
-
+
+

-
+

-
+

-
+




-
+



#include <stdlib.h>

#import "OFInvalidJSONException.h"
#import "OFString.h"

@implementation OFInvalidJSONException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			      line: (size_t)line
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				       line: line] autorelease];
}

- init
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	   line: (size_t)line_
- initWithClass: (Class)class
	   line: (size_t)line
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	line = line_;
	_line = line;

	return self;
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"The JSON representation class %@ tried to parse is invalid in "
	    @"line %zd!", inClass, line];
	    @"line %zd!", _inClass, _line];

	return description;
	return _description;
}

- (size_t)line
{
	return line;
	return _line;
}
@end

Modified src/exceptions/OFInvalidServerReplyException.m from [6f32896ab7] to [33d6295197].

18
19
20
21
22
23
24
25
26


27
28
29


30
31

32
33
18
19
20
21
22
23
24


25
26
27


28
29
30

31
32
33







-
-
+
+

-
-
+
+

-
+



#import "OFInvalidServerReplyException.h"
#import "OFString.h"

@implementation OFInvalidServerReplyException
- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Got an invalid reply from the server in class %@", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"Got an invalid reply from the server in class %@", _inClass];

	return description;
	return _description;
}
@end

Modified src/exceptions/OFLinkFailedException.h from [dd1a6acbbb] to [2ff6890222].

18
19
20
21
22
23
24
25
26
27


28
29
30
31

32
33
34
35
36
37
38
39
40
41


42
43
44
45
46


47
48
49
50
51
52
53


54
55
56
57
58


59
60
61
62
63
64
65
18
19
20
21
22
23
24



25
26
27
28
29

30

31
32
33
34
35
36
37


38
39
40
41
42


43
44
45
46
47
48
49


50
51
52
53
54


55
56
57
58
59
60
61
62
63







-
-
-
+
+



-
+
-







-
-
+
+



-
-
+
+





-
-
+
+



-
-
+
+








#ifndef _WIN32
/*!
 * @brief An exception indicating that creating a link failed.
 */
@interface OFLinkFailedException: OFException
{
	OFString *sourcePath;
	OFString *destinationPath;
	int errNo;
	OFString *_sourcePath, *_destinationPath;
	int _errNo;
}

# ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath;
@property (readonly, copy, nonatomic) OFString *sourcePath, *destinationPath;
@property (readonly, copy, nonatomic) OFString *destinationPath;
@property (readonly) int errNo;
# endif

/*!
 * @brief Creates a new, autoreleased link failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param source The source for the link
 * @param destination The destination for the link
 * @param sourcePath The source for the link
 * @param destinationPath The destination for the link
 * @return A new, autoreleased link failed exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
			sourcePath: (OFString*)source
		   destinationPath: (OFString*)destination;
			sourcePath: (OFString*)sourcePath
		   destinationPath: (OFString*)destinationPath;

/*!
 * @brief Initializes an already allocated link failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param source The source for the link
 * @param destination The destination for the link
 * @param sourcePath The source for the link
 * @param destinationPath The destination for the link
 * @return An initialized link failed exception
 */
-   initWithClass: (Class)class_
       sourcePath: (OFString*)source
  destinationPath: (OFString*)destination;
       sourcePath: (OFString*)sourcePath
  destinationPath: (OFString*)destinationPath;

/*!
 * @brief Returns the errno from when the exception was created.
 *
 * @return The errno from when the exception was created
 */
- (int)errNo;

Modified src/exceptions/OFLinkFailedException.m from [358646961f] to [f22db317c8].

21
22
23
24
25
26
27
28
29
30



31
32
33
34



35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51



52
53

54
55
56
57
58



59
60
61
62
63
64
65
66
67
68
69
70


71
72
73
74
75
76
77
78


79
80
81
82



83
84

85
86
87
88
89

90
91
92
93
94

95
96
97
98
99

100
101
102
21
22
23
24
25
26
27



28
29
30
31



32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48



49
50
51
52

53
54
55



56
57
58
59
60
61
62
63
64
65
66
67
68


69
70
71
72
73
74
75
76


77
78
79



80
81
82
83

84
85
86
87
88

89
90
91
92
93

94
95
96
97
98

99
100
101
102







-
-
-
+
+
+

-
-
-
+
+
+


-
+











-
-
-
+
+
+

-
+


-
-
-
+
+
+










-
-
+
+






-
-
+
+

-
-
-
+
+
+

-
+




-
+




-
+




-
+



#import "OFLinkFailedException.h"
#import "OFString.h"

#import "common.h"

#ifndef _WIN32
@implementation OFLinkFailedException
+ (instancetype)exceptionWithClass: (Class)class_
			sourcePath: (OFString*)source
		   destinationPath: (OFString*)destination
+ (instancetype)exceptionWithClass: (Class)class
			sourcePath: (OFString*)sourcePath
		   destinationPath: (OFString*)destinationPath
{
	return [[[self alloc] initWithClass: class_
				 sourcePath: source
			    destinationPath: destination] autorelease];
	return [[[self alloc] initWithClass: class
				 sourcePath: sourcePath
			    destinationPath: destinationPath] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

-   initWithClass: (Class)class_
       sourcePath: (OFString*)source
  destinationPath: (OFString*)destination
-   initWithClass: (Class)class
       sourcePath: (OFString*)sourcePath
  destinationPath: (OFString*)destinationPath
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		sourcePath = [source copy];
		destinationPath = [destination copy];
		errNo = GET_ERRNO;
		_sourcePath = [sourcePath copy];
		_destinationPath = [destinationPath copy];
		_errNo = GET_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[sourcePath release];
	[destinationPath release];
	[_sourcePath release];
	[_destinationPath release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Failed to link file %@ to %@ in class %@! " ERRFMT, sourcePath,
	    destinationPath, inClass, ERRPARAM];
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to link file %@ to %@ in class %@! " ERRFMT, _sourcePath,
	    _destinationPath, _inClass, ERRPARAM];

	return description;
	return _description;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}

- (OFString*)sourcePath
{
	OF_GETTER(sourcePath, NO)
	OF_GETTER(_sourcePath, NO)
}

- (OFString*)destinationPath
{
	OF_GETTER(destinationPath, NO)
	OF_GETTER(_destinationPath, NO)
}
@end
#endif

Modified src/exceptions/OFListenFailedException.h from [821019a0e7] to [9a332b8a67].

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







-
-
+
+
-




-
+
-







-
+




-
+






-
+




-
+







@class OFTCPSocket;

/*!
 * @brief An exception indicating that listening on the socket failed.
 */
@interface OFListenFailedException: OFException
{
	OFTCPSocket *socket;
	int	    backLog;
	OFTCPSocket *_socket;
	int _backLog, _errNo;
	int	    errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly) int backLog;
@property (readonly) int backLog, errNo;
@property (readonly) int errNo;
#endif

/*!
 * @brief Creates a new, autoreleased listen failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param socket The socket which failed to listen
 * @param backlog The requested size of the back log
 * @param backLog The requested size of the back log
 * @return A new, autoreleased listen failed exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
			    socket: (OFTCPSocket*)socket
			   backLog: (int)backlog;
			   backLog: (int)backLog;

/*!
 * @brief Initializes an already allocated listen failed exception
 *
 * @param class_ The class of the object which caused the exception
 * @param socket The socket which failed to listen
 * @param backlog The requested size of the back log
 * @param backLog The requested size of the back log
 * @return An initialized listen failed exception
 */
- initWithClass: (Class)class_
	 socket: (OFTCPSocket*)socket
	backLog: (int)backlog;
	backLog: (int)backLog;

/*!
 * @brief Returns the socket which failed to listen.
 *
 * @return The socket which failed to listen
 */
- (OFTCPSocket*)socket;

Modified src/exceptions/OFListenFailedException.m from [8bcf2672cd] to [df82ad09d2].

21
22
23
24
25
26
27
28

29
30

31
32

33
34

35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51



52
53

54
55
56
57



58
59
60
61
62
63
64

65
66
67
68
69
70
71
72


73
74

75
76

77
78

79
80
81
82
83

84
85
86
87
88

89
90
91
92
93

94
95
21
22
23
24
25
26
27

28
29

30
31

32
33

34
35
36

37
38
39
40
41
42
43
44
45
46
47
48



49
50
51
52

53
54



55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70


71
72
73

74
75

76
77

78
79
80
81
82

83
84
85
86
87

88
89
90
91
92

93
94
95







-
+

-
+

-
+

-
+


-
+











-
-
-
+
+
+

-
+

-
-
-
+
+
+






-
+






-
-
+
+

-
+

-
+

-
+




-
+




-
+




-
+


#import "OFListenFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"

#import "common.h"

@implementation OFListenFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    socket: (OFTCPSocket*)socket
			   backLog: (int)backlog
			   backLog: (int)backLog
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     socket: socket
				    backLog: backlog] autorelease];
				    backLog: backLog] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 socket: (OFTCPSocket*)socket_
	backLog: (int)backlog
- initWithClass: (Class)class
	 socket: (OFTCPSocket*)socket
	backLog: (int)backLog
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	socket = [socket_ retain];
	backLog = backlog;
	errNo = GET_SOCK_ERRNO;
	_socket  = [socket retain];
	_backLog = backLog;
	_errNo   = GET_SOCK_ERRNO;

	return self;
}

- (void)dealloc
{
	[socket release];
	[_socket release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to listen in socket of type %@ with a back log of %d! "
	    ERRFMT, inClass, backLog, ERRPARAM];
	    ERRFMT, _inClass, _backLog, ERRPARAM];

	return description;
	return _description;
}

- (OFTCPSocket*)socket
{
	OF_GETTER(socket, NO)
	OF_GETTER(_socket, NO)
}

- (int)backLog
{
	return backLog;
	return _backLog;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}
@end

Modified src/exceptions/OFLockFailedException.h from [188f78e407] to [2b07e05b3e].

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







-
+







#import "OFLocking.h"

/*!
 * @brief An exception indicating that locking a lock failed.
 */
@interface OFLockFailedException: OFException
{
	id <OFLocking> lock;
	id <OFLocking> _lock;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id <OFLocking> lock;
#endif

/*!

Modified src/exceptions/OFLockFailedException.m from [1ba4665169] to [71c95c97b9].

18
19
20
21
22
23
24
25

26
27
28

29
30
31
32
33


34
35

36
37

38
39
40
41
42
43
44

45
46
47
48
49
50
51
52


53
54

55
56

57
58

59
60
61
62
63

64
65
18
19
20
21
22
23
24

25
26
27

28
29
30
31


32
33
34

35
36

37
38
39
40
41
42
43

44
45
46
47
48
49
50


51
52
53

54
55

56
57

58
59
60
61
62

63
64
65







-
+


-
+



-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
+

-
+

-
+




-
+



#import "OFLockFailedException.h"
#import "OFString.h"

#import "macros.h"

@implementation OFLockFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			      lock: (id <OFLocking>)lock
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				       lock: lock] autorelease];
}

- initWithClass: (Class)class_
	   lock: (id <OFLocking>)lock_
- initWithClass: (Class)class
	   lock: (id <OFLocking>)lock
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	lock = [lock_ retain];
	_lock = [lock retain];

	return self;
}

- (void)dealloc
{
	[lock release];
	[_lock release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"A lock of type %@ could not be locked in class %@!",
	    [(id)lock className], inClass];
	    [_lock class], _inClass];

	return description;
	return _description;
}

- (id <OFLocking>)lock
{
	OF_GETTER(lock, NO)
	OF_GETTER(_lock, NO)
}
@end

Modified src/exceptions/OFMalformedXMLException.h from [3ab544f3ad] to [d4ce063be2].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







@class OFXMLParser;

/*!
 * @brief An exception indicating that a parser encountered malformed XML.
 */
@interface OFMalformedXMLException: OFException
{
	OFXMLParser *parser;
	OFXMLParser *_parser;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFXMLParser *parser;
#endif

/*!

Modified src/exceptions/OFMalformedXMLException.m from [fdeb42d350] to [92f13cee04].

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







-
+


-
+



-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
-
-
-
+
+
+
+

-
+

-
+




-
+


#import "OFMalformedXMLException.h"
#import "OFString.h"
#import "OFXMLParser.h"

#import "common.h"

@implementation OFMalformedXMLException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    parser: (OFXMLParser*)parser
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     parser: parser] autorelease];
}

- initWithClass: (Class)class_
	 parser: (OFXMLParser*)parser_
- initWithClass: (Class)class
	 parser: (OFXMLParser*)parser
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	parser = [parser_ retain];
	_parser = [parser retain];

	return self;
}

- (void)dealloc
{
	[parser release];
	[_parser release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	if (parser != nil)
		description = [[OFString alloc] initWithFormat:
		    @"The parser in class %@ encountered malformed XML!",
		    inClass];
	if (_parser != nil)
		_description = [[OFString alloc] initWithFormat:
		    @"The XML parser in class %@ encountered malformed XML!",
		    _inClass];
	else
		description = @"A parser encountered malformed XML!";
		_description = @"An XML parser encountered malformed XML!";

	return description;
	return _description;
}

- (OFXMLParser*)parser
{
	OF_GETTER(parser, NO)
	OF_GETTER(_parser, NO)
}
@end

Modified src/exceptions/OFMemoryNotPartOfObjectException.h from [91de5ea6dc] to [711c041b2a].

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







-
+










-
+



-
+





-
+



-
+








#import "OFException.h"

/*!
 * @brief An exception indicating the given memory is not part of the object.
 */
@interface OFMemoryNotPartOfObjectException: OFException
{
	void *pointer;
	void *_pointer;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly) void *pointer;
#endif

/*!
 * @brief Creates a new, autoreleased memory not part of object exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param ptr A pointer to the memory that is not part of the object
 * @param pointer A pointer to the memory that is not part of the object
 * @return A new, autoreleased memory not part of object exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
			   pointer: (void*)ptr;
			   pointer: (void*)pointer;

/*!
 * @brief Initializes an already allocated memory not part of object exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param ptr A pointer to the memory that is not part of the object
 * @param pointer A pointer to the memory that is not part of the object
 * @return An initialized memory not part of object exception
 */
- initWithClass: (Class)class_
	pointer: (void*)ptr;
	pointer: (void*)pointer;

/*!
 * @brief Returns a pointer to the memory which is not part of the object.
 *
 * @return A pointer to the memory which is not part of the object
 */
- (void*)pointer;
@end

Modified src/exceptions/OFMemoryNotPartOfObjectException.m from [a1452e1fb6] to [b794b10a09].

18
19
20
21
22
23
24
25
26


27
28
29


30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45


46
47

48
49

50
51
52
53
54
55
56
57


58
59

60
61
62
63

64
65

66
67
68
69
70

71
72
18
19
20
21
22
23
24


25
26
27


28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43


44
45
46

47
48

49
50
51
52
53
54
55


56
57
58

59
60
61
62

63
64

65
66
67
68
69

70
71
72







-
-
+
+

-
-
+
+


-
+











-
-
+
+

-
+

-
+






-
-
+
+

-
+



-
+

-
+




-
+



#include <stdlib.h>

#import "OFMemoryNotPartOfObjectException.h"
#import "OFString.h"

@implementation OFMemoryNotPartOfObjectException
+ (instancetype)exceptionWithClass: (Class)class_
			   pointer: (void*)ptr
+ (instancetype)exceptionWithClass: (Class)class
			   pointer: (void*)pointer
{
	return [[[self alloc] initWithClass: class_
				    pointer: ptr] autorelease];
	return [[[self alloc] initWithClass: class
				    pointer: pointer] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	pointer: (void*)ptr
- initWithClass: (Class)class
	pointer: (void*)pointer
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	pointer = ptr;
	_pointer = pointer;

	return self;
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Memory at %p was not allocated as part of object of class %@, "
	    @"thus the memory allocation was not changed! It is also possible "
	    @"that there was an attempt to free the same memory twice.",
	    pointer, inClass];
	    _pointer, _inClass];

	return description;
	return _description;
}

- (void*)pointer
{
	return pointer;
	return _pointer;
}
@end

Modified src/exceptions/OFNotConnectedException.h from [1bd7530b03] to [281c34dc5e].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







@class OFStreamSocket;

/*!
 * @brief An exception indicating a socket is not connected or bound.
 */
@interface OFNotConnectedException: OFException
{
	OFStreamSocket *socket;
	OFStreamSocket *_socket;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFStreamSocket *socket;
#endif

/*!

Modified src/exceptions/OFNotConnectedException.m from [96b427f88f] to [202a3a6c5f].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
-
+
+

-
+




-
+


#import "OFNotConnectedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"

#import "common.h"

@implementation OFNotConnectedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    socket: (OFStreamSocket*)socket
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     socket: socket] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 socket: (OFStreamSocket*)socket_
- initWithClass: (Class)class
	 socket: (OFStreamSocket*)socket
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	socket = [socket_ retain];
	_socket = [socket retain];

	return self;
}

- (void)dealloc
{
	[socket release];
	[_socket release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"The socket of type %@ is not connected or bound!", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"The socket of type %@ is not connected or bound!", _inClass];

	return description;
	return _description;
}

- (OFStreamSocket*)socket
{
	OF_GETTER(socket, NO)
	OF_GETTER(_socket, NO)
}
@end

Modified src/exceptions/OFNotImplementedException.h from [abb1f691d5] to [0e5ad9eeda].

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 An exception indicating that a method or part of it is not
 *        implemented.
 */
@interface OFNotImplementedException: OFException
{
	SEL selector;
	SEL _selector;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly) SEL selector;
#endif

/*!

Modified src/exceptions/OFNotImplementedException.m from [0a119c960d] to [7dc7df3c42].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
-
+
+

-
+

-
+

-
+




-
+



#import "OFNotImplementedException.h"
#import "OFString.h"

#import "common.h"

@implementation OFNotImplementedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			  selector: (SEL)selector
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				   selector: selector] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
       selector: (SEL)selector_
- initWithClass: (Class)class
       selector: (SEL)selector
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	selector = selector_;
	_selector = selector;

	return self;
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"The selector %s is not understood by class %@ or not (fully) "
	    @"implemented!", sel_getName(selector), inClass];
	    @"implemented!", sel_getName(_selector), _inClass];

	return description;
	return _description;
}

- (SEL)selector
{
	return selector;
	return _selector;
}
@end

Modified src/exceptions/OFOpenFileFailedException.h from [dd2d7a6ac4] to [5b0e6f089a].

17
18
19
20
21
22
23
24

25
26

27
28
29
30

31
32
33
34
35
36
37
38
17
18
19
20
21
22
23

24


25
26
27
28

29

30
31
32
33
34
35
36







-
+
-
-
+



-
+
-







#import "OFException.h"

/*!
 * @brief An exception indicating a file couldn't be opened.
 */
@interface OFOpenFileFailedException: OFException
{
	OFString *path;
	OFString *_path, *_mode;
	OFString *mode;
	int errNo;
	int _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly, copy, nonatomic) OFString *path, *mode;
@property (readonly, copy, nonatomic) OFString *mode;
@property (readonly) int errNo;
#endif

/*!
 * @brief Creates a new, autoreleased open file failed exception.
 *
 * @param class_ The class of the object which caused the exception

Modified src/exceptions/OFOpenFileFailedException.m from [2be3d5c462] to [fd065f5f06].

20
21
22
23
24
25
26
27

28
29
30
31

32
33
34
35
36

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



51
52

53
54
55
56
57



58
59
60
61
62
63
64
65
66
67
68
69


70
71
72
73
74
75
76
77


78
79
80
81



82
83

84
85
86
87
88

89
90
91
92
93

94
95
96
97
98

99
100
20
21
22
23
24
25
26

27
28
29
30

31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47



48
49
50
51

52
53
54



55
56
57
58
59
60
61
62
63
64
65
66
67


68
69
70
71
72
73
74
75


76
77
78



79
80
81
82

83
84
85
86
87

88
89
90
91
92

93
94
95
96
97

98
99
100







-
+



-
+




-
+











-
-
-
+
+
+

-
+


-
-
-
+
+
+










-
-
+
+






-
-
+
+

-
-
-
+
+
+

-
+




-
+




-
+




-
+



#import "OFOpenFileFailedException.h"
#import "OFString.h"

#import "common.h"

@implementation OFOpenFileFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			      path: (OFString*)path
			      mode: (OFString*)mode
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				       path: path
				       mode: mode] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	   path: (OFString*)path_
	   mode: (OFString*)mode_
- initWithClass: (Class)class
	   path: (OFString*)path
	   mode: (OFString*)mode
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		path  = [path_ copy];
		mode  = [mode_ copy];
		errNo = GET_ERRNO;
		_path  = [path copy];
		_mode  = [mode copy];
		_errNo = GET_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[path release];
	[mode release];
	[_path release];
	[_mode release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Failed to open file %@ with mode %@ in class %@! " ERRFMT, path,
	    mode, inClass, ERRPARAM];
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to open file %@ with mode %@ in class %@! " ERRFMT, _path,
	    _mode, _inClass, ERRPARAM];

	return description;
	return _description;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}

- (OFString*)path
{
	OF_GETTER(path, NO)
	OF_GETTER(_path, NO)
}

- (OFString*)mode
{
	OF_GETTER(mode, NO)
	OF_GETTER(_mode, NO)
}
@end

Modified src/exceptions/OFOutOfMemoryException.h from [70140dd883] to [fbe9775a49].

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







-
+










-
+



-
+





-
+



-
+








#import "OFException.h"

/*!
 * @brief An exception indicating there is not enough memory available.
 */
@interface OFOutOfMemoryException: OFException
{
	size_t requestedSize;
	size_t _requestedSize;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly) size_t requestedSize;
#endif

/*!
 * @brief Creates a new, autoreleased no memory exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param size The size of the memory that couldn't be allocated
 * @param requestedSize The size of the memory that couldn't be allocated
 * @return A new, autoreleased no memory exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
		     requestedSize: (size_t)size;
		     requestedSize: (size_t)requestedSize;

/*!
 * @brief Initializes an already allocated no memory exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param size The size of the memory that couldn't be allocated
 * @param requestedSize The size of the memory that couldn't be allocated
 * @return An initialized no memory exception
 */
- initWithClass: (Class)class_
  requestedSize: (size_t)size;
  requestedSize: (size_t)requestedSize;

/*!
 * @brief Returns the size of the memoory that couldn't be allocated.
 *
 * @return The size of the memoory that couldn't be allocated
 */
- (size_t)requestedSize;
@end

Modified src/exceptions/OFOutOfMemoryException.m from [1897414e22] to [632b122d6b].

16
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
57
58

59
60
16
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
57

58
59
60







-
-
+
+

-
-
+
+


-
-
+
+

-
+

-
+






-
-
+
+

-
-
-
-
+
+
+
+

-
-
+
+

-
+




-
+



#include "config.h"

#import "OFOutOfMemoryException.h"
#import "OFString.h"

@implementation OFOutOfMemoryException
+ (instancetype)exceptionWithClass: (Class)class_
		     requestedSize: (size_t)size
+ (instancetype)exceptionWithClass: (Class)class
		     requestedSize: (size_t)requestedSize
{
	return [[[self alloc] initWithClass: class_
			      requestedSize: size] autorelease];
	return [[[self alloc] initWithClass: class
			      requestedSize: requestedSize] autorelease];
}

- initWithClass: (Class)class_
  requestedSize: (size_t)size
- initWithClass: (Class)class
  requestedSize: (size_t)requestedSize
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	requestedSize = size;
	_requestedSize = requestedSize;

	return self;
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	if (requestedSize != 0)
		description = [[OFString alloc] initWithFormat:
		    @"Could not allocate %zu bytes in class %@!", requestedSize,
		    inClass];
	if (_requestedSize != 0)
		_description = [[OFString alloc] initWithFormat:
		    @"Could not allocate %zu bytes in class %@!",
		    _requestedSize, _inClass];
	else
		description = [[OFString alloc] initWithFormat:
		    @"Could not allocate enough memory in class %@!", inClass];
		_description = [[OFString alloc] initWithFormat:
		    @"Could not allocate enough memory in class %@!", _inClass];

	return description;
	return _description;
}

- (size_t)requestedSize
{
	return requestedSize;
	return _requestedSize;
}
@end

Modified src/exceptions/OFOutOfRangeException.m from [ae918491aa] to [adf5140fee].

18
19
20
21
22
23
24
25
26


27
28
29


30
31

32
33
18
19
20
21
22
23
24


25
26
27


28
29
30

31
32
33







-
-
+
+

-
-
+
+

-
+



#import "OFOutOfRangeException.h"
#import "OFString.h"

@implementation OFOutOfRangeException
- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Value out of range in class %@!", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"Value out of range in class %@!", _inClass];

	return description;
	return _description;
}
@end

Modified src/exceptions/OFReadFailedException.m from [7235b51172] to [c76f9e9235].

20
21
22
23
24
25
26
27
28


29
30
31
32



33
34

35
36
20
21
22
23
24
25
26


27
28
29



30
31
32
33

34
35
36







-
-
+
+

-
-
-
+
+
+

-
+


#import "OFString.h"

#import "common.h"

@implementation OFReadFailedException
- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Failed to read %zu bytes in class %@! " ERRFMT, requestedLength,
	    inClass, ERRPARAM];
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to read %zu bytes in class %@! " ERRFMT, _requestedLength,
	    _inClass, ERRPARAM];

	return description;
	return _description;
}
@end

Modified src/exceptions/OFReadOrWriteFailedException.h from [578afdb049] to [9ca5afb590].

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







-
-
+
+

-
+













-
-
+
+




-
+






-
-
+
+




-
+







@class OFStream;

/*!
 * @brief An exception indicating a read or write to a stream failed.
 */
@interface OFReadOrWriteFailedException: OFException
{
	OFStream *stream;
	size_t	 requestedLength;
	OFStream *_stream;
	size_t	 _requestedLength;
@public
	int	 errNo;
	int	 _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFStream *stream;
@property (readonly) size_t requestedLength;
@property (readonly) int errNo;
#endif

/*!
 * @brief Creates a new, autoreleased read or write failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param stream The stream which caused the read or write failed exception
 * @param length The requested length of the data that couldn't be read /
 *		 written
 * @param requestedLength The requested length of the data that couldn't be
 *			  read / written
 * @return A new, autoreleased read or write failed exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
			    stream: (OFStream*)stream
		   requestedLength: (size_t)length;
		   requestedLength: (size_t)requestedLength;

/*!
 * @brief Initializes an already allocated read or write failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param stream The stream which caused the read or write failed exception
 * @param length The requested length of the data that couldn't be read /
 *		 written
 * @param requestedLength The requested length of the data that couldn't be
 *			  read / written
 * @return A new open file failed exception
 */
-   initWithClass: (Class)class_
	   stream: (OFStream*)stream
  requestedLength: (size_t)length;
  requestedLength: (size_t)requestedLength;

/*!
 * @brief Returns the stream which caused the read or write failed exception.
 *
 * @return The stream which caused the read or write failed exception
 */
- (OFStream*)stream;

Modified src/exceptions/OFReadOrWriteFailedException.m from [9aff6467fd] to [29e58b37e2].

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







-
+

-
+

-
+

-
+


-
+











-
-
-
+
+
+

-
+

-
-
+
+

-
-
+
+

-
+






-
+






-
+




-
+




-
+


#import "OFReadOrWriteFailedException.h"
#import "OFString.h"
#import "OFStreamSocket.h"

#import "common.h"

@implementation OFReadOrWriteFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    stream: (OFStream*)stream
		   requestedLength: (size_t)length
		   requestedLength: (size_t)requestedLength
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     stream: stream
			    requestedLength: length] autorelease];
			    requestedLength: requestedLength] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

-   initWithClass: (Class)class_
	   stream: (OFStream*)stream_
  requestedLength: (size_t)length
-   initWithClass: (Class)class
	   stream: (OFStream*)stream
  requestedLength: (size_t)requestedLength
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	stream = [stream_ retain];
	requestedLength = length;
	_stream = [stream retain];
	_requestedLength = requestedLength;

	if ([class_ isSubclassOfClass: [OFStreamSocket class]])
		errNo = GET_SOCK_ERRNO;
	if ([class isSubclassOfClass: [OFStreamSocket class]])
		_errNo = GET_SOCK_ERRNO;
	else
		errNo = GET_ERRNO;
		_errNo = GET_ERRNO;

	return self;
}

- (void)dealloc
{
	[stream release];
	[_stream release];

	[super dealloc];
}

- (OFStream*)stream
{
	OF_GETTER(stream, NO)
	OF_GETTER(_stream, NO)
}

- (size_t)requestedLength
{
	return requestedLength;
	return _requestedLength;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}
@end

Modified src/exceptions/OFRenameFileFailedException.h from [fca6849bad] to [0227ecc2e0].

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
57


58
59
60
61
62
63
64
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
57
58
59
60
61
62







-
-
-
+
+



-
+
-







-
-
+
+



-
-
+
+





-
-
+
+



-
-
+
+







#import "OFException.h"

/*!
 * @brief An exception indicating that renaming a file failed.
 */
@interface OFRenameFileFailedException: OFException
{
	OFString *sourcePath;
	OFString *destinationPath;
	int errNo;
	OFString *_sourcePath, *_destinationPath;
	int _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath;
@property (readonly, copy, nonatomic) OFString *sourcePath, *destinationPath;
@property (readonly, copy, nonatomic) OFString *destinationPath;
@property (readonly) int errNo;
#endif

/*!
 * @brief Creates a new, autoreleased rename file failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param source The original path
 * @param destination The new path
 * @param sourcePath The original path
 * @param destinationPath The new path
 * @return A new, autoreleased rename file failed exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
			sourcePath: (OFString*)source
		   destinationPath: (OFString*)destination;
			sourcePath: (OFString*)sourcePath
		   destinationPath: (OFString*)destinationPath;

/*!
 * @brief Initializes an already allocated rename failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param source The original path
 * @param destination The new path
 * @param sourcePath The original path
 * @param destinationPath The new path
 * @return An initialized rename file failed exception
 */
-   initWithClass: (Class)class_
       sourcePath: (OFString*)source
  destinationPath: (OFString*)destination;
       sourcePath: (OFString*)sourcePath
  destinationPath: (OFString*)destinationPath;

/*!
 * @brief Returns the errno from when the exception was created.
 *
 * @return The errno from when the exception was created
 */
- (int)errNo;

Modified src/exceptions/OFRenameFileFailedException.m from [985b1ab9ce] to [300b802be6].

20
21
22
23
24
25
26
27
28
29



30
31
32
33



34
35
36

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



51
52

53
54
55
56
57



58
59
60
61
62
63
64
65
66
67
68
69


70
71
72
73
74
75
76
77


78
79
80
81



82
83

84
85
86
87
88

89
90
91
92
93

94
95
96
97
98

99
100
20
21
22
23
24
25
26



27
28
29
30



31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47



48
49
50
51

52
53
54



55
56
57
58
59
60
61
62
63
64
65
66
67


68
69
70
71
72
73
74
75


76
77
78



79
80
81
82

83
84
85
86
87

88
89
90
91
92

93
94
95
96
97

98
99
100







-
-
-
+
+
+

-
-
-
+
+
+


-
+











-
-
-
+
+
+

-
+


-
-
-
+
+
+










-
-
+
+






-
-
+
+

-
-
-
+
+
+

-
+




-
+




-
+




-
+



#import "OFRenameFileFailedException.h"
#import "OFString.h"

#import "common.h"

@implementation OFRenameFileFailedException
+ (instancetype)exceptionWithClass: (Class)class_
			sourcePath: (OFString*)source
		   destinationPath: (OFString*)destination
+ (instancetype)exceptionWithClass: (Class)class
			sourcePath: (OFString*)sourcePath
		   destinationPath: (OFString*)destinationPath
{
	return [[[self alloc] initWithClass: class_
				 sourcePath: source
			    destinationPath: destination] autorelease];
	return [[[self alloc] initWithClass: class
				 sourcePath: sourcePath
			    destinationPath: destinationPath] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

-   initWithClass: (Class)class_
       sourcePath: (OFString*)source
  destinationPath: (OFString*)destination
-   initWithClass: (Class)class
       sourcePath: (OFString*)sourcePath
  destinationPath: (OFString*)destinationPath
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		sourcePath = [source copy];
		destinationPath = [destination copy];
		errNo = GET_ERRNO;
		_sourcePath = [sourcePath copy];
		_destinationPath = [destinationPath copy];
		_errNo = GET_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[sourcePath release];
	[destinationPath release];
	[_sourcePath release];
	[_destinationPath release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Failed to rename file %@ to %@ in class %@! " ERRFMT, sourcePath,
	    destinationPath, inClass, ERRPARAM];
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to rename file %@ to %@ in class %@! " ERRFMT,
	    _sourcePath, _destinationPath, _inClass, ERRPARAM];

	return description;
	return _description;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}

- (OFString*)sourcePath
{
	OF_GETTER(sourcePath, NO)
	OF_GETTER(_sourcePath, NO)
}

- (OFString*)destinationPath
{
	OF_GETTER(destinationPath, NO)
	OF_GETTER(_destinationPath, NO)
}
@end

Modified src/exceptions/OFSeekFailedException.h from [f8c1d060d7] to [0430f3b8bb].

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
21
22
23
24
25
26
27



28
29
30

31
32
33
34
35

36

37
38
39
40
41
42
43







-
-
-
+
+
+
-





-
+
-







@class OFSeekableStream;

/*!
 * @brief An exception indicating that seeking in a stream failed.
 */
@interface OFSeekFailedException: OFException
{
	OFSeekableStream *stream;
	off_t		 offset;
	int		 whence;
	OFSeekableStream *_stream;
	off_t _offset;
	int _whence, _errNo;
	int		 errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFSeekableStream *stream;
@property (readonly) off_t offset;
@property (readonly) int whence;
@property (readonly) int whence, errNo;
@property (readonly) int errNo;
#endif

/*!
 * @brief Creates a new, autoreleased seek failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param stream The stream for which seeking failed

Modified src/exceptions/OFSeekFailedException.m from [817ab9cf57] to [b267411948].

21
22
23
24
25
26
27
28

29
30
31
32
33

34
35
36
37
38
39

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




55
56

57
58
59
60
61




62
63
64
65
66
67
68

69
70
71
72
73
74
75
76


77
78
79


80
81

82
83
84
85
86

87
88
89
90
91

92
93
94
95
96

97
98
99
100
101

102
103
21
22
23
24
25
26
27

28
29
30
31
32

33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50




51
52
53
54
55

56
57




58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74


75
76
77


78
79
80

81
82
83
84
85

86
87
88
89
90

91
92
93
94
95

96
97
98
99
100

101
102
103







-
+




-
+





-
+











-
-
-
-
+
+
+
+

-
+

-
-
-
-
+
+
+
+






-
+






-
-
+
+

-
-
+
+

-
+




-
+




-
+




-
+




-
+


#import "OFSeekFailedException.h"
#import "OFString.h"
#import "OFSeekableStream.h"

#import "common.h"

@implementation OFSeekFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    stream: (OFSeekableStream*)stream
			    offset: (off_t)offset
			    whence: (int)whence
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     stream: stream
				     offset: offset
				     whence: whence] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 stream: (OFSeekableStream*)stream_
	 offset: (off_t)offset_
	 whence: (int)whence_
- initWithClass: (Class)class
	 stream: (OFSeekableStream*)stream
	 offset: (off_t)offset
	 whence: (int)whence
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	stream = [stream_ retain];
	offset = offset_;
	whence = whence_;
	errNo = GET_ERRNO;
	_stream = [stream retain];
	_offset = offset;
	_whence = whence;
	_errNo = GET_ERRNO;

	return self;
}

- (void)dealloc
{
	[stream	release];
	[_stream release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Seeking failed in class %@! " ERRFMT, inClass, ERRPARAM];
	_description = [[OFString alloc] initWithFormat:
	    @"Seeking failed in class %@! " ERRFMT, _inClass, ERRPARAM];

	return description;
	return _description;
}

- (OFSeekableStream*)stream
{
	OF_GETTER(stream, NO)
	OF_GETTER(_stream, NO)
}

- (off_t)offset
{
	return offset;
	return _offset;
}

- (int)whence
{
	return whence;
	return _whence;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}
@end

Modified src/exceptions/OFSetOptionFailedException.h from [bd44868d64] to [2d153af019].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







@class OFStream;

/*!
 * @brief An exception indicating that setting an option for a stream failed.
 */
@interface OFSetOptionFailedException: OFException
{
	OFStream *stream;
	OFStream *_stream;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFStream *stream;
#endif

/*!

Modified src/exceptions/OFSetOptionFailedException.m from [e3ec9f7433] to [440af04fa4].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
-
+
+

-
+




-
+


#import "OFSetOptionFailedException.h"
#import "OFString.h"
#import "OFStream.h"

#import "common.h"

@implementation OFSetOptionFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    stream: (OFStream*)stream
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     stream: stream] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 stream: (OFStream*)stream_
- initWithClass: (Class)class
	 stream: (OFStream*)stream
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	stream = [stream_ retain];
	_stream = [stream retain];

	return self;
}

- (void)dealloc
{
	[stream release];
	[_stream release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Setting an option in class %@ failed!", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"Setting an option in class %@ failed!", _inClass];

	return description;
	return _description;
}

- (OFStream*)stream
{
	OF_GETTER(stream, NO)
	OF_GETTER(_stream, NO)
}
@end

Modified src/exceptions/OFStillLockedException.h from [8fd0b0d990] to [cb52dc053c].

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







-
+







#import "OFLocking.h"

/*!
 * @brief An exception indicating that a lock is still locked.
 */
@interface OFStillLockedException: OFException
{
	id <OFLocking> lock;
	id <OFLocking> _lock;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id <OFLocking> lock;
#endif

/*!

Modified src/exceptions/OFStillLockedException.m from [a5659659aa] to [3a0467e9cd].

18
19
20
21
22
23
24
25

26
27
28

29
30
31
32
33


34
35

36
37

38
39
40
41
42
43
44

45
46
47
48
49
50
51
52


53
54

55
56

57
58

59
60
61
62
63

64
65
18
19
20
21
22
23
24

25
26
27

28
29
30
31


32
33
34

35
36

37
38
39
40
41
42
43

44
45
46
47
48
49
50


51
52
53

54
55

56
57

58
59
60
61
62

63
64
65







-
+


-
+



-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
+

-
+

-
+




-
+



#import "OFStillLockedException.h"
#import "OFString.h"

#import "macros.h"

@implementation OFStillLockedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			      lock: (id <OFLocking>)lock
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				       lock: lock] autorelease];
}

- initWithClass: (Class)class_
	   lock: (id <OFLocking>)lock_
- initWithClass: (Class)class
	   lock: (id <OFLocking>)lock
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	lock = [lock_ retain];
	_lock = [lock retain];

	return self;
}

- (void)dealloc
{
	[lock release];
	[_lock release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Deallocation of a lock of type %@ was tried in class %@, even "
	    @"though it was still locked!", [(id)lock className], inClass];
	    @"though it was still locked!", [_lock class], _inClass];

	return description;
	return _description;
}

- (id <OFLocking>)lock
{
	OF_GETTER(lock, NO)
	OF_GETTER(_lock, NO)
}
@end

Modified src/exceptions/OFSymlinkFailedException.h from [946be7c3c1] to [0ceec2f0f6].

18
19
20
21
22
23
24
25
26
27


28
29
30
31

32
33
34
35
36
37
38
39
40
41


42
43
44
45
46


47
48
49
50
51
52
53


54
55
56
57
58


59
60
61
62
63
64
65
18
19
20
21
22
23
24



25
26
27
28
29

30

31
32
33
34
35
36
37


38
39
40
41
42


43
44
45
46
47
48
49


50
51
52
53
54


55
56
57
58
59
60
61
62
63







-
-
-
+
+



-
+
-







-
-
+
+



-
-
+
+





-
-
+
+



-
-
+
+








#ifndef _WIN32
/*!
 * @brief An exception indicating that creating a symlink failed.
 */
@interface OFSymlinkFailedException: OFException
{
	OFString *sourcePath;
	OFString *destinationPath;
	int errNo;
	OFString *_sourcePath, *_destinationPath;
	int _errNo;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath;
@property (readonly, copy, nonatomic) OFString *sourcePath, *destinationPath;
@property (readonly, copy, nonatomic) OFString *destinationPath;
@property (readonly) int errNo;
#endif

/*!
 * @brief Creates a new, autoreleased symlink failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param source The source for the symlink
 * @param destination The destination for the symlink
 * @param sourcePath The source for the symlink
 * @param destinationPath The destination for the symlink
 * @return A new, autoreleased symlink failed exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
			sourcePath: (OFString*)source
		   destinationPath: (OFString*)destination;
			sourcePath: (OFString*)sourcePath
		   destinationPath: (OFString*)destinationPath;

/*!
 * @brief Initializes an already allocated symlink failed exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param source The source for the symlink
 * @param destination The destination for the symlink
 * @param sourcePath The source for the symlink
 * @param destinationPath The destination for the symlink
 * @return An initialized symlink failed exception
 */
-   initWithClass: (Class)class_
       sourcePath: (OFString*)source
  destinationPath: (OFString*)destination;
       sourcePath: (OFString*)sourcePath
  destinationPath: (OFString*)destinationPath;

/*!
 * @brief Returns the errno from when the exception was created.
 *
 * @return The errno from when the exception was created
 */
- (int)errNo;

Modified src/exceptions/OFSymlinkFailedException.m from [2eea5d324c] to [98d414e112].

21
22
23
24
25
26
27
28
29
30



31
32
33
34



35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51



52
53

54
55
56
57
58



59
60
61
62
63
64
65
66
67
68
69
70


71
72
73
74
75
76
77
78


79
80
81
82



83
84

85
86
87
88
89

90
91
92
93
94

95
96
97
98
99

100
101
102
21
22
23
24
25
26
27



28
29
30
31



32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48



49
50
51
52

53
54
55



56
57
58
59
60
61
62
63
64
65
66
67
68


69
70
71
72
73
74
75
76


77
78
79



80
81
82
83

84
85
86
87
88

89
90
91
92
93

94
95
96
97
98

99
100
101
102







-
-
-
+
+
+

-
-
-
+
+
+


-
+











-
-
-
+
+
+

-
+


-
-
-
+
+
+










-
-
+
+






-
-
+
+

-
-
-
+
+
+

-
+




-
+




-
+




-
+



#import "OFSymlinkFailedException.h"
#import "OFString.h"

#import "common.h"

#ifndef _WIN32
@implementation OFSymlinkFailedException
+ (instancetype)exceptionWithClass: (Class)class_
			sourcePath: (OFString*)source
		   destinationPath: (OFString*)destination
+ (instancetype)exceptionWithClass: (Class)class
			sourcePath: (OFString*)sourcePath
		   destinationPath: (OFString*)destinationPath
{
	return [[[self alloc] initWithClass: class_
				 sourcePath: source
			    destinationPath: destination] autorelease];
	return [[[self alloc] initWithClass: class
				 sourcePath: sourcePath
			    destinationPath: destinationPath] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

-   initWithClass: (Class)class_
       sourcePath: (OFString*)source
  destinationPath: (OFString*)destination
-   initWithClass: (Class)class
       sourcePath: (OFString*)sourcePath
  destinationPath: (OFString*)destinationPath
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		sourcePath = [source copy];
		destinationPath = [destination copy];
		errNo = GET_ERRNO;
		_sourcePath = [sourcePath copy];
		_destinationPath = [destinationPath copy];
		_errNo = GET_ERRNO;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[sourcePath release];
	[destinationPath release];
	[_sourcePath release];
	[_destinationPath release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Failed to symlink file %@ to %@ in class %@! " ERRFMT, sourcePath,
	    destinationPath, inClass, ERRPARAM];
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to symlink file %@ to %@ in class %@! " ERRFMT,
	    _sourcePath, _destinationPath, _inClass, ERRPARAM];

	return description;
	return _description;
}

- (int)errNo
{
	return errNo;
	return _errNo;
}

- (OFString*)sourcePath
{
	OF_GETTER(sourcePath, NO)
	OF_GETTER(_sourcePath, NO)
}

- (OFString*)destinationPath
{
	OF_GETTER(destinationPath, NO)
	OF_GETTER(_destinationPath, NO)
}
@end
#endif

Modified src/exceptions/OFThreadJoinFailedException.h from [2a2936121c] to [8ae844634a].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







@class OFThread;

/*!
 * @brief An exception indicating that joining a thread failed.
 */
@interface OFThreadJoinFailedException: OFException
{
	OFThread *thread;
	OFThread *_thread;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFThread *thread;
#endif

/*!

Modified src/exceptions/OFThreadJoinFailedException.m from [4dd632518d] to [1398fa6a7a].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
+

-
+

-
+




-
+


#include <stdlib.h>

#import "OFThreadJoinFailedException.h"
#import "OFString.h"
#import "OFThread.h"

@implementation OFThreadJoinFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    thread: (OFThread*)thread
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     thread: thread] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 thread: (OFThread*)thread_
- initWithClass: (Class)class
	 thread: (OFThread*)thread
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	thread = [thread_ retain];
	_thread = [thread retain];

	return self;
}

- (void)dealloc
{
	[thread release];
	[_thread release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Joining a thread of class %@ failed! Most likely, another thread "
	    @"already waits for the thread to join.", inClass];
	    @"already waits for the thread to join.", _inClass];

	return description;
	return _description;
}

- (OFThread*)thread
{
	OF_GETTER(thread, NO)
	OF_GETTER(_thread, NO)
}
@end

Modified src/exceptions/OFThreadStartFailedException.h from [f0826175fb] to [b941a35e28].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







@class OFThread;

/*!
 * @brief An exception indicating that starting a thread failed.
 */
@interface OFThreadStartFailedException: OFException
{
	OFThread *thread;
	OFThread *_thread;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFThread *thread;
#endif

/*!

Modified src/exceptions/OFThreadStartFailedException.m from [dc9d7f84a8] to [c4d2751745].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
-
+
+

-
+




-
+


#include <stdlib.h>

#import "OFThreadStartFailedException.h"
#import "OFString.h"
#import "OFThread.h"

@implementation OFThreadStartFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    thread: (OFThread*)thread
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     thread: thread] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 thread: (OFThread*)thread_
- initWithClass: (Class)class
	 thread: (OFThread*)thread
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	thread = [thread_ retain];
	_thread = [thread retain];

	return self;
}

- (void)dealloc
{
	[thread release];
	[_thread release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Starting a thread of class %@ failed!", inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"Starting a thread of class %@ failed!", _inClass];

	return description;
	return _description;
}

- (OFThread*)thread
{
	OF_GETTER(thread, NO)
	OF_GETTER(_thread, NO)
}
@end

Modified src/exceptions/OFThreadStillRunningException.h from [d927ce5d9d] to [405b10fbdf].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







@class OFThread;

/*!
 * @brief An exception indicating that a thread is still running.
 */
@interface OFThreadStillRunningException: OFException
{
	OFThread *thread;
	OFThread *_thread;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFThread *thread;
#endif

/*!

Modified src/exceptions/OFThreadStillRunningException.m from [b0e805dcc0] to [fb8e07d9a0].

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







-
+


-
+



-
+











-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
+

-
+

-
+




-
+


#include <stdlib.h>

#import "OFThreadStillRunningException.h"
#import "OFString.h"
#import "OFThread.h"

@implementation OFThreadStillRunningException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    thread: (OFThread*)thread
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     thread: thread] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	 thread: (OFThread*)thread_
- initWithClass: (Class)class
	 thread: (OFThread*)thread
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	thread = [thread_ retain];
	_thread = [thread retain];

	return self;
}

- (void)dealloc
{
	[thread release];
	[_thread release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Deallocation of a thread of type %@ was tried, even though it "
	    @"was still running!", inClass];
	    @"was still running!", _inClass];

	return description;
	return _description;
}

- (OFThread*)thread
{
	OF_GETTER(thread, NO)
	OF_GETTER(_thread, NO)
}
@end

Modified src/exceptions/OFTruncatedDataException.m from [c262fab980] to [0c9b919885].

18
19
20
21
22
23
24
25
26


27
28

29
30

31
32

33
34
18
19
20
21
22
23
24


25
26
27

28
29

30
31

32
33
34







-
-
+
+

-
+

-
+

-
+



#import "OFTruncatedDataException.h"
#import "OFString.h"

@implementation OFTruncatedDataException
- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Truncated data was received or produced in class %@ while it "
	    @"should not have been truncated!", inClass];
	    @"should not have been truncated!", _inClass];

	return description;
	return _description;
}
@end

Modified src/exceptions/OFUnboundNamespaceException.h from [a52b906543] to [39eed6d3dc].

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
57

58
59
60
61

62
63
64
65
66
67
68
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
57
58

59
60
61
62
63
64
65
66







-
+
-



-
-
+






-
+



-
+















-
+



-
+







#import "OFException.h"

/*!
 * @brief An exception indicating an attempt to use an unbound namespace.
 */
@interface OFUnboundNamespaceException: OFException
{
	OFString *ns;
	OFString *_namespace, *_prefix;
	OFString *prefix;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic, getter=namespace) OFString *ns;
@property (readonly, copy, nonatomic) OFString *prefix;
@property (readonly, copy, nonatomic) OFString *namespace, *prefix;
#endif

/*!
 * @brief Creates a new, autoreleased unbound namespace exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param ns The namespace which is unbound
 * @param namespace The namespace which is unbound
 * @return A new, autoreleased unbound namespace exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
			 namespace: (OFString*)ns;
			 namespace: (OFString*)namespace;

/*!
 * @brief Creates a new, autoreleased unbound namespace exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param prefix The prefix which is unbound
 * @return A new, autoreleased unbound namespace exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
			    prefix: (OFString*)prefix;

/*!
 * @brief Initializes an already allocated unbound namespace exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param ns The namespace which is unbound
 * @param namespace The namespace which is unbound
 * @return An initialized unbound namespace exception
 */
- initWithClass: (Class)class_
      namespace: (OFString*)ns;
      namespace: (OFString*)namespace;

/*!
 * @brief Initializes an already allocated unbound namespace exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param prefix The prefix which is unbound
 * @return An initialized unbound namespace exception

Modified src/exceptions/OFUnboundNamespaceException.m from [042719481e] to [8482013ced].

20
21
22
23
24
25
26
27
28


29
30
31


32
33
34

35
36
37

38
39
40
41

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


55
56

57
58
59

60
61
62
63
64
65
66
67
68
69


70
71

72
73
74

75
76
77
78
79
80
81
82
83
84
85
86


87
88
89
90
91
92
93
94


95
96
97
98
99
100






101
102

103
104

105
106
107
108
109

110
111
112
113
114

115
116
20
21
22
23
24
25
26


27
28
29


30
31
32
33

34
35
36

37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52


53
54
55

56
57
58

59
60
61
62
63
64
65
66
67


68
69
70

71
72
73

74
75
76
77
78
79
80
81
82
83
84


85
86
87
88
89
90
91
92


93
94
95





96
97
98
99
100
101
102

103
104

105
106
107
108
109

110
111
112
113
114

115
116
117







-
-
+
+

-
-
+
+


-
+


-
+



-
+











-
-
+
+

-
+


-
+








-
-
+
+

-
+


-
+










-
-
+
+






-
-
+
+

-
-
-
-
-
+
+
+
+
+
+

-
+

-
+




-
+




-
+



#import "OFUnboundNamespaceException.h"
#import "OFString.h"

#import "common.h"

@implementation OFUnboundNamespaceException
+ (instancetype)exceptionWithClass: (Class)class_
			 namespace: (OFString*)ns
+ (instancetype)exceptionWithClass: (Class)class
			 namespace: (OFString*)namespace
{
	return [[[self alloc] initWithClass: class_
				  namespace: ns] autorelease];
	return [[[self alloc] initWithClass: class
				  namespace: namespace] autorelease];
}

+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			    prefix: (OFString*)prefix
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				     prefix: prefix] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
      namespace: (OFString*)ns_
- initWithClass: (Class)class
      namespace: (OFString*)namespace
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		ns = [ns_ copy];
		_namespace = [namespace copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithClass: (Class)class_
	 prefix: (OFString*)prefix_
- initWithClass: (Class)class
	 prefix: (OFString*)prefix
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		prefix = [prefix_ copy];
		_prefix = [prefix copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[ns release];
	[prefix release];
	[_namespace release];
	[_prefix release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	if (ns != nil)
		description = [[OFString alloc] initWithFormat:
		    @"The namespace %@ is not bound in class %@", ns, inClass];
	else if (prefix != nil)
		description = [[OFString alloc] initWithFormat:
	if (_namespace != nil)
		_description = [[OFString alloc] initWithFormat:
		    @"The namespace %@ is not bound in class %@", _namespace,
		    _inClass];
	else if (_prefix != nil)
		_description = [[OFString alloc] initWithFormat:
		    @"The prefix %@ is not bound to any namespace in class %@",
		    prefix, inClass];
		    _prefix, _inClass];

	return description;
	return _description;
}

- (OFString*)namespace
{
	OF_GETTER(ns, NO)
	OF_GETTER(_namespace, NO)
}

- (OFString*)prefix
{
	OF_GETTER(prefix, NO)
	OF_GETTER(_prefix, NO)
}
@end

Modified src/exceptions/OFUnlockFailedException.h from [d78e1a213b] to [0bb7635d95].

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







-
+







#import "OFLocking.h"

/*!
 * @brief An exception indicating that unlocking a lock failed.
 */
@interface OFUnlockFailedException: OFException
{
	id <OFLocking> lock;
	id <OFLocking> _lock;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id <OFLocking> lock;
#endif

/*!

Modified src/exceptions/OFUnlockFailedException.m from [3a12901a60] to [93c2224d43].

18
19
20
21
22
23
24
25

26
27
28

29
30
31
32
33


34
35

36
37

38
39
40
41
42
43
44

45
46
47
48
49
50
51
52


53
54

55
56

57
58

59
60
61
62
63

64
65
18
19
20
21
22
23
24

25
26
27

28
29
30
31


32
33
34

35
36

37
38
39
40
41
42
43

44
45
46
47
48
49
50


51
52
53

54
55

56
57

58
59
60
61
62

63
64
65







-
+


-
+



-
-
+
+

-
+

-
+






-
+






-
-
+
+

-
+

-
+

-
+




-
+



#import "OFUnlockFailedException.h"
#import "OFString.h"

#import "macros.h"

@implementation OFUnlockFailedException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			      lock: (id <OFLocking>)lock
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				       lock: lock] autorelease];
}

- initWithClass: (Class)class_
	   lock: (id <OFLocking>)lock_
- initWithClass: (Class)class
	   lock: (id <OFLocking>)lock
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	lock = [lock_ retain];
	_lock = [lock retain];

	return self;
}

- (void)dealloc
{
	[lock release];
	[_lock release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"A lock of class %@ could not be unlocked in class %@!",
	    [(id)lock className], inClass];
	    [_lock class], _inClass];

	return description;
	return _description;
}

- (id <OFLocking>)lock
{
	OF_GETTER(lock, NO)
	OF_GETTER(_lock, NO)
}
@end

Modified src/exceptions/OFUnsupportedProtocolException.h from [8ebd174edb] to [b626bac85b].

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







-
+










-
+



-
+





-
+



-
+









/*!
 * @brief An exception indicating that the protocol specified by the URL is not
 *	  supported.
 */
@interface OFUnsupportedProtocolException: OFException
{
	OFURL *URL;
	OFURL *_URL;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFURL *URL;
#endif

/*!
 * @brief Creates a new, autoreleased unsupported protocol exception.
 *
 * @param class_ The class of the object which caused the exception
 * @param url The URL whose protocol is unsupported
 * @param URL The URL whose protocol is unsupported
 * @return A new, autoreleased unsupported protocol exception
 */
+ (instancetype)exceptionWithClass: (Class)class_
			       URL: (OFURL*)url;
			       URL: (OFURL*)URL;

/*!
 * @brief Initializes an already allocated unsupported protocol exception
 *
 * @param class_ The class of the object which caused the exception
 * @param url The URL whose protocol is unsupported
 * @param URL The URL whose protocol is unsupported
 * @return An initialized unsupported protocol exception
 */
- initWithClass: (Class)class_
	    URL: (OFURL*)url;
	    URL: (OFURL*)URL;

/*!
 * @brief Returns the URL whose protocol is unsupported.
 *
 * @return The URL whose protocol is unsupported
 */
- (OFURL*)URL;
@end

Modified src/exceptions/OFUnsupportedProtocolException.m from [6a769966a7] to [50dbd9a635].

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







-
+


-
+



-
+











-
-
+
+

-
+


-
+










-
+






-
-
+
+

-
-
-
+
+
+

-
+




-
+


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

#import "common.h"

@implementation OFUnsupportedProtocolException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			       URL: (OFURL*)url
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
					URL: url] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	    URL: (OFURL*)url
- initWithClass: (Class)class
	    URL: (OFURL*)URL
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		URL = [url copy];
		_URL = [URL copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[URL release];
	[_URL release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"The protocol of URL %@ is not supported by class %@", URL,
	    inClass];
	_description = [[OFString alloc] initWithFormat:
	    @"The protocol of URL %@ is not supported by class %@", _URL,
	    _inClass];

	return description;
	return _description;
}

- (OFURL*)URL
{
	OF_GETTER(URL, NO)
	OF_GETTER(_URL, NO)
}
@end

Modified src/exceptions/OFUnsupportedVersionException.h from [4544e1d428] to [d4879e4859].

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 An exception indicating that the specified version of the format or
 *	  protocol is not supported.
 */
@interface OFUnsupportedVersionException: OFException
{
	OFString *version;
	OFString *_version;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *version;
#endif

/*!

Modified src/exceptions/OFUnsupportedVersionException.m from [40aa737247] to [23d60f6018].

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







-
+


-
+



-
+











-
-
+
+

-
+


-
+










-
+






-
-
+
+

-
+

-
+

-
+




-
+



#import "OFUnsupportedVersionException.h"
#import "OFString.h"

#import "common.h"

@implementation OFUnsupportedVersionException
+ (instancetype)exceptionWithClass: (Class)class_
+ (instancetype)exceptionWithClass: (Class)class
			   version: (OFString*)version
{
	return [[[self alloc] initWithClass: class_
	return [[[self alloc] initWithClass: class
				    version: version] autorelease];
}

- initWithClass: (Class)class_
- initWithClass: (Class)class
{
	@try {
		[self doesNotRecognizeSelector: _cmd];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	abort();
}

- initWithClass: (Class)class_
	version: (OFString*)version_
- initWithClass: (Class)class
	version: (OFString*)version
{
	self = [super initWithClass: class_];
	self = [super initWithClass: class];

	@try {
		version = [version_ copy];
		_version = [version copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[version release];
	[_version release];

	[super dealloc];
}

- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	_description = [[OFString alloc] initWithFormat:
	    @"Version %@ of the format or protocol is not supported by class "
	    @"%@", version, inClass];
	    @"%@", _version, _inClass];

	return description;
	return _description;
}

- (OFString*)version
{
	OF_GETTER(version, NO)
	OF_GETTER(_version, NO)
}
@end

Modified src/exceptions/OFWriteFailedException.m from [9862940d46] to [659d063c26].

20
21
22
23
24
25
26
27
28


29
30
31
32



33
34

35
36
20
21
22
23
24
25
26


27
28
29



30
31
32
33

34
35
36







-
-
+
+

-
-
-
+
+
+

-
+


#import "OFString.h"

#import "common.h"

@implementation OFWriteFailedException
- (OFString*)description
{
	if (description != nil)
		return description;
	if (_description != nil)
		return _description;

	description = [[OFString alloc] initWithFormat:
	    @"Failed to write %zu bytes in class %@! " ERRFMT, requestedLength,
	    inClass, ERRPARAM];
	_description = [[OFString alloc] initWithFormat:
	    @"Failed to write %zu bytes in class %@! " ERRFMT, _requestedLength,
	    _inClass, ERRPARAM];

	return description;
	return _description;
}
@end

Modified src/exceptions/common.h from [9a8f628a9b] to [258ae8e83b].

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







-
-
-
+
+
+









-
+

-
+

-
+







-
-
+
+

 */

#include <string.h>

#import "macros.h"

#ifndef _WIN32
#if !defined(HAVE_THREADSAFE_GETADDRINFO) && !defined(_PSP)
# include <netdb.h>
#endif
# if !defined(HAVE_THREADSAFE_GETADDRINFO) && !defined(_PSP)
#  include <netdb.h>
# endif
# include <errno.h>
# define GET_ERRNO	errno
# ifndef HAVE_THREADSAFE_GETADDRINFO
#  define GET_AT_ERRNO	h_errno
# else
#  define GET_AT_ERRNO	errno
# endif
# define GET_SOCK_ERRNO	errno
# define ERRFMT		"Error string was: %s"
# define ERRPARAM	strerror(errNo)
# define ERRPARAM	strerror(_errNo)
# if !defined(HAVE_THREADSAFE_GETADDRINFO) && !defined(_PSP)
#  define AT_ERRPARAM	hstrerror(errNo)
#  define AT_ERRPARAM	hstrerror(_errNo)
# else
#  define AT_ERRPARAM	strerror(errNo)
#  define AT_ERRPARAM	strerror(_errNo)
# endif
#else
# include <windows.h>
# define GET_ERRNO	GetLastError()
# define GET_AT_ERRNO	WSAGetLastError()
# define GET_SOCK_ERRNO	WSAGetLastError()
# define ERRFMT		"Error code was: %d"
# define ERRPARAM	errNo
# define AT_ERRPARAM	errNo
# define ERRPARAM	_errNo
# define AT_ERRPARAM	_errNo
#endif

Modified tests/TestsAppDelegate.h from [7bc108d8f9] to [d5a4c58861].

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







-
+







							\
		if (cond)				\
			[self outputSuccess: test	\
				   inModule: module];	\
		else {					\
			[self outputFailure: test	\
				   inModule: module];	\
			fails++;			\
			_fails++;			\
		}					\
	}
#define EXPECT_EXCEPTION(test, exception, code)		\
	{						\
		BOOL caught = NO;			\
							\
		[self outputTesting: test		\
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69







-
+








-
+







							\
		if (caught)				\
			[self outputSuccess: test	\
				   inModule: module];	\
		else {					\
			[self outputFailure: test	\
				   inModule: module];	\
			fails++;			\
			_fails++;			\
		}					\
	}
#define R(x) (x, 1)

@class OFString;

@interface TestsAppDelegate: OFObject
{
	int fails;
	int _fails;
}

- (void)outputString: (OFString*)str
	   withColor: (int)color;
- (void)outputTesting: (OFString*)test
	     inModule: (OFString*)module;
- (void)outputSuccess: (OFString*)test

Modified tests/TestsAppDelegate.m from [573b357575] to [07d163fa23].

152
153
154
155
156
157
158
159

160
161
152
153
154
155
156
157
158

159
160
161







-
+


	[self pluginTests];
#endif
	[self forwardingTests];
#ifdef OF_HAVE_PROPERTIES
	[self propertiesTests];
#endif

	[OFApplication terminateWithStatus: fails];
	[OFApplication terminateWithStatus: _fails];
}
@end