ObjFW  Check-in [63caea2ec6]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Finish migrating to the ARC functions for RR
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 63caea2ec6bac1c27049436666c65f18814ea7dfcd47c73bd9d1dc8ffaf469f2
User & Date: js 2025-04-16 00:07:52.733
Context
2025-04-18
14:58
Optimize objc_{retain,release} by inlining check-in: 99212998dd user: js tags: trunk
2025-04-16
00:07
Finish migrating to the ARC functions for RR check-in: 63caea2ec6 user: js tags: trunk
2025-04-15
22:57
GitHub Actions: Explicitly install awk on Fedora check-in: b42fe78166 user: js tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to tests/ForwardingTests.m.
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
	[ForwardingTestObject test];
	OTAssertEqual(forwardingsCount, 1);
}

- (void)forwardingMessageAndAddingInstanceMethod
{
	ForwardingTestObject *testObject =
	    [[[ForwardingTestObject alloc] init] autorelease];

	[testObject test];
	OTAssertTrue(success);
	OTAssertEqual(forwardingsCount, 1);

	[testObject test];
	OTAssertEqual(forwardingsCount, 1);
}

#ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
- (void)testForwardingTargetForSelector
{
	ForwardingTestObject *testObject =
	    [[[ForwardingTestObject alloc] init] autorelease];

	target = [[[ForwardingTarget alloc] init] autorelease];

	OTAssertEqual(
	    [testObject forwardingTargetTest: 0xDEADBEEF
					    : -1
					    : 1.25
					    : 2.75], 0x12345678);
}

- (void)testForwardingTargetForSelectorWithVariableArguments
{
	ForwardingTestObject *testObject =
	    [[[ForwardingTestObject alloc] init] autorelease];

	target = [[[ForwardingTarget alloc] init] autorelease];

	OTAssertEqualObjects(
	    ([testObject forwardingTargetVarArgTest: FORMAT, ARGS]), RESULT);
}

/*
 * Don't try fpret on Win64 if we don't have stret forwarding, as long double
 * is handled as a struct there.
 *
 * Don't try fpret on macOS on x86_64 with the Apple runtime as a regression
 * was introduced in either macOS 14 or 15 where objc_msgSend_fpret calls the
 * stret forwarding handler instead of the regular one.
 */
# if !(defined(OF_WINDOWS) && defined(OF_AMD64) && \
    defined(OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET)) && \
    !(defined(OF_APPLE_RUNTIME) && defined(OF_AMD64))
- (void)testForwardingTargetForSelectorFPRet
{
	ForwardingTestObject *testObject =
	    [[[ForwardingTestObject alloc] init] autorelease];

	target = [[[ForwardingTarget alloc] init] autorelease];

	OTAssertEqual([testObject forwardingTargetFPRetTest],
	    12345678.00006103515625);
}
# endif

# ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
- (void)testForwardingTargetForSelectorStRet
{
	ForwardingTestObject *testObject =
	    [[[ForwardingTestObject alloc] init] autorelease];

	target = [[[ForwardingTarget alloc] init] autorelease];

	OTAssertEqual(memcmp([testObject forwardingTargetStRetTest].buffer,
	    "abcdefghijklmnopqrstuvwxyz", 27), 0);
}
# endif

- (void)testForwardingTargetForSelectorReturningNilThrows
{
	ForwardingTestObject *testObject =
	    [[[ForwardingTestObject alloc] init] autorelease];

	target = [[[ForwardingTarget alloc] init] autorelease];

	OTAssertThrowsSpecific([testObject forwardingTargetNilTest],
	    OFNotImplementedException);
}

- (void)testForwardingTargetForSelectorReturningSelfThrows
{
	ForwardingTestObject *testObject =
	    [[[ForwardingTestObject alloc] init] autorelease];

	target = [[[ForwardingTarget alloc] init] autorelease];

	OTAssertThrowsSpecific([testObject forwardingTargetSelfTest],
	    OFNotImplementedException);
}

# ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
- (void)testForwardingTargetForSelectorStRetReturningNilThrows
{
	ForwardingTestObject *testObject =
	    [[[ForwardingTestObject alloc] init] autorelease];

	target = [[[ForwardingTarget alloc] init] autorelease];

	OTAssertThrowsSpecific([testObject forwardingTargetNilStRetTest],
	    OFNotImplementedException);
}

- (void)testForwardingTargetForSelectorStRetReturningSelfThrows
{
	ForwardingTestObject *testObject =
	    [[[ForwardingTestObject alloc] init] autorelease];

	target = [[[ForwardingTarget alloc] init] autorelease];

	OTAssertThrowsSpecific([testObject forwardingTargetSelfStRetTest],
	    OFNotImplementedException);
}
# endif
#endif
@end







|













|

|











|

|



















|

|










|

|









|

|








|

|









|

|








|

|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
	[ForwardingTestObject test];
	OTAssertEqual(forwardingsCount, 1);
}

- (void)forwardingMessageAndAddingInstanceMethod
{
	ForwardingTestObject *testObject =
	    objc_autorelease([[ForwardingTestObject alloc] init]);

	[testObject test];
	OTAssertTrue(success);
	OTAssertEqual(forwardingsCount, 1);

	[testObject test];
	OTAssertEqual(forwardingsCount, 1);
}

#ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
- (void)testForwardingTargetForSelector
{
	ForwardingTestObject *testObject =
	    objc_autorelease([[ForwardingTestObject alloc] init]);

	target = objc_autorelease([[ForwardingTarget alloc] init]);

	OTAssertEqual(
	    [testObject forwardingTargetTest: 0xDEADBEEF
					    : -1
					    : 1.25
					    : 2.75], 0x12345678);
}

- (void)testForwardingTargetForSelectorWithVariableArguments
{
	ForwardingTestObject *testObject =
	    objc_autorelease([[ForwardingTestObject alloc] init]);

	target = objc_autorelease([[ForwardingTarget alloc] init]);

	OTAssertEqualObjects(
	    ([testObject forwardingTargetVarArgTest: FORMAT, ARGS]), RESULT);
}

/*
 * Don't try fpret on Win64 if we don't have stret forwarding, as long double
 * is handled as a struct there.
 *
 * Don't try fpret on macOS on x86_64 with the Apple runtime as a regression
 * was introduced in either macOS 14 or 15 where objc_msgSend_fpret calls the
 * stret forwarding handler instead of the regular one.
 */
# if !(defined(OF_WINDOWS) && defined(OF_AMD64) && \
    defined(OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET)) && \
    !(defined(OF_APPLE_RUNTIME) && defined(OF_AMD64))
- (void)testForwardingTargetForSelectorFPRet
{
	ForwardingTestObject *testObject =
	    objc_autorelease([[ForwardingTestObject alloc] init]);

	target = objc_autorelease([[ForwardingTarget alloc] init]);

	OTAssertEqual([testObject forwardingTargetFPRetTest],
	    12345678.00006103515625);
}
# endif

# ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
- (void)testForwardingTargetForSelectorStRet
{
	ForwardingTestObject *testObject =
	    objc_autorelease([[ForwardingTestObject alloc] init]);

	target = objc_autorelease([[ForwardingTarget alloc] init]);

	OTAssertEqual(memcmp([testObject forwardingTargetStRetTest].buffer,
	    "abcdefghijklmnopqrstuvwxyz", 27), 0);
}
# endif

- (void)testForwardingTargetForSelectorReturningNilThrows
{
	ForwardingTestObject *testObject =
	    objc_autorelease([[ForwardingTestObject alloc] init]);

	target = objc_autorelease([[ForwardingTarget alloc] init]);

	OTAssertThrowsSpecific([testObject forwardingTargetNilTest],
	    OFNotImplementedException);
}

- (void)testForwardingTargetForSelectorReturningSelfThrows
{
	ForwardingTestObject *testObject =
	    objc_autorelease([[ForwardingTestObject alloc] init]);

	target = objc_autorelease([[ForwardingTarget alloc] init]);

	OTAssertThrowsSpecific([testObject forwardingTargetSelfTest],
	    OFNotImplementedException);
}

# ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
- (void)testForwardingTargetForSelectorStRetReturningNilThrows
{
	ForwardingTestObject *testObject =
	    objc_autorelease([[ForwardingTestObject alloc] init]);

	target = objc_autorelease([[ForwardingTarget alloc] init]);

	OTAssertThrowsSpecific([testObject forwardingTargetNilStRetTest],
	    OFNotImplementedException);
}

- (void)testForwardingTargetForSelectorStRetReturningSelfThrows
{
	ForwardingTestObject *testObject =
	    objc_autorelease([[ForwardingTestObject alloc] init]);

	target = objc_autorelease([[ForwardingTarget alloc] init]);

	OTAssertThrowsSpecific([testObject forwardingTargetSelfStRetTest],
	    OFNotImplementedException);
}
# endif
#endif
@end
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
{
	va_list args;
	OFString *ret;

	OFEnsure(self == target);

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

	return ret;
}

