ObjFW  Check-in [1255f3a11a]

Overview
Comment:Directly use the runtime's autorelease pools.

This greatly improves performance, as it gets rid of the overhead of
OFAutoreleasePool.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 1255f3a11a56620ece5736a95d26820c96fecdb9c9d35033d46b205e0c35f1d0
User & Date: js on 2012-08-10 20:08:24
Other Links: manifest | tags
Context
2012-08-10
20:08
Add GNU stack note. check-in: 7e27f00a5d user: js tags: trunk
20:08
Directly use the runtime's autorelease pools. check-in: 1255f3a11a user: js tags: trunk
2012-08-09
15:37
Cache 32 autorelease pools per thread. check-in: 4ad6599390 user: js tags: trunk
Changes

Modified src/OFApplication.m from [26c169306d] to [77883af432].

24
25
26
27
28
29
30
31
32
33


34
35
36
37
38
39
40
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41







-


+
+








#include <signal.h>

#import "OFApplication.h"
#import "OFString.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFAutoreleasePool.h"

#import "OFNotImplementedException.h"

#import "autorelease.h"

#if defined(__MACH__) && !defined(OF_IOS)
# include <crt_externs.h>
#elif !defined(OF_IOS)
extern char **environ;
#endif

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







-
+











-
-





+
+

















-
+








+
+




















+
+

-













-
+




















-
+







}

- init
{
	self = [super init];

	@try {
		OFAutoreleasePool *pool;
		void *pool;
#if defined(__MACH__) && !defined(OF_IOS)
		char **env = *_NSGetEnviron();
#elif !defined(OF_IOS)
		char **env = environ;
#else
		char *env;
#endif

		environment = [[OFMutableDictionary alloc] init];

		atexit(atexit_handler);

		pool = [[OFAutoreleasePool alloc] init];
#ifndef OF_IOS
		for (; *env != NULL; env++) {
			OFString *key;
			OFString *value;
			char *sep;

			pool = objc_autoreleasePoolPush();

			if ((sep = strchr(*env, '=')) == NULL) {
				fprintf(stderr, "Warning: Invalid environment "
				    "variable: %s\n", *env);
				continue;
			}

			key = [OFString
			    stringWithCString: *env
				     encoding: OF_STRING_ENCODING_NATIVE
				       length: sep - *env];
			value = [OFString
			    stringWithCString: sep + 1
				     encoding: OF_STRING_ENCODING_NATIVE];
			[environment setObject: value
					forKey: key];

			[pool releaseObjects];
			objc_autoreleasePoolPop(pool);
		}
#else
		/*
		 * iOS does not provide environ and Apple does not allow using
		 * _NSGetEnviron on iOS. Therefore, we just get a few common
		 * variables from the environment which applications might
		 * expect.
		 */
		pool = objc_autoreleasePoolPush();

		if ((env = getenv("HOME")) != NULL)
			[environment
			    setObject: [OFString stringWithUTF8String: env]
			       forKey: @"HOME"];
		if ((env = getenv("PATH")) != NULL)
			[environment
			    setObject: [OFString stringWithUTF8String: env]
			       forKey: @"PATH"];
		if ((env = getenv("SHELL")) != NULL)
			[environment
			    setObject: [OFString stringWithUTF8String: env]
			       forKey: @"SHELL"];
		if ((env = getenv("TMPDIR")) != NULL)
			[environment
			    setObject: [OFString stringWithUTF8String: env]
			       forKey: @"TMPDIR"];
		if ((env = getenv("USER")) != NULL)
			[environment
			    setObject: [OFString stringWithUTF8String: env]
			       forKey: @"USER"];

		objc_autoreleasePoolPop(pool);
#endif
		[pool release];

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

	return self;
}

- (void)setArgumentCount: (int*)argc_
       andArgumentValues: (char***)argv_
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	int i;

	[programName release];
	[arguments release];

	argc = argc_;
	argv = argv_;

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

	[pool release];
	objc_autoreleasePoolPop(pool);
}

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

Modified src/OFArray.m from [3601f4b0dd] to [208e599910].

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

33
34
35
36
37
38
39
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39







-






+







#include <stdarg.h>

#import "OFArray.h"
#import "OFArray_subarray.h"
#import "OFArray_adjacent.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfRangeException.h"

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

static struct {
	Class isa;
} placeholder;

@interface OFArray_placeholder: OFArray
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
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







-
+













-
+


+
-
+

-




-
+






-
+







	return [self componentsJoinedByString: separator
				usingSelector: @selector(description)];
}

- (OFString*)componentsJoinedByString: (OFString*)separator
			usingSelector: (SEL)selector
{
	OFAutoreleasePool *pool, *pool2;
	void *pool;
	OFMutableString *ret;
	id *objects;
	size_t i, count = [self count];
	IMP append;

	if (count == 0)
		return @"";
	if (count == 1)
		return [[self firstObject] performSelector: selector];

	ret = [OFMutableString string];
	append = [ret methodForSelector: @selector(appendString:)];

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();
	objects = [self objects];

	for (i = 0; i < count - 1; i++) {
	pool2 = [[OFAutoreleasePool alloc] init];
		void *pool2 = objc_autoreleasePoolPush();

	for (i = 0; i < count - 1; i++) {
		append(ret, @selector(appendString:),
		    [objects[i] performSelector: selector]);
		append(ret, @selector(appendString:), separator);

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool2);
	}
	append(ret, @selector(appendString:),
	    [objects[i] performSelector: selector]);

	[ret makeImmutable];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return ret;
}

- (BOOL)isEqual: (id)object
{
	/* FIXME: Optimize (for example, buffer of 16 for each) */
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
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







-
+





-
+












-
+


-

-
+




-
-
+











+
-
+

-


-
+



-
-
+
+

-
+




-
+





-
-






+
+
-
+







	OF_HASH_FINALIZE(hash);

	return hash;
}

- (OFString*)description
{
	OFAutoreleasePool *pool;
	void *pool;
	OFMutableString *ret;

	if ([self count] == 0)
		return @"()";

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();
	ret = [[self componentsJoinedByString: @",\n"] mutableCopy];

	@try {
		[ret prependString: @"(\n"];
		[ret replaceOccurrencesOfString: @"\n"
				     withString: @"\n\t"];
		[ret appendString: @"\n)"];
	} @catch (id e) {
		[ret release];
		@throw e;
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	[ret makeImmutable];
	[ret autorelease];

	return ret;
	return [ret autorelease];
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFAutoreleasePool *pool2;
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;
	id <OFSerialization> *objects = [self objects];
	size_t i, count = [self count];

	if ([self isKindOfClass: [OFMutableArray class]])
		element = [OFXMLElement elementWithName: @"OFMutableArray"
					      namespace: OF_SERIALIZATION_NS];
	else
		element = [OFXMLElement elementWithName: @"OFArray"
					      namespace: OF_SERIALIZATION_NS];

	for (i = 0; i < count; i++) {
	pool2 = [[OFAutoreleasePool alloc] init];
		void *pool2 = objc_autoreleasePoolPush();

	for (i = 0; i < count; i++) {
		[element addChild: [objects[i] XMLElementBySerializing]];

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool2);
	}

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}

- (OFString*)JSONRepresentation
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFMutableString *JSON;

	JSON = [[self componentsJoinedByString: @","
				 usingSelector: @selector(JSONRepresentation)]
	    mutableCopy];
	[pool release];
	[JSON autorelease];

	[JSON prependString: @"["];
	[JSON appendString: @"]"];

	[JSON makeImmutable];

	objc_autoreleasePoolPop(pool);

	return JSON;
	return [JSON autorelease];
}

- (void)makeObjectsPerformSelector: (SEL)selector
{
	id *objects = [self objects];
	size_t i, count = [self count];

Modified src/OFArray_adjacent.m from [a6c8e71afe] to [9a07b7851a].

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

33
34
35
36
37
38
39
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39







-





+








#import "OFArray_adjacent.h"
#import "OFMutableArray_adjacent.h"
#import "OFArray_adjacentSubarray.h"
#import "OFDataArray.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfRangeException.h"

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

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

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







-
+



-
-









-


+
+
+
-
+



-
+


-
+







}

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

	@try {
		OFAutoreleasePool *pool, *pool2;
		void *pool = objc_autoreleasePoolPush();
		OFEnumerator *enumerator;
		OFXMLElement *child;

		pool = [[OFAutoreleasePool alloc] init];

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

		enumerator = [[element elementsForNamespace:
		    OF_SERIALIZATION_NS] objectEnumerator];
		pool2 = [[OFAutoreleasePool alloc] init];

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

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

			[pool2 releaseObjects];
			objc_autoreleasePoolPop(pool2);
		}

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

	return self;
}

Modified src/OFCountedSet.m from [e5a46a4669] to [3f8c1b4cf9].

17
18
19
20
21
22
23
24
25
26


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

24
25
26
27
28
29
30
31
32
33
34







-


+
+







#include "config.h"

#import "OFCountedSet.h"
#import "OFCountedSet_hashtable.h"
#import "OFNumber.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFNotImplementedException.h"

#import "autorelease.h"

static struct {
	Class isa;
} placeholder;

@interface OFCountedSet_placeholder: OFCountedSet
@end
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
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







-
+








-
-
+
+

+

+
-
+

-






-
+







-
+
















-
-
+









-

+
+















-
+



-
-
+
+

-
+














-
+




















-
+




-
+




















-
+


	@throw [OFNotImplementedException exceptionWithClass: [self class]
						    selector: _cmd];
}

- (OFString*)description
{
	OFMutableString *ret;
	OFAutoreleasePool *pool, *pool2;
	void *pool;
	OFEnumerator *enumerator;
	size_t i, count = [self count];
	id object;

	if (count == 0)
		return @"{()}";

	ret = [OFMutableString stringWithString: @"{(\n"];
	pool = [[OFAutoreleasePool alloc] init];
	enumerator = [self objectEnumerator];

	pool = objc_autoreleasePoolPush();

	enumerator = [self objectEnumerator];
	i = 0;
	while ((object = [enumerator nextObject]) != nil) {
	pool2 = [[OFAutoreleasePool alloc] init];
		void *pool2 = objc_autoreleasePoolPush();

	while ((object = [enumerator nextObject]) != nil) {
		[ret appendString: object];
		[ret appendFormat: @": %zu", [self countForObject: object]];

		if (++i < count)
			[ret appendString: @",\n"];

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool2);
	}
	[ret replaceOccurrencesOfString: @"\n"
			     withString: @"\n\t"];
	[ret appendString: @"\n)}"];

	[ret makeImmutable];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return ret;
}

- copy
{
	return [[OFCountedSet alloc] initWithSet: self];
}

- mutableCopy
{
	return [[OFCountedSet alloc] initWithSet: self];
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFAutoreleasePool *pool2;
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;
	OFEnumerator *enumerator;
	id <OFSerialization> object;

	element = [OFXMLElement elementWithName: @"OFCountedSet"
				      namespace: OF_SERIALIZATION_NS];

	enumerator = [self objectEnumerator];

	pool2 = [[OFAutoreleasePool alloc] init];
	while ((object = [enumerator nextObject]) != nil) {
		void *pool2 = objc_autoreleasePoolPush();

		OFXMLElement *objectElement;
		OFString *count;

		count =
		    [OFString stringWithFormat: @"%zu",
						[self countForObject: object]];

		objectElement = [OFXMLElement
		    elementWithName: @"object"
			  namespace: OF_SERIALIZATION_NS];
		[objectElement addAttributeWithName: @"count"
					stringValue: count];
		[objectElement addChild: [object XMLElementBySerializing]];
		[element addChild: objectElement];

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool2);
	}

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}

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

- (void)minusSet: (OFSet*)set
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();

	if ([set isKindOfClass: [OFCountedSet class]]) {
		OFCountedSet *countedSet = (OFCountedSet*)set;
		OFEnumerator *enumerator = [countedSet objectEnumerator];
		id object;

		while ((object = [enumerator nextObject]) != nil) {
			size_t i, count = [countedSet countForObject: object];

			for (i = 0; i < count; i++)
				[self removeObject: object];
		}
	} else {
		OFEnumerator *enumerator = [set objectEnumerator];
		id object;

		while ((object = [enumerator nextObject]) != nil)
			[self removeObject: object];
	}

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)unionSet: (OFSet*)set
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();

	if ([set isKindOfClass: [OFCountedSet class]]) {
		OFCountedSet *countedSet = (OFCountedSet*)set;
		OFEnumerator *enumerator = [countedSet objectEnumerator];
		id object;

		while ((object = [enumerator nextObject]) != nil) {
			size_t i, count = [countedSet countForObject: object];

			for (i = 0; i < count; i++)
				[self addObject: object];
		}
	} else {
		OFEnumerator *enumerator = [set objectEnumerator];
		id object;

		while ((object = [enumerator nextObject]) != nil)
			[self addObject: object];
	}

	[pool release];
	objc_autoreleasePoolPop(pool);
}
@end

Modified src/OFCountedSet_hashtable.m from [b90b5a288c] to [f28bc3a5ac].

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







-



+
+













-
+







#import "OFCountedSet_hashtable.h"
#import "OFMutableDictionary_hashtable.h"
#import "OFString.h"
#import "OFNumber.h"
#import "OFArray.h"
#import "OFXMLElement.h"
#import "OFXMLAttribute.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"

#import "autorelease.h"

@implementation OFCountedSet_hashtable
+ (void)initialize
{
	if (self == [OFCountedSet_hashtable class])
		[self inheritMethodsFromClass: [OFMutableSet_hashtable class]];
}

- initWithSet: (OFSet*)set
{
	self = [self init];

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();

		if ([set isKindOfClass: [OFCountedSet class]]) {
			OFCountedSet *countedSet = (OFCountedSet*)countedSet;
			OFEnumerator *enumerator =
			    [countedSet objectEnumerator];
			id object;

63
64
65
66
67
68
69
70

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

71
72
73
74
75
76
77
78







-
+







			OFEnumerator *enumerator = [set objectEnumerator];
			id object;

			while ((object = [enumerator nextObject]) != nil)
				[self addObject: object];
		}

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

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







-
-
+














-
-

+



















-
+


-
+







}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		OFAutoreleasePool *pool2;
		void *pool = objc_autoreleasePoolPush();
		OFArray *objects;
		OFEnumerator *enumerator;
		OFXMLElement *objectElement;

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

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

		enumerator = [objects objectEnumerator];
		pool2 = [[OFAutoreleasePool alloc] init];

		while ((objectElement = [enumerator nextObject]) != nil) {
			void *pool2 = objc_autoreleasePoolPush();
			OFXMLElement *object;
			OFXMLAttribute *count;
			OFNumber *number;

			object = [[objectElement elementsForNamespace:
			    OF_SERIALIZATION_NS] firstObject];
			count = [objectElement attributeForName: @"count"];

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

			number = [OFNumber numberWithSize:
			    (size_t)[[count stringValue] decimalValue]];

			[dictionary _setObject: number
					forKey: [object objectByDeserializing]
				       copyKey: NO];

			[pool2 releaseObjects];
			objc_autoreleasePoolPop(pool2);
		}

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

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







-
+













-
+





-
+




-
+











-
+






		block(key, [object sizeValue], stop);
	}];
}
#endif

- (void)addObject: (id)object
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFNumber *count;

	count = [[dictionary objectForKey: object] numberByIncreasing];

	if (count == nil)
		count = [OFNumber numberWithSize: 1];

	[dictionary _setObject: count
			forKey: object
		       copyKey: NO];

	mutations++;

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)removeObject: (id)object
{
	OFNumber *count = [dictionary objectForKey: object];
	OFAutoreleasePool *pool;
	void *pool;

	if (count == nil)
		return;

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();
	count = [count numberByDecreasing];

	if ([count sizeValue] > 0)
		[dictionary _setObject: count
				forKey: object
			       copyKey: NO];
	else
		[dictionary removeObjectForKey: object];

	mutations++;

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)makeImmutable
{
}
@end

Modified src/OFDataArray+Hashing.m from [1c7d02816a] to [763b1e6eda].

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







+
-
+






-
+



















-
+








-
+



















-
+







#include "config.h"

#import "OFDataArray.h"
#import "OFString.h"
#import "OFMD5Hash.h"
#import "OFSHA1Hash.h"

#import "OFAutoreleasePool.h"
#import "autorelease.h"

int _OFDataArray_Hashing_reference;

@implementation OFDataArray (Hashing)
- (OFString*)MD5Hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFMD5Hash *hash = [OFMD5Hash hash];
	uint8_t *digest;
	char cString[OF_MD5_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: data
			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;

		cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: 32];
}

- (OFString*)SHA1Hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFMD5Hash *hash = [OFSHA1Hash hash];
	uint8_t *digest;
	char cString[OF_SHA1_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: data
			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;

		cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: 40];
}
@end

Modified src/OFDataArray.m from [3687781c21] to [aae2d470af].

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

38
39
40
41
42
43
44
22
23
24
25
26
27
28

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







-








+








#import "OFDataArray.h"
#import "OFString.h"
#import "OFFile.h"
#import "OFURL.h"
#import "OFHTTPRequest.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFHTTPRequestFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidEncodingException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

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

/* References for static linking */
void _references_to_categories_of_OFDataArray(void)
{
	_OFDataArray_Hashing_reference = 1;
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
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







-
+







-
+



-
+













-
+







	}

	return self;
}

- initWithContentsOfURL: (OFURL*)URL
{
	OFAutoreleasePool *pool;
	void *pool;
	OFHTTPRequest *request;
	OFHTTPRequestResult *result;
	Class c;

	c = [self class];
	[self release];

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	if ([[URL scheme] isEqual: @"file"]) {
		self = [[c alloc] initWithContentsOfFile: [URL path]];
		[pool release];
		objc_autoreleasePoolPop(pool);
		return self;
	}

	request = [OFHTTPRequest requestWithURL: URL];
	result = [request perform];

	if ([result statusCode] != 200)
		@throw [OFHTTPRequestFailedException
		    exceptionWithClass: [request class]
			   HTTPRequest: request
				result: result];

	self = [[result data] retain];
	[pool release];
	objc_autoreleasePoolPop(pool);
	return self;
}

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

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