- (long double)forwardingTargetFPRetTest
{
	OFEnsure(self == target);

	return 12345678.00006103515625;







|
<


|







295
296
297
298
299
300
301
302

303
304
305
306
307
308
309
310
311
312
{
	va_list args;
	OFString *ret;

	OFEnsure(self == target);

	va_start(args, format);
	ret = [[OFString alloc] initWithFormat: format arguments: args];

	va_end(args);

	return objc_autoreleaseReturnValue(ret);
}

- (long double)forwardingTargetFPRetTest
{
	OFEnsure(self == target);

	return 12345678.00006103515625;
Changes to tests/OFArrayTests.m.
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
	_array = [[self.arrayClass alloc]
	    initWithObjects: cArray
		      count: sizeof(cArray) / sizeof(*cArray)];
}

- (void)dealloc
{
	[_array release];

	[super dealloc];
}

- (void)testArray
{
	OFArray *array = [self.arrayClass array];







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
	_array = [[self.arrayClass alloc]
	    initWithObjects: cArray
		      count: sizeof(cArray) / sizeof(*cArray)];
}

- (void)dealloc
{
	objc_release(_array);

	[super dealloc];
}

- (void)testArray
{
	OFArray *array = [self.arrayClass array];
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

	OTAssertEqual(array.hash, _array.hash);
	OTAssertNotEqual(array.hash, [[OFArray array] hash]);
}

- (void)testCopy
{
	OTAssertEqualObjects([[_array copy] autorelease], _array);
}

- (void)testMutableCopy
{
	OTAssertEqualObjects([[_array mutableCopy] autorelease], _array);
}

- (void)testObjectAtIndex
{
	OTAssertEqualObjects([_array objectAtIndex: 0], cArray[0]);
	OTAssertEqualObjects([_array objectAtIndex: 1], cArray[1]);
	OTAssertEqualObjects([_array objectAtIndex: 2], cArray[2]);







|




|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

	OTAssertEqual(array.hash, _array.hash);
	OTAssertNotEqual(array.hash, [[OFArray array] hash]);
}

- (void)testCopy
{
	OTAssertEqualObjects(objc_autorelease([_array copy]), _array);
}

- (void)testMutableCopy
{
	OTAssertEqualObjects(objc_autorelease([_array mutableCopy]), _array);
}

- (void)testObjectAtIndex
{
	OTAssertEqualObjects([_array objectAtIndex: 0], cArray[0]);
	OTAssertEqualObjects([_array objectAtIndex: 1], cArray[1]);
	OTAssertEqualObjects([_array objectAtIndex: 2], cArray[2]);
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
{
	self = [super init];

	@try {
		_array = [[OFArray alloc] initWithObjects: objects
						    count: count];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_array release];

	[super dealloc];
}

- (id)objectAtIndex: (size_t)idx
{
	return [_array objectAtIndex: idx];







|








|







305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
{
	self = [super init];

	@try {
		_array = [[OFArray alloc] initWithObjects: objects
						    count: count];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_array);

	[super dealloc];
}

- (id)objectAtIndex: (size_t)idx
{
	return [_array objectAtIndex: idx];
Changes to tests/OFBlockTests.m.
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#endif

static int
(^returnStackBlock(void))(void)
{
	__block int i = 42;

	return [Block_copy(^ int { return ++i; }) autorelease];
}

static double
forwardTest(void)
{
	__block double d;
	void (^block)(void) = Block_copy(^ {







|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#endif

static int
(^returnStackBlock(void))(void)
{
	__block int i = 42;

	return objc_autorelease(Block_copy(^ int { return ++i; }));
}

static double
forwardTest(void)
{
	__block double d;
	void (^block)(void) = Block_copy(^ {
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
	__block int x;
	void (^stackBlock)(void) = ^ {
		x = 0;
		(void)x;
	};
	void (^mallocBlock)(void);

	mallocBlock = [[stackBlock copy] autorelease];
	OTAssertEqual([mallocBlock class], objc_getClass("OFMallocBlock"));
	OTAssertTrue([mallocBlock isKindOfClass: [OFBlock class]]);
}

- (void)testCopyStackBlockAndReferenceVariable
{
	OTAssertEqual(forwardTest(), 5);







|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
	__block int x;
	void (^stackBlock)(void) = ^ {
		x = 0;
		(void)x;
	};
	void (^mallocBlock)(void);

	mallocBlock = objc_autorelease([stackBlock copy]);
	OTAssertEqual([mallocBlock class], objc_getClass("OFMallocBlock"));
	OTAssertTrue([mallocBlock isKindOfClass: [OFBlock class]]);
}

- (void)testCopyStackBlockAndReferenceVariable
{
	OTAssertEqual(forwardTest(), 5);
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
	OTAssertEqual(voidBlock(), 44);
	OTAssertEqual(voidBlock(), 45);
}

#if !defined(OF_WINDOWS) || !defined(__clang__)
- (void)testCopyGlobalBlock
{
	OTAssertEqual([[globalBlock copy] autorelease], (id)globalBlock);
}
#endif

- (void)testCopyMallocBlock
{
	__block int x;
	void (^stackBlock)(void) = ^ {
		x = 0;
		(void)x;
	};
	void (^mallocBlock)(void);

	mallocBlock = [[stackBlock copy] autorelease];
	OTAssertEqual([[mallocBlock copy] autorelease], (id)mallocBlock);
	OTAssertEqual([mallocBlock retainCount], 2);
}
@end







|












|
|



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
	OTAssertEqual(voidBlock(), 44);
	OTAssertEqual(voidBlock(), 45);
}

#if !defined(OF_WINDOWS) || !defined(__clang__)
- (void)testCopyGlobalBlock
{
	OTAssertEqual(objc_autorelease([globalBlock copy]), (id)globalBlock);
}
#endif

- (void)testCopyMallocBlock
{
	__block int x;
	void (^stackBlock)(void) = ^ {
		x = 0;
		(void)x;
	};
	void (^mallocBlock)(void);

	mallocBlock = objc_autorelease([stackBlock copy]);
	OTAssertEqual(objc_autorelease([mallocBlock copy]), (id)mallocBlock);
	OTAssertEqual([mallocBlock retainCount], 2);
}
@end
Changes to tests/OFCharacterSetTests.m.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
}
@end

@implementation OFCharacterSetTests
- (void)testCustomCharacterSet
{
	OFCharacterSet *characterSet =
	    [[[CustomCharacterSet alloc] init] autorelease];

	for (OFUnichar c = 0; c < 65536; c++)
		if (c % 2 == 0)
			OTAssertTrue([characterSet characterIsMember: c]);
		else
			OTAssertFalse([characterSet characterIsMember: c]);
}







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
}
@end

@implementation OFCharacterSetTests
- (void)testCustomCharacterSet
{
	OFCharacterSet *characterSet =
	    objc_autorelease([[CustomCharacterSet alloc] init]);

	for (OFUnichar c = 0; c < 65536; c++)
		if (c % 2 == 0)
			OTAssertTrue([characterSet characterIsMember: c]);
		else
			OTAssertFalse([characterSet characterIsMember: c]);
}
Changes to tests/OFColorTests.m.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
					green: 127.f / 255
					 blue: 1
					alpha: 1];
}

- (void)dealloc
{
	[_color release];

	[super dealloc];
}

#ifdef OF_OBJFW_RUNTIME
- (void)testReturnsTaggedPointer
{







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
					green: 127.f / 255
					 blue: 1
					alpha: 1];
}

- (void)dealloc
{
	objc_release(_color);

	[super dealloc];
}

#ifdef OF_OBJFW_RUNTIME
- (void)testReturnsTaggedPointer
{
Changes to tests/OFConcreteMutableDictionaryTests.m.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
	return [OFConcreteMutableDictionary class];
}

- (void)testDetectMutationDuringEnumeration
{
	OFMutableDictionary *mutableDictionary =
	    [[_dictionary mutableCopy] autorelease];
	OFEnumerator *keyEnumerator = [mutableDictionary keyEnumerator];
	OFEnumerator *objectEnumerator = [mutableDictionary objectEnumerator];
	OFString *key;
	size_t i;

	i = 0;
	while ((key = [keyEnumerator nextObject]) != nil) {







|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
	return [OFConcreteMutableDictionary class];
}

- (void)testDetectMutationDuringEnumeration
{
	OFMutableDictionary *mutableDictionary =
	    objc_autorelease([_dictionary mutableCopy]);
	OFEnumerator *keyEnumerator = [mutableDictionary keyEnumerator];
	OFEnumerator *objectEnumerator = [mutableDictionary objectEnumerator];
	OFString *key;
	size_t i;

	i = 0;
	while ((key = [keyEnumerator nextObject]) != nil) {
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
	OTAssertThrowsSpecific([objectEnumerator nextObject],
	    OFEnumerationMutationException);
}

- (void)testDetectMutationDuringFastEnumeration
{
	OFMutableDictionary *mutableDictionary =
	    [[_dictionary mutableCopy] autorelease];
	bool detected = false;
	size_t i;

	i = 0;
	for (OFString *key in mutableDictionary) {
		[mutableDictionary setObject: @"test" forKey: key];
		i++;







|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
	OTAssertThrowsSpecific([objectEnumerator nextObject],
	    OFEnumerationMutationException);
}

- (void)testDetectMutationDuringFastEnumeration
{
	OFMutableDictionary *mutableDictionary =
	    objc_autorelease([_dictionary mutableCopy]);
	bool detected = false;
	size_t i;

	i = 0;
	for (OFString *key in mutableDictionary) {
		[mutableDictionary setObject: @"test" forKey: key];
		i++;
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
	OTAssertTrue(detected);
}

#ifdef OF_HAVE_BLOCKS
- (void)testDetectMutationDuringEnumerateObjectsUsingBlock
{
	OFMutableDictionary *mutableDictionary =
	    [[_dictionary mutableCopy] autorelease];
	__block size_t i;

	i = 0;
	[mutableDictionary enumerateKeysAndObjectsUsingBlock:
	    ^ (id key, id object, bool *stop) {
		[mutableDictionary setObject: @"test" forKey: key];
		i++;







|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
	OTAssertTrue(detected);
}

#ifdef OF_HAVE_BLOCKS
- (void)testDetectMutationDuringEnumerateObjectsUsingBlock
{
	OFMutableDictionary *mutableDictionary =
	    objc_autorelease([_dictionary mutableCopy]);
	__block size_t i;

	i = 0;
	[mutableDictionary enumerateKeysAndObjectsUsingBlock:
	    ^ (id key, id object, bool *stop) {
		[mutableDictionary setObject: @"test" forKey: key];
		i++;
Changes to tests/OFCryptographicHashTests.m.
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
- (void)setUp
{
	OFIRI *IRI;

	[super setUp];

	IRI = [OFIRI IRIWithString: @"embedded:testfile.bin"];
	_stream = [[OFIRIHandler openItemAtIRI: IRI mode: @"r"] retain];
}

- (void)tearDown
{
	[_stream close];

	[super tearDown];
}

- (void)dealloc
{
	[_stream release];

	[super dealloc];
}

- (void)testHash: (Class)hashClass
  expectedDigest: (const unsigned char *)expectedDigest
{
	id <OFCryptographicHash> hash =
	    [hashClass hashWithAllowsSwappableMemory: true];
	id <OFCryptographicHash> copy;

	OTAssertNotNil(hash);

	while (!_stream.atEndOfStream) {
		char buffer[64];
		size_t length = [_stream readIntoBuffer: buffer length: 64];
		[hash updateWithBuffer: buffer length: length];
	}

	copy = [[hash copy] autorelease];

	[hash calculate];
	[copy calculate];

	OTAssertEqual(memcmp(hash.digest, expectedDigest, hash.digestSize), 0);
	OTAssertEqual(memcmp(hash.digest, expectedDigest, hash.digestSize), 0);








|











|



















|







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
- (void)setUp
{
	OFIRI *IRI;

	[super setUp];

	IRI = [OFIRI IRIWithString: @"embedded:testfile.bin"];
	_stream = objc_retain([OFIRIHandler openItemAtIRI: IRI mode: @"r"]);
}

- (void)tearDown
{
	[_stream close];

	[super tearDown];
}

- (void)dealloc
{
	objc_release(_stream);

	[super dealloc];
}

- (void)testHash: (Class)hashClass
  expectedDigest: (const unsigned char *)expectedDigest
{
	id <OFCryptographicHash> hash =
	    [hashClass hashWithAllowsSwappableMemory: true];
	id <OFCryptographicHash> copy;

	OTAssertNotNil(hash);

	while (!_stream.atEndOfStream) {
		char buffer[64];
		size_t length = [_stream readIntoBuffer: buffer length: 64];
		[hash updateWithBuffer: buffer length: length];
	}

	copy = objc_autorelease([hash copy]);

	[hash calculate];
	[copy calculate];

	OTAssertEqual(memcmp(hash.digest, expectedDigest, hash.digestSize), 0);
	OTAssertEqual(memcmp(hash.digest, expectedDigest, hash.digestSize), 0);

Changes to tests/OFDataTests.m.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
	_data = [[self.dataClass alloc] initWithItems: _items
						count: 2
					     itemSize: 4096];
}

- (void)dealloc
{
	[_data release];

	[super dealloc];
}

- (void)testCount
{
	OTAssertEqual(_data.count, 2);







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
	_data = [[self.dataClass alloc] initWithItems: _items
						count: 2
					     itemSize: 4096];
}

- (void)dealloc
{
	objc_release(_data);

	[super dealloc];
}

- (void)testCount
{
	OTAssertEqual(_data.count, 2);
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
	OTAssertEqual([data1 compare: data1], OFOrderedSame);
	OTAssertEqual([data1 compare: data3], OFOrderedAscending);
	OTAssertEqual([data2 compare: data3], OFOrderedDescending);
}

- (void)testCopy
{
	OTAssertEqualObjects([[_data copy] autorelease], _data);
}

- (void)testRangeOfDataOptionsRange
{
	OFData *data = [self.dataClass dataWithItems: "aaabaccdacaabb"
					       count: 7
					    itemSize: 2];







|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
	OTAssertEqual([data1 compare: data1], OFOrderedSame);
	OTAssertEqual([data1 compare: data3], OFOrderedAscending);
	OTAssertEqual([data2 compare: data3], OFOrderedDescending);
}

- (void)testCopy
{
	OTAssertEqualObjects(objc_autorelease([_data copy]), _data);
}

- (void)testRangeOfDataOptionsRange
{
	OFData *data = [self.dataClass dataWithItems: "aaabaccdacaabb"
					       count: 7
					    itemSize: 2];
Changes to tests/OFDateTests.m.
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
	_date[0] = [[OFDate alloc] initWithTimeIntervalSince1970: 0];
	_date[1] = [[OFDate alloc]
	    initWithTimeIntervalSince1970: 3600 * 25 + 5.000002];
}

- (void)dealloc
{
	[_date[0] release];
	[_date[1] release];

	[super dealloc];
}

- (void)testStrPTime
{
	struct tm tm;







|
|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
	_date[0] = [[OFDate alloc] initWithTimeIntervalSince1970: 0];
	_date[1] = [[OFDate alloc]
	    initWithTimeIntervalSince1970: 3600 * 25 + 5.000002];
}

- (void)dealloc
{
	objc_release(_date[0]);
	objc_release(_date[1]);

	[super dealloc];
}

- (void)testStrPTime
{
	struct tm tm;
Changes to tests/OFDictionaryTests.m.
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
	_dictionary = [[self.dictionaryClass alloc] initWithObjects: objects
							    forKeys: keys
							      count: 2];
}

- (void)dealloc
{
	[_dictionary release];

	[super dealloc];
}

- (void)testObjectForKey
{
	OTAssertEqualObjects([_dictionary objectForKey: keys[0]], objects[0]);







|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
	_dictionary = [[self.dictionaryClass alloc] initWithObjects: objects
							    forKeys: keys
							      count: 2];
}

- (void)dealloc
{
	objc_release(_dictionary);

	[super dealloc];
}

- (void)testObjectForKey
{
	OTAssertEqualObjects([_dictionary objectForKey: keys[0]], objects[0]);
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
	OTAssertNotEqual(_dictionary.hash,
	    [[OFDictionary dictionaryWithObject: objects[0]
					 forKey: keys[0]] hash]);
}

- (void)testCopy
{
	OTAssertEqualObjects([[_dictionary copy] autorelease], _dictionary);
}

- (void)testMutableCopy
{
	OTAssertEqualObjects(
	    [[_dictionary mutableCopy] autorelease], _dictionary);
}

- (void)testValueForKey
{
	OTAssertEqualObjects([_dictionary valueForKey: keys[0]], objects[0]);
	OTAssertEqualObjects([_dictionary valueForKey: keys[1]], objects[1]);
	OTAssertEqualObjects(







|





|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
	OTAssertNotEqual(_dictionary.hash,
	    [[OFDictionary dictionaryWithObject: objects[0]
					 forKey: keys[0]] hash]);
}

- (void)testCopy
{
	OTAssertEqualObjects(objc_autorelease([_dictionary copy]), _dictionary);
}

- (void)testMutableCopy
{
	OTAssertEqualObjects(
	    objc_autorelease([_dictionary mutableCopy]), _dictionary);
}

- (void)testValueForKey
{
	OTAssertEqualObjects([_dictionary valueForKey: keys[0]], objects[0]);
	OTAssertEqualObjects([_dictionary valueForKey: keys[1]], objects[1]);
	OTAssertEqualObjects(
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
	OTAssertFalse([_dictionary containsObject: @"nonexistent"]);
}

- (void)testContainsObjectIdenticalTo
{
	OTAssertTrue([_dictionary containsObjectIdenticalTo: objects[0]]);
	OTAssertFalse([_dictionary containsObjectIdenticalTo:
	    [[objects[0] mutableCopy] autorelease]]);
}

- (void)testDescription
{
	OTAssert(
	    [_dictionary.description isEqual:
	    @"{\n\tkey1 = value1;\n\tkey2 = value2;\n}"] ||







|







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
	OTAssertFalse([_dictionary containsObject: @"nonexistent"]);
}

- (void)testContainsObjectIdenticalTo
{
	OTAssertTrue([_dictionary containsObjectIdenticalTo: objects[0]]);
	OTAssertFalse([_dictionary containsObjectIdenticalTo:
	    objc_autorelease([objects[0] mutableCopy])]);
}

- (void)testDescription
{
	OTAssert(
	    [_dictionary.description isEqual:
	    @"{\n\tkey1 = value1;\n\tkey2 = value2;\n}"] ||
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
	self = [super init];

	@try {
		_dictionary = [[OFDictionary alloc] initWithObjects: objects_
							    forKeys: keys_
							      count: count];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_dictionary release];

	[super dealloc];
}

- (id)objectForKey: (id)key
{
	return [_dictionary objectForKey: key];







|








|







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
	self = [super init];

	@try {
		_dictionary = [[OFDictionary alloc] initWithObjects: objects_
							    forKeys: keys_
							      count: count];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_dictionary);

	[super dealloc];
}

- (id)objectForKey: (id)key
{
	return [_dictionary objectForKey: key];
Changes to tests/OFFileManagerTests.m.
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
	OFIRI *_testsDirectoryIRI, *_testFileIRI;
}
@end

@implementation OFFileManagerTests
- (void)setUp
{
	_fileManager = [[OFFileManager defaultManager] retain];

	_testsDirectoryIRI = [[[OFSystemInfo temporaryDirectoryIRI]
	    IRIByAppendingPathComponent: @"objfw-tests"] retain];
	OTAssertNotNil(_testsDirectoryIRI);

	_testFileIRI = [[_testsDirectoryIRI
	    IRIByAppendingPathComponent: @"test.txt"] retain];

	/* In case a previous test run failed and left things. */
	if ([_fileManager directoryExistsAtIRI: _testsDirectoryIRI])
		[_fileManager removeItemAtIRI: _testsDirectoryIRI];

	[_fileManager createDirectoryAtIRI: _testsDirectoryIRI];
	[@"test" writeToIRI: _testFileIRI];
}

- (void)tearDown
{
	if (_testsDirectoryIRI != nil)
		[_fileManager removeItemAtIRI: _testsDirectoryIRI];
}

- (void)dealloc
{
	[_fileManager release];
	[_testsDirectoryIRI release];
	[_testFileIRI release];

	[super dealloc];
}

- (void)testCurrentDirectoryPath
{
	OTAssertEqualObjects(







|

|
|


|
|

















|
|
|







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
	OFIRI *_testsDirectoryIRI, *_testFileIRI;
}
@end

@implementation OFFileManagerTests
- (void)setUp
{
	_fileManager = objc_retain([OFFileManager defaultManager]);

	_testsDirectoryIRI = objc_retain([[OFSystemInfo temporaryDirectoryIRI]
	    IRIByAppendingPathComponent: @"objfw-tests"]);
	OTAssertNotNil(_testsDirectoryIRI);

	_testFileIRI = objc_retain(
	    [_testsDirectoryIRI IRIByAppendingPathComponent: @"test.txt"]);

	/* In case a previous test run failed and left things. */
	if ([_fileManager directoryExistsAtIRI: _testsDirectoryIRI])
		[_fileManager removeItemAtIRI: _testsDirectoryIRI];

	[_fileManager createDirectoryAtIRI: _testsDirectoryIRI];
	[@"test" writeToIRI: _testFileIRI];
}

- (void)tearDown
{
	if (_testsDirectoryIRI != nil)
		[_fileManager removeItemAtIRI: _testsDirectoryIRI];
}

- (void)dealloc
{
	objc_release(_fileManager);
	objc_release(_testsDirectoryIRI);
	objc_release(_testFileIRI);

	[super dealloc];
}

- (void)testCurrentDirectoryPath
{
	OTAssertEqualObjects(
Changes to tests/OFHMACTests.m.
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
- (void)setUp
{
	OFIRI *IRI;

	[super setUp];

	IRI = [OFIRI IRIWithString: @"embedded:testfile.bin"];
	_stream = [[OFIRIHandler openItemAtIRI: IRI mode: @"r"] retain];
}

- (void)tearDown
{
	[_stream close];

	[super tearDown];
}

- (void)dealloc
{
	[_stream release];

	[super dealloc];
}

- (void)testWithHashClass: (Class)hashClass
	   expectedDigest: (const unsigned char *)expectedDigest
{







|











|







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
- (void)setUp
{
	OFIRI *IRI;

	[super setUp];

	IRI = [OFIRI IRIWithString: @"embedded:testfile.bin"];
	_stream = objc_retain([OFIRIHandler openItemAtIRI: IRI mode: @"r"]);
}

- (void)tearDown
{
	[_stream close];

	[super tearDown];
}

- (void)dealloc
{
	objc_release(_stream);

	[super dealloc];
}

- (void)testWithHashClass: (Class)hashClass
	   expectedDigest: (const unsigned char *)expectedDigest
{
Changes to tests/OFHTTPClientTests.m.
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
@property (readonly, nonatomic) OFCondition *condition;
@property (readonly) uint16_t port;
@end

@implementation OFHTTPClientTests
- (void)dealloc
{
	[_response release];

	[super dealloc];
}

-     (void)client: (OFHTTPClient *)client
  wantsRequestBody: (OFStream *)body
	   request: (OFHTTPRequest *)request
{
	[body writeString: @"Hello"];
}

-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (OFHTTPResponse *)response_
	  exception: (id)exception
{
	OTAssertNil(exception);

	[_response release];
	_response = [response_ retain];

	[[OFRunLoop mainRunLoop] stop];
}

- (void)testClient
{
	HTTPClientTestsServer *server;
	OFIRI *IRI;
	OFHTTPRequest *request;
	OFHTTPClient *client;
	OFData *data;

	server = [[[HTTPClientTestsServer alloc] init] autorelease];
	server.supportsSockets = true;

	[server.condition lock];

	[server start];

	[server.condition wait];







|


















|
|












|







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
@property (readonly, nonatomic) OFCondition *condition;
@property (readonly) uint16_t port;
@end

@implementation OFHTTPClientTests
- (void)dealloc
{
	objc_release(_response);

	[super dealloc];
}

-     (void)client: (OFHTTPClient *)client
  wantsRequestBody: (OFStream *)body
	   request: (OFHTTPRequest *)request
{
	[body writeString: @"Hello"];
}

-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (OFHTTPResponse *)response_
	  exception: (id)exception
{
	OTAssertNil(exception);

	objc_release(_response);
	_response = objc_retain(response_);

	[[OFRunLoop mainRunLoop] stop];
}

- (void)testClient
{
	HTTPClientTestsServer *server;
	OFIRI *IRI;
	OFHTTPRequest *request;
	OFHTTPClient *client;
	OFData *data;

	server = objc_autorelease([[HTTPClientTestsServer alloc] init]);
	server.supportsSockets = true;

	[server.condition lock];

	[server start];

	[server.condition wait];
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
- (instancetype)init
{
	self = [super init];

	@try {
		_condition = [[OFCondition alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_condition release];

	[super dealloc];
}

- (id)main
{
	OFTCPSocket *listener, *client;







|








|







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
- (instancetype)init
{
	self = [super init];

	@try {
		_condition = [[OFCondition alloc] init];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_condition);

	[super dealloc];
}

- (id)main
{
	OFTCPSocket *listener, *client;
Changes to tests/OFINIFileTests.m.
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
	IRI = [OFIRI IRIWithString: @"embedded:testfile.ini"];
	_file = [[OFINIFile alloc] initWithIRI: IRI
				      encoding: OFStringEncodingISO8859_1];
}

- (void)dealloc
{
	[_file release];

	[super dealloc];
}

- (void)testSectionForName
{
	OTAssertNotNil([_file sectionForName: @"tests"]);







|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
	IRI = [OFIRI IRIWithString: @"embedded:testfile.ini"];
	_file = [[OFINIFile alloc] initWithIRI: IRI
				      encoding: OFStringEncodingISO8859_1];
}

- (void)dealloc
{
	objc_release(_file);

	[super dealloc];
}

- (void)testSectionForName
{
	OTAssertNotNil([_file sectionForName: @"tests"]);
Changes to tests/OFIRITests.m.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

	_mutableIRI = [[OFMutableIRI alloc] initWithScheme: @"dummy"];
}

- (void)dealloc
{
	for (uint_fast8_t i = 0; i < 11; i++)
		[_IRI[i] release];

	[_mutableIRI release];

	[super dealloc];
}

- (void)testIRIWithStringFailsWithInvalidCharacters
{
	OTAssertThrowsSpecific([OFIRI IRIWithString: @"ht,tp://foo"],







|

|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

	_mutableIRI = [[OFMutableIRI alloc] initWithScheme: @"dummy"];
}

- (void)dealloc
{
	for (uint_fast8_t i = 0; i < 11; i++)
		objc_release(_IRI[i]);

	objc_release(_mutableIRI);

	[super dealloc];
}

- (void)testIRIWithStringFailsWithInvalidCharacters
{
	OTAssertThrowsSpecific([OFIRI IRIWithString: @"ht,tp://foo"],
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
	OTAssertNil(_IRI[3].fragment);
	OTAssertEqualObjects(_IRI[8].fragment, @"frag");
	OTAssertEqualObjects(_IRI[9].fragment, @"frag");
}

- (void)testCopy
{
	OTAssertEqualObjects([[_IRI[0] copy] autorelease], _IRI[0]);
}

- (void)testIsEqual
{
	OTAssertEqualObjects(_IRI[0], [OFIRI IRIWithString: IRI0String]);
	OTAssertNotEqualObjects(_IRI[1], _IRI[2]);
	OTAssertEqualObjects([OFIRI IRIWithString: @"HTTP://bar/"], _IRI[2]);







|







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
	OTAssertNil(_IRI[3].fragment);
	OTAssertEqualObjects(_IRI[8].fragment, @"frag");
	OTAssertEqualObjects(_IRI[9].fragment, @"frag");
}

- (void)testCopy
{
	OTAssertEqualObjects(objc_autorelease([_IRI[0] copy]), _IRI[0]);
}

- (void)testIsEqual
{
	OTAssertEqualObjects(_IRI[0], [OFIRI IRIWithString: IRI0String]);
	OTAssertNotEqualObjects(_IRI[1], _IRI[2]);
	OTAssertEqualObjects([OFIRI IRIWithString: @"HTTP://bar/"], _IRI[2]);
Changes to tests/OFInvocationTests.m.
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
	    [self methodSignatureForSelector: selector];

	_invocation = [[OFInvocation alloc] initWithMethodSignature: signature];
}

- (void)dealloc
{
	[_invocation release];

	[super dealloc];
}

- (void)testSetAndGetReturnValue
{
	struct TestStruct testStruct, testStruct2;







|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
	    [self methodSignatureForSelector: selector];

	_invocation = [[OFInvocation alloc] initWithMethodSignature: signature];
}

- (void)dealloc
{
	objc_release(_invocation);

	[super dealloc];
}

- (void)testSetAndGetReturnValue
{
	struct TestStruct testStruct, testStruct2;
Changes to tests/OFJSONTests.m.
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
		[OFNumber numberWithBool: false],
		nil],
	    nil];
}

- (void)dealloc
{
	[_dictionary release];

	[super dealloc];
}

- (void)testObjectByParsingJSON
{
	OTAssertEqualObjects(string.objectByParsingJSON, _dictionary);







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
		[OFNumber numberWithBool: false],
		nil],
	    nil];
}

- (void)dealloc
{
	objc_release(_dictionary);

	[super dealloc];
}

- (void)testObjectByParsingJSON
{
	OTAssertEqualObjects(string.objectByParsingJSON, _dictionary);
Changes to tests/OFKernelEventObserverTests.m.
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
	[_client connectToHost: @"127.0.0.1"
			  port: OFSocketAddressIPPort(&address)];
	[_client writeBuffer: "0" length: 1];
}

- (void)dealloc
{
	[_client release];
	[_server release];
	[_accepted release];
	[_observer release];

	[super dealloc];
}

- (void)testKernelEventObserverWithClass: (Class)class
{
	bool deadlineExceeded = false;







|
|
|
|







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
	[_client connectToHost: @"127.0.0.1"
			  port: OFSocketAddressIPPort(&address)];
	[_client writeBuffer: "0" length: 1];
}

- (void)dealloc
{
	objc_release(_client);
	objc_release(_server);
	objc_release(_accepted);
	objc_release(_observer);

	[super dealloc];
}

- (void)testKernelEventObserverWithClass: (Class)class
{
	bool deadlineExceeded = false;
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
{
	char buffer;

	switch (_events++) {
	case 0:
		OTAssertEqual(object, _server);

		_accepted = [[object accept] retain];
		[_observer addObjectForReading: _accepted];
		break;
	case 1:
		OTAssert(object, _accepted);

		OTAssertEqual([object readIntoBuffer: &buffer length: 1], 1);
		OTAssertEqual(buffer, '0');







|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
{
	char buffer;

	switch (_events++) {
	case 0:
		OTAssertEqual(object, _server);

		_accepted = objc_retain([object accept]);
		[_observer addObjectForReading: _accepted];
		break;
	case 1:
		OTAssert(object, _accepted);

		OTAssertEqual([object readIntoBuffer: &buffer length: 1], 1);
		OTAssertEqual(buffer, '0');
Changes to tests/OFListTests.m.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
	[_list appendObject: @"Foo"];
	[_list appendObject: @"Bar"];
	[_list appendObject: @"Baz"];
}

- (void)dealloc
{
	[_list release];

	[super dealloc];
}

- (void)testCount
{
	OTAssertEqual(_list.count, 3);







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
	[_list appendObject: @"Foo"];
	[_list appendObject: @"Bar"];
	[_list appendObject: @"Baz"];
}

- (void)dealloc
{
	objc_release(_list);

	[super dealloc];
}

- (void)testCount
{
	OTAssertEqual(_list.count, 3);
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
}

- (void)testContainsObjectIdenticalTo
{
	OFString *foo = _list.firstObject;

	OTAssertTrue([_list containsObjectIdenticalTo: foo]);
	OTAssertFalse(
	    [_list containsObjectIdenticalTo: [[foo mutableCopy] autorelease]]);
}

- (void)testIsEqual
{
	OFList *list = [OFList list];

	[list appendObject: @"Foo"];







|
|







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
}

- (void)testContainsObjectIdenticalTo
{
	OFString *foo = _list.firstObject;

	OTAssertTrue([_list containsObjectIdenticalTo: foo]);
	OTAssertFalse([_list containsObjectIdenticalTo:
	    objc_autorelease([foo mutableCopy])]);
}

- (void)testIsEqual
{
	OFList *list = [OFList list];

	[list appendObject: @"Foo"];
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
	[list appendObject: @"Qux"];

	OTAssertNotEqual(list.hash, _list.hash);
}

- (void)testCopy
{
	OTAssertEqualObjects([[_list copy] autorelease], _list);
}

- (void)testDescription
{
	OTAssertEqualObjects(_list.description, @"[\n\tFoo,\n\tBar,\n\tBaz\n]");
}








|







208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
	[list appendObject: @"Qux"];

	OTAssertNotEqual(list.hash, _list.hash);
}

- (void)testCopy
{
	OTAssertEqualObjects(objc_autorelease([_list copy]), _list);
}

- (void)testDescription
{
	OTAssertEqualObjects(_list.description, @"[\n\tFoo,\n\tBar,\n\tBaz\n]");
}

Changes to tests/OFMatrix4x4Tests.m.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
		{  9, 10, 11, 12 },
		{ 13, 14, 15, 16 }
	}];
}

- (void)dealloc
{
	[_matrix release];

	[super dealloc];
}

- (void)testIdentityMatrix
{
	OTAssertEqual(memcmp([[OFMatrix4x4 identityMatrix] values],







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
		{  9, 10, 11, 12 },
		{ 13, 14, 15, 16 }
	}];
}

- (void)dealloc
{
	objc_release(_matrix);

	[super dealloc];
}

- (void)testIdentityMatrix
{
	OTAssertEqual(memcmp([[OFMatrix4x4 identityMatrix] values],
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
		{ 0, 0, 1, 0 },
		{ 0, 0, 0, 1 }
	    }]) hash]);
}

- (void)testCopy
{
	OTAssertEqualObjects([[_matrix copy] autorelease], _matrix);
}

- (void)testMultiplyWithMatrix
{
	OFMatrix4x4 *matrix;

	matrix = [[_matrix copy] autorelease];
	[matrix multiplyWithMatrix: [OFMatrix4x4 identityMatrix]];
	OTAssertEqualObjects(matrix, _matrix);

	matrix = [OFMatrix4x4 matrixWithValues: (const float [4][4]){
		{  100,  200,  300,  400 },
		{  500,  600,  700,  800 },
		{  900, 1000, 1100, 1200 },







|






|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
		{ 0, 0, 1, 0 },
		{ 0, 0, 0, 1 }
	    }]) hash]);
}

- (void)testCopy
{
	OTAssertEqualObjects(objc_autorelease([_matrix copy]), _matrix);
}

- (void)testMultiplyWithMatrix
{
	OFMatrix4x4 *matrix;

	matrix = objc_autorelease([_matrix copy]);
	[matrix multiplyWithMatrix: [OFMatrix4x4 identityMatrix]];
	OTAssertEqualObjects(matrix, _matrix);

	matrix = [OFMatrix4x4 matrixWithValues: (const float [4][4]){
		{  100,  200,  300,  400 },
		{  500,  600,  700,  800 },
		{  900, 1000, 1100, 1200 },
Changes to tests/OFModuleTests.m.
48
49
50
51
52
53
54
55
56
57
58
	class = (Class (*)(void))(uintptr_t)[module addressForSymbol: @"class"];
	OTAssert(class != NULL);

	@try {
		test = [[class() alloc] init];
		OTAssertEqual([test test: 1234], 2468);
	} @finally {
		[test release];
	}
}
@end







|



48
49
50
51
52
53
54
55
56
57
58
	class = (Class (*)(void))(uintptr_t)[module addressForSymbol: @"class"];
	OTAssert(class != NULL);

	@try {
		test = [[class() alloc] init];
		OTAssertEqual([test test: 1234], 2468);
	} @finally {
		objc_release(test);
	}
}
@end
Changes to tests/OFMutableArrayTests.m.
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
	_mutableArray = [[self.arrayClass alloc]
	    initWithObjects: cArray
		      count: sizeof(cArray) / sizeof(*cArray)];
}

- (void)dealloc
{
	[_mutableArray release];

	[super dealloc];
}

- (void)testAddObject
{
	[_mutableArray addObject: cArray[0]];







|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
	_mutableArray = [[self.arrayClass alloc]
	    initWithObjects: cArray
		      count: sizeof(cArray) / sizeof(*cArray)];
}

- (void)dealloc
{
	objc_release(_mutableArray);

	[super dealloc];
}

- (void)testAddObject
{
	[_mutableArray addObject: cArray[0]];
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

	OTAssertEqualObjects(_mutableArray,
	    ([OFArray arrayWithObjects: @"Foo", @"Foo", @"Foo", @"Baz", nil]));
}

- (void)testReplaceObjectIdenticalToWithObject
{
	[_mutableArray insertObject: [[cArray[1] mutableCopy] autorelease]
			    atIndex: 1];
	[_mutableArray insertObject: [[cArray[1] mutableCopy] autorelease]
			    atIndex: 4];
	[_mutableArray replaceObjectIdenticalTo: cArray[1]
				     withObject: cArray[0]];

	OTAssertEqualObjects(_mutableArray,
	    ([OFArray arrayWithObjects: @"Foo", @"Bar", @"Foo", @"Baz", @"Bar",
	    nil]));







|

|







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

	OTAssertEqualObjects(_mutableArray,
	    ([OFArray arrayWithObjects: @"Foo", @"Foo", @"Foo", @"Baz", nil]));
}

- (void)testReplaceObjectIdenticalToWithObject
{
	[_mutableArray insertObject: objc_autorelease([cArray[1] mutableCopy])
			    atIndex: 1];
	[_mutableArray insertObject: objc_autorelease([cArray[1] mutableCopy])
			    atIndex: 4];
	[_mutableArray replaceObjectIdenticalTo: cArray[1]
				     withObject: cArray[0]];

	OTAssertEqualObjects(_mutableArray,
	    ([OFArray arrayWithObjects: @"Foo", @"Bar", @"Foo", @"Baz", @"Bar",
	    nil]));
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
{
	self = [super init];

	@try {
		_array = [[OFMutableArray alloc] initWithObjects: objects
							   count: count];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_array release];

	[super dealloc];
}

- (id)objectAtIndex: (size_t)idx
{
	return [_array objectAtIndex: idx];







|








|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
{
	self = [super init];

	@try {
		_array = [[OFMutableArray alloc] initWithObjects: objects
							   count: count];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_array);

	[super dealloc];
}

- (id)objectAtIndex: (size_t)idx
{
	return [_array objectAtIndex: idx];
Changes to tests/OFMutableDataTests.m.
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
	[super setUp];

	_mutableData = [[OFMutableData alloc] initWithItems: "abcdef" count: 6];
}

- (void)dealloc
{
	[_mutableData release];

	[super dealloc];
}

- (void)testMutableCopy
{
	OTAssertEqualObjects([[_data mutableCopy] autorelease], _data);
	OTAssertNotEqual([[_data mutableCopy] autorelease], _data);
}

- (void)testAddItem
{
	[_mutableData addItem: "g"];

	OTAssertEqualObjects(_mutableData,







|






|
|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
	[super setUp];

	_mutableData = [[OFMutableData alloc] initWithItems: "abcdef" count: 6];
}

- (void)dealloc
{
	objc_release(_mutableData);

	[super dealloc];
}

- (void)testMutableCopy
{
	OTAssertEqualObjects(objc_autorelease([_data mutableCopy]), _data);
	OTAssertNotEqual(objc_autorelease([_data mutableCopy]), _data);
}

- (void)testAddItem
{
	[_mutableData addItem: "g"];

	OTAssertEqualObjects(_mutableData,
Changes to tests/OFMutableDictionaryTests.m.
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
	[super setUp];

	_mutableDictionary = [[self.dictionaryClass alloc] init];
}

- (void)dealloc
{
	[_mutableDictionary release];

	[super dealloc];
}

- (void)testSetObjectForKey
{
	[_mutableDictionary setObject: @"bar" forKey: @"foo"];







|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
	[super setUp];

	_mutableDictionary = [[self.dictionaryClass alloc] init];
}

- (void)dealloc
{
	objc_release(_mutableDictionary);

	[super dealloc];
}

- (void)testSetObjectForKey
{
	[_mutableDictionary setObject: @"bar" forKey: @"foo"];
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
	OTAssertEqual(_mutableDictionary.count, 1);
	OTAssertEqualObjects(_mutableDictionary,
	    [OFDictionary dictionaryWithObject: @"value1" forKey: @"key1"]);
}

- (void)testMutableCopy
{
	OFMutableDictionary *copy = [[_dictionary mutableCopy] autorelease];

	OTAssertEqualObjects(copy, _dictionary);
	OTAssertNotEqual(copy, _dictionary);
}

#ifdef OF_HAVE_BLOCKS
- (void)testReplaceObjectsUsingBlock
{
	OFMutableDictionary *mutableDictionary =
	    [[_dictionary mutableCopy] autorelease];

	[mutableDictionary replaceObjectsUsingBlock: ^ id (id key, id object) {
		if ([key isEqual: @"key1"])
			return @"value_1";
		if ([key isEqual: @"key2"])
			return @"value_2";








|









|







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
	OTAssertEqual(_mutableDictionary.count, 1);
	OTAssertEqualObjects(_mutableDictionary,
	    [OFDictionary dictionaryWithObject: @"value1" forKey: @"key1"]);
}

- (void)testMutableCopy
{
	OFMutableDictionary *copy = objc_autorelease([_dictionary mutableCopy]);

	OTAssertEqualObjects(copy, _dictionary);
	OTAssertNotEqual(copy, _dictionary);
}

#ifdef OF_HAVE_BLOCKS
- (void)testReplaceObjectsUsingBlock
{
	OFMutableDictionary *mutableDictionary =
	    objc_autorelease([_dictionary mutableCopy]);

	[mutableDictionary replaceObjectsUsingBlock: ^ id (id key, id object) {
		if ([key isEqual: @"key1"])
			return @"value_1";
		if ([key isEqual: @"key2"])
			return @"value_2";

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
- (instancetype)init
{
	self = [super init];

	@try {
		_dictionary = [[OFMutableDictionary alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithObjects: (const id *)objects_
			forKeys: (const id *)keys_
			  count: (size_t)count
{
	self = [super init];

	@try {
		_dictionary = [[OFMutableDictionary alloc]
		    initWithObjects: objects_
			    forKeys: keys_
			      count: count];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_dictionary release];

	[super dealloc];
}

- (id)objectForKey: (id)key
{
	return [_dictionary objectForKey: key];







|


















|








|







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
- (instancetype)init
{
	self = [super init];

	@try {
		_dictionary = [[OFMutableDictionary alloc] init];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (instancetype)initWithObjects: (const id *)objects_
			forKeys: (const id *)keys_
			  count: (size_t)count
{
	self = [super init];

	@try {
		_dictionary = [[OFMutableDictionary alloc]
		    initWithObjects: objects_
			    forKeys: keys_
			      count: count];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_dictionary);

	[super dealloc];
}

- (id)objectForKey: (id)key
{
	return [_dictionary objectForKey: key];
Changes to tests/OFMutableSetTests.m.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

	_mutableSet = [[OFMutableSet alloc]
	    initWithObjects: @"foo", @"bar", @"baz", nil];
}

- (void)dealloc
{
	[_mutableSet release];

	[super dealloc];
}

- (void)testAddObject
{
	[_mutableSet addObject: @"x"];







|







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

	_mutableSet = [[OFMutableSet alloc]
	    initWithObjects: @"foo", @"bar", @"baz", nil];
}

- (void)dealloc
{
	objc_release(_mutableSet);

	[super dealloc];
}

- (void)testAddObject
{
	[_mutableSet addObject: @"x"];
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
{
	self = [super init];

	@try {
		_set = [[OFMutableSet alloc] initWithObjects: objects
						       count: count];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_set release];

	[super dealloc];
}

- (size_t)count
{
	return _set.count;







|








|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
{
	self = [super init];

	@try {
		_set = [[OFMutableSet alloc] initWithObjects: objects
						       count: count];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_set);

	[super dealloc];
}

- (size_t)count
{
	return _set.count;
Changes to tests/OFMutableStringTests.m.
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
	[super setUp];

	_mutableString = [[self.stringClass alloc] initWithString: @"täṠ€🤔"];
}

- (void)dealloc
{
	[_mutableString release];

	[super dealloc];
}

- (void)testAppendString
{
	[_mutableString appendString: @"ö"];







|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
	[super setUp];

	_mutableString = [[self.stringClass alloc] initWithString: @"täṠ€🤔"];
}

- (void)dealloc
{
	objc_release(_mutableString);

	[super dealloc];
}

- (void)testAppendString
{
	[_mutableString appendString: @"ö"];
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
- (instancetype)init
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		_string = [string mutableCopy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithCString: (const char *)cString
		       encoding: (OFStringEncoding)encoding
			 length: (size_t)length
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] initWithCString: cString
							  encoding: encoding
							    length: length];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithUTF16String: (const OFChar16 *)UTF16String
			     length: (size_t)length
			  byteOrder: (OFByteOrder)byteOrder
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc]
		    initWithUTF16String: UTF16String
				 length: length
			      byteOrder: byteOrder];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithUTF32String: (const OFChar32 *)UTF32String
			     length: (size_t)length
			  byteOrder: (OFByteOrder)byteOrder
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc]
		    initWithUTF32String: UTF32String
				 length: length
			      byteOrder: byteOrder];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithFormat: (OFConstantString *)format
		     arguments: (va_list)arguments
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] initWithFormat: format
							arguments: arguments];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_string release];

	[super dealloc];
}

- (OFUnichar)characterAtIndex: (size_t)idx
{
	return [_string characterAtIndex: idx];







|













|

















|


















|


















|















|








|







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
- (instancetype)init
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] init];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

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

	@try {
		_string = [string mutableCopy];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (instancetype)initWithCString: (const char *)cString
		       encoding: (OFStringEncoding)encoding
			 length: (size_t)length
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] initWithCString: cString
							  encoding: encoding
							    length: length];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (instancetype)initWithUTF16String: (const OFChar16 *)UTF16String
			     length: (size_t)length
			  byteOrder: (OFByteOrder)byteOrder
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc]
		    initWithUTF16String: UTF16String
				 length: length
			      byteOrder: byteOrder];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (instancetype)initWithUTF32String: (const OFChar32 *)UTF32String
			     length: (size_t)length
			  byteOrder: (OFByteOrder)byteOrder
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc]
		    initWithUTF32String: UTF32String
				 length: length
			      byteOrder: byteOrder];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (instancetype)initWithFormat: (OFConstantString *)format
		     arguments: (va_list)arguments
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] initWithFormat: format
							arguments: arguments];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_string);

	[super dealloc];
}

- (OFUnichar)characterAtIndex: (size_t)idx
{
	return [_string characterAtIndex: idx];
Changes to tests/OFNotificationCenterTests.m.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
@implementation OFNotificationCenterTests
- (void)testNotificationCenter
{
	OFNotificationCenter *center = [OFNotificationCenter defaultCenter];
	OFNotificationCenterTestClass *test1, *test2, *test3, *test4;
	OFNotification *notification;

	test1 = [[[OFNotificationCenterTestClass alloc] init] autorelease];
	test1->_expectedObject = self;
	test2 = [[[OFNotificationCenterTestClass alloc] init] autorelease];
	test3 = [[[OFNotificationCenterTestClass alloc] init] autorelease];
	test3->_expectedObject = self;
	test4 = [[[OFNotificationCenterTestClass alloc] init] autorelease];

	/* First one intentionally added twice to test deduplication. */
	[center addObserver: test1
		   selector: @selector(handleNotification:)
		       name: notificationName
		     object: self];
	[center addObserver: test1







|

|
|

|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
@implementation OFNotificationCenterTests
- (void)testNotificationCenter
{
	OFNotificationCenter *center = [OFNotificationCenter defaultCenter];
	OFNotificationCenterTestClass *test1, *test2, *test3, *test4;
	OFNotification *notification;

	test1 = objc_autorelease([[OFNotificationCenterTestClass alloc] init]);
	test1->_expectedObject = self;
	test2 = objc_autorelease([[OFNotificationCenterTestClass alloc] init]);
	test3 = objc_autorelease([[OFNotificationCenterTestClass alloc] init]);
	test3->_expectedObject = self;
	test4 = objc_autorelease([[OFNotificationCenterTestClass alloc] init]);

	/* First one intentionally added twice to test deduplication. */
	[center addObserver: test1
		   selector: @selector(handleNotification:)
		       name: notificationName
		     object: self];
	[center addObserver: test1
Changes to tests/OFNumberTests.m.
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
	[super setUp];

	_number = [[OFNumber alloc] initWithLongLong: 123456789];
}

- (void)dealloc
{
	[_number release];

	[super dealloc];
}

- (void)testIsEqual
{
	OTAssertEqualObjects(_number, [OFNumber numberWithLong: 123456789]);







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
	[super setUp];

	_number = [[OFNumber alloc] initWithLongLong: 123456789];
}

- (void)dealloc
{
	objc_release(_number);

	[super dealloc];
}

- (void)testIsEqual
{
	OTAssertEqualObjects(_number, [OFNumber numberWithLong: 123456789]);
Changes to tests/OFObjectTests.m.
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
	[super setUp];

	_myObject = [[MyObject alloc] init];
}

- (void)dealloc
{
	[_myObject release];

	[super dealloc];
}

- (void)testClassDescription
{
	OTAssertEqualObjects([OFObject description], @"OFObject");
	OTAssertEqualObjects([MyObject description], @"MyObject");
}

- (void)testInstanceDescription
{
	OFObject *object = [[[OFObject alloc] init] autorelease];

	OTAssertEqualObjects(object.description, @"<OFObject>");
	OTAssertEqualObjects(_myObject.description, @"<MyObject>");
}

- (void)testValueForKey
{







|












|







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
	[super setUp];

	_myObject = [[MyObject alloc] init];
}

- (void)dealloc
{
	objc_release(_myObject);

	[super dealloc];
}

- (void)testClassDescription
{
	OTAssertEqualObjects([OFObject description], @"OFObject");
	OTAssertEqualObjects([MyObject description], @"MyObject");
}

- (void)testInstanceDescription
{
	OFObject *object = objc_autorelease([[OFObject alloc] init]);

	OTAssertEqualObjects(object.description, @"<OFObject>");
	OTAssertEqualObjects(_myObject.description, @"<MyObject>");
}

- (void)testValueForKey
{
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
	OTAssertThrowsSpecific(
	    [_myObject setValue: (id _Nonnull)nil forKey: @"intValue"],
	    OFInvalidArgumentException);
}

- (void)testValueForKeyPath
{
	_myObject.objectValue = [[[MyObject alloc] init] autorelease];
	[_myObject.objectValue setObjectValue:
	    [[[MyObject alloc] init] autorelease]];
	[[_myObject.objectValue objectValue] setDoubleValue: 0.5];

	OTAssertEqual([[_myObject valueForKeyPath:
	    @"objectValue.objectValue.doubleValue"] doubleValue], 0.5);
}

- (void)testSetValueForKeyPath
{
	_myObject.objectValue = [[[MyObject alloc] init] autorelease];
	[_myObject.objectValue setObjectValue:
	    [[[MyObject alloc] init] autorelease]];
	[_myObject setValue: [OFNumber numberWithDouble: 0.75]
		 forKeyPath: @"objectValue.objectValue.doubleValue"];

	OTAssertEqual([[_myObject.objectValue objectValue] doubleValue], 0.75);
}
@end








|

|








|

|







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
	OTAssertThrowsSpecific(
	    [_myObject setValue: (id _Nonnull)nil forKey: @"intValue"],
	    OFInvalidArgumentException);
}

- (void)testValueForKeyPath
{
	_myObject.objectValue = objc_autorelease([[MyObject alloc] init]);
	[_myObject.objectValue setObjectValue:
	    objc_autorelease([[MyObject alloc] init])];
	[[_myObject.objectValue objectValue] setDoubleValue: 0.5];

	OTAssertEqual([[_myObject valueForKeyPath:
	    @"objectValue.objectValue.doubleValue"] doubleValue], 0.5);
}

- (void)testSetValueForKeyPath
{
	_myObject.objectValue = objc_autorelease([[MyObject alloc] init]);
	[_myObject.objectValue setObjectValue:
	    objc_autorelease([[MyObject alloc] init])];
	[_myObject setValue: [OFNumber numberWithDouble: 0.75]
		 forKeyPath: @"objectValue.objectValue.doubleValue"];

	OTAssertEqual([[_myObject.objectValue objectValue] doubleValue], 0.75);
}
@end

254
255
256
257
258
259
260
261
262
263
264
265
@synthesize unsignedIntValue = _unsignedIntValue;
@synthesize unsignedLongValue = _unsignedLongValue;
@synthesize unsignedLongLongValue = _unsignedLongLongValue;
@synthesize floatValue = _floatValue, doubleValue = _doubleValue;

- (void)dealloc
{
	[_objectValue release];

	[super dealloc];
}
@end







|




254
255
256
257
258
259
260
261
262
263
264
265
@synthesize unsignedIntValue = _unsignedIntValue;
@synthesize unsignedLongValue = _unsignedLongValue;
@synthesize unsignedLongLongValue = _unsignedLongLongValue;
@synthesize floatValue = _floatValue, doubleValue = _doubleValue;

- (void)dealloc
{
	objc_release(_objectValue);

	[super dealloc];
}
@end
Changes to tests/OFPBKDF2Tests.m.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

	_HMAC = [[OFHMAC alloc] initWithHashClass: [OFSHA1Hash class]
			    allowsSwappableMemory: true];
}

- (void)dealloc
{
	[_HMAC release];

	[super dealloc];
}

/* Test vectors from RFC 6070 */

- (void)testRFC6070TestVector1







|







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

	_HMAC = [[OFHMAC alloc] initWithHashClass: [OFSHA1Hash class]
			    allowsSwappableMemory: true];
}

- (void)dealloc
{
	objc_release(_HMAC);

	[super dealloc];
}

/* Test vectors from RFC 6070 */

- (void)testRFC6070TestVector1
Changes to tests/OFSPXSocketTests.m.
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
			@throw e;
		}
	}
}

- (void)dealloc
{
	[_sockServer release];

	[super dealloc];
}

- (void)testSPXSocket
{
	OFSPXSocket *sockClient, *sockAccepted;







|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
			@throw e;
		}
	}
}

- (void)dealloc
{
	objc_release(_sockServer);

	[super dealloc];
}

- (void)testSPXSocket
{
	OFSPXSocket *sockClient, *sockAccepted;
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
	OFSocketAddressGetIPXNode(addrAccepted, node2);
	OTAssertEqual(memcmp(node, node2, IPX_NODE_LEN), 0);
}

- (void)testAsyncSPXSocket
{
	SPXSocketDelegate *delegate =
	    [[[SPXSocketDelegate alloc] init] autorelease];
	uint32_t network;
	unsigned char node[IPX_NODE_LEN];
	uint16_t port;
	OFDictionary *networkInterfaces;
	OFSPXSocket *sockClient;

	delegate->_expectedServerSocket = _sockServer;







|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
	OFSocketAddressGetIPXNode(addrAccepted, node2);
	OTAssertEqual(memcmp(node, node2, IPX_NODE_LEN), 0);
}

- (void)testAsyncSPXSocket
{
	SPXSocketDelegate *delegate =
	    objc_autorelease([[SPXSocketDelegate alloc] init]);
	uint32_t network;
	unsigned char node[IPX_NODE_LEN];
	uint16_t port;
	OFDictionary *networkInterfaces;
	OFSPXSocket *sockClient;

	delegate->_expectedServerSocket = _sockServer;
Changes to tests/OFSPXStreamSocketTests.m.
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
			@throw e;
		}
	}
}

- (void)dealloc
{
	[_sockServer release];

	[super dealloc];
}

- (void)testSPXStreamSocket
{
	OFSPXStreamSocket *sockClient, *sockAccepted;







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
			@throw e;
		}
	}
}

- (void)dealloc
{
	objc_release(_sockServer);

	[super dealloc];
}

- (void)testSPXStreamSocket
{
	OFSPXStreamSocket *sockClient, *sockAccepted;
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
	OFSocketAddressGetIPXNode(addrAccepted, node2);
	OTAssertEqual(memcmp(node, node2, IPX_NODE_LEN), 0);
}

- (void)testAsyncSPXStreamSocket
{
	SPXStreamSocketDelegate *delegate =
	    [[[SPXStreamSocketDelegate alloc] init] autorelease];
	uint32_t network;
	unsigned char node[IPX_NODE_LEN];
	uint16_t port;
	OFDictionary *networkInterfaces;
	OFSPXStreamSocket *sockClient;

	delegate->_expectedServerSocket = _sockServer;







|







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
	OFSocketAddressGetIPXNode(addrAccepted, node2);
	OTAssertEqual(memcmp(node, node2, IPX_NODE_LEN), 0);
}

- (void)testAsyncSPXStreamSocket
{
	SPXStreamSocketDelegate *delegate =
	    objc_autorelease([[SPXStreamSocketDelegate alloc] init]);
	uint32_t network;
	unsigned char node[IPX_NODE_LEN];
	uint16_t port;
	OFDictionary *networkInterfaces;
	OFSPXStreamSocket *sockClient;

	delegate->_expectedServerSocket = _sockServer;
Changes to tests/OFSetTests.m.
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
	[super setUp];

	_set = [[OFSet alloc] initWithObjects: @"foo", @"bar", @"baz", nil];
}

- (void)dealloc
{
	[_set release];

	[super dealloc];
}

- (void)testSetWithArray
{
	OTAssertEqualObjects([self.setClass setWithArray:







|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
	[super setUp];

	_set = [[OFSet alloc] initWithObjects: @"foo", @"bar", @"baz", nil];
}

- (void)dealloc
{
	objc_release(_set);

	[super dealloc];
}

- (void)testSetWithArray
{
	OTAssertEqualObjects([self.setClass setWithArray:
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	    [description isEqual: @"{(\n\tbar,\n\tbaz,\n\tfoo\n)}"] ||
	    [description isEqual: @"{(\n\tbaz,\n\tfoo,\n\tbar\n)}"] ||
	    [description isEqual: @"{(\n\tbaz,\n\tbar,\n\tfoo\n)}"]);
}

- (void)testCopy
{
	OTAssertEqualObjects([[_set copy] autorelease], _set);
}

- (void)testMutableCopy
{
	OTAssertEqualObjects([[_set mutableCopy] autorelease], _set);
}

- (void)testIsSubsetOfSet
{
	OTAssertTrue([([OFSet setWithObjects: @"foo", nil])
	    isSubsetOfSet: _set]);
	OTAssertFalse([([OFSet setWithObjects: @"foo", @"Foo", nil])







|




|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	    [description isEqual: @"{(\n\tbar,\n\tbaz,\n\tfoo\n)}"] ||
	    [description isEqual: @"{(\n\tbaz,\n\tfoo,\n\tbar\n)}"] ||
	    [description isEqual: @"{(\n\tbaz,\n\tbar,\n\tfoo\n)}"]);
}

- (void)testCopy
{
	OTAssertEqualObjects(objc_autorelease([_set copy]), _set);
}

- (void)testMutableCopy
{
	OTAssertEqualObjects(objc_autorelease([_set mutableCopy]), _set);
}

- (void)testIsSubsetOfSet
{
	OTAssertTrue([([OFSet setWithObjects: @"foo", nil])
	    isSubsetOfSet: _set]);
	OTAssertFalse([([OFSet setWithObjects: @"foo", @"Foo", nil])
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
- (instancetype)initWithObjects: (id const *)objects count: (size_t)count
{
	self = [super init];

	@try {
		_set = [[OFSet alloc] initWithObjects: objects count: count];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_set release];

	[super dealloc];
}

- (size_t)count
{
	return _set.count;







|








|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
- (instancetype)initWithObjects: (id const *)objects count: (size_t)count
{
	self = [super init];

	@try {
		_set = [[OFSet alloc] initWithObjects: objects count: count];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_set);

	[super dealloc];
}

- (size_t)count
{
	return _set.count;
Changes to tests/OFStreamTests.m.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
}
@end

@implementation OFStreamTests
- (void)testStream
{
	size_t pageSize = [OFSystemInfo pageSize];
	OFTestStream *stream = [[[OFTestStream alloc] init] autorelease];
	char *cString = OFAllocMemory(pageSize - 2, 1);

	@try {
		OFString *string;

		memset(cString, 'X', pageSize - 3);
		cString[pageSize - 3] = '\0';







|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
}
@end

@implementation OFStreamTests
- (void)testStream
{
	size_t pageSize = [OFSystemInfo pageSize];
	OFTestStream *stream = objc_autorelease([[OFTestStream alloc] init]);
	char *cString = OFAllocMemory(pageSize - 2, 1);

	@try {
		OFString *string;

		memset(cString, 'X', pageSize - 3);
		cString[pageSize - 3] = '\0';
Changes to tests/OFStringTests.m.
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
	[super setUp];

	_string = [[self.stringClass alloc] initWithString: @"täṠ€🤔"];
}

- (void)dealloc
{
	[_string release];

	[super dealloc];
}

- (void)testIsEqual
{
	OTAssertEqualObjects(_string, @"täṠ€🤔");







|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
	[super setUp];

	_string = [[self.stringClass alloc] initWithString: @"täṠ€🤔"];
}

- (void)dealloc
{
	objc_release(_string);

	[super dealloc];
}

- (void)testIsEqual
{
	OTAssertEqualObjects(_string, @"täṠ€🤔");
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
	OTAssertEqual(_string.hash, @"täṠ€🤔".hash);
	OTAssertNotEqual([[self.stringClass stringWithString: @"test"] hash],
	    @"täṠ€".hash);
}

- (void)testCopy
{
	OTAssertEqualObjects([[_string copy] autorelease], _string);
}

- (void)testMutableCopy
{
	OTAssertEqualObjects([[_string mutableCopy] autorelease], _string);
}

- (void)testCompare
{
	OTAssertEqual([_string compare: @"täṠ€🤔"], OFOrderedSame);
	OTAssertEqual([[self.stringClass stringWithString: @""]
	    compare: @"a"], OFOrderedAscending);







|




|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
	OTAssertEqual(_string.hash, @"täṠ€🤔".hash);
	OTAssertNotEqual([[self.stringClass stringWithString: @"test"] hash],
	    @"täṠ€".hash);
}

- (void)testCopy
{
	OTAssertEqualObjects(objc_autorelease([_string copy]), _string);
}

- (void)testMutableCopy
{
	OTAssertEqualObjects(objc_autorelease([_string mutableCopy]), _string);
}

- (void)testCompare
{
	OTAssertEqual([_string compare: @"täṠ€🤔"], OFOrderedSame);
	OTAssertEqual([[self.stringClass stringWithString: @""]
	    compare: @"a"], OFOrderedAscending);
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
	OTAssertThrowsSpecific([[self.stringClass stringWithString: @"&#xg;"]
	    stringByXMLUnescaping], OFInvalidFormatException);
}

- (void)testStringByXMLUnescapingWithDelegate
{
	EntityHandler *entityHandler =
	    [[[EntityHandler alloc] init] autorelease];

	OTAssertEqualObjects([[self.stringClass stringWithString: @"x&foo;y"]
	    stringByXMLUnescapingWithDelegate: entityHandler],
	    @"xbary");
}

#ifdef OF_HAVE_BLOCKS







|







1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
	OTAssertThrowsSpecific([[self.stringClass stringWithString: @"&#xg;"]
	    stringByXMLUnescaping], OFInvalidFormatException);
}

- (void)testStringByXMLUnescapingWithDelegate
{
	EntityHandler *entityHandler =
	    objc_autorelease([[EntityHandler alloc] init]);

	OTAssertEqualObjects([[self.stringClass stringWithString: @"x&foo;y"]
	    stringByXMLUnescapingWithDelegate: entityHandler],
	    @"xbary");
}

#ifdef OF_HAVE_BLOCKS
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
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
- (instancetype)init
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		_string = [string mutableCopy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithCString: (const char *)cString
		       encoding: (OFStringEncoding)encoding
			 length: (size_t)length
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] initWithCString: cString
							  encoding: encoding
							    length: length];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithUTF16String: (const OFChar16 *)UTF16String
			     length: (size_t)length
			  byteOrder: (OFByteOrder)byteOrder
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc]
		    initWithUTF16String: UTF16String
				 length: length
			      byteOrder: byteOrder];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithUTF32String: (const OFChar32 *)UTF32String
			     length: (size_t)length
			  byteOrder: (OFByteOrder)byteOrder
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc]
		    initWithUTF32String: UTF32String
				 length: length
			      byteOrder: byteOrder];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithFormat: (OFConstantString *)format
		     arguments: (va_list)arguments
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] initWithFormat: format
							arguments: arguments];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_string release];

	[super dealloc];
}

- (OFUnichar)characterAtIndex: (size_t)idx
{
	return [_string characterAtIndex: idx];







|













|

















|


















|


















|















|








|







1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
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
- (instancetype)init
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] init];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

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

	@try {
		_string = [string mutableCopy];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (instancetype)initWithCString: (const char *)cString
		       encoding: (OFStringEncoding)encoding
			 length: (size_t)length
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] initWithCString: cString
							  encoding: encoding
							    length: length];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (instancetype)initWithUTF16String: (const OFChar16 *)UTF16String
			     length: (size_t)length
			  byteOrder: (OFByteOrder)byteOrder
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc]
		    initWithUTF16String: UTF16String
				 length: length
			      byteOrder: byteOrder];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (instancetype)initWithUTF32String: (const OFChar32 *)UTF32String
			     length: (size_t)length
			  byteOrder: (OFByteOrder)byteOrder
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc]
		    initWithUTF32String: UTF32String
				 length: length
			      byteOrder: byteOrder];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (instancetype)initWithFormat: (OFConstantString *)format
		     arguments: (va_list)arguments
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] initWithFormat: format
							arguments: arguments];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_string);

	[super dealloc];
}

- (OFUnichar)characterAtIndex: (size_t)idx
{
	return [_string characterAtIndex: idx];
Changes to tests/OFSubprocessTests.m.
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
	OFString *program = [@"subprocess" stringByAppendingPathComponent:
	    @"subprocess" @PROG_SUFFIX];
#else
	OFString *program = @"subprocess/subprocess" @PROG_SUFFIX;
#endif
	OFArray *arguments = [OFArray arrayWithObjects: @"tést", @"123", nil];
	OFMutableDictionary *environment =
	    [[[OFApplication environment] mutableCopy] autorelease];
	OFSubprocess *subprocess;

	[environment setObject: @"yés" forKey: @"tëst"];

	subprocess = [OFSubprocess subprocessWithProgram: program
					     programName: program
					       arguments: arguments







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
	OFString *program = [@"subprocess" stringByAppendingPathComponent:
	    @"subprocess" @PROG_SUFFIX];
#else
	OFString *program = @"subprocess/subprocess" @PROG_SUFFIX;
#endif
	OFArray *arguments = [OFArray arrayWithObjects: @"tést", @"123", nil];
	OFMutableDictionary *environment =
	    objc_autorelease([[OFApplication environment] mutableCopy]);
	OFSubprocess *subprocess;

	[environment setObject: @"yés" forKey: @"tëst"];

	subprocess = [OFSubprocess subprocessWithProgram: program
					     programName: program
					       arguments: arguments
Changes to tests/OFWindowsRegistryKeyTests.m.
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
@end

@implementation OFWindowsRegistryKeyTests
- (void)setUp
{
	[super setUp];

	_softwareKey = [[[OFWindowsRegistryKey currentUserKey]
	    openSubkeyAtPath: @"Software"
		accessRights: KEY_ALL_ACCESS
		     options: 0] retain];
	_objFWKey = [[_softwareKey createSubkeyAtPath: @"ObjFW"
					 accessRights: KEY_ALL_ACCESS
				   securityAttributes: NULL
					      options: 0
					  disposition: NULL] retain];
}

- (void)tearDown
{
	[_softwareKey deleteSubkeyAtPath: @"ObjFW"];

	[super tearDown];
}

- (void)dealloc
{
	[_softwareKey release];
	[_objFWKey release];

	[super dealloc];
}

- (void)testClassesRootKey
{
	OTAssertEqual([[OFWindowsRegistryKey classesRootKey] class],







|


|
|
|
|
|
|











|
|







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

@implementation OFWindowsRegistryKeyTests
- (void)setUp
{
	[super setUp];

	_softwareKey = objc_retain([[OFWindowsRegistryKey currentUserKey]
	    openSubkeyAtPath: @"Software"
		accessRights: KEY_ALL_ACCESS
		     options: 0]);
	_objFWKey = objc_retain([_softwareKey createSubkeyAtPath: @"ObjFW"
						    accessRights: KEY_ALL_ACCESS
					      securityAttributes: NULL
							 options: 0
						     disposition: NULL]);
}

- (void)tearDown
{
	[_softwareKey deleteSubkeyAtPath: @"ObjFW"];

	[super tearDown];
}

- (void)dealloc
{
	objc_release(_softwareKey);
	objc_release(_objFWKey);

	[super dealloc];
}

- (void)testClassesRootKey
{
	OTAssertEqual([[OFWindowsRegistryKey classesRootKey] class],
Changes to tests/OFXMLElementBuilderTests.m.
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
	size_t _i;
}
@end

@implementation OFXMLElementBuilderTests
- (void)dealloc
{
	[_nodes[0] release];
	[_nodes[1] release];

	[super dealloc];
}

- (void)elementBuilder: (OFXMLElementBuilder *)builder
       didBuildElement: (OFXMLElement *)element
{
	OTAssertEqual(_i, 0);
	_nodes[_i++] = [element retain];
}

- (void)elementBuilder: (OFXMLElementBuilder *)builder
    didBuildOrphanNode: (OFXMLNode *)node
{
	OTAssertEqual(_i, 1);
	_nodes[_i++] = [node retain];
}

- (void)testElementBuilder
{
	OFXMLParser *parser = [OFXMLParser parser];
	OFXMLElementBuilder *builder = [OFXMLElementBuilder builder];
	OFString *string = @"<foo>bar<![CDATA[f<oo]]>baz<qux/>"







|
|








|






|







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
	size_t _i;
}
@end

@implementation OFXMLElementBuilderTests
- (void)dealloc
{
	objc_release(_nodes[0]);
	objc_release(_nodes[1]);

	[super dealloc];
}

- (void)elementBuilder: (OFXMLElementBuilder *)builder
       didBuildElement: (OFXMLElement *)element
{
	OTAssertEqual(_i, 0);
	_nodes[_i++] = objc_retain(element);
}

- (void)elementBuilder: (OFXMLElementBuilder *)builder
    didBuildOrphanNode: (OFXMLNode *)node
{
	OTAssertEqual(_i, 1);
	_nodes[_i++] = objc_retain(node);
}

- (void)testElementBuilder
{
	OFXMLParser *parser = [OFXMLParser parser];
	OFXMLElementBuilder *builder = [OFXMLElementBuilder builder];
	OFString *string = @"<foo>bar<![CDATA[f<oo]]>baz<qux/>"
Changes to tests/RuntimeTests.m.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
	[super setUp];

	_test = [[RuntimeTestClass alloc] init];
}

- (void)dealloc
{
	[_test release];

	[super dealloc];
}

- (void)testCallNonExistentMethodViaSuper
{
	OTAssertThrowsSpecific([_test superTest], OFNotImplementedException);







|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
	[super setUp];

	_test = [[RuntimeTestClass alloc] init];
}

- (void)dealloc
{
	objc_release(_test);

	[super dealloc];
}

- (void)testCallNonExistentMethodViaSuper
{
	OTAssertThrowsSpecific([_test superTest], OFNotImplementedException);
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

@implementation RuntimeTestClass
@synthesize foo = _foo;
@synthesize bar = _bar;

- (void)dealloc
{
	[_foo release];
	[_bar release];

	[super dealloc];
}

- (id)superTest
{
	return [super superTest];







|
|







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

@implementation RuntimeTestClass
@synthesize foo = _foo;
@synthesize bar = _bar;

- (void)dealloc
{
	objc_release(_foo);
	objc_release(_bar);

	[super dealloc];
}

- (id)superTest
{
	return [super superTest];
Changes to tests/gamecontroller/GameControllerTests.m.
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
- (void)updateOutput
{
	OHLeftJoyCon *leftJoyCon = nil;
	OHRightJoyCon *rightJoyCon = nil;

	if (_lastControllersUpdate == nil ||
	    -[_lastControllersUpdate timeIntervalSinceNow] > 1) {
		[_joyConPair release];
		[_controllers release];
		[_lastControllersUpdate release];

		_joyConPair = nil;
		_controllers = [[OHGameController controllers] retain];
		_lastControllersUpdate = [[OFDate alloc] init];

		[OFStdOut clear];
	}

	[OFStdOut setCursorPosition: OFMakePoint(0, 0)];








|
|
|


|







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
- (void)updateOutput
{
	OHLeftJoyCon *leftJoyCon = nil;
	OHRightJoyCon *rightJoyCon = nil;

	if (_lastControllersUpdate == nil ||
	    -[_lastControllersUpdate timeIntervalSinceNow] > 1) {
		objc_release(_joyConPair);
		objc_release(_controllers);
		objc_release(_lastControllersUpdate);

		_joyConPair = nil;
		_controllers = objc_retain([OHGameController controllers]);
		_lastControllersUpdate = [[OFDate alloc] init];

		[OFStdOut clear];
	}

	[OFStdOut setCursorPosition: OFMakePoint(0, 0)];

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
		if ([profile isKindOfClass: [OHLeftJoyCon class]])
			leftJoyCon = (OHLeftJoyCon *)profile;
		else if ([profile isKindOfClass: [OHRightJoyCon class]])
			rightJoyCon = (OHRightJoyCon *)profile;

		if (_joyConPair == nil && leftJoyCon != nil &&
		    rightJoyCon != nil)
			_joyConPair = [[OHJoyConPair
			    gamepadWithLeftJoyCon: leftJoyCon
				      rightJoyCon: rightJoyCon] retain];
	}

	if (_joyConPair) {
		OFStdOut.foregroundColor = [OFColor green];
		[OFStdOut writeLine: @"Joy-Con Pair"];

		printProfile(_joyConPair);







|
|
|







273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
		if ([profile isKindOfClass: [OHLeftJoyCon class]])
			leftJoyCon = (OHLeftJoyCon *)profile;
		else if ([profile isKindOfClass: [OHRightJoyCon class]])
			rightJoyCon = (OHRightJoyCon *)profile;

		if (_joyConPair == nil && leftJoyCon != nil &&
		    rightJoyCon != nil)
			_joyConPair = objc_retain(
			    [OHJoyConPair gamepadWithLeftJoyCon: leftJoyCon
						    rightJoyCon: rightJoyCon]);
	}

	if (_joyConPair) {
		OFStdOut.foregroundColor = [OFColor green];
		[OFStdOut writeLine: @"Joy-Con Pair"];

		printProfile(_joyConPair);
Changes to utils/objfw-new/NewClass.m.
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
		[implFile writeString: @"\n"
				       @"- (void)dealloc\n"
				       @"{\n"];

		for (Property *property in properties)
			if ([property.attributes containsObject: @"retain"] ||
			    [property.attributes containsObject: @"copy"])
				[implFile writeFormat: @"\t[_%@ release];\n",
						       property.name];

		[implFile writeString: @"\n"
				       @"\t[super dealloc];\n"
				       @"}\n"];
	}

	[implFile writeString: @"@end\n"];







|
|







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
		[implFile writeString: @"\n"
				       @"- (void)dealloc\n"
				       @"{\n"];

		for (Property *property in properties)
			if ([property.attributes containsObject: @"retain"] ||
			    [property.attributes containsObject: @"copy"])
				[implFile writeFormat:
				    @"\tobjc_release(_%@);\n", property.name];

		[implFile writeString: @"\n"
				       @"\t[super dealloc];\n"
				       @"}\n"];
	}

	[implFile writeString: @"@end\n"];
Changes to utils/objfw-new/Property.m.
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
@end

@implementation Property
@synthesize name = _name, type = _type, attributes = _attributes;

+ (instancetype)propertyWithString: (OFString *)string
{

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

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

	@try {
		[self parseString: string];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)parseString: (OFString *)string







>
|









|







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

@implementation Property
@synthesize name = _name, type = _type, attributes = _attributes;

+ (instancetype)propertyWithString: (OFString *)string
{
	return objc_autoreleaseReturnValue(
	    [[self alloc] initWithString: string]);
}

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

	@try {
		[self parseString: string];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)parseString: (OFString *)string
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
			if (UTF8String[i] == '(')
				level++;
			else if (UTF8String[i] == ')') {
				if (--level == 0) {
					OFString *attributesString = [OFString
					    stringWithUTF8String: UTF8String + 1
							  length: i - 1];

					attributes = [[[attributesString
					    componentsSeparatedByString: @","]
					    mutableCopy] autorelease];

					UTF8String += i + 1;
					length += i + 1;

					while (*UTF8String == ' ' ||
					    *UTF8String == '\t') {
						UTF8String++;







>
|

|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
			if (UTF8String[i] == '(')
				level++;
			else if (UTF8String[i] == ')') {
				if (--level == 0) {
					OFString *attributesString = [OFString
					    stringWithUTF8String: UTF8String + 1
							  length: i - 1];
					attributes = objc_autorelease(
					    [[attributesString
					    componentsSeparatedByString: @","]
					    mutableCopy]);

					UTF8String += i + 1;
					length += i + 1;

					while (*UTF8String == ' ' ||
					    *UTF8String == '\t') {
						UTF8String++;
120
121
122
123
124
125
126
127
128
129
130
131
132
					      length: (size_t)nameIdx];

	objc_autoreleasePoolPop(pool);
}

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

	[super dealloc];
}
@end







|
|




122
123
124
125
126
127
128
129
130
131
132
133
134
					      length: (size_t)nameIdx];

	objc_autoreleasePoolPop(pool);
}

- (void)dealloc
{
	objc_release(_name);
	objc_release(_type);

	[super dealloc];
}
@end
Changes to utils/ofarc/GZIPArchive.m.
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
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI
			stream: (OF_KINDOF(OFStream *))stream
			  mode: (OFString *)mode
		      encoding: (OFStringEncoding)encoding
{

	return [[[self alloc] initWithIRI: IRI
				   stream: stream
				     mode: mode
				 encoding: encoding] autorelease];
}

- (instancetype)initWithIRI: (OFIRI *)IRI
		     stream: (OF_KINDOF(OFStream *))stream
		       mode: (OFString *)mode
		   encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		_stream = [[OFGZIPStream alloc] initWithStream: stream
							  mode: mode];
		_archiveIRI = [IRI copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_stream release];
	[_archiveIRI release];

	[super dealloc];
}

- (void)listFiles
{
	[OFStdErr writeLine: OF_LOCALIZED(@"cannot_list_gz",







>
|
|
|
|














|








|
|







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
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI
			stream: (OF_KINDOF(OFStream *))stream
			  mode: (OFString *)mode
		      encoding: (OFStringEncoding)encoding
{
	return objc_autoreleaseReturnValue(
	    [[self alloc] initWithIRI: IRI
			       stream: stream
				 mode: mode
			     encoding: encoding]);
}

- (instancetype)initWithIRI: (OFIRI *)IRI
		     stream: (OF_KINDOF(OFStream *))stream
		       mode: (OFString *)mode
		   encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		_stream = [[OFGZIPStream alloc] initWithStream: stream
							  mode: mode];
		_archiveIRI = [IRI copy];
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_stream);
	objc_release(_archiveIRI);

	[super dealloc];
}

- (void)listFiles
{
	[OFStdErr writeLine: OF_LOCALIZED(@"cannot_list_gz",
Changes to utils/ofarc/LHAArchive.m.
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
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI
			stream: (OF_KINDOF(OFStream *))stream
			  mode: (OFString *)mode
		      encoding: (OFStringEncoding)encoding
{

	return [[[self alloc] initWithIRI: IRI
				   stream: stream
				     mode: mode
				 encoding: encoding] autorelease];
}

- (instancetype)initWithIRI: (OFIRI *)IRI
		     stream: (OF_KINDOF(OFStream *))stream
		       mode: (OFString *)mode
		   encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		_archive = [[OFLHAArchive alloc] initWithStream: stream
							   mode: mode];

		if (encoding != OFStringEncodingAutodetect)
			_archive.encoding = encoding;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_archive release];

	[super dealloc];
}

- (void)listFiles
{
	OFLHAArchiveEntry *entry;







>
|
|
|
|
















|








|







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
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI
			stream: (OF_KINDOF(OFStream *))stream
			  mode: (OFString *)mode
		      encoding: (OFStringEncoding)encoding
{
	return objc_autoreleaseReturnValue(
	    [[self alloc] initWithIRI: IRI
			       stream: stream
				 mode: mode
			     encoding: encoding]);
}

- (instancetype)initWithIRI: (OFIRI *)IRI
		     stream: (OF_KINDOF(OFStream *))stream
		       mode: (OFString *)mode
		   encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		_archive = [[OFLHAArchive alloc] initWithStream: stream
							   mode: mode];

		if (encoding != OFStringEncodingAutodetect)
			_archive.encoding = encoding;
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_archive);

	[super dealloc];
}

- (void)listFiles
{
	OFLHAArchiveEntry *entry;
Changes to utils/ofarc/OFArc.m.
495
496
497
498
499
500
501

502
503
504
505
506
507
508
509
510
511

#ifdef OF_MACOS
		if ([IRI.scheme isEqual: @"file"]) {
			@try {
				OFString *attributeName =
				    @"com.apple.quarantine";


				_quarantine = [[[OFFileManager defaultManager]
				    extendedAttributeDataForName: attributeName
						     ofItemAtIRI: IRI] retain];
			} @catch (OFGetItemAttributesFailedException *e) {
				if (e.errNo != /*ENOATTR*/ 93)
					@throw e;
			}
		}
#endif








>
|

|







495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

#ifdef OF_MACOS
		if ([IRI.scheme isEqual: @"file"]) {
			@try {
				OFString *attributeName =
				    @"com.apple.quarantine";

				_quarantine = objc_retain(
				    [[OFFileManager defaultManager]
				    extendedAttributeDataForName: attributeName
						     ofItemAtIRI: IRI]);
			} @catch (OFGetItemAttributesFailedException *e) {
				if (e.errNo != /*ENOATTR*/ 93)
					@throw e;
			}
		}
#endif

839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
		if (component.length == 0 || [component isEqual: @".."]) {
#endif
			objc_autoreleasePoolPop(pool);
			return nil;
		}
	}

	[path retain];

	objc_autoreleasePoolPop(pool);

	return [path autorelease];
}

- (void)quarantineFile: (OFString *)path
{
#ifdef OF_MACOS
	if (_quarantine != nil)
		[[OFFileManager defaultManager]
		    setExtendedAttributeData: _quarantine
				     forName: @"com.apple.quarantine"
				ofItemAtPath: path];
#endif
}
@end







|



|













840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
		if (component.length == 0 || [component isEqual: @".."]) {
#endif
			objc_autoreleasePoolPop(pool);
			return nil;
		}
	}

	objc_retain(path);

	objc_autoreleasePoolPop(pool);

	return objc_autoreleaseReturnValue(path);
}

- (void)quarantineFile: (OFString *)path
{
#ifdef OF_MACOS
	if (_quarantine != nil)
		[[OFFileManager defaultManager]
		    setExtendedAttributeData: _quarantine
				     forName: @"com.apple.quarantine"
				ofItemAtPath: path];
#endif
}
@end
Changes to utils/ofarc/TarArchive.m.
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
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI
			stream: (OF_KINDOF(OFStream *))stream
			  mode: (OFString *)mode
		      encoding: (OFStringEncoding)encoding
{

	return [[[self alloc] initWithIRI: IRI
				   stream: stream
				     mode: mode
				 encoding: encoding] autorelease];
}

- (instancetype)initWithIRI: (OFIRI *)IRI
		     stream: (OF_KINDOF(OFStream *))stream
		       mode: (OFString *)mode
		   encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		_archive = [[OFTarArchive alloc] initWithStream: stream
							   mode: mode];

		if (encoding != OFStringEncodingAutodetect)
			_archive.encoding = encoding;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_archive release];

	[super dealloc];
}

- (void)listFiles
{
	OFTarArchiveEntry *entry;







>
|
|
|
|
















|








|







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
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI
			stream: (OF_KINDOF(OFStream *))stream
			  mode: (OFString *)mode
		      encoding: (OFStringEncoding)encoding
{
	return objc_autoreleaseReturnValue(
	    [[self alloc] initWithIRI: IRI
			       stream: stream
				 mode: mode
			     encoding: encoding]);
}

- (instancetype)initWithIRI: (OFIRI *)IRI
		     stream: (OF_KINDOF(OFStream *))stream
		       mode: (OFString *)mode
		   encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		_archive = [[OFTarArchive alloc] initWithStream: stream
							   mode: mode];

		if (encoding != OFStringEncodingAutodetect)
			_archive.encoding = encoding;
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_archive);

	[super dealloc];
}

- (void)listFiles
{
	OFTarArchiveEntry *entry;
Changes to utils/ofarc/ZIPArchive.m.
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
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI
			stream: (OF_KINDOF(OFStream *))stream
			  mode: (OFString *)mode
		      encoding: (OFStringEncoding)encoding
{

	return [[[self alloc] initWithIRI: IRI
				   stream: stream
				     mode: mode
				 encoding: encoding] autorelease];
}

- (instancetype)initWithIRI: (OFIRI *)IRI
		     stream: (OF_KINDOF(OFStream *))stream
		       mode: (OFString *)mode
		   encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		_archiveIRI = [IRI copy];
		_archive = [[OFZIPArchive alloc] initWithStream: stream
							   mode: mode];
		_archive.delegate = self;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_archiveIRI release];
	[_archive release];

	[super dealloc];
}

- (OFSeekableStream *)archive: (OFZIPArchive *)archive
	    wantsPartNumbered: (unsigned int)partNumber
	       lastPartNumber: (unsigned int)lastPartNumber
{
	OFIRI *IRI;

	if ([_archiveIRI.pathExtension caseInsensitiveCompare: @"zip"] !=
	    OFOrderedSame)
		return nil;

	if (partNumber > 98)
		return nil;

	if (partNumber == lastPartNumber)
		IRI = _archiveIRI;
	else {
		OFMutableIRI *copy = [[_archiveIRI mutableCopy] autorelease];

		[copy deletePathExtension];
		[copy appendPathExtension: [OFString
		    stringWithFormat: @"z%02u", partNumber + 1]];
		[copy makeImmutable];
		IRI = copy;
	}








>
|
|
|
|















|








|
|




















|
>







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
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI
			stream: (OF_KINDOF(OFStream *))stream
			  mode: (OFString *)mode
		      encoding: (OFStringEncoding)encoding
{
	return objc_autoreleaseReturnValue(
	    [[self alloc] initWithIRI: IRI
			       stream: stream
				 mode: mode
			     encoding: encoding]);
}

- (instancetype)initWithIRI: (OFIRI *)IRI
		     stream: (OF_KINDOF(OFStream *))stream
		       mode: (OFString *)mode
		   encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		_archiveIRI = [IRI copy];
		_archive = [[OFZIPArchive alloc] initWithStream: stream
							   mode: mode];
		_archive.delegate = self;
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_archiveIRI);
	objc_release(_archive);

	[super dealloc];
}

- (OFSeekableStream *)archive: (OFZIPArchive *)archive
	    wantsPartNumbered: (unsigned int)partNumber
	       lastPartNumber: (unsigned int)lastPartNumber
{
	OFIRI *IRI;

	if ([_archiveIRI.pathExtension caseInsensitiveCompare: @"zip"] !=
	    OFOrderedSame)
		return nil;

	if (partNumber > 98)
		return nil;

	if (partNumber == lastPartNumber)
		IRI = _archiveIRI;
	else {
		OFMutableIRI *copy =
		    objc_autorelease([_archiveIRI mutableCopy]);
		[copy deletePathExtension];
		[copy appendPathExtension: [OFString
		    stringWithFormat: @"z%02u", partNumber + 1]];
		[copy makeImmutable];
		IRI = copy;
	}

Changes to utils/ofarc/ZooArchive.m.
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
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI
			stream: (OF_KINDOF(OFStream *))stream
			  mode: (OFString *)mode
		      encoding: (OFStringEncoding)encoding
{

	return [[[self alloc] initWithIRI: IRI
				   stream: stream
				     mode: mode
				 encoding: encoding] autorelease];
}

- (instancetype)initWithIRI: (OFIRI *)IRI
		     stream: (OF_KINDOF(OFStream *))stream
		       mode: (OFString *)mode
		   encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		_archive = [[OFZooArchive alloc] initWithStream: stream
							   mode: mode];

		if (encoding != OFStringEncodingAutodetect)
			_archive.encoding = encoding;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_archive release];

	[super dealloc];
}

- (void)listFiles
{
	OFZooArchiveEntry *entry;







>
|
|
|
|
















|








|







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
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI
			stream: (OF_KINDOF(OFStream *))stream
			  mode: (OFString *)mode
		      encoding: (OFStringEncoding)encoding
{
	return objc_autoreleaseReturnValue(
	    [[self alloc] initWithIRI: IRI
			       stream: stream
				 mode: mode
			     encoding: encoding]);
}

- (instancetype)initWithIRI: (OFIRI *)IRI
		     stream: (OF_KINDOF(OFStream *))stream
		       mode: (OFString *)mode
		   encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		_archive = [[OFZooArchive alloc] initWithStream: stream
							   mode: mode];

		if (encoding != OFStringEncodingAutodetect)
			_archive.encoding = encoding;
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	objc_release(_archive);

	[super dealloc];
}

- (void)listFiles
{
	OFZooArchiveEntry *entry;
Changes to utils/ofdns/OFDNS.m.
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
	OFSandbox *sandbox = [[OFSandbox alloc] init];
	@try {
		sandbox.allowsStdIO = true;
		sandbox.allowsDNS = true;

		[OFApplication of_activateSandbox: sandbox];
	} @finally {
		[sandbox release];
	}
#endif

	recordTypes = [OFMutableArray array];

	optionsParser = [OFOptionsParser parserWithOptions: options];
	while ((option = [optionsParser nextOption]) != '\0') {







|







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
	OFSandbox *sandbox = [[OFSandbox alloc] init];
	@try {
		sandbox.allowsStdIO = true;
		sandbox.allowsDNS = true;

		[OFApplication of_activateSandbox: sandbox];
	} @finally {
		objc_release(sandbox);
	}
#endif

	recordTypes = [OFMutableArray array];

	optionsParser = [OFOptionsParser parserWithOptions: options];
	while ((option = [optionsParser nextOption]) != '\0') {
Changes to utils/ofhash/OFHash.m.
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
			for (OFString *path in optionsParser.remainingArguments)
				[sandbox unveilPath: path permissions: @"r"];

		[sandbox unveilPath: @LOCALIZATION_DIR permissions: @"r"];

		[OFApplication of_activateSandbox: sandbox];
	} @finally {
		[sandbox release];
	}
#endif

	if (!calculateMD5 && !calculateRIPEMD160 && !calculateSHA1 &&
	    !calculateSHA224 && !calculateSHA256 && !calculateSHA384 &&
	    !calculateSHA512)
		help();







|







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
			for (OFString *path in optionsParser.remainingArguments)
				[sandbox unveilPath: path permissions: @"r"];

		[sandbox unveilPath: @LOCALIZATION_DIR permissions: @"r"];

		[OFApplication of_activateSandbox: sandbox];
	} @finally {
		objc_release(sandbox);
	}
#endif

	if (!calculateMD5 && !calculateRIPEMD160 && !calculateSHA1 &&
	    !calculateSHA224 && !calculateSHA256 && !calculateSHA384 &&
	    !calculateSHA512)
		help();
Changes to utils/ofhttp/OFHTTP.m.
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
	    (fileName = [params objectForKey: @"filename"]) == nil) {
		objc_autoreleasePoolPop(pool);
		return nil;
	}

	fileName = fileName.lastPathComponent;

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

@implementation OFHTTP
- (instancetype)init
{
	self = [super init];

	@try {
		_method = OFHTTPRequestMethodGet;

		_clientHeaders = [[OFMutableDictionary alloc]
		    initWithObject: @"OFHTTP"
			    forKey: @"User-Agent"];

		_HTTPClient = [[OFHTTPClient alloc] init];
		_HTTPClient.delegate = self;

		_buffer = OFAllocMemory(1, [OFSystemInfo pageSize]);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)addHeader: (OFString *)header







|

|



















|







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
	    (fileName = [params objectForKey: @"filename"]) == nil) {
		objc_autoreleasePoolPop(pool);
		return nil;
	}

	fileName = fileName.lastPathComponent;

	objc_retain(fileName);
	objc_autoreleasePoolPop(pool);
	return objc_autoreleaseReturnValue(fileName);
}

@implementation OFHTTP
- (instancetype)init
{
	self = [super init];

	@try {
		_method = OFHTTPRequestMethodGet;

		_clientHeaders = [[OFMutableDictionary alloc]
		    initWithObject: @"OFHTTP"
			    forKey: @"User-Agent"];

		_HTTPClient = [[OFHTTPClient alloc] init];
		_HTTPClient.delegate = self;

		_buffer = OFAllocMemory(1, [OFSystemInfo pageSize]);
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)addHeader: (OFString *)header
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
	[_clientHeaders setObject: value forKey: name];
}

- (void)setBody: (OFString *)path
{
	OFString *contentLength = nil;

	[_body release];
	_body = nil;

	if ([path isEqual: @"-"])
		_body = [OFStdIn copy];
	else {
		_body = [[OFFile alloc] initWithPath: path mode: @"r"];








|







341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
	[_clientHeaders setObject: value forKey: name];
}

- (void)setBody: (OFString *)path
{
	OFString *contentLength = nil;

	objc_release(_body);
	_body = nil;

	if ([path isEqual: @"-"])
		_body = [OFStdIn copy];
	else {
		_body = [[OFFile alloc] initWithPath: path mode: @"r"];

688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
	  exception: (id)exception
{
	if (exception != nil) {
		OFString *IRI;

		[_progressBar stop];
		[_progressBar draw];
		[_progressBar release];
		_progressBar = nil;

		if (!_quiet) {
			[OFStdErr writeString: @"\n  "];
			[OFStdErr writeLine: OF_LOCALIZED(@"download_error",
			    @"Error!")];
		}







|







688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
	  exception: (id)exception
{
	if (exception != nil) {
		OFString *IRI;

		[_progressBar stop];
		[_progressBar draw];
		objc_release(_progressBar);
		_progressBar = nil;

		if (!_quiet) {
			[OFStdErr writeString: @"\n  "];
			[OFStdErr writeLine: OF_LOCALIZED(@"download_error",
			    @"Error!")];
		}
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734

	_received += length;
	[_progressBar setReceived: _received];

	if (response.atEndOfStream) {
		[_progressBar stop];
		[_progressBar draw];
		[_progressBar release];
		_progressBar = nil;

		if (!_quiet) {
			[OFStdErr writeString: @"\n  "];
			[OFStdErr writeLine:
			    OF_LOCALIZED(@"download_done", @"Done!")];
		}







|







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

	_received += length;
	[_progressBar setReceived: _received];

	if (response.atEndOfStream) {
		[_progressBar stop];
		[_progressBar draw];
		objc_release(_progressBar);
		_progressBar = nil;

		if (!_quiet) {
			[OFStdErr writeString: @"\n  "];
			[OFStdErr writeLine:
			    OF_LOCALIZED(@"download_done", @"Done!")];
		}
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
		    initWithLength: _length
		       resumedFrom: _resumedFrom
			useUnicode: _useUnicode];
		[_progressBar setReceived: _received];
		[_progressBar draw];
	}

	[_currentFileName release];
	_currentFileName = nil;

	response.delegate = self;
	[response asyncReadIntoBuffer: _buffer length: [OFSystemInfo pageSize]];
	return;

next:
	[_currentFileName release];
	_currentFileName = nil;

	[self performSelector: @selector(downloadNextIRI) afterDelay: 0];
}

- (void)downloadNextIRI
{
	OFString *IRIString = nil;
	OFIRI *IRI;
	OFMutableDictionary *clientHeaders;
	OFHTTPRequest *request;

	_received = _length = _resumedFrom = 0;

	if (_output != OFStdOut)
		[_output release];
	_output = nil;

	if (_IRIIndex >= _IRIs.count)
		[OFApplication terminateWithStatus: _errorCode];

	@try {
		IRIString = [_IRIs objectAtIndex: _IRIIndex++];







|







|















|







1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
		    initWithLength: _length
		       resumedFrom: _resumedFrom
			useUnicode: _useUnicode];
		[_progressBar setReceived: _received];
		[_progressBar draw];
	}

	objc_release(_currentFileName);
	_currentFileName = nil;

	response.delegate = self;
	[response asyncReadIntoBuffer: _buffer length: [OFSystemInfo pageSize]];
	return;

next:
	objc_release(_currentFileName);
	_currentFileName = nil;

	[self performSelector: @selector(downloadNextIRI) afterDelay: 0];
}

- (void)downloadNextIRI
{
	OFString *IRIString = nil;
	OFIRI *IRI;
	OFMutableDictionary *clientHeaders;
	OFHTTPRequest *request;

	_received = _length = _resumedFrom = 0;

	if (_output != OFStdOut)
		objc_release(_output);
	_output = nil;

	if (_IRIIndex >= _IRIs.count)
		[OFApplication terminateWithStatus: _errorCode];

	@try {
		IRIString = [_IRIs objectAtIndex: _IRIIndex++];
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
		    @"prog", [OFApplication programName],
		    @"iri", IRIString)];

		_errorCode = 1;
		goto next;
	}

	clientHeaders = [[_clientHeaders mutableCopy] autorelease];

	if (_detectFileName && !_detectedFileName) {
		if (!_quiet) {
			if (_useUnicode)
				[OFStdErr writeFormat: @"â ’ %@", IRI.string];
			else
				[OFStdErr writeFormat: @"? %@", IRI.string];
		}

		request = [OFHTTPRequest requestWithIRI: IRI];
		request.headers = clientHeaders;
		request.method = OFHTTPRequestMethodHead;

		_detectFileNameRequest = true;
		[_HTTPClient asyncPerformRequest: request];
		return;
	}

	if (!_detectedFileName) {
		[_currentFileName release];
		_currentFileName = nil;
	} else
		_detectedFileName = false;

	if (_currentFileName == nil)
		_currentFileName = [_outputPath copy];

	if (_currentFileName == nil)
		_currentFileName = [IRI.path.lastPathComponent copy];

	if ([_currentFileName isEqual: @"/"] || _currentFileName.length == 0) {
		[_currentFileName release];
		_currentFileName = nil;
	}

	if (_currentFileName == nil)
		_currentFileName = @"unnamed";

	if (_continue) {







|



















|











|







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
		    @"prog", [OFApplication programName],
		    @"iri", IRIString)];

		_errorCode = 1;
		goto next;
	}

	clientHeaders = objc_autorelease([_clientHeaders mutableCopy]);

	if (_detectFileName && !_detectedFileName) {
		if (!_quiet) {
			if (_useUnicode)
				[OFStdErr writeFormat: @"â ’ %@", IRI.string];
			else
				[OFStdErr writeFormat: @"? %@", IRI.string];
		}

		request = [OFHTTPRequest requestWithIRI: IRI];
		request.headers = clientHeaders;
		request.method = OFHTTPRequestMethodHead;

		_detectFileNameRequest = true;
		[_HTTPClient asyncPerformRequest: request];
		return;
	}

	if (!_detectedFileName) {
		objc_release(_currentFileName);
		_currentFileName = nil;
	} else
		_detectedFileName = false;

	if (_currentFileName == nil)
		_currentFileName = [_outputPath copy];

	if (_currentFileName == nil)
		_currentFileName = [IRI.path.lastPathComponent copy];

	if ([_currentFileName isEqual: @"/"] || _currentFileName.length == 0) {
		objc_release(_currentFileName);
		_currentFileName = nil;
	}

	if (_currentFileName == nil)
		_currentFileName = @"unnamed";

	if (_continue) {
Changes to utils/ofhttp/ProgressBar.m.
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
		void *pool = objc_autoreleasePoolPush();

		_useUnicode = useUnicode;
		_length = length;
		_resumedFrom = resumedFrom;
		_startDate = [[OFDate alloc] init];
		_lastReceivedDate = [[OFDate alloc] init];
		_drawTimer = [[OFTimer
		    scheduledTimerWithTimeInterval: updateInterval
					    target: self
					  selector: @selector(draw)
					   repeats: true] retain];
		_BPSTimer = [[OFTimer
		    scheduledTimerWithTimeInterval: 1.0
					    target: self
					  selector: @selector(
							_calculateBPSAndETA)
					   repeats: true] retain];

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

	return self;
}

- (void)dealloc
{
	[self stop];

	[_startDate release];
	[_lastReceivedDate release];
	[_drawTimer release];
	[_BPSTimer release];

	[super dealloc];
}

- (void)setReceived: (unsigned long long)received
{
	_received = received;







|



|
|




|



|










|
|
|
|







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
		void *pool = objc_autoreleasePoolPush();

		_useUnicode = useUnicode;
		_length = length;
		_resumedFrom = resumedFrom;
		_startDate = [[OFDate alloc] init];
		_lastReceivedDate = [[OFDate alloc] init];
		_drawTimer = objc_retain([OFTimer
		    scheduledTimerWithTimeInterval: updateInterval
					    target: self
					  selector: @selector(draw)
					   repeats: true]);
		_BPSTimer = objc_retain([OFTimer
		    scheduledTimerWithTimeInterval: 1.0
					    target: self
					  selector: @selector(
							_calculateBPSAndETA)
					   repeats: true]);

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		objc_release(self);
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[self stop];

	objc_release(_startDate);
	objc_release(_lastReceivedDate);
	objc_release(_drawTimer);
	objc_release(_BPSTimer);

	[super dealloc];
}

- (void)setReceived: (unsigned long long)received
{
	_received = received;
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324
325
326
327
328
329
330
	for (size_t i = 0; i < _BPSWindowLength; i++)
		_BPS += _BPSWindow[i];
	_BPS /= _BPSWindowLength;

	_ETA = (double)(_length - _received) / _BPS;

	_lastReceived = _received;

	[_lastReceivedDate release];
	_lastReceivedDate = [[OFDate alloc] init];
}

- (void)stop
{
	[_drawTimer invalidate];
	[_BPSTimer invalidate];

	_stopped = true;

	OFStdErr.cursorVisible = true;
}
@end







>
|













310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
	for (size_t i = 0; i < _BPSWindowLength; i++)
		_BPS += _BPSWindow[i];
	_BPS /= _BPSWindowLength;

	_ETA = (double)(_length - _received) / _BPS;

	_lastReceived = _received;
	objc_release(_lastReceivedDate);
	_lastReceivedDate = nil;
	_lastReceivedDate = [[OFDate alloc] init];
}

- (void)stop
{
	[_drawTimer invalidate];
	[_BPSTimer invalidate];

	_stopped = true;

	OFStdErr.cursorVisible = true;
}
@end