-
+

















-
+







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

	itemSize = 1;

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();
		OFString *stringValue;

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

		stringValue = [element stringValue];

		if (!of_base64_decode(self,
		    [stringValue cStringWithEncoding: OF_STRING_ENCODING_ASCII],
		    [stringValue cStringLengthWithEncoding:
		    OF_STRING_ENCODING_ASCII]))
			@throw [OFInvalidEncodingException
			    exceptionWithClass: [self class]];

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

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







-
+







-
+






-
-
+
+

-
+







	} @finally {
		[file release];
	}
}

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

	if (itemSize != 1)
		@throw [OFNotImplementedException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();
	element = [OFXMLElement
	    elementWithName: [self className]
		  namespace: OF_SERIALIZATION_NS
		stringValue: of_base64_encode(data, count * itemSize)];

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}
@end

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

Modified src/OFDate.m from [1da3535d97] to [91f4360e05].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
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 <sys/time.h>

#import "OFDate.h"
#import "OFString.h"
#import "OFDictionary.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"
#ifdef OF_THREADS
# import "OFThread.h"
#endif

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"

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

#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_THREADS)
static OFMutex *mutex;
#endif
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
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







-
+














-
+







}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();
		union {
			double d;
			uint64_t u;
		} d;

		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 = of_bswap_double_if_le(d.d);

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

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







-
+














-
-
+
+

-
+







- (OFString*)description
{
	return [self dateStringWithFormat: @"%Y-%m-%dT%H:%M:%SZ"];
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;
	union {
		double d;
		uint64_t u;
	} d;

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

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

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}

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

Modified src/OFDictionary.m from [4a522c344b] to [5774d8a182].

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
36







-


+
+







#include <assert.h>

#import "OFDictionary.h"
#import "OFDictionary_hashtable.h"
#import "OFArray.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFNotImplementedException.h"

#import "autorelease.h"

static struct {
	Class isa;
} placeholder;

@interface OFDictionary_placeholder: OFDictionary
@end
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
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







-
+











-
+







-
+




-
+






-
+





-
+




-
+






-
+





-
+




-
+






-
+







-

-





-
+













-
+







-

-





-
+







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

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

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

	otherDictionary = object;

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

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

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

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

	[pool release];
	objc_autoreleasePoolPop(pool);

	return YES;
}

- (BOOL)containsObject: (id)object
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator = [self objectEnumerator];
	id currentObject;

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

	[pool release];
	objc_autoreleasePoolPop(pool);

	return NO;
}

- (BOOL)containsObjectIdenticalTo: (id)object
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator = [self objectEnumerator];
	id currentObject;

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

	[pool release];
	objc_autoreleasePoolPop(pool);

	return NO;
}

- (OFArray*)allKeys
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	id *keys = [self allocMemoryWithSize: sizeof(id)
				       count: [self count]];
	OFArray *ret;
	OFEnumerator *enumerator;
	id key;
	size_t i = 0;

	pool = [[OFAutoreleasePool alloc] init];
	enumerator = [self keyEnumerator];

	while ((key = [enumerator nextObject]) != nil)
		keys[i++] = key;

	assert(i == [self count]);

	[pool release];
	objc_autoreleasePoolPop(pool);

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

	return ret;
}

- (OFArray*)allObjects
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	id *objects = [self allocMemoryWithSize: sizeof(id)
					  count: [self count]];
	OFArray *ret;
	OFEnumerator *enumerator;
	id object;
	size_t i = 0;

	pool = [[OFAutoreleasePool alloc] init];
	enumerator = [self objectEnumerator];

	while ((object = [enumerator nextObject]) != nil)
		objects[i++] = object;

	assert(i == [self count]);

	[pool release];
	objc_autoreleasePoolPop(pool);

	@try {
		ret = [OFArray arrayWithObjects: objects
					  count: [self count]];
	} @finally {
		[self freeMemory: objects];
	}
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
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







-
+









-
+







-
+








-
+




-
-


+
+







-
+







-
+






-
-
+













-
-


+















-
+



-
-
+
+

-
+





-
+






-
-


+
+







-
+


-
-


+
+





	return new;
}
#endif

- (uint32_t)hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator = [self keyEnumerator];
	id key;
	uint32_t hash = 0;

	while ((key = [enumerator nextObject]) != nil) {
		hash += [key hash];
		hash += [[self objectForKey: key] hash];
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return hash;
}

- (OFString*)description
{
	OFMutableString *ret;
	OFAutoreleasePool *pool, *pool2;
	void *pool;
	OFEnumerator *keyEnumerator, *objectEnumerator;
	id key, object;
	size_t i, count = [self count];

	if (count == 0)
		return @"{}";

	ret = [OFMutableString stringWithString: @"{\n"];
	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();
	keyEnumerator = [self keyEnumerator];
	objectEnumerator = [self objectEnumerator];

	i = 0;
	pool2 = [[OFAutoreleasePool alloc] init];

	while ((key = [keyEnumerator nextObject]) != nil &&
	    (object = [objectEnumerator nextObject]) != nil) {
		void *pool2 = objc_autoreleasePoolPush();

		[ret appendString: [key description]];
		[ret appendString: @" = "];
		[ret appendString: [object description]];

		if (++i < count)
			[ret appendString: @";\n"];

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool2);
	}
	[ret replaceOccurrencesOfString: @"\n"
			     withString: @"\n\t"];
	[ret appendString: @";\n}"];

	[ret makeImmutable];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return ret;
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFAutoreleasePool *pool2;
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;
	OFEnumerator *keyEnumerator, *objectEnumerator;
	id key, object;

	if ([self isKindOfClass: [OFMutableDictionary class]])
		element = [OFXMLElement elementWithName: @"OFMutableDictionary"
					      namespace: OF_SERIALIZATION_NS];
	else
		element = [OFXMLElement elementWithName: @"OFDictionary"
					      namespace: OF_SERIALIZATION_NS];

	keyEnumerator = [self keyEnumerator];
	objectEnumerator = [self objectEnumerator];
	pool2 = [[OFAutoreleasePool alloc] init];

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

		keyElement = [OFXMLElement
		    elementWithName: @"key"
			  namespace: OF_SERIALIZATION_NS];
		[keyElement addChild: [key XMLElementBySerializing]];

		objectElement = [OFXMLElement
		    elementWithName: @"object"
			  namespace: OF_SERIALIZATION_NS];
		[objectElement addChild: [object XMLElementBySerializing]];

		[element addChild: keyElement];
		[element addChild: objectElement];

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool2);
	}

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}

- (OFString*)JSONRepresentation
{
	OFMutableString *JSON = [OFMutableString stringWithString: @"{"];
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init], *pool2;
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *keyEnumerator = [self keyEnumerator];
	OFEnumerator *objectEnumerator = [self objectEnumerator];
	size_t i = 0, count = [self count];
	OFString *key;
	OFString *object;

	pool2 = [[OFAutoreleasePool alloc] init];

	while ((key = [keyEnumerator nextObject]) != nil &&
	    (object = [objectEnumerator nextObject]) != nil) {
		void *pool2 = objc_autoreleasePoolPush();

		[JSON appendString: [key JSONRepresentation]];
		[JSON appendString: @":"];
		[JSON appendString: [object JSONRepresentation]];

		if (++i < count)
			[JSON appendString: @","];

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool2);
	}

	[pool release];

	[JSON appendString: @"}"];
	[JSON makeImmutable];

	objc_autoreleasePoolPop(pool);

	return JSON;
}
@end

Modified src/OFDictionary_hashtable.m from [64cc71dd61] to [ce4770d88a].

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

37
38
39
40
41
42
43
22
23
24
25
26
27
28

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







-







+








#import "OFDictionary_hashtable.h"
#import "OFMutableDictionary_hashtable.h"
#import "OFEnumerator.h"
#import "OFArray.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfRangeException.h"

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

struct of_dictionary_hashtable_bucket
    of_dictionary_hashtable_deleted_bucket = {};
#define DELETED &of_dictionary_hashtable_deleted_bucket

@implementation OFDictionary_hashtable
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134







-
+







	    [dictionary class] == [OFMutableDictionary_hashtable class])
		return [self _initWithDictionary: dictionary
					copyKeys: YES];

	self = [super init];

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool;
		OFEnumerator *enumerator;
		id key;
		uint32_t i, newSize;

		count = [dictionary count];

		if (count > UINT32_MAX)
147
148
149
150
151
152
153
154

155
156

157
158
159
160
161
162
163
147
148
149
150
151
152
153

154

155
156
157
158
159
160
161
162
163







-
+
-

+







					   count: newSize];

		for (i = 0; i < newSize; i++)
			data[i] = NULL;

		size = newSize;

		pool = [[OFAutoreleasePool alloc] init];
		pool = objc_autoreleasePoolPush();
		enumerator = [dictionary keyEnumerator];

		enumerator = [dictionary keyEnumerator];
		while ((key = [enumerator nextObject]) != nil) {
			uint32_t hash, last;
			struct of_dictionary_hashtable_bucket *bucket;
			id object;

			hash = [key hash];
			last = size;
183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197







-
+







			bucket->key = [key copy];
			bucket->object = [object retain];
			bucket->hash = hash;

			data[i] = bucket;
		}

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

	return self;
}
497
498
499
500
501
502
503
504
505

506
507
508
509
510
511
512
497
498
499
500
501
502
503


504
505
506
507
508
509
510
511







-
-
+








	return self;
}

- initWithSerialization: (OFXMLElement*)element
{
	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		OFAutoreleasePool *pool2;
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *dictionary;
		OFArray *keys, *objects;
		OFEnumerator *keyEnumerator, *objectEnumerator;
		OFXMLElement *keyElement, *objectElement;

		if ((![[element name] isEqual: @"OFDictionary"] &&
		    ![[element name] isEqual: @"OFMutableDictionary"]) ||
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
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







-
-


+














-
+




-
+








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

		keyEnumerator = [keys objectEnumerator];
		objectEnumerator = [objects objectEnumerator];
		pool2 = [[OFAutoreleasePool alloc] init];

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

			[dictionary setObject: [object objectByDeserializing]
				       forKey: [key objectByDeserializing]];

			[pool2 releaseObjects];
			objc_autoreleasePoolPop(pool2);
		}

		self = [self initWithDictionary: dictionary];

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

	return self;
}

Modified src/OFFile.m from [5fa5942d93] to [9427d5f441].

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

51
52
53
54
55
56
57







-







#import "OFString.h"
#import "OFArray.h"
#ifdef OF_THREADS
# import "threading.h"
#endif
#import "OFDate.h"
#import "OFApplication.h"
#import "OFAutoreleasePool.h"

#import "OFChangeDirectoryFailedException.h"
#import "OFChangeFileModeFailedException.h"
#import "OFChangeFileOwnerFailedException.h"
#import "OFCreateDirectoryFailedException.h"
#import "OFDeleteDirectoryFailedException.h"
#import "OFDeleteFileFailedException.h"
66
67
68
69
70
71
72

73
74
75
76
77
78
79
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79







+







#import "OFOutOfMemoryException.h"
#import "OFReadFailedException.h"
#import "OFRenameFileFailedException.h"
#import "OFSeekFailedException.h"
#import "OFSymlinkFailedException.h"
#import "OFWriteFailedException.h"

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

#ifdef _WIN32
# import <windows.h>
#endif

#ifndef O_BINARY
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
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







-
+
















-
+








	return -1;
}

void
of_log(OFConstantString *format, ...)
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFDate *date;
	OFString *dateString, *me, *msg;
	va_list arguments;

	date = [OFDate date];
	dateString = [date localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"];
	me = [[OFApplication programName] lastPathComponent];

	va_start(arguments, format);
	msg = [[[OFString alloc] initWithFormat: format
				      arguments: arguments] autorelease];
	va_end(arguments);

	[of_stderr writeFormat: @"[%@.%03d %@(%d)] %@\n", dateString,
				[date microsecond] / 1000, me, getpid(), msg];

	[pool release];
	objc_autoreleasePoolPop(pool);
}

@interface OFFileSingleton: OFFile
@end

@implementation OFFile
#if defined(OF_THREADS) && !defined(_WIN32)
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
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







-
+









-
+



-

+
+











-
+
+
+



-
+




-













-
-

+











-
+

-
-




+



-









-
-

+











-
+

-
-




-
+







		    exceptionWithClass: self
				  path: path];
}

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

	if (!createParents) {
		[OFFile createDirectoryAtPath: path];
		return;
	}

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	pathComponents = [path pathComponents];
	enumerator = [pathComponents objectEnumerator];
	pool2 = [[OFAutoreleasePool alloc] init];
	while ((component = [enumerator nextObject]) != nil) {
		void *pool2 = objc_autoreleasePoolPush();

		if (currentPath != nil)
			currentPath = [OFString
			    stringWithPath: currentPath, component, nil];
		else
			currentPath = component;

		if (![currentPath isEqual: @""] &&
		    ![OFFile directoryExistsAtPath: currentPath])
			[OFFile createDirectoryAtPath: currentPath];

		[currentPath retain];
		[pool2 releaseObjects];

		objc_autoreleasePoolPop(pool2);

		[currentPath autorelease];
	}

	[pool release];
	objc_autoreleasePoolPop(pool);
}

+ (OFArray*)filesInDirectoryAtPath: (OFString*)path
{
	OFAutoreleasePool *pool;
	OFMutableArray *files = [OFMutableArray array];

#ifndef _WIN32
	DIR *dir;
	struct dirent *dirent;

	if ((dir = opendir([path cStringWithEncoding:
	    OF_STRING_ENCODING_NATIVE])) == NULL)
		@throw [OFOpenFileFailedException exceptionWithClass: self
								path: path
							  mode: @"r"];

	@try {
		pool = [[OFAutoreleasePool alloc] init];

		while ((dirent = readdir(dir)) != NULL) {
			void *pool = objc_autoreleasePoolPush();
			OFString *file;

			if (!strcmp(dirent->d_name, ".") ||
			    !strcmp(dirent->d_name, ".."))
				continue;

			file = [OFString
			    stringWithCString: dirent->d_name
				     encoding: OF_STRING_ENCODING_NATIVE];
			[files addObject: file];

			[pool releaseObjects];
			objc_autoreleasePoolPop(pool);
		}

		[pool release];
	} @finally {
		closedir(dir);
	}
#else
	void *pool = objc_autoreleasePoolPush();
	HANDLE handle;
	WIN32_FIND_DATA fd;

	pool = [[OFAutoreleasePool alloc] init];
	path = [path stringByAppendingString: @"\\*"];

	if ((handle = FindFirstFile([path cStringWithEncoding:
	    OF_STRING_ENCODING_NATIVE], &fd)) == INVALID_HANDLE_VALUE)
		@throw [OFOpenFileFailedException exceptionWithClass: self
								path: path
								mode: @"r"];

	@try {
		OFAutoreleasePool *pool2 = [[OFAutoreleasePool alloc] init];

		do {
			void *pool2 = objc_autoreleasePoolPush();
			OFString *file;

			if (!strcmp(fd.cFileName, ".") ||
			    !strcmp(fd.cFileName, ".."))
				continue;

			file = [OFString
			    stringWithCString: fd.cFileName
				     encoding: OF_STRING_ENCODING_NATIVE];
			[files addObject: file];

			[pool2 releaseObjects];
			objc_autoreleasePoolPop(pool2);
		} while (FindNextFile(handle, &fd));

		[pool2 release];
	} @finally {
		FindClose(handle);
	}

	[pool release];
	objc_autoreleasePoolPop(pool);
#endif

	[files makeImmutable];

	return files;
}

496
497
498
499
500
501
502
503

504
505
506
507
508
509
510
492
493
494
495
496
497
498

499
500
501
502
503
504
505
506







-
+







				 group: group];
}
#endif

+ (void)copyFileAtPath: (OFString*)source
		toPath: (OFString*)destination
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	BOOL override;
	OFFile *sourceFile = nil;
	OFFile *destinationFile = nil;
	char *buffer;

	if ([self directoryExistsAtPath: destination]) {
		OFString *filename = [source lastPathComponent];
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
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







-
+





-
+



















-
+







#endif
	} @finally {
		[sourceFile close];
		[destinationFile close];
		free(buffer);
	}

	[pool release];
	objc_autoreleasePoolPop(pool);
}

+ (void)renameFileAtPath: (OFString*)source
		  toPath: (OFString*)destination
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();

	if ([self directoryExistsAtPath: destination]) {
		OFString *filename = [source lastPathComponent];
		destination = [OFString stringWithPath: destination, filename,
							nil];
	}

#ifndef _WIN32
	if (rename([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    [destination cStringWithEncoding: OF_STRING_ENCODING_NATIVE]))
#else
	if (!MoveFile([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    [destination cStringWithEncoding: OF_STRING_ENCODING_NATIVE]))
#endif
		@throw [OFRenameFileFailedException
		    exceptionWithClass: self
			    sourcePath: source
		       destinationPath: destination];

	[pool release];
	objc_autoreleasePoolPop(pool);
}

+ (void)deleteFileAtPath: (OFString*)path
{
#ifndef _WIN32
	if (unlink([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE]))
#else
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
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







-
+













-
+







-
+














-
+







				  path: path];
}

#ifndef _WIN32
+ (void)linkFileAtPath: (OFString*)source
		toPath: (OFString*)destination
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();

	if ([self directoryExistsAtPath: destination]) {
		OFString *filename = [source lastPathComponent];
		destination = [OFString stringWithPath: destination, filename,
							nil];
	}

	if (link([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    [destination cStringWithEncoding: OF_STRING_ENCODING_NATIVE]) != 0)
		@throw [OFLinkFailedException exceptionWithClass: self
						      sourcePath: source
						 destinationPath: destination];

	[pool release];
	objc_autoreleasePoolPop(pool);
}
#endif

#if !defined(_WIN32) && !defined(_PSP)
+ (void)symlinkFileAtPath: (OFString*)source
		   toPath: (OFString*)destination
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();

	if ([self directoryExistsAtPath: destination]) {
		OFString *filename = [source lastPathComponent];
		destination = [OFString stringWithPath: destination, filename,
							nil];
	}

	if (symlink([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    [destination cStringWithEncoding: OF_STRING_ENCODING_NATIVE]) != 0)
		@throw [OFSymlinkFailedException
		    exceptionWithClass: self
			    sourcePath: source
		       destinationPath: destination];

	[pool release];
	objc_autoreleasePoolPop(pool);
}
#endif

- init
{
	Class c = [self class];
	[self release];

Modified src/OFHTTPRequest.m from [435afd59fe] to [c7bd138f6a].

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







-










+








#import "OFHTTPRequest.h"
#import "OFString.h"
#import "OFURL.h"
#import "OFTCPSocket.h"
#import "OFDictionary.h"
#import "OFDataArray.h"
#import "OFAutoreleasePool.h"

#import "OFHTTPRequestFailedException.h"
#import "OFInvalidEncodingException.h"
#import "OFInvalidFormatException.h"
#import "OFInvalidServerReplyException.h"
#import "OFOutOfRangeException.h"
#import "OFTruncatedDataException.h"
#import "OFUnsupportedProtocolException.h"
#import "OFUnsupportedVersionException.h"

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

Class of_http_request_tls_socket_class = Nil;

static OF_INLINE void
normalizeKey(OFString *key)
{
183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197







-
+







- (OFHTTPRequestResult*)perform
{
	return [self performWithRedirects: 10];
}

- (OFHTTPRequestResult*)performWithRedirects: (size_t)redirects
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFString *scheme = [URL scheme];
	OFTCPSocket *sock;
	OFHTTPRequestResult *result;
	OFString *line, *path, *version;
	OFMutableDictionary *serverHeaders;
	OFDataArray *data;
	OFEnumerator *keyEnumerator, *objectEnumerator;
363
364
365
366
367
368
369
370

371
372
373
374
375
376
377
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377







-
+








			if (status == 303) {
				requestType = OF_HTTP_REQUEST_TYPE_GET;
				[queryString release];
				queryString = nil;
			}

			[pool release];
			objc_autoreleasePoolPop(pool);

			return [self performWithRedirects: redirects - 1];
		}

		[serverHeaders setObject: value
				  forKey: key];
	}
393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
393
394
395
396
397
398
399


400
401
402
403
404
405
406
407
408
409







-
-


+







			@throw [OFOutOfRangeException
			    exceptionWithClass: [self class]];
	}

	buffer = [self allocMemoryWithSize: of_pagesize];
	bytesReceived = 0;
	@try {
		OFAutoreleasePool *pool2 = [[OFAutoreleasePool alloc] init];

		if (chunked) {
			for (;;) {
				void *pool2 = objc_autoreleasePoolPush();
				size_t pos, toRead;

				@try {
					line = [sock readLine];
				} @catch (OFInvalidEncodingException *e) {
					@throw [OFInvalidServerReplyException
					    exceptionWithClass: [self class]];
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
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







-
+
+
+



















-
+







+
+



-
+
+










-
-








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

					[delegate request: self
					   didReceiveData: buffer
					       withLength: length];
					[pool2 releaseObjects];

					objc_autoreleasePoolPop(pool2);
					pool2 = objc_autoreleasePoolPush();

					bytesReceived += length;
					[data addItemsFromCArray: buffer
							   count: length];

					toRead -= length;
				}

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

				if (![line isEqual: @""])
					@throw [OFInvalidServerReplyException
					    exceptionWithClass: [self class]];

				[pool2 releaseObjects];
				objc_autoreleasePoolPop(pool2);
			}
		} else {
			size_t length;

			while ((length = [sock
			    readIntoBuffer: buffer
				    length: of_pagesize]) > 0) {
				void *pool2 = objc_autoreleasePoolPush();

				[delegate request: self
				   didReceiveData: buffer
				       withLength: length];
				[pool2 releaseObjects];

				objc_autoreleasePoolPop(pool2);

				bytesReceived += length;
				[data addItemsFromCArray: buffer
						   count: length];

				if (contentLengthHeader != nil &&
				    bytesReceived >= contentLength)
					break;
			}
		}

		[pool2 release];
	} @finally {
		[self freeMemory: buffer];
	}

	[sock close];

	/*
516
517
518
519
520
521
522
523

524
525
526
527
528
529
530
518
519
520
521
522
523
524

525
526
527
528
529
530
531
532







-
+







		[result release];
		@throw [OFHTTPRequestFailedException
		    exceptionWithClass: [self class]
			   HTTPRequest: self
				result: result];
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return [result autorelease];
}
@end

@implementation OFHTTPRequestResult
- initWithStatusCode: (short)status

Modified src/OFIntrospection.m from [fd9ea3d6be] to [e0bf0f6365].

21
22
23
24
25
26
27
28
29

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

28
29
30
31
32
33
34
35
36







-

+







#if defined(OF_APPLE_RUNTIME)
# import <objc/runtime.h>
#endif

#import "OFIntrospection.h"
#import "OFString.h"
#import "OFArray.h"
#import "OFAutoreleasePool.h"

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

@implementation OFMethod
#if defined(OF_OBJFW_RUNTIME)
- _initWithMethod: (struct objc_method*)method
{
	self = [super init];
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
215
216
217
218
219
220
221

222
223
224
225
226
227
228







-







}

- initWithClass: (Class)class
{
	self = [super init];

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
#if defined(OF_OBJFW_RUNTIME)
		struct objc_method_list *methodList;
#elif defined(OF_APPLE_RUNTIME)
		Method *methodList;
		Ivar *ivarList;
# ifdef OF_HAVE_PROPERTIES
		objc_property_t *propertyList;
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
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







+



-
+








+




-
+







+






-
+
+









+



-
+








+



-
+








+



-
+








+




-
+












-
-








#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]
				    _initWithMethod: &methodList->methods[i]];
				[classMethods addObject: [method autorelease]];
				[pool releaseObjects];
				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]
				    _initWithMethod: &methodList->methods[i]];
				[instanceMethods addObject:
				    [method autorelease]];
				[pool releaseObjects];
				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]
				    _initWithIvar: &class->ivars->ivars[i]];
				[instanceVariables addObject:
				    [ivar autorelease]];
				[pool releaseObjects];

				objc_autoreleasePoolPop(pool);
			}
		}

		/* TODO: properties */
#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]
				    _initWithMethod: methodList[i]]
				    autorelease]];
				[pool releaseObjects];
				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]
				    _initWithMethod: methodList[i]]
				    autorelease]];
				[pool releaseObjects];
				objc_autoreleasePoolPop(pool);
			}
		} @finally {
			free(methodList);
		}

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

		propertyList = class_copyPropertyList(class, &count);
		@try {
			for (i = 0; i < count; i++) {
				void *pool = objc_autoreleasePoolPush();
				[properties addObject:
				    [[[OFProperty alloc]
				    _initWithProperty: propertyList[i]]
				    autorelease]];
				[pool releaseObjects];
				objc_autoreleasePoolPop(pool);
			}
		} @finally {
			free(propertyList);
		}
#endif

		[classMethods makeImmutable];
		[instanceMethods makeImmutable];
		[instanceVariables makeImmutable];
#ifdef OF_HAVE_PROPERTIES
		[properties makeImmutable];
#endif

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

	return self;
}

Modified src/OFList.m from [22c9c07182] to [c65623ed0a].

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
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 "assert.h"

#import "OFList.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFArray.h"
#import "OFAutoreleasePool.h"

#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"

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

@implementation OFList
+ list
{
	return [[[self alloc] init] autorelease];
}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		OFAutoreleasePool *pool2;
		void *pool = objc_autoreleasePoolPush();
		OFEnumerator *enumerator;
		OFXMLElement *child;

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

		enumerator = [[element elementsForNamespace:
		    OF_SERIALIZATION_NS] objectEnumerator];
		while ((child = [enumerator nextObject]) != nil) {
		pool2 = [[OFAutoreleasePool alloc] init];
			void *pool2 = objc_autoreleasePoolPush();

		while ((child = [enumerator nextObject]) != nil) {
			[self appendObject: [child objectByDeserializing]];

			[pool2 releaseObjects];
			objc_autoreleasePoolPop(pool2);
		}

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

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







-






-


+
+





-
+







-
-





-
-






+
-
+

-


-
+


-
-
-
-








	return hash;
}

- (OFString*)description
{
	OFMutableString *ret;
	OFAutoreleasePool *pool;
	of_list_object_t *iter;

	if (count == 0)
		return @"[]";

	ret = [OFMutableString stringWithString: @"[\n"];
	pool = [[OFAutoreleasePool alloc] init];

	for (iter = firstListObject; iter != NULL; iter = iter->next) {
		void *pool = objc_autoreleasePoolPush();

		[ret appendString: [iter->object description]];

		if (iter->next != NULL)
			[ret appendString: @",\n"];

		[pool releaseObjects];
		objc_autoreleasePoolPop(pool);
	}
	[ret replaceOccurrencesOfString: @"\n"
			     withString: @"\n\t"];
	[ret appendString: @"\n]"];

	[ret makeImmutable];

	[pool release];

	return ret;
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFAutoreleasePool *pool2;
	OFXMLElement *element;
	of_list_object_t *iter;

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

	for (iter = firstListObject; iter != NULL; iter = iter->next) {
	pool2 = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();

	for (iter = firstListObject; iter != NULL; iter = iter->next) {
		[element addChild: [iter->object XMLElementBySerializing]];

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool);
	}

	[element retain];
	[pool release];
	[element autorelease];

	return element;
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
			     count: (int)count_
{

Modified src/OFMutableArray.m from [a85051edf1] to [b2cd72f318].

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

32
33
34
35
36
37
38
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38







-






+








#include <string.h>

#include <assert.h>

#import "OFMutableArray.h"
#import "OFMutableArray_adjacent.h"
#import "OFAutoreleasePool.h"

#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfRangeException.h"

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

static struct {
	Class isa;
} placeholder;

@interface OFMutableArray_placeholder: OFMutableArray
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
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







-
+












-
+







	@throw [OFNotImplementedException exceptionWithClass: [self class]
						    selector: _cmd];
}

- (void)insertObjectsFromArray: (OFArray*)array
		       atIndex: (size_t)index
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator = [array objectEnumerator];
	size_t i, count = [array count];

	for (i = 0; i < count; i++) {
		id object = [enumerator nextObject];

		assert(object != nil);

		[self insertObject: object
			   atIndex: index + i];
	}

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)replaceObjectAtIndex: (size_t)index
		  withObject: (id)object
{
	@throw [OFNotImplementedException exceptionWithClass: [self class]
						    selector: _cmd];

Modified src/OFMutableArray_adjacent.m from [6feaf02274] to [b8f5cd2bb5].

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







-







#include "config.h"

#include <string.h>

#import "OFMutableArray_adjacent.h"
#import "OFArray_adjacent.h"
#import "OFDataArray.h"
#import "OFAutoreleasePool.h"

#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfRangeException.h"

@implementation OFMutableArray_adjacent
+ (void)initialize

Modified src/OFMutableDictionary.m from [d28ad27aa9] to [46ace486e0].

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

20
21
22
23
24
25
26







-







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

#include "config.h"

#import "OFMutableDictionary_hashtable.h"
#import "OFAutoreleasePool.h"

#import "OFNotImplementedException.h"

static struct {
	Class isa;
} placeholder;

Modified src/OFMutableDictionary_hashtable.m from [131e6a2740] to [b21568683c].

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

23
24
25
26
27
28
29







-








#include "config.h"

#include <string.h>

#import "OFMutableDictionary_hashtable.h"
#import "OFDictionary_hashtable.h"
#import "OFAutoreleasePool.h"

#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfRangeException.h"

#import "macros.h"

Modified src/OFMutableSet.m from [cfc47921d9] to [3f9a210be5].

16
17
18
19
20
21
22
23
24
25


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

23
24
25
26
27
28
29
30
31
32
33







-


+
+








#include "config.h"

#include <assert.h>

#import "OFMutableSet.h"
#import "OFMutableSet_hashtable.h"
#import "OFAutoreleasePool.h"

#import "OFNotImplementedException.h"

#import "autorelease.h"

static struct {
	Class isa;
} placeholder;

@interface OFMutableSet_placeholder: OFMutableSet
@end
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
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







-
+






-
+




-
+







{
	@throw [OFNotImplementedException exceptionWithClass: [self class]
						    selector: _cmd];
}

- (void)minusSet: (OFSet*)set
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator = [set objectEnumerator];
	id object;

	while ((object = [enumerator nextObject]) != nil)
		[self removeObject: object];

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)intersectSet: (OFSet*)set
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	size_t count = [self count];
	id *cArray;

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

	@try {
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
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







-
+




-
+






-
+






		for (i = 0; i < count; i++)
			if (![set containsObject: cArray[i]])
			      [self removeObject: cArray[i]];
	} @finally {
		[self freeMemory: cArray];
	}

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)unionSet: (OFSet*)set
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator = [set objectEnumerator];
	id object;

	while ((object = [enumerator nextObject]) != nil)
		[self addObject: object];

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)makeImmutable
{
}
@end

Modified src/OFMutableSet_hashtable.m from [a0924df2b2] to [e8d7f3a5b9].

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







-








#define OF_MUTABLE_SET_HASHTABLE_M

#import "OFSet_hashtable.h"
#import "OFMutableSet_hashtable.h"
#import "OFMutableDictionary_hashtable.h"
#import "OFNumber.h"
#import "OFAutoreleasePool.h"

@implementation OFMutableSet_hashtable
+ (void)initialize
{
	if (self == [OFMutableSet_hashtable class])
		[self inheritMethodsFromClass: [OFSet_hashtable class]];
}

Modified src/OFMutableString.m from [dd89e81e6e] to [808aebc7d8].

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

34
35
36
37
38
39
40
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40







-






+







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

#include <sys/types.h>

#import "OFString.h"
#import "OFMutableString_UTF8.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfRangeException.h"

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

#import "of_asprintf.h"
#import "unicode.h"

static struct {
	Class isa;
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270







-
+







}

- (void)_convertWithWordStartTable: (const of_unichar_t *const[])startTable
		   wordMiddleTable: (const of_unichar_t *const[])middleTable
		wordStartTableSize: (size_t)startTableSize
	       wordMiddleTableSize: (size_t)middleTableSize
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *string = [self unicodeString];
	size_t i, length = [self length];
	BOOL isStart = YES;

	for (i = 0; i < length; i++) {
		const of_unichar_t *const *table;
		size_t tableSize;
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
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







-
+











-
+



-
+





-
+




-
+





-
+




-
+






-
+





-
+







			break;
		default:
			isStart = NO;
			break;
		}
	}

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)setCharacter: (of_unichar_t)character
	     atIndex: (size_t)index
{
	@throw [OFNotImplementedException exceptionWithClass: [self class]
						    selector: _cmd];
}

- (void)appendUTF8String: (const char*)UTF8String
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();

	[self appendString: [OFString stringWithUTF8String: UTF8String]];

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)appendUTF8String: (const char*)UTF8String
	      withLength: (size_t)UTF8StringLength
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();

	[self appendString: [OFString stringWithUTF8String: UTF8String
						    length: UTF8StringLength]];

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)appendCString: (const char*)cString
	 withEncoding: (of_string_encoding_t)encoding
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();

	[self appendString: [OFString stringWithCString: cString
					       encoding: encoding]];

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)appendCString: (const char*)cString
	 withEncoding: (of_string_encoding_t)encoding
	       length: (size_t)cStringLength
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();

	[self appendString: [OFString stringWithCString: cString
					       encoding: encoding
						 length: cStringLength]];

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)appendString: (OFString*)string
{
	return [self insertString: string
			  atIndex: [self length]];
}
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
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







-
+










-
+



-
+















-
+
+




-
+







				 inRange: of_range(0, [self length])];
}

- (void)replaceOccurrencesOfString: (OFString*)string
			withString: (OFString*)replacement
			   inRange: (of_range_t)range
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init], *pool2;
	void *pool = objc_autoreleasePoolPush(), *pool2;
	const of_unichar_t *unicodeString;
	const of_unichar_t *searchString = [string unicodeString];
	size_t searchLength = [string length];
	size_t replacementLength = [replacement length];
	size_t i;

	if (range.start + range.length > [self length])
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	if (searchLength > range.length) {
		[pool release];
		objc_autoreleasePoolPop(pool);
		return;
	}

	pool2 = [[OFAutoreleasePool alloc] init];
	pool2 = objc_autoreleasePoolPush();
	unicodeString = [self unicodeString];

	for (i = range.start; i <= range.length - searchLength; i++) {
		if (memcmp(unicodeString + i, searchString,
		    searchLength * sizeof(of_unichar_t)))
			continue;

		[self replaceCharactersInRange: of_range(i, searchLength)
				    withString: replacement];

		range.length -= searchLength;
		range.length += replacementLength;

		i += replacementLength - 1;

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool2);
		pool2 = objc_autoreleasePoolPush();

		unicodeString = [self unicodeString];
	}

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (void)deleteLeadingWhitespaces
{
	size_t i, length = [self length];

	for (i = 0; i < length; i++) {

Modified src/OFMutableString_UTF8.m from [30423a3dc6] to [9ad6fdf9a8].

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

35
36
37
38
39
40
41
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41







-







+







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

#import "OFString.h"
#import "OFString_UTF8.h"
#import "OFMutableString_UTF8.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidEncodingException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

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

#import "of_asprintf.h"
#import "unicode.h"

@implementation OFMutableString_UTF8
+ (void)initialize
340
341
342
343
344
345
346
347

348
349
350
351
352

353
354
355
356
357
358
359
340
341
342
343
344
345
346

347
348
349
350
351

352
353
354
355
356
357
358
359







-
+




-
+







	 withEncoding: (of_string_encoding_t)encoding
	       length: (size_t)cStringLength
{
	if (encoding == OF_STRING_ENCODING_UTF_8)
		[self appendUTF8String: cString
			    withLength: cStringLength];
	else {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();
		[self appendString:
		    [OFString stringWithCString: cString
				       encoding: encoding
					 length: cStringLength]];
		[pool release];
		objc_autoreleasePoolPop(pool);
	}
}

- (void)appendString: (OFString*)string
{
	size_t UTF8StringLength;

Modified src/OFNull.m from [2dd9bd511c] to [712c4645d0].

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







-



+
+
















-
+



-
+







-
+
















-
+






-
-
+
+

-
+







 */

#include "config.h"

#import "OFNull.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"
#import "OFNotImplementedException.h"

#import "autorelease.h"

static OFNull *null = nil;

@implementation OFNull
+ null
{
	if (null != nil)
		return null;

	null = [[self alloc] init];

	return null;
}

- initWithSerialization: (OFXMLElement*)element
{
	OFAutoreleasePool *pool;
	void *pool;

	[self release];

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

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

	[pool release];
	objc_autoreleasePoolPop(pool);

	return [OFNull null];
}

- (OFString*)description
{
	return @"<null>";
}

- copy
{
	return self;
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;

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

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}

- (OFString*)JSONRepresentation
{
	return @"null";
}

Modified src/OFNumber.m from [b7208d53f6] to [70f21d39ef].

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

31
32
33
34
35
36
37
18
19
20
21
22
23
24

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







-





+








#include <math.h>

#import "OFNumber.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFXMLAttribute.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"

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

#define RETURN_AS(t)							\
	switch (type) {							\
	case OF_NUMBER_BOOL:						\
		return (t)value.bool_;					\
	case OF_NUMBER_CHAR:						\
715
716
717
718
719
720
721
722

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

722
723
724
725
726
727
728
729







-
+







}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();
		OFString *typeString;

		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];
772
773
774
775
776
777
778
779

780
781
782
783
784
785
786
772
773
774
775
776
777
778

779
780
781
782
783
784
785
786







-
+







			type = OF_NUMBER_DOUBLE;
			value.double_ = of_bswap_double_if_le(d.d);
		} else
			@throw [OFInvalidArgumentException
			    exceptionWithClass: [self class]
				      selector: _cmd];

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

	return self;
}
1207
1208
1209
1210
1211
1212
1213
1214

1215
1216
1217
1218
1219
1220
1221
1207
1208
1209
1210
1211
1212
1213

1214
1215
1216
1217
1218
1219
1220
1221







-
+







		@throw [OFInvalidFormatException
		    exceptionWithClass: [self class]];
	}
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;

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

	switch (type) {
1282
1283
1284
1285
1286
1287
1288
1289
1290


1291
1292

1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1282
1283
1284
1285
1286
1287
1288


1289
1290
1291

1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302







-
-
+
+

-
+










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

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}

- (OFString*)JSONRepresentation
{
	if (type == OF_NUMBER_BOOL)
		return (value.bool_ ? @"true" : @"false");

	return [self description];
}
@end

Modified src/OFObject+Serialization.m from [d27599f768] to [c7f6b6d6fd].

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







-


+
+






-
+









-
+












-
-
+
+

-
+


#include "config.h"

#import "OFObject.h"
#import "OFObject+Serialization.h"
#import "OFSerialization.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFNotImplementedException.h"

#import "autorelease.h"

int _OFObject_Serialization_reference;

@implementation OFObject (Serialization)
- (OFString*)stringBySerializing
{
	OFAutoreleasePool *pool;
	void *pool;
	OFXMLElement *element;
	OFXMLElement *root;
	OFString *ret;

	if (![self conformsToProtocol: @protocol(OFSerialization)])
		@throw [OFNotImplementedException
		    exceptionWithClass: [self class]
			      selector: @selector(stringBySerializing)];

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();
	element = [(id)self XMLElementBySerializing];

	root = [OFXMLElement elementWithName: @"serialization"
				   namespace: OF_SERIALIZATION_NS];
	[root addAttributeWithName: @"version"
		       stringValue: @"1"];
	[root addChild: element];

	ret = [@"<?xml version='1.0' encoding='UTF-8'?>\n"
	    stringByAppendingString: [root XMLStringWithIndentation: 2]];

	[ret retain];
	[pool release];
	[ret autorelease];

	objc_autoreleasePoolPop(pool);

	return ret;
	return [ret autorelease];
}
@end

Modified src/OFObject.m from [ef2b5b53fe] to [b19596ca32].

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







-










+







#include <assert.h>

#ifdef __QNX__
# include <sys/syspage.h>
#endif

#import "OFObject.h"
#import "OFAutoreleasePool.h"

#import "OFAllocFailedException.h"
#import "OFEnumerationMutationException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFMemoryNotPartOfObjectException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

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

#if defined(OF_APPLE_RUNTIME) && __OBJC2__
# import <objc/objc-exception.h>
#elif defined(OF_OBJFW_RUNTIME)
# import "runtime.h"
#endif
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
82
83
84
85
86
87
88

89
90
91
92
93
94
95







-







#define PRE_MEM_ALIGN ((sizeof(struct pre_mem) + \
	(__BIGGEST_ALIGNMENT__ - 1)) & ~(__BIGGEST_ALIGNMENT__ - 1))
#define PRE_MEM(mem) ((struct pre_mem*)(void*)((char*)mem - PRE_MEM_ALIGN))

static struct {
	Class isa;
} alloc_failed_exception;
static Class autoreleasePool = Nil;

static SEL cxx_construct = NULL;
static SEL cxx_destruct = NULL;

size_t of_pagesize;
size_t of_num_cpus;

809
810
811
812
813
814
815
816
817
818
819
820
821
822

823
824
825
826
827
828
829
830
808
809
810
811
812
813
814







815

816
817
818
819
820
821
822







-
-
-
-
-
-
-
+
-







	if (--PRE_IVAR->retainCount == 0)
		[self dealloc];
#endif
}

- autorelease
{
	/*
	 * Cache OFAutoreleasePool since class lookups are expensive with the
	 * GNU ABI used by GCC.
	 */
	if (autoreleasePool == Nil)
		autoreleasePool = [OFAutoreleasePool class];

	return _objc_rootAutorelease(self);
	return [autoreleasePool addObject: self];
}

- self
{
	return self;
}

Modified src/OFPlugin.m from [c230c7ec3d] to [a25e85e2c5].

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







-



+
+










-
+





-








-
+








#ifndef _WIN32
#include <dlfcn.h>
#endif

#import "OFPlugin.h"
#import "OFString.h"
#import "OFAutoreleasePool.h"

#import "OFInitializationFailedException.h"
#import "OFNotImplementedException.h"

#import "autorelease.h"

#ifdef _WIN32
# define dlopen(file, mode) LoadLibrary(file)
# define dlsym(handle, symbol) GetProcAddress(handle, symbol)
# define dlclose(handle) FreeLibrary(handle)
#endif

@implementation OFPlugin
+ (id)pluginFromFile: (OFString*)path
{
	OFAutoreleasePool *pool;
	void *pool = objc_autoreleasePoolPush();
	OFMutableString *file;
	of_plugin_handle_t handle;
	OFPlugin *(*initPlugin)(void);
	OFPlugin *plugin;

	pool = [[OFAutoreleasePool alloc] init];
	file = [OFMutableString stringWithString: path];
	[file appendString: @PLUGIN_SUFFIX];

	if ((handle = dlopen([file cStringWithEncoding:
	    OF_STRING_ENCODING_NATIVE], RTLD_LAZY)) == NULL)
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];

	[pool release];
	objc_autoreleasePoolPop(pool);

	*(void**)&initPlugin = dlsym(handle, "init_plugin");
	if (initPlugin == NULL || (plugin = initPlugin()) == nil) {
		dlclose(handle);
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
	}

Modified src/OFProcess.m from [a1bb959d69] to [769871dec1].

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


38
39
40
41
42
43
44
22
23
24
25
26
27
28

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







-








+
+







# include <unistd.h>
# include <sys/wait.h>
#endif

#import "OFProcess.h"
#import "OFString.h"
#import "OFArray.h"
#import "OFAutoreleasePool.h"

#import "OFInitializationFailedException.h"
#import "OFReadFailedException.h"
#import "OFWriteFailedException.h"

#ifdef _WIN32
# include <windows.h>
#endif

#import "autorelease.h"

@implementation OFProcess
+ processWithProgram: (OFString*)program
{
	return [[[self alloc] initWithProgram: program] autorelease];
}

121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136







-
+







			close(writePipe[0]);
			break;
		}
#else
		SECURITY_ATTRIBUTES sa;
		PROCESS_INFORMATION pi;
		STARTUPINFO si;
		OFAutoreleasePool *pool;
		void *pool;
		OFMutableString *argumentsString;
		OFEnumerator *enumerator;
		OFString *argument;
		char *argumentsCString;

		sa.nLength = sizeof(sa);
		sa.bInheritHandle = TRUE;
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171







-
+








		si.cb = sizeof(si);
		si.hStdInput = writePipe[0];
		si.hStdOutput = readPipe[1];
		si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
		si.dwFlags |= STARTF_USESTDHANDLES;

		pool = [[OFAutoreleasePool alloc] init];
		pool = objc_autoreleasePoolPush();

		argumentsString =
		    [OFMutableString stringWithString: programName];
		[argumentsString replaceOccurrencesOfString: @"\\\""
						 withString: @"\\\\\""];
		[argumentsString replaceOccurrencesOfString: @"\""
						 withString: @"\\\""];
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219







-
+







			    NULL, TRUE, 0, NULL, NULL, &si, &pi))
				@throw [OFInitializationFailedException
				    exceptionWithClass: [self class]];
		} @finally {
			free(argumentsString);
		}

		[pool release];
		objc_autoreleasePoolPop(pool);

		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);

		CloseHandle(readPipe[1]);
		CloseHandle(writePipe[0]);
#endif

Modified src/OFSet.m from [7c97ea2061] to [9be4537608].

16
17
18
19
20
21
22
23
24
25


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

23
24
25
26
27
28
29
30
31
32
33







-


+
+








#include "config.h"

#import "OFSet.h"
#import "OFSet_hashtable.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFNotImplementedException.h"

#import "autorelease.h"

static struct {
	Class isa;
} placeholder;

@interface OFSet_placeholder: OFSet
@end
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
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







-
+







-
+






+

-








+
-
+



+
-
+

-





-
+







-
+
















-
+





-
+




-
+






-
+





-
+




-
+






-
-
+













-

+
+


-
+



-
-
+
+

-
+







		return NO;

	return [otherSet isSubsetOfSet: self];
}

- (uint32_t)hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator = [self objectEnumerator];
	id object;
	uint32_t hash = 0;

	while ((object = [enumerator nextObject]) != nil)
		hash += [object hash];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return hash;
}

- (OFString*)description
{
	void *pool;
	OFMutableString *ret;
	OFAutoreleasePool *pool, *pool2;
	OFEnumerator *enumerator;
	size_t i, count = [self count];
	id object;

	if (count == 0)
		return @"{()}";

	ret = [OFMutableString stringWithString: @"{(\n"];

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();
	enumerator = [self objectEnumerator];

	i = 0;
	while ((object = [enumerator nextObject]) != nil) {
	pool2 = [[OFAutoreleasePool alloc] init];
		void *pool2 = objc_autoreleasePoolPush();

	while ((object = [enumerator nextObject]) != nil) {
		[ret appendString: [object description]];

		if (++i < count)
			[ret appendString: @",\n"];

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool2);
	}
	[ret replaceOccurrencesOfString: @"\n"
			     withString: @"\n\t"];
	[ret appendString: @"\n)}"];

	[ret makeImmutable];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return ret;
}

- copy
{
	return [self retain];
}

- mutableCopy
{
	return [[OFMutableSet alloc] initWithSet: self];
}

- (BOOL)isSubsetOfSet: (OFSet*)set
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator = [self objectEnumerator];
	id object;

	while ((object = [enumerator nextObject]) != nil) {
		if (![set containsObject: object]) {
			[pool release];
			objc_autoreleasePoolPop(pool);
			return NO;
		}
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return YES;
}

- (BOOL)intersectsSet: (OFSet*)set
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator = [self objectEnumerator];
	id object;

	while ((object = [enumerator nextObject]) != nil) {
		if ([set containsObject: object]) {
			[pool release];
			objc_autoreleasePoolPop(pool);
			return YES;
		}
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return NO;
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFAutoreleasePool *pool2;
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;
	OFEnumerator *enumerator;
	id <OFSerialization> object;

	if ([self isKindOfClass: [OFMutableSet class]])
		element = [OFXMLElement elementWithName: @"OFMutableSet"
					      namespace: OF_SERIALIZATION_NS];
	else
		element = [OFXMLElement elementWithName: @"OFSet"
					      namespace: OF_SERIALIZATION_NS];

	enumerator = [self objectEnumerator];

	pool2 = [[OFAutoreleasePool alloc] init];
	while ((object = [enumerator nextObject]) != nil) {
		void *pool2 = objc_autoreleasePoolPush();

		[element addChild: [object XMLElementBySerializing]];

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool2);
	}

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}

#if defined(OF_HAVE_BLOCKS) && defined(OF_HAVE_FAST_ENUMERATION)
- (void)enumerateObjectsUsingBlock: (of_set_enumeration_block_t)block
{
	BOOL stop = NO;

Modified src/OFSet_hashtable.m from [38338532b1] to [6230f1526a].

22
23
24
25
26
27
28
29
30
31


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

29
30
31
32
33
34
35
36
37
38
39







-


+
+







#import "OFMutableSet_hashtable.h"
#import "OFCountedSet_hashtable.h"
#import "OFMutableDictionary_hashtable.h"
#import "OFArray.h"
#import "OFString.h"
#import "OFNumber.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"

#import "autorelease.h"

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

	@try {
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
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







-
+













-
+













-
+









-
+














-
+








-
+














-
+












-
+













-
+




-
-











+
-
+

-




-
+


-
+







}

- initWithSet: (OFSet*)set
{
	self = [self init];

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();
		OFNumber *one = [OFNumber numberWithSize: 1];
		OFEnumerator *enumerator = [set objectEnumerator];
		id object;

		/*
		 * We can't just copy the dictionary as the specified set might
		 * be a counted set, but we're just a normal set.
		 */
		while ((object = [enumerator nextObject]) != nil)
			[dictionary _setObject: one
					forKey: object
				       copyKey: NO];

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

	return self;
}

- initWithArray: (OFArray*)array
{
	self = [self init];

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();
		OFNumber *one = [OFNumber numberWithSize: 1];
		id *objects = [array objects];
		size_t i, count = [array count];

		for (i = 0; i < count; i++)
			[dictionary _setObject: one
					forKey: objects[i]
				       copyKey: NO];

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

	return self;
}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();
		OFNumber *one = [OFNumber numberWithSize: 1];
		size_t i;

		for (i = 0; i < count; i++)
			[dictionary _setObject: one
					forKey: objects[i]
				       copyKey: NO];

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

	return self;
}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();
		OFNumber *one = [OFNumber numberWithSize: 1];
		id object;

		[dictionary _setObject: one
				forKey: firstObject
			       copyKey: NO];

		while ((object = va_arg(arguments, id)) != nil)
			[dictionary _setObject: one
					forKey: object
				       copyKey: NO];

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

	return self;
}

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

	@try {
		OFAutoreleasePool *pool, *pool2;
		void *pool = objc_autoreleasePoolPush();
		OFNumber *one;
		OFEnumerator *enumerator;
		OFXMLElement *child;

		pool = [[OFAutoreleasePool alloc] init];

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

		one = [OFNumber numberWithSize: 1];

		enumerator = [[element elementsForNamespace:
		    OF_SERIALIZATION_NS] objectEnumerator];
		while ((child = [enumerator nextObject]) != nil) {
		pool2 = [[OFAutoreleasePool alloc] init];
			void *pool2  = objc_autoreleasePoolPush();

		while ((child = [enumerator nextObject]) != nil) {
			[dictionary _setObject: one
					forKey: [child objectByDeserializing]
				       copyKey: NO];

			[pool2 releaseObjects];
			objc_autoreleasePoolPop(pool2);
		}

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

	return self;
}

Modified src/OFStreamObserver.m from [46e892e905] to [44b77ee334].

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
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 "OFDictionary.h"
#import "OFStream.h"
#import "OFDataArray.h"
#ifdef _WIN32
# import "OFTCPSocket.h"
#endif
#import "OFThread.h"
#import "OFAutoreleasePool.h"

#ifdef HAVE_KQUEUE
# import "OFStreamObserver_kqueue.h"
#endif
#ifdef HAVE_POLL_H
# import "OFStreamObserver_poll.h"
#endif
#if defined(HAVE_SYS_SELECT_H) || defined(_WIN32)
# import "OFStreamObserver_select.h"
#endif

#import "OFInitializationFailedException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfRangeException.h"

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

enum {
	QUEUE_ADD = 0,
	QUEUE_REMOVE = 1,
	QUEUE_READ = 0,
	QUEUE_WRITE = 2
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
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







-




-


+


+


-
+



-
-







{
	@throw [OFNotImplementedException exceptionWithClass: [self class]
						    selector: _cmd];
}

- (BOOL)_processCache
{
	OFAutoreleasePool *pool;
	OFStream **objects = [readStreams objects];
	size_t i, count = [readStreams count];
	BOOL foundInCache = NO;

	pool = [[OFAutoreleasePool alloc] init];

	for (i = 0; i < count; i++) {

		if ([objects[i] pendingBytes] > 0 &&
		    ![objects[i] _isWaitingForDelimiter]) {
			void *pool = objc_autoreleasePoolPush();
			[delegate streamIsReadyForReading: objects[i]];
			foundInCache = YES;
			[pool releaseObjects];
			objc_autoreleasePoolPop(pool);
		}
	}

	[pool release];

	/*
	 * As long as we have data in the cache for any stream, we don't want
	 * to block.
	 */
	if (foundInCache)
		return YES;

Modified src/OFStreamObserver_kqueue.m from [0f25fb90be] to [ef7d60eaa2].

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







-




+








#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>

#import "OFStreamObserver_kqueue.h"
#import "OFDataArray.h"
#import "OFAutoreleasePool.h"

#import "OFInitializationFailedException.h"
#import "OFOutOfMemoryException.h"

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

#define EVENTLIST_SIZE 64

@implementation OFStreamObserver_kqueue
- init
{
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
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







-
+







-
+


+
+








-


-









-
+
-

-









+
+




-
+







-




-





+


-
-




	EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
	[changeList addItem: &event];
}

- (BOOL)observeWithTimeout: (int)timeout
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	struct timespec timespec = { timeout, 0 };
	struct kevent eventList[EVENTLIST_SIZE];
	int i, events;

	[self _processQueue];

	if ([self _processCache]) {
		[pool release];
		objc_autoreleasePoolPop(pool);
		return YES;
	}

	objc_autoreleasePoolPop(pool);

	events = kevent(kernelQueue, [changeList cArray],
	    (int)[changeList count], eventList, EVENTLIST_SIZE,
	    (timeout == -1 ? NULL : &timespec));

	if (events == -1) {
		switch (errno) {
		case EINTR:
			[pool release];
			return NO;
		case ENOMEM:
			[pool release];
			@throw [OFOutOfMemoryException
			    exceptionWithClass: [self class]];
		default:
			assert(0);
		}
	}

	[changeList removeAllItems];

	if (events == 0) {
	if (events == 0)
		[pool release];
		return NO;
	}

	for (i = 0; i < events; i++) {
		if (eventList[i].ident == cancelFD[0]) {
			char buffer;

			OF_ENSURE(read(cancelFD[0], &buffer, 1) > 0);

			continue;
		}

		pool = objc_autoreleasePoolPush();

		if (eventList[i].flags & EV_ERROR) {
			[delegate streamDidReceiveException:
			    FDToStream[eventList[i].ident]];
			[pool releaseObjects];
			objc_autoreleasePoolPop(pool);
			continue;
		}

		switch (eventList[i].filter) {
		case EVFILT_READ:
			[delegate streamIsReadyForReading:
			    FDToStream[eventList[i].ident]];
			[pool releaseObjects];
			break;
		case EVFILT_WRITE:
			[delegate streamIsReadyForWriting:
			    FDToStream[eventList[i].ident]];
			[pool releaseObjects];
			break;
		default:
			assert(0);
		}

		objc_autoreleasePoolPop(pool);
	}

	[pool release];

	return YES;
}
@end

Modified src/OFStreamObserver_poll.m from [17f5ac1ccb] to [a6a3da0735].

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







-



+







#define __NO_EXT_QNX

#include <unistd.h>
#include <poll.h>

#import "OFStreamObserver_poll.h"
#import "OFDataArray.h"
#import "OFAutoreleasePool.h"

#import "OFOutOfRangeException.h"

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

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

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







-
+






-
+


+
+









-
+
-

-
+
-

+
+







+





-





-





-



-
-
+
+
+
-




{
	[self _removeFileDescriptor: fd
			 withEvents: POLLOUT];
}

- (BOOL)observeWithTimeout: (int)timeout
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	struct pollfd *FDsCArray;
	size_t i, nFDs;

	[self _processQueue];

	if ([self _processCache]) {
		[pool release];
		objc_autoreleasePoolPop(pool);
		return YES;
	}

	objc_autoreleasePoolPop(pool);

	FDsCArray = [FDs cArray];
	nFDs = [FDs count];

#ifdef OPEN_MAX
	if (nFDs > OPEN_MAX)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#endif

	if (poll(FDsCArray, (nfds_t)nFDs, timeout) < 1) {
	if (poll(FDsCArray, (nfds_t)nFDs, timeout) < 1)
		[pool release];
		return NO;
	}


	for (i = 0; i < nFDs; i++) {
		pool = objc_autoreleasePoolPush();

		if (FDsCArray[i].revents & POLLIN) {
			if (FDsCArray[i].fd == cancelFD[0]) {
				char buffer;

				OF_ENSURE(read(cancelFD[0], &buffer, 1) > 0);
				FDsCArray[i].revents = 0;

				objc_autoreleasePoolPop(pool);
				continue;
			}

			[delegate streamIsReadyForReading:
			    FDToStream[FDsCArray[i].fd]];
			[pool releaseObjects];
		}

		if (FDsCArray[i].revents & POLLOUT) {
			[delegate streamIsReadyForWriting:
			    FDToStream[FDsCArray[i].fd]];
			[pool releaseObjects];
		}

		if (FDsCArray[i].revents & POLLERR) {
			[delegate streamDidReceiveException:
			    FDToStream[FDsCArray[i].fd]];
			[pool releaseObjects];
		}

		FDsCArray[i].revents = 0;
	}


		objc_autoreleasePoolPop(pool);
	}
	[pool release];

	return YES;
}
@end

Modified src/OFStreamObserver_select.m from [937ba60b81] to [2098b64113].

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







-

+








#include <string.h>
#include <unistd.h>

#import "OFStreamObserver_select.h"
#import "OFStream.h"
#import "OFArray.h"
#import "OFAutoreleasePool.h"

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

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

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







-
+










-
+


+
+















-
+
-

-
















+
+
-
+

-
-



-







+
+








+
+
-
+

-
-
+
-
-
+

-
-
+
+

-
-





	if (!FD_ISSET(fd, &readFDs))
		FD_CLR(fd, &exceptFDs);
}

- (BOOL)observeWithTimeout: (int)timeout
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFStream **objects;
	fd_set readFDs_;
	fd_set writeFDs_;
	fd_set exceptFDs_;
	struct timeval time;
	size_t i, count;

	[self _processQueue];

	if ([self _processCache]) {
		[pool release];
		objc_autoreleasePoolPop(pool);
		return YES;
	}

	objc_autoreleasePoolPop(pool);

#ifdef FD_COPY
	FD_COPY(&readFDs, &readFDs_);
	FD_COPY(&writeFDs, &writeFDs_);
	FD_COPY(&exceptFDs, &exceptFDs_);
#else
	readFDs_ = readFDs;
	writeFDs_ = writeFDs;
	exceptFDs_ = exceptFDs;
#endif

	time.tv_sec = timeout / 1000;
	time.tv_usec = (timeout % 1000) * 1000;

	if (select((int)maxFD + 1, &readFDs_, &writeFDs_, &exceptFDs_,
	    (timeout != -1 ? &time : NULL)) < 1) {
	    (timeout != -1 ? &time : NULL)) < 1)
		[pool release];
		return NO;
	}

	if (FD_ISSET(cancelFD[0], &readFDs_)) {
		char buffer;
#ifndef _WIN32
		OF_ENSURE(read(cancelFD[0], &buffer, 1) > 0);
#else
		OF_ENSURE(recvfrom(cancelFD[0], &buffer, 1, 0, NULL, NULL) > 0);
#endif
	}

	objects = [readStreams objects];
	count = [readStreams count];

	for (i = 0; i < count; i++) {
		int fileDescriptor = [objects[i] fileDescriptor];

		pool = objc_autoreleasePoolPush();

		if (FD_ISSET(fileDescriptor, &readFDs_)) {
		if (FD_ISSET(fileDescriptor, &readFDs_))
			[delegate streamIsReadyForReading: objects[i]];
			[pool releaseObjects];
		}

		if (FD_ISSET(fileDescriptor, &exceptFDs_)) {
			[delegate streamDidReceiveException: objects[i]];
			[pool releaseObjects];

			/*
			 * Prevent calling it twice in case the FD is in both
			 * sets.
			 */
			FD_CLR(fileDescriptor, &exceptFDs_);
		}

		objc_autoreleasePoolPop(pool);
	}

	objects = [writeStreams objects];
	count = [writeStreams count];

	for (i = 0; i < count; i++) {
		int fileDescriptor = [objects[i] fileDescriptor];

		pool = objc_autoreleasePoolPush();

		if (FD_ISSET(fileDescriptor, &writeFDs_)) {
		if (FD_ISSET(fileDescriptor, &writeFDs_))
			[delegate streamIsReadyForWriting: objects[i]];
			[pool releaseObjects];
		}


		if (FD_ISSET(fileDescriptor, &exceptFDs_)) {
		if (FD_ISSET(fileDescriptor, &exceptFDs_))
			[delegate streamDidReceiveException: objects[i]];
			[pool releaseObjects];
		}

		objc_autoreleasePoolPop(pool);
	}

	[pool release];

	return YES;
}
@end

Modified src/OFString+Hashing.m from [e987d561c5] to [c7fc790b94].

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







+
-
+






-
+



















-
+








-
+



















-
+






 */

#include "config.h"

#import "OFString.h"
#import "OFMD5Hash.h"
#import "OFSHA1Hash.h"

#import "OFAutoreleasePool.h"
#import "autorelease.h"

int _OFString_Hashing_reference;

@implementation OFString (Hashing)
- (OFString*)MD5Hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFMD5Hash *hash = [OFMD5Hash hash];
	uint8_t *digest;
	char ret[OF_MD5_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: [self UTF8String]
			length: [self UTF8StringLength]];
	digest = [hash digest];

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

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

		ret[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		ret[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: ret
				  encoding: OF_STRING_ENCODING_ASCII
				    length: 32];
}

- (OFString*)SHA1Hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFMD5Hash *hash = [OFSHA1Hash hash];
	uint8_t *digest;
	char ret[OF_SHA1_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: [self UTF8String]
			length: [self UTF8StringLength]];
	digest = [hash digest];

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

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

		ret[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		ret[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: ret
				  encoding: OF_STRING_ENCODING_ASCII
				    length: 40];
}
@end

Modified src/OFString+Serialization.m from [fdc1d789a4] to [6b475d1780].

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







-





+
+






-
+








#import "OFString.h"
#import "OFString+Serialization.h"
#import "OFSerialization.h"
#import "OFArray.h"
#import "OFXMLElement.h"
#import "OFXMLAttribute.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"
#import "OFMalformedXMLException.h"
#import "OFUnboundNamespaceException.h"
#import "OFUnsupportedVersionException.h"

#import "autorelease.h"

int _OFString_Serialization_reference;

@implementation OFString (Serialization)
- (id)objectByDeserializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *root;
	OFString *version;
	OFArray *elements;
	id object;

	@try {
		root = [OFXMLElement elementWithXMLString: self];
66
67
68
69
70
71
72
73

74
75
76
77

78
79

80
81
67
68
69
70
71
72
73

74
75



76
77

78
79
80







-
+

-
-
-
+

-
+


	elements = [root elementsForNamespace: OF_SERIALIZATION_NS];

	if ([elements count] != 1)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	object = [[elements firstObject] objectByDeserializing];
	object = [[[elements firstObject] objectByDeserializing] retain];

	[object retain];
	[pool release];
	[object autorelease];
	objc_autoreleasePoolPop(pool);

	return object;
	return [object autorelease];
}
@end

Modified src/OFString+XMLUnescaping.m from [9d6ca887c3] to [c2d8e053db].

15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32







-



+







 */

#include "config.h"

#include <string.h>

#import "OFString.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidEncodingException.h"

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

int _OFString_XMLUnescaping_reference;

static OF_INLINE OFString*
parse_numeric_entity(const char *entity, size_t length)
{
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
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







-
+


-
+








-
+

-
+


-
+












-
+







				      withEncoding: OF_STRING_ENCODING_ASCII
					    length: 1];
			else if (entityLength == 3 && !memcmp(entity, "amp", 3))
				[ret appendCString: "&"
				      withEncoding: OF_STRING_ENCODING_ASCII
					    length: 1];
			else if (entity[0] == '#') {
				OFAutoreleasePool *pool;
				void *pool;
				OFString *tmp;

				pool = [[OFAutoreleasePool alloc] init];
				pool = objc_autoreleasePoolPush();
				tmp = parse_numeric_entity(entity,
				    entityLength);

				if (tmp == nil)
					@throw [OFInvalidEncodingException
					    exceptionWithClass: [self class]];

				[ret appendString: tmp];
				[pool release];
				objc_autoreleasePoolPop(pool);
			} else if (delegate != nil) {
				OFAutoreleasePool *pool;
				void *pool;
				OFString *n, *tmp;

				pool = [[OFAutoreleasePool alloc] init];
				pool = objc_autoreleasePoolPush();

				n = [OFString
				    stringWithUTF8String: entity
						  length: entityLength];
				tmp =	  [delegate string: self
				containsUnknownEntityNamed: n];

				if (tmp == nil)
					@throw [OFInvalidEncodingException
					    exceptionWithClass: [self class]];

				[ret appendString: tmp];
				[pool release];
				objc_autoreleasePoolPop(pool);
			} else
				@throw [OFInvalidEncodingException
				    exceptionWithClass: [self class]];

			last = i + 1;
			inEntity = NO;
		}
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
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







-
+


-
+








-
+

-
+


-
+











-
+







				      withEncoding: OF_STRING_ENCODING_ASCII
					    length: 1];
			else if (entityLength == 3 && !memcmp(entity, "amp", 3))
				[ret appendCString: "&"
				      withEncoding: OF_STRING_ENCODING_ASCII
					    length: 1];
			else if (entity[0] == '#') {
				OFAutoreleasePool *pool;
				void *pool;
				OFString *tmp;

				pool = [[OFAutoreleasePool alloc] init];
				pool = objc_autoreleasePoolPush();
				tmp = parse_numeric_entity(entity,
				    entityLength);

				if (tmp == nil)
					@throw [OFInvalidEncodingException
					    exceptionWithClass: [self class]];

				[ret appendString: tmp];
				[pool release];
				objc_autoreleasePoolPop(pool);
			} else {
				OFAutoreleasePool *pool;
				void *pool;
				OFString *entityString, *tmp;

				pool = [[OFAutoreleasePool alloc] init];
				pool = objc_autoreleasePoolPush();

				entityString = [OFString
				    stringWithUTF8String: entity
						  length: entityLength];
				tmp = block(self, entityString);

				if (tmp == nil)
					@throw [OFInvalidEncodingException
					    exceptionWithClass: [self class]];

				[ret appendString: tmp];
				[pool release];
				objc_autoreleasePoolPop(pool);
			}

			last = i + 1;
			inEntity = NO;
		}
	}

Modified src/OFString.m from [ff0024cc41] to [bc6ced3df8].

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







-











+







#import "OFArray.h"
#import "OFDictionary.h"
#import "OFFile.h"
#import "OFURL.h"
#import "OFHTTPRequest.h"
#import "OFDataArray.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFHTTPRequestFailedException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidEncodingException.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"
#import "OFOpenFileFailedException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

#import "autorelease.h"
#import "macros.h"
#import "of_asprintf.h"
#import "unicode.h"

/*
 * It seems strtod is buggy on Win32.
 * However, the MinGW version __strtod seems to be ok.
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
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







-
+








-
+







-
+







	return [self initWithContentsOfURL: URL
				  encoding: OF_STRING_ENCODING_AUTODETECT];
}

- initWithContentsOfURL: (OFURL*)URL
	       encoding: (of_string_encoding_t)encoding
{
	OFAutoreleasePool *pool;
	void *pool;
	OFHTTPRequest *request;
	OFHTTPRequestResult *result;
	OFString *contentType;
	Class c;

	c = [self class];
	[self release];

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	if ([[URL scheme] isEqual: @"file"]) {
		if (encoding == OF_STRING_ENCODING_AUTODETECT)
			encoding = OF_STRING_ENCODING_UTF_8;

		self = [[c alloc] initWithContentsOfFile: [URL path]
						encoding: encoding];
		[pool release];
		objc_autoreleasePoolPop(pool);
		return self;
	}

	request = [OFHTTPRequest requestWithURL: URL];
	result = [request perform];

	if ([result statusCode] != 200)
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
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







-
+






-
+




















-
+







	if (encoding == OF_STRING_ENCODING_AUTODETECT)
		encoding = OF_STRING_ENCODING_UTF_8;

	self = [[c alloc] initWithCString: (char*)[[result data] cArray]
				 encoding: encoding
				   length: [[result data] count]];

	[pool release];
	objc_autoreleasePoolPop(pool);
	return self;
}

- initWithSerialization: (OFXMLElement*)element
{
	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();

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

		if ([self isKindOfClass: [OFMutableString class]]) {
			if (![[element name] isEqual: @"OFMutableString"])
				@throw [OFInvalidArgumentException
				    exceptionWithClass: [self class]
					      selector: _cmd];
		} else {
			if (![[element name] isEqual: @"OFString"])
				@throw [OFInvalidArgumentException
				    exceptionWithClass: [self class]
					      selector: _cmd];
		}

		self = [self initWithString: [element stringValue]];

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

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







-
+
















-
+






-
+



-
+
















-
+
















-
+






-
+




-
+




-
+











-
+








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

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

	if (object == self)
		return YES;

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

	otherString = object;
	length = [self length];

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

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	unicodeString = [self unicodeString];
	otherUnicodeString = [otherString unicodeString];

	if (memcmp(unicodeString, otherUnicodeString,
	    length * sizeof(of_unichar_t))) {
		[pool release];
		objc_autoreleasePoolPop(pool);
		return NO;
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return YES;
}

- copy
{
	return [self retain];
}

- mutableCopy
{
	return [[OFMutableString alloc] initWithString: self];
}

- (of_comparison_result_t)compare: (id)object
{
	OFAutoreleasePool *pool;
	void *pool;
	OFString *otherString;
	const of_unichar_t *unicodeString, *otherUnicodeString;
	size_t i, minimumLength;

	if (object == self)
		return OF_ORDERED_SAME;

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

	otherString = object;
	minimumLength = ([self length] > [otherString length]
	    ? [otherString length] : [self length]);

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	unicodeString = [self unicodeString];
	otherUnicodeString = [otherString unicodeString];

	for (i = 0; i < minimumLength; i++) {
		if (unicodeString[i] > otherUnicodeString[i]) {
			[pool release];
			objc_autoreleasePoolPop(pool);
			return OF_ORDERED_DESCENDING;
		}

		if (unicodeString[i] < otherUnicodeString[i]) {
			[pool release];
			objc_autoreleasePoolPop(pool);
			return OF_ORDERED_ASCENDING;
		}
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	if ([self length] > [otherString length])
		return OF_ORDERED_DESCENDING;
	if ([self length] < [otherString length])
		return OF_ORDERED_ASCENDING;

	return OF_ORDERED_SAME;
}

- (of_comparison_result_t)caseInsensitiveCompare: (OFString*)otherString
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *string, *otherUnicodeString;
	size_t i, length, otherLength, minimumLength;

	if (otherString == self)
		return OF_ORDERED_SAME;

	string = [self unicodeString];
1206
1207
1208
1209
1210
1211
1212
1213

1214
1215
1216
1217

1218
1219
1220
1221
1222

1223
1224
1225
1226
1227
1228
1229
1206
1207
1208
1209
1210
1211
1212

1213
1214
1215
1216

1217
1218
1219
1220
1221

1222
1223
1224
1225
1226
1227
1228
1229







-
+



-
+




-
+







			    of_unicode_casefolding_table[oc >> 8][oc & 0xFF];

			if (tc)
				oc = tc;
		}

		if (c > oc) {
			[pool release];
			objc_autoreleasePoolPop(pool);
			return OF_ORDERED_DESCENDING;
		}
		if (c < oc) {
			[pool release];
			objc_autoreleasePoolPop(pool);
			return OF_ORDERED_ASCENDING;
		}
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	if (length > otherLength)
		return OF_ORDERED_DESCENDING;
	if (length < otherLength)
		return OF_ORDERED_ASCENDING;

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







-
+













-
-
+
+

-
+







- (OFString*)description
{
	return [[self copy] autorelease];
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;
	OFString *className;

	if ([self isKindOfClass: [OFMutableString class]])
		className = @"OFMutableString";
	else
		className = @"OFString";

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

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}

- (OFString*)JSONRepresentation
{
	OFMutableString *JSON = [[self mutableCopy] autorelease];

	/* FIXME: This is slow! Write it in pure C! */
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
1363
1364
1365
1366
1367

1368
1369
1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
1392

1393
1394
1395
1396
1397

1398
1399
1400
1401
1402
1403
1404

1405
1406
1407
1408
1409
1410
1411

1412
1413
1414
1415

1416
1417
1418
1419
1420
1421
1422
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
1363
1364
1365
1366

1367
1368
1369
1370
1371
1372
1373

1374
1375
1376
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
1391

1392
1393
1394
1395
1396

1397
1398
1399
1400
1401
1402
1403

1404
1405
1406
1407
1408
1409
1410

1411
1412
1413
1414

1415
1416
1417
1418
1419
1420
1421
1422







-
+









-
+







-
+




-
+






-
+









-
+







-
+








-
+






-
+









-
+







-
+




-
+






-
+






-
+



-
+







	[JSON makeImmutable];

	return JSON;
}

- (size_t)indexOfFirstOccurrenceOfString: (OFString*)string
{
	OFAutoreleasePool *pool;
	void *pool;
	const of_unichar_t *unicodeString, *searchString;
	size_t i, length, searchLength;

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

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

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	unicodeString = [self unicodeString];
	searchString = [string unicodeString];

	for (i = 0; i <= length - searchLength; i++) {
		if (!memcmp(unicodeString + i, searchString,
		    searchLength * sizeof(of_unichar_t))) {
			[pool release];
			objc_autoreleasePoolPop(pool);
			return i;
		}
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return OF_INVALID_INDEX;
}

- (size_t)indexOfLastOccurrenceOfString: (OFString*)string
{
	OFAutoreleasePool *pool;
	void *pool;
	const of_unichar_t *unicodeString, *searchString;
	size_t i, length, searchLength;

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

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

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	unicodeString = [self unicodeString];
	searchString = [string unicodeString];

	for (i = length - searchLength;; i--) {
		if (!memcmp(unicodeString + i, searchString,
		    searchLength * sizeof(of_unichar_t))) {
			[pool release];
			objc_autoreleasePoolPop(pool);
			return i;
		}

		/* Did not match and we're at the last character */
		if (i == 0)
			break;
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return OF_INVALID_INDEX;
}

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

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

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

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	unicodeString = [self unicodeString];
	searchString = [string unicodeString];

	for (i = 0; i <= length - searchLength; i++) {
		if (!memcmp(unicodeString + i, searchString,
		    searchLength * sizeof(of_unichar_t))) {
			[pool release];
			objc_autoreleasePoolPop(pool);
			return YES;
		}
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return NO;
}

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

	if (range.start + range.length > [self length])
		@throw [OFOutOfRangeException
		    exceptionWithClass: [self class]];

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();
	ret = [[OFString alloc]
	    initWithUnicodeString: [self unicodeString] + range.start
			   length: range.length];
	[pool release];
	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

- (OFString*)stringByAppendingString: (OFString*)string
{
	OFMutableString *new;
1548
1549
1550
1551
1552
1553
1554
1555

1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566

1567
1568
1569
1570
1571
1572
1573
1548
1549
1550
1551
1552
1553
1554

1555
1556
1557
1558
1559


1560
1561
1562
1563

1564
1565
1566
1567
1568
1569
1570
1571







-
+




-
-




-
+








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

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

		[self getCharacters: tmp
			    inRange: of_range(0, prefixLength)];

		pool = [[OFAutoreleasePool alloc] init];

		prefixString = [prefix unicodeString];
		compare = memcmp(tmp, prefixString,
		    prefixLength * sizeof(of_unichar_t));

		[pool release];
		objc_autoreleasePoolPop(pool);
	} @finally {
		[self freeMemory: tmp];
	}

	return !compare;
}

1582
1583
1584
1585
1586
1587
1588
1589

1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601

1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618

1619
1620
1621
1622
1623
1624
1625
1626

1627
1628
1629
1630
1631
1632
1633
1634
1635

1636
1637
1638
1639
1640
1641
1642
1580
1581
1582
1583
1584
1585
1586

1587
1588
1589
1590
1591
1592


1593
1594
1595
1596

1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613

1614
1615
1616
1617
1618
1619
1620
1621

1622
1623
1624
1625
1626
1627
1628
1629
1630

1631
1632
1633
1634
1635
1636
1637
1638







-
+





-
-




-
+
















-
+







-
+








-
+







		return NO;

	length = [self length];

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

		[self getCharacters: tmp
			    inRange: of_range(length - suffixLength,
					 suffixLength)];

		pool = [[OFAutoreleasePool alloc] init];

		suffixString = [suffix unicodeString];
		compare = memcmp(tmp, suffixString,
		    suffixLength * sizeof(of_unichar_t));

		[pool release];
		objc_autoreleasePoolPop(pool);
	} @finally {
		[self freeMemory: tmp];
	}

	return !compare;
}

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
{
	return [self componentsSeparatedByString: delimiter
				       skipEmpty: NO];
}

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
			      skipEmpty: (BOOL)skipEmpty
{
	OFAutoreleasePool *pool;
	void *pool;
	OFMutableArray *array = [OFMutableArray array];
	const of_unichar_t *string, *delimiterString;
	size_t length = [self length];
	size_t delimiterLength = [delimiter length];
	size_t i, last;
	OFString *component;

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	string = [self unicodeString];
	delimiterString = [delimiter unicodeString];

	if (delimiterLength > length) {
		[array addObject: [[self copy] autorelease]];
		[array makeImmutable];

		[pool release];
		objc_autoreleasePoolPop(pool);

		return array;
	}

	for (i = 0, last = 0; i <= length - delimiterLength; i++) {
		if (memcmp(string + i, delimiterString,
		    delimiterLength * sizeof(of_unichar_t)))
1651
1652
1653
1654
1655
1656
1657
1658

1659
1660
1661
1662
1663
1664
1665
1666

1667
1668
1669
1670
1671
1672
1673
1674
1675

1676
1677
1678
1679
1680
1681
1682
1647
1648
1649
1650
1651
1652
1653

1654
1655
1656
1657
1658
1659
1660
1661

1662
1663
1664
1665
1666
1667
1668
1669
1670

1671
1672
1673
1674
1675
1676
1677
1678







-
+







-
+








-
+







	}
	component = [self substringWithRange: of_range(last, length - last)];
	if (!skipEmpty || ![component isEqual: @""])
		[array addObject: component];

	[array makeImmutable];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return array;
}

- (OFArray*)pathComponents
{
	OFMutableArray *ret;
	OFAutoreleasePool *pool;
	void *pool;
	const of_unichar_t *string;
	size_t i, last = 0, length = [self length];

	ret = [OFMutableArray array];

	if (length == 0)
		return ret;

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	string = [self unicodeString];

#ifndef _WIN32
	if (string[length - 1] == OF_PATH_DELIMITER)
#else
	if (string[length - 1] == '/' || string[length - 1] == '\\')
1696
1697
1698
1699
1700
1701
1702
1703

1704
1705
1706
1707
1708
1709
1710

1711
1712
1713
1714
1715
1716
1717
1718

1719
1720
1721
1722
1723
1724
1725
1692
1693
1694
1695
1696
1697
1698

1699
1700
1701
1702
1703
1704
1705

1706
1707
1708
1709
1710
1711
1712
1713

1714
1715
1716
1717
1718
1719
1720
1721







-
+






-
+







-
+







		}
	}

	[ret addObject: [self substringWithRange: of_range(last, i - last)]];

	[ret makeImmutable];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return ret;
}

- (OFString*)lastPathComponent
{
	OFAutoreleasePool *pool;
	void *pool;
	const of_unichar_t *string;
	size_t length = [self length];
	ssize_t i;

	if (length == 0)
		return @"";

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	string = [self unicodeString];

#ifndef _WIN32
	if (string[length - 1] == OF_PATH_DELIMITER)
#else
	if (string[length - 1] == '/' || string[length - 1] == '\\')
1733
1734
1735
1736
1737
1738
1739
1740

1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754

1755
1756
1757
1758
1759
1760
1761

1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773

1774
1775
1776
1777
1778
1779
1780
1781
1782
1783

1784
1785
1786
1787
1788
1789
1790
1791
1792
1793

1794
1795
1796
1797

1798
1799
1800
1801
1802
1803
1804

1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818

1819
1820
1821
1822
1823
1824
1825
1729
1730
1731
1732
1733
1734
1735

1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749

1750
1751
1752
1753
1754
1755
1756

1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768

1769
1770
1771
1772
1773
1774
1775
1776
1777
1778

1779
1780
1781
1782
1783
1784
1785
1786
1787
1788

1789
1790
1791
1792

1793
1794
1795
1796
1797
1798
1799

1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813

1814
1815
1816
1817
1818
1819
1820
1821







-
+













-
+






-
+











-
+









-
+









-
+



-
+






-
+













-
+







		if (string[i] == '/' || string[i] == '\\') {
#endif
			i++;
			break;
		}
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	/*
	 * Only one component, but the trailing delimiter might have been
	 * removed, so return a new string anyway.
	 */
	if (i < 0)
		i = 0;

	return [self substringWithRange: of_range(i, length - i)];
}

- (OFString*)stringByDeletingLastPathComponent
{
	OFAutoreleasePool *pool;
	void *pool;
	const of_unichar_t *string;
	size_t i, length = [self length];

	if (length == 0)
		return @"";

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	string = [self unicodeString];

#ifndef _WIN32
	if (string[length - 1] == OF_PATH_DELIMITER)
#else
	if (string[length - 1] == '/' || string[length - 1] == '\\')
#endif
		length--;

	if (length == 0) {
		[pool release];
		objc_autoreleasePoolPop(pool);
		return [self substringWithRange: of_range(0, 1)];
	}

	for (i = length - 1; i >= 1; i--) {
#ifndef _WIN32
		if (string[i] == OF_PATH_DELIMITER) {
#else
		if (string[i] == '/' || string[i] == '\\') {
#endif
			[pool release];
			objc_autoreleasePoolPop(pool);
			return [self substringWithRange: of_range(0, i)];
		}
	}

#ifndef _WIN32
	if (string[0] == OF_PATH_DELIMITER) {
#else
	if (string[0] == '/' || string[0] == '\\') {
#endif
		[pool release];
		objc_autoreleasePoolPop(pool);
		return [self substringWithRange: of_range(0, 1)];
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return @".";
}

- (intmax_t)decimalValue
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *string = [self unicodeString];
	size_t length = [self length];
	int i = 0;
	intmax_t value = 0;
	BOOL expectWhitespace = NO;

	while (*string == ' ' || *string == '\t' || *string == '\n' ||
	    *string == '\r' || *string == '\f') {
		string++;
		length--;
	}

	if (length == 0) {
		[pool release];
		objc_autoreleasePoolPop(pool);
		return 0;
	}

	if (string[0] == '-' || string[0] == '+')
		i++;

	for (; i < length; i++) {
1847
1848
1849
1850
1851
1852
1853
1854

1855
1856
1857
1858
1859
1860
1861

1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875

1876
1877
1878
1879
1880
1881
1882
1843
1844
1845
1846
1847
1848
1849

1850
1851
1852
1853
1854
1855
1856

1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870

1871
1872
1873
1874
1875
1876
1877
1878







-
+






-
+













-
+







			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];
	}

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

	[pool release];
	objc_autoreleasePoolPop(pool);

	return value;
}

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

	while (*string == ' ' || *string == '\t' || *string == '\n' ||
	    *string == '\r' || *string == '\f') {
		string++;
		length--;
	}

	if (length == 0) {
		[pool release];
		objc_autoreleasePoolPop(pool);
		return 0;
	}

	if (length >= 2 && string[0] == '0' && string[1] == 'x')
		i = 2;
	else if (length >= 1 && (string[0] == 'x' || string[0] == '$'))
		i = 1;
1918
1919
1920
1921
1922
1923
1924
1925

1926
1927
1928
1929
1930
1931
1932

1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952

1953
1954
1955
1956
1957
1958
1959

1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979

1980
1981
1982
1983
1984
1985
1986
1914
1915
1916
1917
1918
1919
1920

1921
1922
1923
1924
1925
1926
1927

1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947

1948
1949
1950
1951
1952
1953
1954

1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974

1975
1976
1977
1978
1979
1980
1981
1982







-
+






-
+



















-
+






-
+



















-
+







		value = newValue;
	}

	if (!foundValue)
		@throw [OFInvalidFormatException
		    exceptionWithClass: [self class]];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return value;
}

- (float)floatValue
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	const char *cString = [self UTF8String];
	char *endPointer = NULL;
	float value;

	while (*cString == ' ' || *cString == '\t' || *cString == '\n' ||
	    *cString == '\r' || *cString == '\f')
		cString++;

	value = strtof(cString, &endPointer);

	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)
			if (*endPointer != ' ' && *endPointer != '\t' &&
			    *endPointer != '\n' && *endPointer != '\r' &&
			    *endPointer != '\f')
				@throw [OFInvalidFormatException
				    exceptionWithClass: [self class]];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return value;
}

- (double)doubleValue
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	const char *cString = [self UTF8String];
	char *endPointer = NULL;
	double value;

	while (*cString == ' ' || *cString == '\t' || *cString == '\n' ||
	    *cString == '\r' || *cString == '\f')
		cString++;

	value = strtod(cString, &endPointer);

	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)
			if (*endPointer != ' ' && *endPointer != '\t' &&
			    *endPointer != '\n' && *endPointer != '\r' &&
			    *endPointer != '\f')
				@throw [OFInvalidFormatException
				    exceptionWithClass: [self class]];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return value;
}

- (const of_unichar_t*)unicodeString
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
1995
1996
1997
1998
1999
2000
2001
2002

2003
2004
2005
2006
2007
2008
2009
1991
1992
1993
1994
1995
1996
1997

1998
1999
2000
2001
2002
2003
2004
2005







-
+








	return ret;
}

- (const uint16_t*)UTF16String
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *unicodeString = [self unicodeString];
	size_t length = [self length];
	uint16_t *ret;
	size_t i, j;

	/* Allocate memory for the worst case */
	ret = [object allocMemoryWithSize: sizeof(uint16_t)
2032
2033
2034
2035
2036
2037
2038
2039

2040
2041
2042
2043
2044
2045
2046

2047
2048
2049
2050
2051
2052
2053

2054
2055
2056
2057
2058
2059

2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074


2075
2076
2077
2078
2079

2080
2081
2082
2083
2084
2085
2086
2087
2088
2089

2090
2091
2092
2028
2029
2030
2031
2032
2033
2034

2035
2036
2037
2038
2039
2040
2041

2042
2043
2044
2045
2046
2047
2048

2049
2050
2051
2052
2053
2054

2055
2056
2057
2058
2059


2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074

2075
2076
2077
2078
2079
2080
2081
2082
2083
2084

2085
2086
2087
2088







-
+






-
+






-
+





-
+




-
-









+
+




-
+









-
+



		ret = [object resizeMemory: ret
				      size: sizeof(uint16_t)
				     count: j + 1];
	} @catch (OFOutOfMemoryException *e) {
		/* We don't care, as we only tried to make it smaller */
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	return ret;
}

- (void)writeToFile: (OFString*)path
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFFile *file;

	file = [OFFile fileWithPath: path
			       mode: @"wb"];
	[file writeString: self];

	[pool release];
	objc_autoreleasePoolPop(pool);
}

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

	pool2 = [[OFAutoreleasePool alloc] init];

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

			continue;
		}

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

			block([self substringWithRange:
			    of_range(last, i - last)], &stop);
			last = i + 1;

			[pool2 releaseObjects];
			objc_autoreleasePoolPop(pool2);
		}

		lastCarriageReturn = (string[i] == '\r');
	}

	if (!stop)
		block([self substringWithRange: of_range(last, i - last)],
		    &stop);

	[pool release];
	objc_autoreleasePoolPop(pool);
}
#endif
@end

Modified src/OFString_UTF8.m from [090bb87767] to [b0a0f37ea8].

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

39
40
41
42
43
44
45
22
23
24
25
26
27
28

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







-









+







#include <ctype.h>

#include <sys/types.h>

#import "OFString_UTF8.h"
#import "OFMutableString_UTF8.h"
#import "OFArray.h"
#import "OFAutoreleasePool.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidEncodingException.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

#import "autorelease.h"
#import "macros.h"
#import "of_asprintf.h"
#import "unicode.h"

extern const uint16_t of_iso_8859_15[256];
extern const uint16_t of_windows_1252[256];

818
819
820
821
822
823
824
825

826
827
828
829
830
831

832
833
834
835
836
837
838
818
819
820
821
822
823
824

825
826
827
828
829
830

831
832
833
834
835
836
837
838







-
+





-
+







	return character;
}

- (void)getCharacters: (of_unichar_t*)buffer
	      inRange: (of_range_t)range
{
	/* TODO: Could be slightly optimized */
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *unicodeString = [self unicodeString];

	memcpy(buffer, unicodeString + range.start,
	    range.length * sizeof(of_unichar_t));

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (size_t)indexOfFirstOccurrenceOfString: (OFString*)string
{
	const char *cString = [string UTF8String];
	size_t i, cStringLength = [string UTF8StringLength];

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







-
+







-
+



-
+







	return !memcmp(s->cString + (s->cStringLength - cStringLength),
	    [suffix UTF8String], cStringLength);
}

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
			      skipEmpty: (BOOL)skipEmpty
{
	OFAutoreleasePool *pool;
	void *pool;
	OFMutableArray *array;
	const char *cString = [delimiter UTF8String];
	size_t cStringLength = [delimiter UTF8StringLength];
	size_t i, last;
	OFString *component;

	array = [OFMutableArray array];
	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	if (cStringLength > s->cStringLength) {
		[array addObject: [[self copy] autorelease]];
		[pool release];
		objc_autoreleasePoolPop(pool);

		return array;
	}

	for (i = 0, last = 0; i <= s->cStringLength - cStringLength; i++) {
		if (memcmp(s->cString + i, cString, cStringLength))
			continue;
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
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







-
+







-
+







-
+







	}
	component = [OFString stringWithUTF8String: s->cString + last];
	if (!skipEmpty || ![component isEqual: @""])
		[array addObject: component];

	[array makeImmutable];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return array;
}

- (OFArray*)pathComponents
{
	OFMutableArray *ret;
	OFAutoreleasePool *pool;
	void *pool;
	size_t i, last = 0, pathCStringLength = s->cStringLength;

	ret = [OFMutableArray array];

	if (pathCStringLength == 0)
		return ret;

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

#ifndef _WIN32
	if (s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
#else
	if (s->cString[pathCStringLength - 1] == '/' ||
	    s->cString[pathCStringLength - 1] == '\\')
#endif
1007
1008
1009
1010
1011
1012
1013
1014

1015
1016
1017
1018
1019
1020
1021
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017
1018
1019
1020
1021







-
+







	}

	[ret addObject: [OFString stringWithUTF8String: s->cString + last
						length: i - last]];

	[ret makeImmutable];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return ret;
}

- (OFString*)lastPathComponent
{
	size_t pathCStringLength = s->cStringLength;
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
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







-
+















+
+





-
+






+
+




-
+




	return ret;
}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool;
	const char *cString = s->cString;
	const char *last = cString;
	BOOL stop = NO, lastCarriageReturn = NO;

	while (!stop && *cString != 0) {
		if (lastCarriageReturn && *cString == '\n') {
			lastCarriageReturn = NO;

			cString++;
			last++;

			continue;
		}

		if (*cString == '\n' || *cString == '\r') {
			pool = objc_autoreleasePoolPush();

			block([OFString
			    stringWithUTF8String: last
					  length: cString - last], &stop);
			last = cString + 1;

			[pool releaseObjects];
			objc_autoreleasePoolPop(pool);
		}

		lastCarriageReturn = (*cString == '\r');
		cString++;
	}

	pool = objc_autoreleasePoolPush();

	if (!stop)
		block([OFString stringWithUTF8String: last
					      length: cString - last], &stop);

	[pool release];
	objc_autoreleasePoolPop(pool);
}
#endif
@end

Modified src/OFThreadPool.m from [8a78192e7d] to [46f0aec229].

16
17
18
19
20
21
22

23

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

24
25
26
27
28
29
30
31







+
-
+








#include "config.h"

#import "OFThreadPool.h"
#import "OFArray.h"
#import "OFList.h"
#import "OFThread.h"

#import "OFAutoreleasePool.h"
#import "autorelease.h"

@interface OFThreadPoolJob: OFObject
{
	id target;
	SEL selector;
	id object;
#ifdef OF_HAVE_BLOCKS
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
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







-
+

-
+
-

-
+
+









-
+









-
+













-
+






-
+



-
+
+




-
+







	[countCondition release];

	[super dealloc];
}

- (id)main
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool;

	if (terminate) {
	if (terminate)
		[pool release];
		return nil;
	}

	pool = objc_autoreleasePoolPush();

	for (;;) {
		OFThreadPoolJob *job;

		[queueCondition lock];
		@try {
			of_list_object_t *listObject;

			if (terminate) {
				[pool release];
				objc_autoreleasePoolPop(pool);
				return nil;
			}

			listObject = [queue firstListObject];

			while (listObject == NULL) {
				[queueCondition wait];

				if (terminate) {
					[pool release];
					objc_autoreleasePoolPop(pool);
					return nil;
				}

				listObject = [queue firstListObject];
			}

			job = [[listObject->object retain] autorelease];
			[queue removeListObject: listObject];
		} @finally {
			[queueCondition unlock];
		}

		if (terminate) {
			[pool release];
			objc_autoreleasePoolPop(pool);
			return nil;
		}

		[job perform];

		if (terminate) {
			[pool release];
			objc_autoreleasePoolPop(pool);
			return nil;
		}

		[pool releaseObjects];
		objc_autoreleasePoolPop(pool);
		pool = objc_autoreleasePoolPush();

		[countCondition lock];
		@try {
			if (terminate) {
				[pool release];
				objc_autoreleasePoolPop(pool);
				return nil;
			}

			(*doneCount)++;

			[countCondition signal];
		} @finally {
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
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







-









+
+





-
+











-
-










-
+

















-
+







}

- initWithSize: (size_t)size_
{
	self = [super init];

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		size_t i;

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

			[pool releaseObjects];
			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];

			[thread start];
		}

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

	return self;
}

- (void)dealloc
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	[queueCondition lock];
	@try {
		[countCondition lock];
		@try {
			OFEnumerator *enumerator = [threads objectEnumerator];
			OFThreadPoolThread *thread;

			while ((thread = [enumerator nextObject]) != nil)
				thread->terminate = YES;
		} @finally {
			[countCondition unlock];
		}

		[queueCondition broadcast];
	} @finally {
		[queueCondition unlock];
	}
	[pool release];
	objc_autoreleasePoolPop(pool);

	[threads release];
	[queue release];
	[queueCondition release];
	[countCondition release];

	[super dealloc];

Modified src/OFURL.m from [9e27844090] to [4eed3ec6f3].

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







-





+





-
+







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

#import "OFURL.h"
#import "OFString.h"
#import "OFArray.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"

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

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

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

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







-
+







				break;
			}
		}
	}

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

	[pool release];
	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

@implementation OFURL
+ URLWithString: (OFString*)string
{
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
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







-
+








-
+








-
+







				user = [[OFString alloc]
				    initWithUTF8String: UTF8String];

			UTF8String = tmp2;
		}

		if ((tmp2 = strchr(UTF8String, ':')) != NULL) {
			OFAutoreleasePool *pool;
			void *pool;
			OFString *portString;

			*tmp2 = '\0';
			tmp2++;

			host = [[OFString alloc]
			    initWithUTF8String: UTF8String];

			pool = [[OFAutoreleasePool alloc] init];
			pool = objc_autoreleasePoolPush();
			portString = [OFString stringWithUTF8String: tmp2];

			if ([portString decimalValue] > 65535)
				@throw [OFInvalidFormatException
				    exceptionWithClass: [self class]];

			port = [portString decimalValue];

			[pool release];
			objc_autoreleasePoolPop(pool);
		} else {
			host = [[OFString alloc]
			    initWithUTF8String: UTF8String];

			if ([scheme isEqual: @"http"])
				port = 80;
			else if ([scheme isEqual: @"https"])
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
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







-
+


-
+












-
+














-
+









-
+







			    initWithUTF8String: tmp + 1];
		}

		if (*UTF8String == '/')
			path = [[OFString alloc]
			    initWithUTF8String: UTF8String];
		else {
			OFAutoreleasePool *pool;
			void *pool;
			OFString *s;

			pool = [[OFAutoreleasePool alloc] init];
			pool = objc_autoreleasePoolPush();

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

			path = [resolve_relative_path(s) copy];

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

	return self;
}

- initWithSerialization: (OFXMLElement*)element
{
	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();

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

		self = [self initWithString: [element stringValue]];

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

	return self;
}
550
551
552
553
554
555
556
557

558
559
560
561
562
563
564
565
566


567
568

569
570
550
551
552
553
554
555
556

557
558
559
560
561
562
563
564


565
566
567

568
569
570







-
+







-
-
+
+

-
+


- (OFString*)description
{
	return [self string];
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;

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

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}
@end

Modified src/OFXMLAttribute.m from [9f7e711096] to [3e96efbf3c].

16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
32
33







-



+








#include "config.h"

#import "OFXMLAttribute.h"
#import "OFString.h"
#import "OFDictionary.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"

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

@implementation OFXMLAttribute
+ attributeWithName: (OFString*)name
	  namespace: (OFString*)ns
	stringValue: (OFString*)value
{
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
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







-
+














-
+







}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();

		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"]
		    stringValue] copy];

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

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







-
+
















-
-
+
+

-
+









	OF_HASH_FINALIZE(hash);

	return hash;
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;

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

	[element addAttributeWithName: @"name"
			  stringValue: name];

	if (ns != nil)
		[element addAttributeWithName: @"namespace"
				  stringValue: ns];

	[element addAttributeWithName: @"stringValue"
			  stringValue: stringValue];

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}

- (OFString*)description
{
	return [OFString stringWithFormat: @"<OFXMLAttribute, name=%@, "
					   @"namespace=%@, stringValue=%@>",
					   name, ns, stringValue];
}
@end

Modified src/OFXMLCDATA.m from [de756c000b] to [65a1f72f30].

15
16
17
18
19
20
21
22
23
24


25
26
27
28
29
30
31
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32







-


+
+







 */

#include "config.h"

#import "OFXMLCDATA.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"

#import "autorelease.h"

@implementation OFXMLCDATA
+ CDATAWithString: (OFString*)string
{
	return [[[self alloc] initWithString: string] autorelease];
}

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







-
+









-
+







}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();

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

		CDATA = [[element stringValue] copy];

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

	return self;
}

Modified src/OFXMLCharacters.m from [992b1e5e2e] to [c037bb1a71].

15
16
17
18
19
20
21
22
23
24


25
26
27
28
29
30
31
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32







-


+
+







 */

#include "config.h"

#import "OFXMLCharacters.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"

#import "autorelease.h"

@implementation OFXMLCharacters
+ charactersWithString: (OFString*)string
{
	return [[[self alloc] initWithString: string] autorelease];
}

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







-
+









-
+







}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();

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

		characters = [[element stringValue] copy];

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

	return self;
}

Modified src/OFXMLComment.m from [b127c0c456] to [b39210532d].

17
18
19
20
21
22
23
24
25
26


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

24
25
26
27
28
29
30
31
32
33
34







-


+
+







#include "config.h"

#include <string.h>

#import "OFXMLComment.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"

#import "autorelease.h"

@implementation OFXMLComment
+ commentWithString: (OFString*)string
{
	return [[[self alloc] initWithString: string] autorelease];
}

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







-
+









-
+







}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();

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

		comment = [[element stringValue] copy];

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

	return self;
}

Modified src/OFXMLElement+Serialization.m from [570cb9f649] to [2f13ccd9ab].

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







-




+







-
+



-
-











-
+





#include "config.h"

#import "OFXMLElement.h"
#import "OFXMLElement+Serialization.h"
#import "OFSerialization.h"
#import "OFString.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"
#import "OFNotImplementedException.h"

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

int _OFXMLElement_Serialization_reference;

@implementation OFXMLElement (Serialization)
- (id)objectByDeserializing
{
	OFAutoreleasePool *pool;
	void *pool = objc_autoreleasePoolPush();
	Class class;
	id object;

	pool = [[OFAutoreleasePool alloc] init];

	if ((class = objc_lookUpClass([name cStringWithEncoding:
	    OF_STRING_ENCODING_ASCII])) == Nil)
		@throw [OFNotImplementedException exceptionWithClass: Nil];

	if (![class conformsToProtocol: @protocol(OFSerialization)])
		@throw [OFNotImplementedException
		    exceptionWithClass: class
			      selector: @selector(initWithSerialization:)];

	object = [[class alloc] initWithSerialization: self];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return [object autorelease];
}
@end

Modified src/OFXMLElement.m from [103672a799] to [01c2a13f7b].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46







-







+







#import "OFDictionary.h"
#import "OFDataArray.h"
#import "OFXMLAttribute.h"
#import "OFXMLCharacters.h"
#import "OFXMLCDATA.h"
#import "OFXMLParser.h"
#import "OFXMLElementBuilder.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFMalformedXMLException.h"
#import "OFNotImplementedException.h"
#import "OFUnboundNamespaceException.h"

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

/* References for static linking */
void _references_to_categories_of_OFXMLElement(void)
{
	_OFXMLElement_Serialization_reference = 1;
}
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
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







-
+












-
+

















-
+






-
+








-
+

















-
+









-
+







	}

	return self;
}

- initWithXMLString: (OFString*)string
{
	OFAutoreleasePool *pool;
	void *pool;
	OFXMLParser *parser;
	OFXMLElementBuilder *builder;
	OFXMLElement_OFXMLElementBuilderDelegate *delegate;
	Class c;

	c = [self class];
	[self release];

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

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	parser = [OFXMLParser parser];
	builder = [OFXMLElementBuilder elementBuilder];
	delegate = [[[OFXMLElement_OFXMLElementBuilderDelegate alloc] init]
	    autorelease];

	[parser setDelegate: builder];
	[builder setDelegate: delegate];

	[parser parseString: string];

	if (![parser finishedParsing])
		@throw [OFMalformedXMLException exceptionWithClass: c
							    parser: parser];

	self = [delegate->element retain];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return self;
}

- initWithFile: (OFString*)path
{
	OFAutoreleasePool *pool;
	void *pool;
	OFXMLParser *parser;
	OFXMLElementBuilder *builder;
	OFXMLElement_OFXMLElementBuilderDelegate *delegate;
	Class c;

	c = [self class];
	[self release];

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	parser = [OFXMLParser parser];
	builder = [OFXMLElementBuilder elementBuilder];
	delegate = [[[OFXMLElement_OFXMLElementBuilderDelegate alloc] init]
	    autorelease];

	[parser setDelegate: builder];
	[builder setDelegate: delegate];

	[parser parseFile: path];

	if (![parser finishedParsing])
		@throw [OFMalformedXMLException exceptionWithClass: c
							    parser: parser];

	self = [delegate->element retain];

	[pool release];
	objc_autoreleasePoolPop(pool);

	return self;
}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();
		OFXMLElement *attributesElement, *namespacesElement;
		OFXMLElement *childrenElement;
		OFEnumerator *keyEnumerator, *objectEnumerator;
		id key, object;

		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381







-
+







			       forKey: @"http://www.w3.org/2000/xmlns/"];

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

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

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







-
+




-
+




-









-


+
+

-
+
+




-
-








-
+







-
+







- (OFArray*)children
{
	OF_GETTER(children, YES)
}

- (void)setStringValue: (OFString*)stringValue
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();

	[self setChildren: [OFArray arrayWithObject:
	    [OFXMLCharacters charactersWithString: stringValue]]];

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (OFString*)stringValue
{
	OFAutoreleasePool *pool;
	OFMutableString *ret;
	OFXMLElement **objects;
	size_t i, count = [children count];

	if (count == 0)
		return @"";

	ret = [OFMutableString string];
	objects = [children objects];
	pool = [[OFAutoreleasePool alloc] init];

	for (i = 0; i < count; i++) {
		void *pool = objc_autoreleasePoolPush();

		[ret appendString: [objects[i] stringValue]];
		[pool releaseObjects];

		objc_autoreleasePoolPop(pool);
	}

	[ret makeImmutable];

	[pool release];

	return ret;
}

- (OFString*)_XMLStringWithParent: (OFXMLElement*)parent
		       namespaces: (OFDictionary*)allNamespaces
		      indentation: (unsigned int)indentation
			    level: (unsigned int)level
{
	OFAutoreleasePool *pool, *pool2;
	void *pool;
	char *cString;
	size_t length, i, j, attributesCount;
	OFString *prefix, *parentPrefix;
	OFXMLAttribute **attributesObjects;
	OFString *ret;
	OFString *defaultNS;

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	parentPrefix = [allNamespaces objectForKey:
	    (parent != nil && parent->ns != nil ? parent->ns : (OFString*)@"")];

	/* Add the namespaces of the current element */
	if (allNamespaces != nil) {
		OFEnumerator *keyEnumerator = [namespaces keyEnumerator];
550
551
552
553
554
555
556
557
558

559
560
561
562
563
564
565
549
550
551
552
553
554
555

556
557
558
559
560
561
562
563
564







-

+







		cString[i++] = '\'';
	}

	/* Attributes */
	attributesObjects = [attributes objects];
	attributesCount = [attributes count];

	pool2 = [[OFAutoreleasePool alloc] init];
	for (j = 0; j < attributesCount; j++) {
		void *pool2 = objc_autoreleasePoolPush();
		OFString *attributeName = [attributesObjects[j] name];
		OFString *attributePrefix = nil;
		OFString *tmp =
		    [[attributesObjects[j] stringValue] stringByXMLEscaping];

		if ([attributesObjects[j] namespace] != nil &&
		    (attributePrefix = [allNamespaces objectForKey:
594
595
596
597
598
599
600
601

602
603
604
605
606
607
608
593
594
595
596
597
598
599

600
601
602
603
604
605
606
607







-
+







		i += [attributeName UTF8StringLength];
		cString[i++] = '=';
		cString[i++] = '\'';
		memcpy(cString + i, [tmp UTF8String], [tmp UTF8StringLength]);
		i += [tmp UTF8StringLength];
		cString[i++] = '\'';

		[pool2 releaseObjects];
		objc_autoreleasePoolPop(pool2);
	}

	/* Childen */
	if (children != nil) {
		OFXMLElement **childrenObjects = [children objects];
		size_t childrenCount = [children count];
		OFDataArray *tmp = [OFDataArray dataArray];
689
690
691
692
693
694
695
696

697
698
699
700
701
702
703
688
689
690
691
692
693
694

695
696
697
698
699
700
701
702







-
+







		i += [name UTF8StringLength];
	} else
		cString[i++] = '/';

	cString[i++] = '>';
	assert(i == length);

	[pool release];
	objc_autoreleasePoolPop(pool);

	@try {
		ret = [OFString stringWithUTF8String: cString
					      length: length];
	} @finally {
		[self freeMemory: cString];
	}
727
728
729
730
731
732
733
734

735
736
737
738
739
740
741
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740







-
+







			       namespaces: nil
			      indentation: indentation
				    level: level];
}

- (OFXMLElement*)XMLElementBySerializing
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;

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

	if (name != nil)
		[element addAttributeWithName: @"name"
787
788
789
790
791
792
793
794
795


796
797

798
799
800
801
802
803
804
786
787
788
789
790
791
792


793
794
795

796
797
798
799
800
801
802
803







-
-
+
+

-
+







		    [OFXMLElement elementWithName: @"children"
					namespace: OF_SERIALIZATION_NS];
		[childrenElement addChild: [children XMLElementBySerializing]];
		[element addChild: childrenElement];
	}

	[element retain];
	[pool release];
	[element autorelease];

	objc_autoreleasePoolPop(pool);

	return element;
	return [element autorelease];
}

- (void)addAttribute: (OFXMLAttribute*)attribute
{
	if (attributes == nil)
		attributes = [[OFMutableArray alloc] init];

815
816
817
818
819
820
821
822

823
824
825
826
827
828

829
830
831
832
833
834
835
814
815
816
817
818
819
820

821
822
823
824
825
826

827
828
829
830
831
832
833
834







-
+





-
+







		       stringValue: stringValue];
}

- (void)addAttributeWithName: (OFString*)name_
		   namespace: (OFString*)ns_
		 stringValue: (OFString*)stringValue
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	void *pool = objc_autoreleasePoolPush();

	[self addAttribute: [OFXMLAttribute attributeWithName: name_
						    namespace: ns_
						  stringValue: stringValue]];

	[pool release];
	objc_autoreleasePoolPop(pool);
}

- (OFXMLAttribute*)attributeForName: (OFString*)attributeName
{
	OFXMLAttribute **objects = [attributes objects];
	size_t i, count = [attributes count];

Modified src/OFXMLParser.m from [c329ebfb71] to [5b68538ff6].

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
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 "OFString.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFDataArray.h"
#import "OFXMLAttribute.h"
#import "OFStream.h"
#import "OFFile.h"
#import "OFAutoreleasePool.h"

#import "OFInitializationFailedException.h"
#import "OFMalformedXMLException.h"
#import "OFUnboundNamespaceException.h"

#import "autorelease.h"

typedef void (*state_function)(id, SEL, const char*, size_t*, size_t*);
static SEL selectors[OF_XMLPARSER_NUM_STATES];
static state_function lookupTable[OF_XMLPARSER_NUM_STATES];

static OF_INLINE void
cache_append(OFDataArray *cache, const char *string,
    of_string_encoding_t encoding, size_t length)
{
	if (OF_LIKELY(encoding == OF_STRING_ENCODING_UTF_8))
		[cache addItemsFromCArray: string
				    count: length];
	else {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();
		OFString *tmp = [OFString stringWithCString: string
						   encoding: encoding
						     length: length];
		[cache addItemsFromCArray: [tmp UTF8String]
				    count: [tmp UTF8StringLength]];
		[pool release];
		objc_autoreleasePoolPop(pool);
	}
}

static OFString*
transform_string(OFDataArray *cache, size_t cut, BOOL unescape,
    OFObject <OFStringXMLUnescapingDelegate> *delegate)
{
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
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







-
+







-
+









-
+







}

- init
{
	self = [super init];

	@try {
		OFAutoreleasePool *pool;
		void *pool;
		OFMutableDictionary *dict;

		cache = [[OFBigDataArray alloc] init];
		previous = [[OFMutableArray alloc] init];
		namespaces = [[OFMutableArray alloc] init];
		attributes = [[OFMutableArray alloc] init];

		pool = [[OFAutoreleasePool 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];

		acceptProlog = YES;
		lineNumber = 1;
		encoding = OF_STRING_ENCODING_UTF_8;

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

	return self;
}
317
318
319
320
321
322
323
324
325

326
327
328

329
330
331
332
333

334
335
336
337
338
339
340
318
319
320
321
322
323
324


325



326
327
328
329
330

331
332
333
334
335
336
337
338







-
-
+
-
-
-
+




-
+







	if (buffer[*i] != '<')
		return;

	if ((length = *i - *last) > 0)
		cache_append(cache, buffer + *last, encoding, length);

	if ([cache count] > 0) {
		OFString *characters;
		OFAutoreleasePool *pool;
		void *pool = objc_autoreleasePoolPush();

		pool = [[OFAutoreleasePool alloc] init];
		characters = transform_string(cache, 0, YES, self);
		OFString *characters = transform_string(cache, 0, YES, self);

		[delegate parser: self
		 foundCharacters: characters];

		[pool release];
		objc_autoreleasePoolPop(pool);
	}

	[cache removeAllItems];

	*last = *i + 1;
	state = OF_XMLPARSER_TAG_OPENED;
}
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
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







-
+
















-
+














-
+











-
+



















-









-
-

















-
-










-
-
-
+
-

-
-
+
+










-
+












-
+







- (void)_parseInProcessingInstructionsWithBuffer: (const char*)buffer
					       i: (size_t*)i
					    last: (size_t*)last
{
	if (buffer[*i] == '?')
		level = 1;
	else if (level == 1 && buffer[*i] == '>') {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();
		OFString *pi;

		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 _parseXMLProcessingInstructions: pi])
				@throw [OFMalformedXMLException
				    exceptionWithClass: [self class]
						parser: self];

		[delegate parser: self
		    foundProcessingInstructions: pi];

		[pool release];
		objc_autoreleasePoolPop(pool);

		[cache removeAllItems];

		*last = *i + 1;
		state = OF_XMLPARSER_OUTSIDE_TAG;
	} else
		level = 0;
}

/* Inside a tag, no name yet */
- (void)_parseInTagNameWithBuffer: (const char*)buffer
				i: (size_t*)i
			     last: (size_t*)last
{
	OFAutoreleasePool *pool;
	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);

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	cacheCString = [cache cArray];
	cacheLength = [cache count];
	cacheString = [OFString stringWithUTF8String: cacheCString
					      length: cacheLength];

	if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) {
		name = [[OFString alloc]
		    initWithUTF8String: tmp + 1
				length: cacheLength - (tmp - cacheCString) - 1];
		prefix = [[OFString alloc]
		    initWithUTF8String: cacheCString
				length: tmp - cacheCString];
	} else {
		name = [cacheString copy];
		prefix = nil;
	}

	if (buffer[*i] == '>' || buffer[*i] == '/') {
		OFAutoreleasePool *pool2;
		OFString *ns;

		ns = namespace_for_prefix(prefix, namespaces);

		if (prefix != nil && ns == nil)
			@throw [OFUnboundNamespaceException
			    exceptionWithClass: [self class]
					prefix: prefix];

		pool2 = [[OFAutoreleasePool alloc] init];

		[delegate parser: self
		 didStartElement: name
		      withPrefix: prefix
		       namespace: ns
		      attributes: nil];

		if (buffer[*i] == '/') {
			[delegate parser: self
			   didEndElement: name
			      withPrefix: prefix
			       namespace: ns];

			if ([previous count] == 0)
				finishedParsing = YES;
		} else
			[previous addObject: cacheString];

		[pool2 release];

		[name release];
		[prefix release];
		name = prefix = nil;

		state = (buffer[*i] == '/'
		    ? OF_XMLPARSER_EXPECT_CLOSE
		    : OF_XMLPARSER_OUTSIDE_TAG);
	} else
		state = OF_XMLPARSER_IN_TAG;

	[pool release];

	if (buffer[*i] != '/') {
	if (buffer[*i] != '/')
		pool = [[OFAutoreleasePool alloc] init];
		[namespaces addObject: [OFMutableDictionary dictionary]];
		[pool release];
	}

	objc_autoreleasePoolPop(pool);

	[cache removeAllItems];
	*last = *i + 1;
}

/* Inside a close tag, no name yet */
- (void)_parseInCloseTagNameWithBuffer: (const char*)buffer
				     i: (size_t*)i
				  last: (size_t*)last
{
	OFAutoreleasePool *pool;
	void *pool;
	const char *cacheCString, *tmp;
	size_t length, cacheLength;
	OFString *cacheString;
	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);

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	cacheCString = [cache cArray];
	cacheLength = [cache count];
	cacheString = [OFString stringWithUTF8String: cacheCString
					      length: cacheLength];

	if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) {
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
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







-
+




















-
+







				prefix: prefix];

	[delegate parser: self
	   didEndElement: name
	      withPrefix: prefix
	       namespace: ns];

	[pool release];
	objc_autoreleasePoolPop(pool);

	[namespaces removeLastObject];
	[name release];
	[prefix release];
	name = prefix = nil;

	*last = *i + 1;
	state = (buffer[*i] == '>'
	    ? OF_XMLPARSER_OUTSIDE_TAG
	    : OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE);

	if ([previous count] == 0)
		finishedParsing = YES;
}

/* Inside a tag, name found */
- (void)_parseInTagWithBuffer: (const char*)buffer
			    i: (size_t*)i
			 last: (size_t*)last
{
	OFAutoreleasePool *pool;
	void *pool;
	OFString *ns;
	OFXMLAttribute **attributesObjects;
	size_t j, attributesCount;

	if (buffer[*i] != '>' && buffer[*i] != '/') {
		if (buffer[*i] != ' ' && buffer[*i] != '\t' &&
		    buffer[*i] != '\n' && buffer[*i] != '\r') {
696
697
698
699
700
701
702
703

704
705
706
707
708
709
710
686
687
688
689
690
691
692

693
694
695
696
697
698
699
700







-
+







		    exceptionWithClass: [self class]
				prefix: prefix];

	for (j = 0; j < attributesCount; j++)
		resolve_attribute_namespace(attributesObjects[j], namespaces,
		    self);

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	[delegate parser: self
	 didStartElement: name
	      withPrefix: prefix
	       namespace: ns
	      attributes: attributes];

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







-
+

















-
+










-
+







	} else if (prefix != nil) {
		OFString *str = [OFString stringWithFormat: @"%@:%@",
							    prefix, name];
		[previous addObject: str];
	} else
		[previous addObject: name];

	[pool release];
	objc_autoreleasePoolPop(pool);

	[name release];
	[prefix release];
	[attributes removeAllObjects];
	name = prefix = nil;

	*last = *i + 1;
	state = (buffer[*i] == '/'
	    ? OF_XMLPARSER_EXPECT_CLOSE
	    : OF_XMLPARSER_OUTSIDE_TAG);
}

/* Looking for attribute name */
- (void)_parseInAttributeNameWithBuffer: (const char*)buffer
				      i: (size_t*)i
				   last: (size_t*)last
{
	OFAutoreleasePool *pool;
	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);

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	cacheString = [OFMutableString stringWithUTF8String: [cache cArray]
						     length: [cache count]];
	[cacheString deleteEnclosingWhitespaces];
	/* Prevent a useless copy later */
	[cacheString makeImmutable];

773
774
775
776
777
778
779
780

781
782
783
784
785
786
787
763
764
765
766
767
768
769

770
771
772
773
774
775
776
777







-
+







		    initWithUTF8String: cacheCString
				length: tmp - cacheCString];
	} else {
		attributeName = [cacheString copy];
		attributePrefix = nil;
	}

	[pool release];
	objc_autoreleasePoolPop(pool);

	[cache removeAllItems];

	*last = *i + 1;
	state = OF_XMLPARSER_EXPECT_DELIM;
}

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







-
+









-
+














-
+







}

/* Looking for attribute value */
- (void)_parseInAttributeValueWithBuffer: (const char*)buffer
				       i: (size_t*)i
				    last: (size_t*)last
{
	OFAutoreleasePool *pool;
	void *pool;
	OFString *attributeValue;
	size_t length;

	if (buffer[*i] != delimiter)
		return;

	if ((length = *i - *last) > 0)
		cache_append(cache, buffer + *last, encoding, length);

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();
	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];

	[attributes addObject:
	    [OFXMLAttribute attributeWithName: attributeName
				    namespace: attributePrefix
				  stringValue: attributeValue]];

	[pool release];
	objc_autoreleasePoolPop(pool);

	[cache removeAllItems];
	[attributeName release];
	[attributePrefix release];
	attributeName = attributePrefix = nil;

	*last = *i + 1;
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
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







-
+









-
+







-
+







		state = OF_XMLPARSER_IN_CDATA_2;
}

- (void)_parseInCDATA2WithBuffer: (const char*)buffer
			       i: (size_t*)i
			    last: (size_t*)last
{
	OFAutoreleasePool *pool;
	void *pool;
	OFString *CDATA;

	if (buffer[*i] != '>') {
		state = OF_XMLPARSER_IN_CDATA_1;
		level = (buffer[*i] == ']' ? 1 : 0);

		return;
	}

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	cache_append(cache, buffer + *last, encoding, *i - *last);
	CDATA = transform_string(cache, 2, NO, nil);

	[delegate parser: self
	      foundCDATA: CDATA];

	[pool release];
	objc_autoreleasePoolPop(pool);

	[cache removeAllItems];

	*last = *i + 1;
	state = OF_XMLPARSER_OUTSIDE_TAG;
}

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







-
+






-
+







-
+







		state = OF_XMLPARSER_IN_COMMENT_2;
}

- (void)_parseInComment2WithBuffer: (const char*)buffer
				 i: (size_t*)i
			      last: (size_t*)last
{
	OFAutoreleasePool *pool;
	void *pool;
	OFString *comment;

	if (buffer[*i] != '>')
		@throw [OFMalformedXMLException exceptionWithClass: [self class]
							    parser: self];

	pool = [[OFAutoreleasePool alloc] init];
	pool = objc_autoreleasePoolPush();

	cache_append(cache, buffer + *last, encoding, *i - *last);
	comment = transform_string(cache, 2, NO, nil);

	[delegate parser: self
	    foundComment: comment];

	[pool release];
	objc_autoreleasePoolPop(pool);

	[cache removeAllItems];

	*last = *i + 1;
	state = OF_XMLPARSER_OUTSIDE_TAG;
}

Modified src/OFXMLProcessingInstructions.m from [a0218b0933] to [00953e389a].

17
18
19
20
21
22
23
24
25
26


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

24
25
26
27
28
29
30
31
32
33
34







-


+
+







#include "config.h"

#include <string.h>

#import "OFXMLProcessingInstructions.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidArgumentException.h"

#import "autorelease.h"

@implementation OFXMLProcessingInstructions
+ processingInstructionsWithString: (OFString*)string
{
	return [[[self alloc] initWithString: string] autorelease];
}

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







-
+









-
+







}

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

	@try {
		OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
		void *pool = objc_autoreleasePoolPush();

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

		processingInstructions = [[element stringValue] copy];

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

	return self;
}