ObjFW  Check-in [4af49a13c3]

Overview
Comment:Small code style change

Casts are now written like types in variable declarations.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 4af49a13c3efca3420218812e4d0148c33100418421bab60129a65d6212e8c56
User & Date: js on 2017-05-07 20:10:13
Other Links: manifest | tags
Context
2017-05-07
21:16
Make -[OFHTTPRequest setBodyFromString:] nonnull check-in: 8016757def user: js tags: trunk
20:10
Small code style change check-in: 4af49a13c3 user: js tags: trunk
15:39
Do not include any addresses in -[description] check-in: 7c2a0dda3d user: js tags: trunk
Changes

Modified configure.ac from [f0dfe7a194] to [b157727f9f].

300
301
302
303
304
305
306
307

308
309
310

311
312
313
314
315
316
317
300
301
302
303
304
305
306

307
308
309

310
311
312
313
314
315
316
317







-
+


-
+








			@implementation Test
			+ (void)test
			{
			}
			@end

			void*
			void *
			objc_msg_lookup(void *obj, void *sel)
			{
				return (void*)0;
				return (void *)0;
			}

			void
			__objc_exec_class(void *module)
			{
			}
		], [
1240
1241
1242
1243
1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254
1240
1241
1242
1243
1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
1254







-
+







		}
		@end

		static struct {
			struct objc_class *_isa;
		} object;
	], [
		Foo *test = (Foo*)&object;
		Foo *test = (Foo *)&object;
		(void)test; /* Get rid of unused variable warning */
	], [
		AC_MSG_RESULT(no)
	], [
		AC_MSG_RESULT(yes)
		OBJCFLAGS="$OBJCFLAGS -Wno-strict-aliasing"
	])
1265
1266
1267
1268
1269
1270
1271
1272

1273
1274
1275
1276
1277
1278

1279
1280

1281
1282
1283
1284
1285
1286
1287
1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277

1278
1279

1280
1281
1282
1283
1284
1285
1286
1287







-
+





-
+

-
+







		{
			struct objc_class *_isa;
			Foo *_foo;
		}

		@property (readonly, retain) Foo *foo;

		+ (Foo*)foo;
		+ (Foo *)foo;
		@end

		@implementation Foo
		@synthesize foo = _foo;

		+ (Foo*)foo
		+ (Foo *)foo
		{
			return (Foo*)0;
			return (Foo *)0;
		}
		@end
	], [
	], [
		AC_MSG_RESULT(no)
	], [
		AC_MSG_RESULT(yes)

Modified generators/TableGenerator.h from [a1dab56d44] to [8a6be049f9].

32
33
34
35
36
37
38
39
40


41
32
33
34
35
36
37
38


39
40
41







-
-
+
+

	size_t _lowercaseTableSize;
	size_t _titlecaseTableSize;
	size_t _casefoldingTableSize;
}

- (void)parseUnicodeData;
- (void)parseCaseFolding;
- (void)writeTablesToFile: (OFString*)path;
- (void)writeHeaderToFile: (OFString*)path;
- (void)writeTablesToFile: (OFString *)path;
- (void)writeHeaderToFile: (OFString *)path;
@end

Modified generators/TableGenerator.m from [ca882f1ae4] to [dca1029f28].

85
86
87
88
89
90
91
92

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

92
93
94
95
96
97
98
99







-
+







	request = [OFHTTPRequest requestWithURL:
	    [OFURL URLWithString: UNICODE_DATA_URL]];
	client = [OFHTTPClient client];
	response = [client performRequest: request];

	while ((line = [response readLine]) != nil) {
		void *pool2;
		OFArray OF_GENERIC(OFString*) *split;
		OFArray OF_GENERIC(OFString *) *split;
		OFString *const *splitObjects;
		of_unichar_t codep;

		if ([line length] == 0)
			continue;

		pool2 = objc_autoreleasePoolPush();
134
135
136
137
138
139
140
141

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

141
142
143
144
145
146
147
148







-
+







	request = [OFHTTPRequest requestWithURL:
	    [OFURL URLWithString: CASE_FOLDING_URL]];
	client = [OFHTTPClient client];
	response = [client performRequest: request];

	while ((line = [response readLine]) != nil) {
		void *pool2;
		OFArray OF_GENERIC(OFString*) *split;
		OFArray OF_GENERIC(OFString *) *split;
		OFString *const *splitObjects;
		of_unichar_t codep;

		if ([line length] == 0 || [line hasPrefix: @"#"])
			continue;

		pool2 = objc_autoreleasePoolPush();
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180







-
+







	}

	[of_stdout writeLine: @" done"];

	objc_autoreleasePoolPop(pool);
}

- (void)writeTablesToFile: (OFString*)path
- (void)writeTablesToFile: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFFile *file = [OFFile fileWithPath: path
				       mode: @"wb"];

	[file writeString: COPYRIGHT
	    @"#include \"config.h\"\n"
442
443
444
445
446
447
448
449

450
451
452
453
454
455
456
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456







-
+







	}

	[file writeString: @"\n};\n"];

	objc_autoreleasePoolPop(pool);
}

- (void)writeHeaderToFile: (OFString*)path
- (void)writeHeaderToFile: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFFile *file = [OFFile fileWithPath: path
				       mode: @"wb"];

	[file writeString: COPYRIGHT
	    @"#import \"OFString.h\"\n\n"];

Modified src/OFApplication.h from [7c21208134] to [2fba27a966].

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







-
-
+
+




















-
+





-
+






-
+






-
+






-
+






-
+







 * `OF_APPLICATION_DELEGATE(NameOfYourClass)` in the .m file of that class. The
 * only required method of the @ref OFApplicationDelegate protocol is
 * @ref OFApplicationDelegate::applicationDidFinishLaunching.
 */
@interface OFApplication: OFObject
{
	OFString *_programName;
	OFArray OF_GENERIC(OFString*) *_arguments;
	OFDictionary OF_GENERIC(OFString*, OFString*) *_environment;
	OFArray OF_GENERIC(OFString *) *_arguments;
	OFDictionary OF_GENERIC(OFString *, OFString *) *_environment;
	int *_argc;
	char ***_argv;
@public
	id <OFApplicationDelegate> _delegate;
	void (*_SIGINTHandler)(id, SEL);
#ifndef OF_WINDOWS
	void (*_SIGHUPHandler)(id, SEL);
	void (*_SIGUSR1Handler)(id, SEL);
	void (*_SIGUSR2Handler)(id, SEL);
#endif
}

/*!
 * The name of the program (argv[0]).
 */
@property (readonly, nonatomic) OFString *programName;

/*!
 * The arguments passed to the application.
 */
@property (readonly, nonatomic) OFArray OF_GENERIC(OFString*) *arguments;
@property (readonly, nonatomic) OFArray OF_GENERIC(OFString *) *arguments;

/*!
 * The environment of the application.
 */
@property (readonly, nonatomic)
    OFDictionary OF_GENERIC(OFString*, OFString*) *environment;
    OFDictionary OF_GENERIC(OFString *, OFString *) *environment;

/*!
 * @brief Returns the only OFApplication instance in the application.
 *
 * @return The only OFApplication instance in the application
 */
+ (OFApplication*)sharedApplication;
+ (OFApplication *)sharedApplication;

/*!
 * @brief Returns the name of the program (argv[0]).
 *
 * @return The name of the program (argv[0])
 */
+ (OFString*)programName;
+ (OFString *)programName;

/*!
 * @brief Returns the arguments passed to the application.
 *
 * @return The arguments passed to the application
 */
+ (OFArray OF_GENERIC(OFString*)*)arguments;
+ (OFArray OF_GENERIC(OFString *) *)arguments;

/*!
 * @brief Returns the environment of the application.
 *
 * @return The environment of the application
 */
+ (OFDictionary OF_GENERIC(OFString*, OFString*)*)environment;
+ (OFDictionary OF_GENERIC(OFString *, OFString *) *)environment;

/*!
 * @brief Terminates the application with the EXIT_SUCCESS status.
 */
+ (void)terminate OF_NO_RETURN;

/*!
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213







-
+







/*!
 * @brief Activates the specified sandbox for the application.
 *
 * This is only available if `OF_HAVE_SANDBOX` is defined.
 *
 * @param sandbox The sandbox to activate
 */
+ (void)activateSandbox: (OFSandbox*)sandbox;
+ (void)activateSandbox: (OFSandbox *)sandbox;
#endif

/*!
 * @brief Gets argc and argv.
 *
 * @param argc A pointer where a pointer to argc should be stored
 * @param argv A pointer where a pointer to argv should be stored
245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263
264
265
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259
260
261
262
263
264
265







-
+













/*!
 * @brief Activates the specified sandbox for the application.
 *
 * This is only available if `OF_HAVE_SANDBOX` is defined.
 *
 * @param sandbox The sandbox to activate
 */
- (void)activateSandbox: (OFSandbox*)sandbox;
- (void)activateSandbox: (OFSandbox *)sandbox;
#endif
@end

#ifdef __cplusplus
extern "C" {
#endif
extern int of_application_main(int *_Nonnull,
    char *_Nonnull *_Nonnull[_Nonnull], Class);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFApplication.m from [788679a7cf] to [f1ddeada14].

41
42
43
44
45
46
47
48

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

48
49
50
51
52
53
54
55







-
+








#if defined(OF_MACOS)
# include <crt_externs.h>
#elif defined(OF_WINDOWS)
# include <windows.h>

extern int _CRT_glob;
extern void __wgetmainargs(int*, wchar_t***, wchar_t***, int, int*);
extern void __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *);
#elif !defined(OF_IOS)
extern char **environ;
#endif

#ifdef OF_PSP
# include <pspkerneltypes.h>
# include <psploadexec.h>
64
65
66
67
68
69
70
71
72


73
74
75

76
77
78
79
80
81
82
64
65
66
67
68
69
70


71
72
73
74

75
76
77
78
79
80
81
82







-
-
+
+


-
+







#ifdef HAVE_SIGACTION
# ifndef SA_RESTART
#  define SA_RESTART 0
# endif
#endif

@interface OFApplication ()
- (void)OF_setArgumentCount: (int*)argc
	  andArgumentValues: (char**[])argv;
- (void)OF_setArgumentCount: (int *)argc
	  andArgumentValues: (char **[])argv;
#ifdef OF_WINDOWS
- (void)OF_setArgumentCount: (int)argc
      andWideArgumentValues: (wchar_t*[])argv;
      andWideArgumentValues: (wchar_t *[])argv;
#endif
- (void)OF_run;
@end

static OFApplication *app = nil;

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







-
+




-
+




-
+




-
+







	return 0;
}

@implementation OFApplication
@synthesize programName = _programName, arguments = _arguments;
@synthesize environment = _environment;

+ (OFApplication*)sharedApplication
+ (OFApplication *)sharedApplication
{
	return app;
}

+ (OFString*)programName
+ (OFString *)programName
{
	return [app programName];
}

+ (OFArray*)arguments
+ (OFArray *)arguments
{
	return [app arguments];
}

+ (OFDictionary*)environment
+ (OFDictionary *)environment
{
	return [app environment];
}

+ (void)terminate
{
	[self terminateWithStatus: EXIT_SUCCESS];
190
191
192
193
194
195
196
197

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

197
198
199
200
201
202
203
204







-
+







	sceKernelExitGame();

	OF_UNREACHABLE
#endif
}

#ifdef OF_HAVE_SANDBOX
+ (void)activateSandbox: (OFSandbox*)sandbox
+ (void)activateSandbox: (OFSandbox *)sandbox
{
	[app activateSandbox: sandbox];
}
#endif

- init
{
355
356
357
358
359
360
361
362
363


364
365
366
367
368
369
370
355
356
357
358
359
360
361


362
363
364
365
366
367
368
369
370







-
-
+
+







{
	[_arguments release];
	[_environment release];

	[super dealloc];
}

- (void)OF_setArgumentCount: (int*)argc
	  andArgumentValues: (char***)argv
- (void)OF_setArgumentCount: (int *)argc
	  andArgumentValues: (char ***)argv
{
#ifndef OF_WINDOWS
	void *pool = objc_autoreleasePoolPush();
	OFMutableArray *arguments;
	of_string_encoding_t encoding;

	_argc = argc;
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425


426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423


424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444

445
446
447
448
449
450
451
452
453
454
455
456
457

458
459
460
461
462
463
464
465







-
+




















-
-
+
+



















-
+












-
+







	_argc = argc;
	_argv = argv;
#endif
}

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

	if (argc > 0) {
		_programName = [[OFString alloc] initWithUTF16String: argv[0]];
		arguments = [[OFMutableArray alloc] init];

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

		[arguments makeImmutable];
		_arguments = arguments;
	}

	objc_autoreleasePoolPop(pool);
}
#endif

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

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

- (void)setDelegate: (id <OFApplicationDelegate>)delegate
{
#ifdef HAVE_SIGACTION
	struct sigaction sa = { .sa_flags = SA_RESTART };
	sigemptyset(&sa.sa_mask);

# define REGISTER_SIGNAL(sig)						\
	if ([delegate respondsToSelector:				\
	    @selector(applicationDidReceive##sig)]) {			\
		_##sig##Handler = (void(*)(id, SEL))[(id)delegate	\
		_##sig##Handler = (void (*)(id, SEL))[(id)delegate	\
		    methodForSelector:					\
		    @selector(applicationDidReceive##sig)];		\
									\
		sa.sa_handler = handle##sig;				\
	} else								\
		sa.sa_handler = SIG_DFL;				\
									\
	OF_ENSURE(sigaction(sig, &sa, NULL) == 0);
#else
# define REGISTER_SIGNAL(sig)						\
	if ([delegate respondsToSelector:				\
	    @selector(applicationDidReceive##sig)]) {			\
		_##sig##Handler = (void(*)(id, SEL))[(id)delegate	\
		_##sig##Handler = (void (*)(id, SEL))[(id)delegate	\
		    methodForSelector:					\
		    @selector(applicationDidReceive##sig)];		\
		signal(sig, handle##sig);				\
	} else								\
		signal(sig, SIG_DFL);
#endif

519
520
521
522
523
524
525
526

527
528
529
530
531
532
533
519
520
521
522
523
524
525

526
527
528
529
530
531
532
533







-
+







{
	[[self class] terminateWithStatus: status];

	OF_UNREACHABLE
}

#ifdef OF_HAVE_SANDBOX
- (void)activateSandbox: (OFSandbox*)sandbox
- (void)activateSandbox: (OFSandbox *)sandbox
{
# ifdef OF_HAVE_PLEDGE
	void *pool = objc_autoreleasePoolPush();
	const char *promises = [[sandbox pledgeString]
	    cStringWithEncoding: [OFLocalization encoding]];

	if (pledge(promises, NULL) != 0)

Modified src/OFArray.h from [df07e44a1f] to [824ca8afe1].

83
84
85
86
87
88
89
90

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

90
91
92
93
94
95
96
97







-
+








/*!
 * @class OFArray OFArray.h ObjFW/OFArray.h
 *
 * @brief An abstract class for storing objects in an array.
 */
#ifdef OF_HAVE_GENERICS
@interface OFArray <ObjectType>:
@interface OFArray<ObjectType>:
#else
# ifndef DOXYGEN
#  define ObjectType id
# endif
@interface OFArray:
#endif
    OFObject <OFCopying, OFMutableCopying, OFCollection, OFSerialization,
121
122
123
124
125
126
127
128

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

128
129
130
131
132
133
134
135







-
+








/*!
 * @brief Creates a new OFArray with the objects from the specified array.
 *
 * @param array An array
 * @return A new autoreleased OFArray
 */
+ (instancetype)arrayWithArray: (OFArray OF_GENERIC(ObjectType)*)array;
+ (instancetype)arrayWithArray: (OFArray OF_GENERIC(ObjectType) *)array;

/*!
 * @brief Creates a new OFArray with the objects from the specified C array of
 *	  the specified length.
 *
 * @param objects A C array of objects
 * @param count The length of the C array
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181







-
+








/*!
 * @brief Initializes an OFArray with the objects from the specified array.
 *
 * @param array An array
 * @return An initialized OFArray
 */
- initWithArray: (OFArray OF_GENERIC(ObjectType)*)array;
- initWithArray: (OFArray OF_GENERIC(ObjectType) *)array;

/*!
 * @brief Initializes an OFArray with the objects from the specified C array of
 *	  the specified length.
 *
 * @param objects A C array of objects
 * @param count The length of the C array
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235







-
+















-
+







 * specified key for each object is returned.
 *
 * @note Any nil values are replaced with @ref OFNull!
 *
 * @param key The key of the value to return
 * @return The value for the specified key
 */
- (nullable id)valueForKey: (OFString*)key;
- (nullable id)valueForKey: (OFString *)key;

/*!
 * @brief Set the value for the specified key
 *
 * If the key starts with an `@`, the `@` is stripped and
 * `[super setValue:forKey:]` is called.
 * If the key does not start with an `@`, @ref setValue:forKey: is called for
 * each object.
 *
 * @note A @ref OFNull value is translated to nil!
 *
 * @param value The value for the specified key
 * @param key The key of the value to set
 */
- (void)setValue: (nullable id)value
	  forKey: (OFString*)key;
	  forKey: (OFString *)key;

/*!
 * @brief Copies the objects at the specified range to the specified buffer.
 *
 * @param buffer The buffer to copy the objects to
 * @param range The range to copy
 */
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
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







-
+







-
+












-
-
+
+









-
-
+
+














-
-
-
+
+
+








/*!
 * @brief Returns the objects in the specified range as a new OFArray.
 *
 * @param range The range for the subarray
 * @return The subarray as a new autoreleased OFArray
 */
- (OFArray OF_GENERIC(ObjectType)*)objectsInRange: (of_range_t)range;
- (OFArray OF_GENERIC(ObjectType) *)objectsInRange: (of_range_t)range;

/*!
 * @brief Creates a string by joining all objects of the array.
 *
 * @param separator The string with which the objects should be joined
 * @return A string containing all objects joined by the separator
 */
- (OFString*)componentsJoinedByString: (OFString*)separator;
- (OFString *)componentsJoinedByString: (OFString *)separator;

/*!
 * @brief Creates a string by joining all objects of the array.
 *
 * @param separator The string with which the objects should be joined
 * @param options Options according to which the objects should be joined.@n
 *		  Possible values are:
 *		  Value                 | Description
 *		  ----------------------|----------------------
 * 		  `OF_ARRAY_SKIP_EMPTY` | Skip empty components
 * @return A string containing all objects joined by the separator
 */
- (OFString*)componentsJoinedByString: (OFString*)separator
			      options: (int)options;
- (OFString *)componentsJoinedByString: (OFString *)separator
			       options: (int)options;

/*!
 * @brief Creates a string by calling the selector on all objects of the array
 *	  and joining the strings returned by calling the selector.
 *
 * @param separator The string with which the objects should be joined
 * @param selector The selector to perform on the objects
 * @return A string containing all objects joined by the separator
 */
- (OFString*)componentsJoinedByString: (OFString*)separator
			usingSelector: (SEL)selector;
- (OFString *)componentsJoinedByString: (OFString *)separator
			 usingSelector: (SEL)selector;

/*!
 * @brief Creates a string by calling the selector on all objects of the array
 *	  and joining the strings returned by calling the selector.
 *
 * @param separator The string with which the objects should be joined
 * @param selector The selector to perform on the objects
 * @param options Options according to which the objects should be joined.@n
 *		  Possible values are:
 *		  Value                 | Description
 *		  ----------------------|----------------------
 * 		  `OF_ARRAY_SKIP_EMPTY` | Skip empty components
 * @return A string containing all objects joined by the separator
 */
- (OFString*)componentsJoinedByString: (OFString*)separator
			usingSelector: (SEL)selector
			      options: (int)options;
- (OFString *)componentsJoinedByString: (OFString *)separator
			 usingSelector: (SEL)selector
			       options: (int)options;

/*!
 * @brief Performs the specified selector on all objects in the array.
 *
 * @param selector The selector to perform on all objects in the array
 */
- (void)makeObjectsPerformSelector: (SEL)selector;
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394
395
396
397
398

399
400
401
402
403
404
405

406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422


423
424
425
426
427
428
429
430

431
432
433
434
435
436
437
438

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

455
456
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404

405
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420


421
422
423
424
425
426
427
428
429

430
431
432
433
434
435
436
437

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

454
455
456
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471







-
+











-
+






-
+







-
+







-
-
+
+







-
+







-
+















-
+









-
+







			withObject: (nullable id)object;

/*!
 * @brief Returns a sorted copy of the array.
 *
 * @return A sorted copy of the array
 */
- (OFArray OF_GENERIC(ObjectType)*)sortedArray;
- (OFArray OF_GENERIC(ObjectType) *)sortedArray;

/*!
 * @brief Returns a sorted copy of the array.
 *
 * @param options The options to use when sorting the array.@n
 *		  Possible values are:
 *		  Value                      | Description
 *		  ---------------------------|-------------------------
 *		  `OF_ARRAY_SORT_DESCENDING` | Sort in descending order
 * @return A sorted copy of the array
 */
- (OFArray OF_GENERIC(ObjectType)*)sortedArrayWithOptions: (int)options;
- (OFArray OF_GENERIC(ObjectType) *)sortedArrayWithOptions: (int)options;

/*!
 * @brief Returns a copy of the array with the order reversed.
 *
 * @return A copy of the array with the order reversed
 */
- (OFArray OF_GENERIC(ObjectType)*)reversedArray;
- (OFArray OF_GENERIC(ObjectType) *)reversedArray;

/*!
 * @brief Creates a new array with the specified object added.
 *
 * @param object The object to add
 * @return A new array with the specified object added
 */
- (OFArray OF_GENERIC(ObjectType)*)arrayByAddingObject: (ObjectType)object;
- (OFArray OF_GENERIC(ObjectType) *)arrayByAddingObject: (ObjectType)object;

/*!
 * @brief Creates a new array with the objects from the specified array added.
 *
 * @param array The array with objects to add
 * @return A new array with the objects from the specified array added
 */
- (OFArray OF_GENERIC(ObjectType)*)arrayByAddingObjectsFromArray:
    (OFArray OF_GENERIC(ObjectType)*)array;
- (OFArray OF_GENERIC(ObjectType) *)arrayByAddingObjectsFromArray:
    (OFArray OF_GENERIC(ObjectType) *)array;

/*!
 * @brief Creates a new array with the specified object removed.
 *
 * @param object The object to remove
 * @return A new array with the specified object removed
 */
- (OFArray OF_GENERIC(ObjectType)*)arrayByRemovingObject: (ObjectType)object;
- (OFArray OF_GENERIC(ObjectType) *)arrayByRemovingObject: (ObjectType)object;

/*!
 * @brief Returns an OFEnumerator to enumerate through all objects of the
 *	  array.
 *
 * @returns An OFEnumerator to enumerate through all objects of the array
 */
- (OFEnumerator OF_GENERIC(ObjectType)*)objectEnumerator;
- (OFEnumerator OF_GENERIC(ObjectType) *)objectEnumerator;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Executes a block for each object.
 *
 * @param block The block to execute for each object
 */
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block;

/*!
 * @brief Creates a new array, mapping each object using the specified block.
 *
 * @param block A block which maps an object for each object
 * @return A new, autoreleased OFArray
 */
- (OFArray*)mappedArrayUsingBlock: (of_array_map_block_t)block;
- (OFArray *)mappedArrayUsingBlock: (of_array_map_block_t)block;

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

/*!
 * @brief Folds the array to a single object using the specified block.
 *
 * If the array is empty, it will return `nil`.
 *
492
493
494
495
496
497
498
499

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

499
500
501
502
503
504
505
506
507
508
509
510







-
+











	OFArray	      *_array;
	size_t	      _count;
	unsigned long _mutations;
	unsigned long *_mutationsPtr;
	size_t	      _position;
}

- initWithArray: (OFArray*)data
- initWithArray: (OFArray *)data
   mutationsPtr: (unsigned long *_Nullable)mutationsPtr;
@end

OF_ASSUME_NONNULL_END

#import "OFMutableArray.h"

#if !defined(NSINTEGER_DEFINED) && !__has_feature(modules)
/* Required for array literals to work */
@compatibility_alias NSArray OFArray;
#endif

Modified src/OFArray.m from [5b8c0b589b] to [acebabe718].

34
35
36
37
38
39
40
41
42


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


41
42
43
44
45
46
47
48
49







-
-
+
+







#import "OFOutOfRangeException.h"

static struct {
	Class isa;
} placeholder;

@interface OFArray ()
- (OFString*)OF_JSONRepresentationWithOptions: (int)options
					depth: (size_t)depth;
- (OFString *)OF_JSONRepresentationWithOptions: (int)options
					 depth: (size_t)depth;
@end

@interface OFArray_placeholder: OFArray
@end

@implementation OFArray_placeholder
- init
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
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







-
+




-
+






-
+







- initWithObject: (id)firstObject
       arguments: (va_list)arguments
{
	return (id)[[OFArray_adjacent alloc] initWithObject: firstObject
						  arguments: arguments];
}

- initWithArray: (OFArray*)array
- initWithArray: (OFArray *)array
{
	return (id)[[OFArray_adjacent alloc] initWithArray: array];
}

- initWithObjects: (id const*)objects
- initWithObjects: (id const *)objects
	    count: (size_t)count
{
	return (id)[[OFArray_adjacent alloc] initWithObjects: objects
						       count: count];
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFArray_adjacent alloc] initWithSerialization: element];
}

- retain
{
	return self;
147
148
149
150
151
152
153
154

155
156
157
158
159

160
161
162
163
164
165
166
147
148
149
150
151
152
153

154
155
156
157
158

159
160
161
162
163
164
165
166







-
+




-
+







	ret = [[[self alloc] initWithObject: firstObject
				  arguments: arguments] autorelease];
	va_end(arguments);

	return ret;
}

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

+ (instancetype)arrayWithObjects: (id const*)objects
+ (instancetype)arrayWithObjects: (id const *)objects
			   count: (size_t)count
{
	return [[[self alloc] initWithObjects: objects
					count: count] autorelease];
}

- init
204
205
206
207
208
209
210
211

212
213
214
215
216

217
218
219
220
221
222

223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239

240
241
242
243
244
245
246
204
205
206
207
208
209
210

211
212
213
214
215

216
217
218
219
220
221

222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238

239
240
241
242
243
244
245
246







-
+




-
+





-
+









-
+






-
+








- initWithObject: (id)firstObject
       arguments: (va_list)arguments
{
	OF_INVALID_INIT_METHOD
}

- initWithArray: (OFArray*)array
- initWithArray: (OFArray *)array
{
	OF_INVALID_INIT_METHOD
}

- initWithObjects: (id const*)objects
- initWithObjects: (id const *)objects
	    count: (size_t)count
{
	OF_INVALID_INIT_METHOD
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	OF_INVALID_INIT_METHOD
}

- (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)getObjects: (id*)buffer
- (void)getObjects: (id *)buffer
	   inRange: (of_range_t)range
{
	for (size_t i = 0; i < range.length; i++)
		buffer[i] = [self objectAtIndex: range.location + i];
}

- (id const*)objects
- (id const *)objects
{
	OFObject *container;
	size_t count;
	id *buffer;

	container = [[[OFObject alloc] init] autorelease];
	count = [self count];
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283







-
+







}

- (id)objectAtIndexedSubscript: (size_t)index
{
	return [self objectAtIndex: index];
}

- (id)valueForKey: (OFString*)key
- (id)valueForKey: (OFString *)key
{
	OFMutableArray *ret;

	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();
		id ret;

302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316







-
+








	[ret makeImmutable];

	return ret;
}

- (void)setValue: (id)value
	  forKey: (OFString*)key
	  forKey: (OFString *)key
{
	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();

		key = [key substringWithRange: of_range(1, [key length] - 1)];
		[super setValue: value
			 forKey: key];
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399







-
+








	if (count > 0)
		return [self objectAtIndex: count - 1];

	return nil;
}

- (OFArray*)objectsInRange: (of_range_t)range
- (OFArray *)objectsInRange: (of_range_t)range
{
	OFArray *ret;
	id *buffer;

	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length < [self count])
		@throw [OFOutOfRangeException exception];
414
415
416
417
418
419
420
421

422
423
424
425
426
427
428
429


430
431
432
433
434
435
436
437


438
439
440
441
442
443
444
445
446



447
448
449
450
451
452
453
414
415
416
417
418
419
420

421
422
423
424
425
426
427


428
429
430
431
432
433
434
435


436
437
438
439
440
441
442
443



444
445
446
447
448
449
450
451
452
453







-
+






-
-
+
+






-
-
+
+






-
-
-
+
+
+







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

	return ret;
}

- (OFString*)componentsJoinedByString: (OFString*)separator
- (OFString *)componentsJoinedByString: (OFString *)separator
{
	return [self componentsJoinedByString: separator
				usingSelector: @selector(description)
				      options: 0];
}

- (OFString*)componentsJoinedByString: (OFString*)separator
			      options: (int)options
- (OFString *)componentsJoinedByString: (OFString *)separator
			       options: (int)options
{
	return [self componentsJoinedByString: separator
				usingSelector: @selector(description)
				      options: options];
}

- (OFString*)componentsJoinedByString: (OFString*)separator
			usingSelector: (SEL)selector
- (OFString *)componentsJoinedByString: (OFString *)separator
			 usingSelector: (SEL)selector
{
	return [self componentsJoinedByString: separator
				usingSelector: selector
				      options: 0];
}

- (OFString*)componentsJoinedByString: (OFString*)separator
			usingSelector: (SEL)selector
			      options: (int)options
- (OFString *)componentsJoinedByString: (OFString *)separator
			 usingSelector: (SEL)selector
			       options: (int)options
{
	OFMutableString *ret;

	if (separator == nil)
		@throw [OFInvalidArgumentException exception];

	if ([self count] == 0)
527
528
529
530
531
532
533
534

535
536
537
538
539
540
541
527
528
529
530
531
532
533

534
535
536
537
538
539
540
541







-
+







		OF_HASH_ADD_HASH(hash, [object hash]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

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

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

555
556
557
558
559
560
561
562

563
564
565
566
567
568
569
555
556
557
558
559
560
561

562
563
564
565
566
567
568
569







-
+







	objc_autoreleasePoolPop(pool);

	[ret makeImmutable];

	return [ret autorelease];
}

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

	if ([self isKindOfClass: [OFMutableArray class]])
		element = [OFXMLElement elementWithName: @"OFMutableArray"
					      namespace: OF_SERIALIZATION_NS];
582
583
584
585
586
587
588
589

590
591
592
593
594
595

596
597
598
599
600
601
602


603
604
605
606
607
608
609
582
583
584
585
586
587
588

589
590
591
592
593
594

595
596
597
598
599
600


601
602
603
604
605
606
607
608
609







-
+





-
+





-
-
+
+







	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (OFString*)JSONRepresentation
- (OFString *)JSONRepresentation
{
	return [self OF_JSONRepresentationWithOptions: 0
						depth: 0];
}

- (OFString*)JSONRepresentationWithOptions: (int)options
- (OFString *)JSONRepresentationWithOptions: (int)options
{
	return [self OF_JSONRepresentationWithOptions: options
						depth: 0];
}

- (OFString*)OF_JSONRepresentationWithOptions: (int)options
					depth: (size_t)depth
- (OFString *)OF_JSONRepresentationWithOptions: (int)options
					 depth: (size_t)depth
{
	OFMutableString *JSON = [OFMutableString stringWithString: @"["];
	void *pool = objc_autoreleasePoolPush();
	size_t i, count = [self count];

	if (options & OF_JSON_REPRESENTATION_PRETTY) {
		OFMutableString *indentation = [OFMutableString string];
652
653
654
655
656
657
658
659

660
661
662
663
664
665
666
652
653
654
655
656
657
658

659
660
661
662
663
664
665
666







-
+







	[JSON makeImmutable];

	objc_autoreleasePoolPop(pool);

	return JSON;
}

- (OFDataArray*)messagePackRepresentation
- (OFDataArray *)messagePackRepresentation
{
	OFDataArray *data;
	size_t i, count;
	void *pool;

	data = [OFDataArray dataArray];
	count = [self count];
718
719
720
721
722
723
724
725

726
727
728
729
730
731
732
733
734
735
736

737
738
739
740
741
742
743
744
745
746
747

748
749
750
751
752
753
754
755
756
757
758
759


760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778

779
780
781
782
783

784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804

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

820
821
822
823
824
825
826
827
828
829

830
831
832
833
834
835
836
837
838
839
840

841
842
843
844
845
846
847
718
719
720
721
722
723
724

725
726
727
728
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743
744
745
746

747
748
749
750
751
752
753
754
755
756
757


758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777

778
779
780
781
782

783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803

804
805
806
807
808
809
810
811
812
813
814
815
816
817
818

819
820
821
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836
837
838
839

840
841
842
843
844
845
846
847







-
+










-
+










-
+










-
-
+
+


















-
+




-
+




















-
+














-
+









-
+










-
+







			withObject: (id)object
{
	for (id object in self)
		[object performSelector: selector
			     withObject: object];
}

- (OFArray*)sortedArray
- (OFArray *)sortedArray
{
	OFMutableArray *new = [[self mutableCopy] autorelease];

	[new sort];

	[new makeImmutable];

	return new;
}

- (OFArray*)sortedArrayWithOptions: (int)options
- (OFArray *)sortedArrayWithOptions: (int)options
{
	OFMutableArray *new = [[self mutableCopy] autorelease];

	[new sortWithOptions: options];

	[new makeImmutable];

	return new;
}

- (OFArray*)reversedArray
- (OFArray *)reversedArray
{
	OFMutableArray *new = [[self mutableCopy] autorelease];

	[new reverse];

	[new makeImmutable];

	return new;
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state
			   objects: (id *)objects
			     count: (int)count
{
	of_range_t range = of_range(state->state, count);

	if (range.length > SIZE_MAX - range.location)
		@throw [OFOutOfRangeException exception];

	if (range.location + range.length > [self count])
		range.length = [self count] - range.location;

	[self getObjects: objects
		 inRange: range];

	if (range.location + range.length > ULONG_MAX)
		@throw [OFOutOfRangeException exception];

	state->state = (unsigned long)(range.location + range.length);
	state->itemsPtr = objects;
	state->mutationsPtr = (unsigned long*)self;
	state->mutationsPtr = (unsigned long *)self;

	return (int)range.length;
}

- (OFEnumerator*)objectEnumerator
- (OFEnumerator *)objectEnumerator
{
	return [[[OFArrayEnumerator alloc] initWithArray: self
					    mutationsPtr: NULL] autorelease];
}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
	size_t i = 0;
	bool stop = false;

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

		if (stop)
			break;
	}
}
#endif

- (OFArray*)arrayByAddingObject: (id)object
- (OFArray *)arrayByAddingObject: (id)object
{
	OFMutableArray *ret;

	if (object == nil)
		@throw [OFInvalidArgumentException exception];

	ret = [[self mutableCopy] autorelease];

	[ret addObject: object];
	[ret makeImmutable];

	return ret;
}

- (OFArray*)arrayByAddingObjectsFromArray: (OFArray*)array
- (OFArray *)arrayByAddingObjectsFromArray: (OFArray *)array
{
	OFMutableArray *ret = [[self mutableCopy] autorelease];

	[ret addObjectsFromArray: array];
	[ret makeImmutable];

	return ret;
}

- (OFArray*)arrayByRemovingObject: (id)object
- (OFArray *)arrayByRemovingObject: (id)object
{
	OFMutableArray *ret = [[self mutableCopy] autorelease];

	[ret removeObject: object];
	[ret makeImmutable];

	return ret;
}

#ifdef OF_HAVE_BLOCKS
- (OFArray*)mappedArrayUsingBlock: (of_array_map_block_t)block
- (OFArray *)mappedArrayUsingBlock: (of_array_map_block_t)block
{
	OFArray *ret;
	size_t count = [self count];
	id *tmp = [self allocMemoryWithSize: sizeof(id)
				      count: count];

	@try {
855
856
857
858
859
860
861
862

863
864
865
866
867
868
869
855
856
857
858
859
860
861

862
863
864
865
866
867
868
869







-
+







	} @finally {
		[self freeMemory: tmp];
	}

	return ret;
}

- (OFArray*)filteredArrayUsingBlock: (of_array_filter_block_t)block
- (OFArray *)filteredArrayUsingBlock: (of_array_filter_block_t)block
{
	OFArray *ret;
	size_t count = [self count];
	id *tmp = [self allocMemoryWithSize: sizeof(id)
				      count: count];

	@try {
913
914
915
916
917
918
919
920
921


922
923
924
925
926
927
928
913
914
915
916
917
918
919


920
921
922
923
924
925
926
927
928







-
-
+
+








	return [current autorelease];
}
#endif
@end

@implementation OFArrayEnumerator
- initWithArray: (OFArray*)array
   mutationsPtr: (unsigned long*)mutationsPtr
- initWithArray: (OFArray *)array
   mutationsPtr: (unsigned long *)mutationsPtr
{
	self = [super init];

	_array = [array retain];
	_count = [array count];
	_mutations = (mutationsPtr != NULL ? *mutationsPtr : 0);
	_mutationsPtr = mutationsPtr;

Modified src/OFArray_adjacent.m from [d6653b4737] to [8a91f0e096].

81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95







-
+







		[self release];
		@throw e;
	}

	return self;
}

- initWithArray: (OFArray*)array
- initWithArray: (OFArray *)array
{
	id const *objects;
	size_t count;

	self = [super init];

	if (array == nil)
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137







-
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		bool ok = true;

154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168







-
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		void *pool = objc_autoreleasePoolPush();

		if ((![[element name] isEqual: @"OFArray"] &&
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206

207
208
209
210
211

212
213
214

215
216
217
218
219
220
221
192
193
194
195
196
197
198

199
200
201
202
203
204
205

206
207
208
209
210

211
212
213

214
215
216
217
218
219
220
221







-
+






-
+




-
+


-
+







}

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

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

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

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

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

	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > count)
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280







-
+







-
+







		if (objects[i] == object)
			return i;

	return OF_NOT_FOUND;
}


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

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

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

- (bool)isEqual: (id)object
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
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







-
-
+
+


















-
+







		OF_HASH_ADD_HASH(hash, [objects[i] hash]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state
			   objects: (id *)objects
			     count: (int)count_
{
	size_t count = [_array count];

	if (count > INT_MAX)
		/*
		 * Use the implementation from OFArray, which is slower, but can
		 * enumerate in chunks.
		 */
		return [super countByEnumeratingWithState: state
						  objects: objects
						    count: count_];

	if (state->state >= count)
		return 0;

	state->state = (unsigned long)count;
	state->itemsPtr = [_array items];
	state->mutationsPtr = (unsigned long*)self;
	state->mutationsPtr = (unsigned long *)self;

	return (int)count;
}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{

Modified src/OFArray_adjacentSubarray.m from [50efd5ea53] to [d63ca8de44].

17
18
19
20
21
22
23
24

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

24
25
26
27
28
29
30
31







-
+







#include "config.h"

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

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

- (bool)isEqual: (id)object
{
	OFArray *otherArray;

Modified src/OFArray_subarray.h from [fb06afe382] to [716934f439].

20
21
22
23
24
25
26
27

28
29

30
31
32
33
20
21
22
23
24
25
26

27
28

29
30
31
32
33







-
+

-
+





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

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

OF_ASSUME_NONNULL_END

Modified src/OFArray_subarray.m from [bf40b440c5] to [b087bc3ca0].

17
18
19
20
21
22
23
24

25
26
27
28
29
30
31

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

24
25
26
27
28
29
30

31
32
33
34
35
36
37
38







-
+






-
+







#include "config.h"

#import "OFArray_subarray.h"

#import "OFOutOfRangeException.h"

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

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

	@try {
		/* Should usually be retain, as it's useless with a copy */
		_array = [array copy];
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75







-
+







{
	if (index >= _range.length)
		@throw [OFOutOfRangeException exception];

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

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

	range.location += _range.location;
104
105
106
107
108
109
110
111

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

111
112
113
114
115
116
117
118
119
120
121







-
+











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

	return index;
}

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

	range.location += _range.location;

	return [_array objectsInRange: range];
}
@end

Modified src/OFAutoreleasePool.m from [88fd4d2a1a] to [d441366c61].

140
141
142
143
144
145
146
147

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

147
148
149
150
151
152
153
154







-
+







		return;

	_ignoreRelease = true;

	objc_autoreleasePoolPop(_pool);

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

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

Modified src/OFBigDataArray.m from [2fc9519558] to [13f7d8fe72].

67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81







-
+







		[self release];
		@throw e;
	}

	return self;
}

- (void)addItem: (const void*)item
- (void)addItem: (const void *)item
{
	if (SIZE_MAX - _count < 1 || _count + 1 > SIZE_MAX / _itemSize)
		@throw [OFOutOfRangeException exception];

	if (_count + 1 > _capacity) {
		size_t size, pageSize;

90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104







-
+







	}

	memcpy(_items + _count * _itemSize, item, _itemSize);

	_count++;
}

- (void)addItems: (const void*)items
- (void)addItems: (const void *)items
	   count: (size_t)count
{
	if (count > SIZE_MAX - _count || _count + count > SIZE_MAX / _itemSize)
		@throw [OFOutOfRangeException exception];

	if (_count + count > _capacity) {
		size_t size, pageSize;
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128







-
+







	}

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

	_count += count;
}

- (void)insertItems: (const void*)items
- (void)insertItems: (const void *)items
	    atIndex: (size_t)index
	      count: (size_t)count
{
	if (count > SIZE_MAX - _count || index > _count ||
	    _count + count > SIZE_MAX / _itemSize)
		@throw [OFOutOfRangeException exception];

Modified src/OFBlock.m from [067d5d407d] to [48fc4cece6].

39
40
41
42
43
44
45
46

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

46
47
48
49
50
51
52
53







-
+







typedef struct of_block_byref_t of_block_byref_t;
struct of_block_byref_t {
	Class isa;
	of_block_byref_t *forwarding;
	int flags;
	int size;
	void (*byref_keep)(void *dest, void *src);
	void (*byref_dispose)(void*);
	void (*byref_dispose)(void *);
};

enum {
	OF_BLOCK_HAS_COPY_DISPOSE = (1 << 25),
	OF_BLOCK_HAS_CTOR	  = (1 << 26),
	OF_BLOCK_IS_GLOBAL	  = (1 << 28),
	OF_BLOCK_HAS_STRET	  = (1 << 29),
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
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







-
-
+
+



-
-
+
+



-
-
+
+








-
-
+
+







- retain;
- (void)release;
@end

#ifdef OF_OBJFW_RUNTIME
/* Begin of ObjC module */
static struct objc_abi_class _NSConcreteStackBlock_metaclass = {
	(struct objc_abi_class*)(void*)"OFBlock", "OFBlock", "OFStackBlock", 8,
	OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_abi_class), NULL, NULL
	(struct objc_abi_class *)(void *)"OFBlock", "OFBlock", "OFStackBlock",
	8, OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_abi_class), NULL, NULL
};

struct objc_abi_class _NSConcreteStackBlock = {
	&_NSConcreteStackBlock_metaclass, "OFBlock", "OFStackBlock", 8,
	OBJC_CLASS_INFO_CLASS, sizeof(of_block_literal_t), NULL, NULL
	&_NSConcreteStackBlock_metaclass, "OFBlock", "OFStackBlock",
	8, OBJC_CLASS_INFO_CLASS, sizeof(of_block_literal_t), NULL, NULL
};

static struct objc_abi_class _NSConcreteGlobalBlock_metaclass = {
	(struct objc_abi_class*)(void*)"OFBlock", "OFBlock", "OFGlobalBlock", 8,
	OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_abi_class), NULL, NULL
	(struct objc_abi_class *)(void *)"OFBlock", "OFBlock", "OFGlobalBlock",
	8, OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_abi_class), NULL, NULL
};

struct objc_abi_class _NSConcreteGlobalBlock = {
	&_NSConcreteGlobalBlock_metaclass, "OFBlock", "OFGlobalBlock",
	8, OBJC_CLASS_INFO_CLASS, sizeof(of_block_literal_t), NULL, NULL
};

static struct objc_abi_class _NSConcreteMallocBlock_metaclass = {
	(struct objc_abi_class*)(void*)"OFBlock", "OFBlock", "OFMallocBlock", 8,
	OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_abi_class), NULL, NULL
	(struct objc_abi_class *)(void *)"OFBlock", "OFBlock", "OFMallocBlock",
	8, OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_abi_class), NULL, NULL
};

struct objc_abi_class _NSConcreteMallocBlock = {
	&_NSConcreteMallocBlock_metaclass, "OFBlock", "OFMallocBlock",
	8, OBJC_CLASS_INFO_CLASS, sizeof(of_block_literal_t), NULL, NULL
};

110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133







-
+








-
+







	{
		&_NSConcreteStackBlock, &_NSConcreteGlobalBlock,
		&_NSConcreteMallocBlock, NULL
	}
};

static struct objc_abi_module module = {
	8, sizeof(module), NULL, (struct objc_abi_symtab*)&symtab
	8, sizeof(module), NULL, (struct objc_abi_symtab *)&symtab
};

OF_CONSTRUCTOR()
{
	__objc_exec_class(&module);
}
/* End of ObjC module */
#elif defined(OF_APPLE_RUNTIME)
extern Class objc_initializeClassPair(Class, const char*, Class, Class);
extern Class objc_initializeClassPair(Class, const char *, Class, Class);

struct class {
	struct class *isa, *super_class;
	const char *name;
	long version, info, instance_size;
	struct ivar_list *ivars;
	struct method_list **methodLists;
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
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







-
+


-
+







-
+
+







#ifndef OF_HAVE_ATOMIC_OPS
# define NUM_SPINLOCKS 8	/* needs to be a power of 2 */
# define SPINLOCK_HASH(p) ((uintptr_t)p >> 4) & (NUM_SPINLOCKS - 1)
static of_spinlock_t blockSpinlocks[NUM_SPINLOCKS];
static of_spinlock_t byrefSpinlocks[NUM_SPINLOCKS];
#endif

void*
void *
_Block_copy(const void *block_)
{
	of_block_literal_t *block = (of_block_literal_t*)block_;
	of_block_literal_t *block = (of_block_literal_t *)block_;

	if (object_getClass((id)block) == (Class)&_NSConcreteStackBlock) {
		of_block_literal_t *copy;

		if ((copy = malloc(block->descriptor->size)) == NULL) {
			alloc_failed_exception.isa =
			    [OFAllocFailedException class];
			@throw (OFAllocFailedException*)&alloc_failed_exception;
			@throw (OFAllocFailedException *)
			    &alloc_failed_exception;
		}
		memcpy(copy, block, block->descriptor->size);

		object_setClass((id)copy, (Class)&_NSConcreteMallocBlock);
		copy->flags++;

		if (block->flags & OF_BLOCK_HAS_COPY_DISPOSE)
196
197
198
199
200
201
202
203

204
205
206
207
208
209
210
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211







-
+








	return block;
}

void
_Block_release(const void *block_)
{
	of_block_literal_t *block = (of_block_literal_t*)block_;
	of_block_literal_t *block = (of_block_literal_t *)block_;

	if (object_getClass((id)block) != (Class)&_NSConcreteMallocBlock)
		return;

#ifdef OF_HAVE_ATOMIC_OPS
	if ((of_atomic_int_dec(&block->flags) & OF_BLOCK_REFCOUNT_MASK) == 0) {
		if (block->flags & OF_BLOCK_HAS_COPY_DISPOSE)
237
238
239
240
241
242
243
244

245
246
247
248

249
250
251
252


253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
238
239
240
241
242
243
244

245
246
247
248

249
250
251


252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281







-
+



-
+


-
-
+
+







-
+












-
+







	    OF_BLOCK_FIELD_IS_OBJECT | OF_BLOCK_FIELD_IS_BYREF);

	if (src_ == NULL)
		return;

	switch (flags) {
	case OF_BLOCK_FIELD_IS_BLOCK:
		*(of_block_literal_t**)dst_ = _Block_copy(src_);
		*(of_block_literal_t **)dst_ = _Block_copy(src_);
		break;
	case OF_BLOCK_FIELD_IS_OBJECT:
		if (!(flags_ & OF_BLOCK_BYREF_CALLER))
			*(id*)dst_ = [(id)src_ retain];
			*(id *)dst_ = [(id)src_ retain];
		break;
	case OF_BLOCK_FIELD_IS_BYREF:;
		of_block_byref_t *src = (of_block_byref_t*)src_;
		of_block_byref_t **dst = (of_block_byref_t**)dst_;
		of_block_byref_t *src = (of_block_byref_t *)src_;
		of_block_byref_t **dst = (of_block_byref_t **)dst_;

		src = src->forwarding;

		if ((src->flags & OF_BLOCK_REFCOUNT_MASK) == 0) {
			if ((*dst = malloc(src->size)) == NULL) {
				alloc_failed_exception.isa =
				    [OFAllocFailedException class];
				@throw (OFAllocFailedException*)
				@throw (OFAllocFailedException *)
				    &alloc_failed_exception;
			}

			memcpy(*dst, src, src->size);
			(*dst)->flags =
			    ((*dst)->flags & ~OF_BLOCK_REFCOUNT_MASK) | 1;
			(*dst)->forwarding = *dst;

			if (src->flags & OF_BLOCK_HAS_COPY_DISPOSE)
				src->byref_keep(*dst, src);

#ifdef OF_HAVE_ATOMIC_OPS
			if (!of_atomic_ptr_cmpswap((void**)&src->forwarding,
			if (!of_atomic_ptr_cmpswap((void **)&src->forwarding,
			    src, *dst)) {
				src->byref_dispose(*dst);
				free(*dst);

				*dst = src->forwarding;
			}
#else
321
322
323
324
325
326
327
328

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

329
330
331
332
333
334
335
336







-
+







		_Block_release(obj_);
		break;
	case OF_BLOCK_FIELD_IS_OBJECT:
		if (!(flags_ & OF_BLOCK_BYREF_CALLER))
			[(id)obj_ release];
		break;
	case OF_BLOCK_FIELD_IS_BYREF:;
		of_block_byref_t *obj = (of_block_byref_t*)obj_;
		of_block_byref_t *obj = (of_block_byref_t *)obj_;

		obj = obj->forwarding;

#ifdef OF_HAVE_ATOMIC_OPS
		if ((of_atomic_int_dec(&obj->flags) &
		    OF_BLOCK_REFCOUNT_MASK) == 0) {
			if (obj->flags & OF_BLOCK_HAS_COPY_DISPOSE)
430
431
432
433
434
435
436
437







438
439
440
441
442
443


444
445
446
447
448
449



450
451
452
453
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446
447
448


449
450
451
452
453
454


455
456
457
458
459
460
461








462
463
464
465
466
467
468
469







-
+
+
+
+
+
+
+




-
-
+
+




-
-
+
+
+




-
-
-
-
-
-
-
-
+







}

- init
{
	OF_INVALID_INIT_METHOD
}

- (void*)allocMemoryWithSize: (size_t)size
- (void *)allocMemoryWithSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)allocMemoryWithSize: (size_t)size
			count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)allocMemoryWithSize: (size_t)size
		       count: (size_t)count
- (void *)resizeMemory: (void *)ptr
		  size: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)resizeMemory: (void*)ptr
		 size: (size_t)size
- (void *)resizeMemory: (void *)ptr
		  size: (size_t)size
		 count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)resizeMemory: (void*)ptr
		 size: (size_t)size
		count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)freeMemory: (void*)ptr
- (void)freeMemory: (void *)ptr
{
	OF_UNRECOGNIZED_SELECTOR
}

- retain
{
	if (object_getClass(self) == (Class)&_NSConcreteMallocBlock)
483
484
485
486
487
488
489
490

491
492
493
494
495
496
497
484
485
486
487
488
489
490

491
492
493
494
495
496
497
498







-
+








	return self;
}

- (unsigned int)retainCount
{
	if (object_getClass(self) == (Class)&_NSConcreteMallocBlock)
		return ((of_block_literal_t*)self)->flags &
		return ((of_block_literal_t *)self)->flags &
		    OF_BLOCK_REFCOUNT_MASK;

	return OF_RETAIN_COUNT_MAX;
}

- (void)release
{

Modified src/OFCondition.h from [16117b4325] to [6e7cc3def8].

65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
65
66
67
68
69
70
71

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







-
+













 *
 * @note Waiting might have been interrupted by a signal. It is thus recommended
 *	 to check the condition again after @ref waitUntilDate: returned!
 *
 * @param date The date at which the timeout is reached
 * @return Whether the condition has been signaled
 */
- (bool)waitUntilDate: (OFDate*)date;
- (bool)waitUntilDate: (OFDate *)date;

/*!
 * @brief Signals the next waiting thread to continue.
 */
- (void)signal;

/*!
 * @brief Signals all threads to continue.
 */
- (void)broadcast;
@end

OF_ASSUME_NONNULL_END

Modified src/OFCondition.m from [d93a5c097f] to [c3c05a120f].

64
65
66
67
68
69
70
71

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

71
72
73
74
75
76
77
78







-
+







}

- (bool)waitForTimeInterval: (of_time_interval_t)timeInterval
{
	return of_condition_timed_wait(&_condition, &_mutex, timeInterval);
}

- (bool)waitUntilDate: (OFDate*)date
- (bool)waitUntilDate: (OFDate *)date
{
	return of_condition_timed_wait(&_condition, &_mutex,
	    [date timeIntervalSinceNow]);
}

- (void)signal
{

Modified src/OFConstantString.m from [5483ae8a87] to [606ccc29ff].

50
51
52
53
54
55
56
57







58
59
60
61
62
63


64
65
66
67
68
69



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

82
83
84
85
86
87
88
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67


68
69
70
71
72
73


74
75
76
77
78
79
80








81
82
83
84
85
86
87
88







-
+
+
+
+
+
+
+




-
-
+
+




-
-
+
+
+




-
-
-
-
-
-
-
-
+







@implementation OFString_const
+ alloc
{
	OF_UNRECOGNIZED_SELECTOR
}


- (void*)allocMemoryWithSize: (size_t)size
- (void *)allocMemoryWithSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)allocMemoryWithSize: (size_t)size
			count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)allocMemoryWithSize: (size_t)size
		       count: (size_t)count
- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)resizeMemory: (void*)pointer
		 size: (size_t)size
- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
		 count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)resizeMemory: (void*)pointer
		 size: (size_t)size
		count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)freeMemory: (void*)pointer
- (void)freeMemory: (void *)pointer
{
	OF_UNRECOGNIZED_SELECTOR
}

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







-
+









-
+
+
+
+
+
+
+




-
-
+
+




-
-
+
+
+




-
-
-
-
-
-
-
-
+







				ivars->isUTF8 = true;
				break;
			case -1:
				free(ivars);
				@throw [OFInvalidEncodingException exception];
		}

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

+ alloc
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)allocMemoryWithSize: (size_t)size
- (void *)allocMemoryWithSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)allocMemoryWithSize: (size_t)size
			count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)allocMemoryWithSize: (size_t)size
		       count: (size_t)count
- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)resizeMemory: (void*)pointer
		 size: (size_t)size
- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
		 count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)resizeMemory: (void*)pointer
		 size: (size_t)size
		count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)freeMemory: (void*)pointer
- (void)freeMemory: (void *)pointer
{
	OF_UNRECOGNIZED_SELECTOR
}

- retain
{
	return self;
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278

279
280
281
282
283
284
285

286
287
288
289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277

278
279
280
281
282
283
284

285
286
287
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
303







-
+







-
+






-
+










-
+







- (uint32_t)hash
{
	[self finishInitialization];

	return [self hash];
}

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

	return [self description];
}

/* From OFString */
- (const char*)UTF8String
- (const char *)UTF8String
{
	[self finishInitialization];

	return [self UTF8String];
}

- (size_t)getCString: (char*)cString_
- (size_t)getCString: (char *)cString_
	   maxLength: (size_t)maxLength
	    encoding: (of_string_encoding_t)encoding
{
	[self finishInitialization];

	return [self getCString: cString_
		      maxLength: maxLength
		       encoding: encoding];
}

- (const char*)cStringWithEncoding: (of_string_encoding_t)encoding
- (const char *)cStringWithEncoding: (of_string_encoding_t)encoding
{
	[self finishInitialization];

	return [self cStringWithEncoding: encoding];
}

- (size_t)length
317
318
319
320
321
322
323
324

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

339
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354

355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381

382
383
384
385
386
387
388

389
390
391
392
393
394
395
396


397
398
399
400
401
402
403
404

405
406
407
408
409
410
411

412
413
414
415
416
417
418
419


420
421
422
423
424
425
426
427
428
429
430




431
432
433
434
435
436
437
438
439
440

441
442
443
444
445
446
447

448
449
450
451
452
453
454

455
456
457
458
459
460
461

462
463
464
465
466
467
468

469
470
471
472
473
474
475

476
477
478
479
480
481
482

483
484
485
486
487
488
489

490
491
492
493
494
495
496

497
498
499
500
501
502
503
504


505
506
507
508
509
510
511
512

513
514
515
516
517
518
519

520
521
522
523
524
525
526

527
528
529
530
531
532
533
317
318
319
320
321
322
323

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

338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
372
373

374
375
376
377
378
379
380

381
382
383
384
385
386
387

388
389
390
391
392
393
394


395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410

411
412
413
414
415
416
417


418
419
420
421
422
423
424
425
426




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

440
441
442
443
444
445
446

447
448
449
450
451
452
453

454
455
456
457
458
459
460

461
462
463
464
465
466
467

468
469
470
471
472
473
474

475
476
477
478
479
480
481

482
483
484
485
486
487
488

489
490
491
492
493
494
495

496
497
498
499
500
501
502


503
504
505
506
507
508
509
510
511

512
513
514
515
516
517
518

519
520
521
522
523
524
525

526
527
528
529
530
531
532
533







-
+













-
+








-
+






-
+








-
+










-
+






-
+






-
+






-
-
+
+







-
+






-
+






-
-
+
+







-
-
-
-
+
+
+
+









-
+






-
+






-
+






-
+






-
+






-
+






-
+






-
+






-
+






-
-
+
+







-
+






-
+






-
+







- (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding
{
	[self finishInitialization];

	return [self cStringLengthWithEncoding: encoding];
}

- (of_comparison_result_t)caseInsensitiveCompare: (OFString*)otherString
- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)otherString
{
	[self finishInitialization];

	return [self caseInsensitiveCompare: otherString];
}

- (of_unichar_t)characterAtIndex: (size_t)index
{
	[self finishInitialization];

	return [self characterAtIndex: index];
}

- (void)getCharacters: (of_unichar_t*)buffer
- (void)getCharacters: (of_unichar_t *)buffer
	      inRange: (of_range_t)range
{
	[self finishInitialization];

	[self getCharacters: buffer
		    inRange: range];
}

- (of_range_t)rangeOfString: (OFString*)string
- (of_range_t)rangeOfString: (OFString *)string
{
	[self finishInitialization];

	return [self rangeOfString: string];
}

- (of_range_t)rangeOfString: (OFString*)string
- (of_range_t)rangeOfString: (OFString *)string
		    options: (int)options
{
	[self finishInitialization];

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

- (of_range_t)rangeOfString: (OFString*)string
- (of_range_t)rangeOfString: (OFString *)string
		    options: (int)options
		      range: (of_range_t)range
{
	[self finishInitialization];

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

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

	return [self containsString: string];
}

- (OFString*)substringWithRange: (of_range_t)range
- (OFString *)substringWithRange: (of_range_t)range
{
	[self finishInitialization];

	return [self substringWithRange: range];
}

- (OFString*)stringByAppendingString: (OFString*)string
- (OFString *)stringByAppendingString: (OFString *)string
{
	[self finishInitialization];

	return [self stringByAppendingString: string];
}

- (OFString*)stringByAppendingFormat: (OFConstantString*)format
			   arguments: (va_list)arguments
- (OFString *)stringByAppendingFormat: (OFConstantString *)format
			    arguments: (va_list)arguments
{
	[self finishInitialization];

	return [self stringByAppendingFormat: format
				   arguments: arguments];
}

- (OFString*)stringByAppendingPathComponent: (OFString*)component
- (OFString *)stringByAppendingPathComponent: (OFString *)component
{
	[self finishInitialization];

	return [self stringByAppendingPathComponent: component];
}

- (OFString*)stringByPrependingString: (OFString*)string
- (OFString *)stringByPrependingString: (OFString *)string
{
	[self finishInitialization];

	return [self stringByPrependingString: string];
}

- (OFString*)stringByReplacingOccurrencesOfString: (OFString*)string
				       withString: (OFString*)replacement
- (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string
					withString: (OFString *)replacement
{
	[self finishInitialization];

	return [self stringByReplacingOccurrencesOfString: string
					       withString: replacement];
}

- (OFString*)stringByReplacingOccurrencesOfString: (OFString*)string
				       withString: (OFString*)replacement
					  options: (int)options
					    range: (of_range_t)range
- (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string
					withString: (OFString *)replacement
					   options: (int)options
					     range: (of_range_t)range
{
	[self finishInitialization];

	return [self stringByReplacingOccurrencesOfString: string
					       withString: replacement
						  options: options
						    range: range];
}

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

	return [self uppercaseString];
}

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

	return [self lowercaseString];
}

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

	return [self capitalizedString];
}

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

	return [self stringByDeletingLeadingWhitespaces];
}

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

	return [self stringByDeletingTrailingWhitespaces];
}

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

	return [self stringByDeletingEnclosingWhitespaces];
}

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

	return [self hasPrefix: prefix];
}

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

	return [self hasSuffix: suffix];
}

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
- (OFArray *)componentsSeparatedByString: (OFString *)delimiter
{
	[self finishInitialization];

	return [self componentsSeparatedByString: delimiter];
}

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
				options: (int)options
- (OFArray *)componentsSeparatedByString: (OFString *)delimiter
				 options: (int)options
{
	[self finishInitialization];

	return [self componentsSeparatedByString: delimiter
					 options: options];
}

- (OFArray*)pathComponents
- (OFArray *)pathComponents
{
	[self finishInitialization];

	return [self pathComponents];
}

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

	return [self lastPathComponent];
}

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

	return [self stringByDeletingLastPathComponent];
}

- (intmax_t)decimalValue
561
562
563
564
565
566
567
568

569
570
571
572
573
574
575

576
577
578
579
580
581
582

583
584
585
586
587
588
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603

604
605
606
607
608
609
610

611
612
613
614
615
616
617

618
619
620
621
622
623
624
561
562
563
564
565
566
567

568
569
570
571
572
573
574

575
576
577
578
579
580
581

582
583
584
585
586
587
588
589
590
591
592
593
594
595

596
597
598
599
600
601
602

603
604
605
606
607
608
609

610
611
612
613
614
615
616

617
618
619
620
621
622
623
624







-
+






-
+






-
+













-
+






-
+






-
+






-
+







- (double)doubleValue
{
	[self finishInitialization];

	return [self doubleValue];
}

- (const of_unichar_t*)characters
- (const of_unichar_t *)characters
{
	[self finishInitialization];

	return [self characters];
}

- (const of_char16_t*)UTF16String
- (const of_char16_t *)UTF16String
{
	[self finishInitialization];

	return [self UTF16String];
}

- (const of_char16_t*)UTF16StringWithByteOrder: (of_byte_order_t)byteOrder
- (const of_char16_t *)UTF16StringWithByteOrder: (of_byte_order_t)byteOrder
{
	[self finishInitialization];

	return [self UTF16StringWithByteOrder: byteOrder];
}

- (size_t)UTF16StringLength
{
	[self finishInitialization];

	return [self UTF16StringLength];
}

- (const of_char32_t*)UTF32String
- (const of_char32_t *)UTF32String
{
	[self finishInitialization];

	return [self UTF32String];
}

- (const of_char32_t*)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
- (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
{
	[self finishInitialization];

	return [self UTF32StringWithByteOrder: byteOrder];
}

- (void)writeToFile: (OFString*)path
- (void)writeToFile: (OFString *)path
{
	[self finishInitialization];

	[self writeToFile: path];
}

- (void)writeToFile: (OFString*)path
- (void)writeToFile: (OFString *)path
	   encoding: (of_string_encoding_t)encoding
{
	[self finishInitialization];

	[self writeToFile: path
		 encoding: encoding];
}

Modified src/OFCountedSet.h from [f159833e6a] to [e7560cca06].

36
37
38
39
40
41
42
43

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

43
44
45
46
47
48
49
50







-
+







/*!
 * @class OFCountedSet OFCountedSet.h ObjFW/OFCountedSet.h
 *
 * @brief An abstract class for a mutable unordered set of objects, counting how
 *	  often it contains an object.
 */
#ifdef OF_HAVE_GENERICS
@interface OFCountedSet <ObjectType>: OFMutableSet <ObjectType>
@interface OFCountedSet<ObjectType>: OFMutableSet<ObjectType>
#else
# ifndef DOXYGEN
#  define ObjectType id
# endif
@interface OFCountedSet: OFMutableSet
#endif
/*!

Modified src/OFCountedSet.m from [4d6644549a] to [08a16819c3].

33
34
35
36
37
38
39
40

41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

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

78
79
80
81
82
83
84
33
34
35
36
37
38
39

40
41
42
43
44

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

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

77
78
79
80
81
82
83
84







-
+




-
+

















-
+













-
+








@implementation OFCountedSet_placeholder
- init
{
	return (id)[[OFCountedSet_hashtable alloc] init];
}

- initWithSet: (OFSet*)set
- initWithSet: (OFSet *)set
{
	return (id)[[OFCountedSet_hashtable alloc] initWithSet: set];
}

- initWithArray: (OFArray*)array
- initWithArray: (OFArray *)array
{
	return (id)[[OFCountedSet_hashtable alloc] initWithArray: array];
}

- initWithObjects: (id)firstObject, ...
{
	id ret;
	va_list arguments;

	va_start(arguments, firstObject);
	ret = [[OFCountedSet_hashtable alloc] initWithObject: firstObject
						   arguments: arguments];
	va_end(arguments);

	return ret;
}

- initWithObjects: (id const*)objects
- initWithObjects: (id const *)objects
	    count: (size_t)count
{
	return (id)[[OFCountedSet_hashtable alloc] initWithObjects: objects
							     count: count];
}

- initWithObject: (id)firstObject
       arguments: (va_list)arguments
{
	return (id)[[OFCountedSet_hashtable alloc] initWithObject: firstObject
							arguments: arguments];
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFCountedSet_hashtable alloc]
	    initWithSerialization: element];
}

- retain
{
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146







-
+







}

- (size_t)countForObject: (id)object
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFString*)description
- (OFString *)description
{
	OFMutableString *ret;
	void *pool;
	size_t i, count = [self count];

	if (count == 0)
		return @"{()}";
178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192







-
+







}

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

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

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

224
225
226
227
228
229
230
231

232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

252
253
254
255
256

257
258
259
260
261
262
263
224
225
226
227
228
229
230

231
232
233
234
235

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255

256
257
258
259
260
261
262
263







-
+




-
+














-
+




-
+







{
	[self enumerateObjectsUsingBlock: ^ (id object, bool *stop) {
		block(object, [self countForObject: object], stop);
	}];
}
#endif

- (void)minusSet: (OFSet*)set
- (void)minusSet: (OFSet *)set
{
	void *pool = objc_autoreleasePoolPush();

	if ([set isKindOfClass: [OFCountedSet class]]) {
		OFCountedSet *countedSet = (OFCountedSet*)set;
		OFCountedSet *countedSet = (OFCountedSet *)set;

		for (id object in countedSet) {
			size_t count = [countedSet countForObject: object];

			for (size_t i = 0; i < count; i++)
				[self removeObject: object];
		}
	} else
		for (id object in set)
			[self removeObject: object];

	objc_autoreleasePoolPop(pool);
}

- (void)unionSet: (OFSet*)set
- (void)unionSet: (OFSet *)set
{
	void *pool = objc_autoreleasePoolPush();

	if ([set isKindOfClass: [OFCountedSet class]]) {
		OFCountedSet *countedSet = (OFCountedSet*)set;
		OFCountedSet *countedSet = (OFCountedSet *)set;

		for (id object in countedSet) {
			size_t count = [countedSet countForObject: object];

			for (size_t i = 0; i < count; i++)
				[self addObject: object];
		}

Modified src/OFCountedSet_hashtable.m from [43de300ded] to [b91174aa25].

32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54







-
+







-
+







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

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

	@try {
		void *pool = objc_autoreleasePoolPush();

		if ([set isKindOfClass: [OFCountedSet class]]) {
			OFCountedSet *countedSet = (OFCountedSet*)countedSet;
			OFCountedSet *countedSet = (OFCountedSet *)countedSet;

			for (id object in countedSet) {
				size_t count =
				    [countedSet countForObject: object];

				for (size_t i = 0; i < count; i++)
					[self addObject: object];
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
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







-
+

















-
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		id const *objects = [array objects];
		size_t count = [array count];

		for (size_t i = 0; i < count; i++)
			[self addObject: objects[i]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		for (size_t i = 0; i < count; i++)
			[self addObject: objects[i]];
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130







-
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		void *pool = objc_autoreleasePoolPush();

		if (![[element name] isEqual: @"OFCountedSet"] ||
144
145
146
147
148
149
150
151

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

151
152
153
154
155
156
157
158







-
+







			count_ = [objectElement attributeForName: @"count"];

			if (object == nil || count_ == nil)
				@throw [OFInvalidFormatException exception];

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

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

			objc_autoreleasePoolPop(pool2);
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217







-
+













-
+









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

	if (SIZE_MAX - count < 1 || UINTPTR_MAX - count < 1)
		@throw [OFOutOfRangeException exception];

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

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

	if (count == 0)
		return;

	count--;

	if (count > 0)
		[_mapTable setObject: (void*)(uintptr_t)count
		[_mapTable setObject: (void *)(uintptr_t)count
			      forKey: object];
	else
		[_mapTable removeObjectForKey: object];
}

- (void)makeImmutable
{
}
@end

Modified src/OFCryptoHash.h from [14a9d18645] to [fb07c27325].

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







-
+










-
+













/*!
 * @brief Adds a buffer to the cryptographic hash to be calculated.
 *
 * @param buffer The buffer which should be included into the calculation
 * @param length The length of the buffer
 */
- (void)updateWithBuffer: (const void*)buffer
- (void)updateWithBuffer: (const void *)buffer
		  length: (size_t)length;

/*!
 * @brief Returns a buffer containing the cryptographic hash.
 *
 * The size of the buffer depends on the hash used. The buffer is part of the
 * receiver's memory pool.
 *
 * @return A buffer containing the hash
 */
- (const unsigned char*)digest OF_RETURNS_INNER_POINTER;
- (const unsigned char *)digest OF_RETURNS_INNER_POINTER;

/*!
 * @brief Resets all state so that a new hash can be calculated.
 *
 * @warning This invalidates any pointer previously returned by @ref digest. If
 *	    you are still interested in the previous digest, you need to memcpy
 *	    it yourself before calling @ref reset!
 */
- (void)reset;
@end

OF_ASSUME_NONNULL_END

Modified src/OFDataArray+CryptoHashing.h from [ea6c2c832e] to [f47c276d77].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45

46
47
48
49
50
51
52

53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84

85
86
87
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44

45
46
47
48
49
50
51

52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83

84
85
86
87







-
+







-
+






-
+







-
+







-
+







-
+







-
+




@interface OFDataArray (CryptoHashing)
/*!
 * @brief Returns the MD5 hash of the data array as an autoreleased OFString.
 *
 * @return The MD5 hash of the data array as an autoreleased OFString
 */
- (OFString*)MD5Hash;
- (OFString *)MD5Hash;

/*!
 * @brief Returns the RIPEMD-160 hash of the data array as an autoreleased
 *	  OFString.
 *
 * @return The RIPEMD-160 hash of the data array as an autoreleased OFString
 */
- (OFString*)RIPEMD160Hash;
- (OFString *)RIPEMD160Hash;

/*!
 * @brief Returns the SHA-1 hash of the data array as an autoreleased OFString.
 *
 * @return The SHA-1 hash of the data array as an autoreleased OFString
 */
- (OFString*)SHA1Hash;
- (OFString *)SHA1Hash;

/*!
 * @brief Returns the SHA-224 hash of the data array as an autoreleased
 *	  OFString.
 *
 * @return The SHA-224 hash of the data array as an autoreleased OFString
 */
- (OFString*)SHA224Hash;
- (OFString *)SHA224Hash;

/*!
 * @brief Returns the SHA-256 hash of the data array as an autoreleased
 *	  OFString.
 *
 * @return The SHA-256 hash of the data array as an autoreleased OFString
 */
- (OFString*)SHA256Hash;
- (OFString *)SHA256Hash;

/*!
 * @brief Returns the SHA-384 hash of the data array as an autoreleased
 *	  OFString.
 *
 * @return The SHA-384 hash of the data array as an autoreleased OFString
 */
- (OFString*)SHA384Hash;
- (OFString *)SHA384Hash;

/*!
 * @brief Returns the SHA-512 hash of the data array as an autoreleased
 *	  OFString.
 *
 * @return The SHA-512 hash of the data array as an autoreleased OFString
 */
- (OFString*)SHA512Hash;
- (OFString *)SHA512Hash;
@end

OF_ASSUME_NONNULL_END

Modified src/OFDataArray+CryptoHashing.m from [093e57a2e6] to [07e9d87070].

26
27
28
29
30
31
32
33

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

33
34
35
36
37
38
39
40







-
+







#import "OFSHA256Hash.h"
#import "OFSHA384Hash.h"
#import "OFSHA512Hash.h"

int _OFDataArray_CryptoHashing_reference;

@implementation OFDataArray (Hashing)
- (OFString*)OF_cryptoHashWithClass: (Class <OFCryptoHash>)class
- (OFString *)OF_cryptoHashWithClass: (Class <OFCryptoHash>)class
{
	void *pool = objc_autoreleasePoolPush();
	id <OFCryptoHash> hash = [class cryptoHash];
	size_t digestSize = [class digestSize];
	const unsigned char *digest;
	char cString[digestSize * 2];

55
56
57
58
59
60
61
62

63
64
65
66
67

68
69
70
71
72

73
74
75
76
77

78
79
80
81
82

83
84
85
86
87

88
89
90
91
92

93
94
95
96
55
56
57
58
59
60
61

62
63
64
65
66

67
68
69
70
71

72
73
74
75
76

77
78
79
80
81

82
83
84
85
86

87
88
89
90
91

92
93
94
95
96







-
+




-
+




-
+




-
+




-
+




-
+




-
+




	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: digestSize * 2];
}

- (OFString*)MD5Hash
- (OFString *)MD5Hash
{
	return [self OF_cryptoHashWithClass: [OFMD5Hash class]];
}

- (OFString*)RIPEMD160Hash
- (OFString *)RIPEMD160Hash
{
	return [self OF_cryptoHashWithClass: [OFRIPEMD160Hash class]];
}

- (OFString*)SHA1Hash
- (OFString *)SHA1Hash
{
	return [self OF_cryptoHashWithClass: [OFSHA1Hash class]];
}

- (OFString*)SHA224Hash
- (OFString *)SHA224Hash
{
	return [self OF_cryptoHashWithClass: [OFSHA224Hash class]];
}

- (OFString*)SHA256Hash
- (OFString *)SHA256Hash
{
	return [self OF_cryptoHashWithClass: [OFSHA256Hash class]];
}

- (OFString*)SHA384Hash
- (OFString *)SHA384Hash
{
	return [self OF_cryptoHashWithClass: [OFSHA384Hash class]];
}

- (OFString*)SHA512Hash
- (OFString *)SHA512Hash
{
	return [self OF_cryptoHashWithClass: [OFSHA512Hash class]];
}
@end

Modified src/OFDataArray+MessagePackValue.m from [1eb966f163] to [d21c98d61f].

25
26
27
28
29
30
31
32

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

32
33
34
35
36
37
38
39







-
+







#import "OFDictionary.h"
#import "OFMessagePackExtension.h"

#import "OFInvalidFormatException.h"

int _OFDataArray_MessagePackValue_reference;

static size_t parseObject(const uint8_t*, size_t, id*);
static size_t parseObject(const uint8_t *, size_t, id *);

static uint16_t
readUInt16(const uint8_t *buffer)
{
	return ((uint16_t)buffer[0] << 8) | buffer[1];
}

161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175







-
+







	if ((buffer[0] & 0xE0) == 0xA0) {
		count = buffer[0] & 0x1F;

		if (length < count + 1)
			goto error;

		*object = [OFString
		    stringWithUTF8String: (const char*)buffer + 1
		    stringWithUTF8String: (const char *)buffer + 1
				  length: count];
		return count + 1;
	}

	/* fixarray */
	if ((buffer[0] & 0xF0) == 0x90)
		return parseArray(buffer + 1, length - 1, object,
491
492
493
494
495
496
497
498

499
500
501
502
503
504
505
506
507
508
509
510
511

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

525
526
527
528
529
530
531
491
492
493
494
495
496
497

498
499
500
501
502
503
504
505
506
507
508
509
510

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

524
525
526
527
528
529
530
531







-
+












-
+












-
+








		count = buffer[1];

		if (length < count + 2)
			goto error;

		*object = [OFString
		    stringWithUTF8String: (const char*)buffer + 2
		    stringWithUTF8String: (const char *)buffer + 2
				  length: count];
		return count + 2;
	case 0xDA: /* str 16 */
		if (length < 3)
			goto error;

		count = readUInt16(buffer + 1);

		if (length < count + 3)
			goto error;

		*object = [OFString
		    stringWithUTF8String: (const char*)buffer + 3
		    stringWithUTF8String: (const char *)buffer + 3
				  length: count];
		return count + 3;
	case 0xDB: /* str 32 */
		if (length < 5)
			goto error;

		count = readUInt32(buffer + 1);

		if (length < count + 5)
			goto error;

		*object = [OFString
		    stringWithUTF8String: (const char*)buffer + 5
		    stringWithUTF8String: (const char *)buffer + 5
				  length: count];
		return count + 5;
	/* Arrays */
	case 0xDC: /* array 16 */
		if (length < 3)
			goto error;

Modified src/OFDataArray.h from [31d759cbe2] to [dfeb1bb755].

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







-
+










-
+









-
+








-
+







/*!
 * @brief Creates a new OFDataArary with an item size of 1, containing the data
 *	  of the specified file.
 *
 * @param path The path of the file
 * @return A new autoreleased OFDataArray
 */
+ (instancetype)dataArrayWithContentsOfFile: (OFString*)path;
+ (instancetype)dataArrayWithContentsOfFile: (OFString *)path;
#endif

#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS)
/*!
 * @brief Creates a new OFDataArray with an item size of 1, containing the data
 *	  of the specified URL.
 *
 * @param URL The URL to the contents for the OFDataArray
 * @return A new autoreleased OFDataArray
 */
+ (instancetype)dataArrayWithContentsOfURL: (OFURL*)URL;
+ (instancetype)dataArrayWithContentsOfURL: (OFURL *)URL;
#endif

/*!
 * @brief Creates a new OFDataArray with an item size of 1, containing the data
 *	  of the string representation.
 *
 * @param string The string representation of the data
 * @return A new autoreleased OFDataArray
 */
+ (instancetype)dataArrayWithStringRepresentation: (OFString*)string;
+ (instancetype)dataArrayWithStringRepresentation: (OFString *)string;

/*!
 * @brief Creates a new OFDataArray with an item size of 1, containing the data
 *	  of the Base64-encoded string.
 *
 * @param string The string with the Base64-encoded data
 * @return A new autoreleased OFDataArray
 */
+ (instancetype)dataArrayWithBase64EncodedString: (OFString*)string;
+ (instancetype)dataArrayWithBase64EncodedString: (OFString *)string;

/*!
 * @brief Initializes an already allocated OFDataArray whose items all have the
 *	  same size.
 *
 * @param itemSize The size of a single element in the OFDataArray
 * @return An initialized OFDataArray
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193

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

213
214
215
216
217
218
219
220

221
222
223
224
225
226
227

228
229
230
231
232
233
234

235
236
237
238
239
240
241

242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258

259
260
261
262
263
264
265
266
267
268

269
270
271
272
273
274
275
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
192

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

212
213
214
215
216
217
218
219

220
221
222
223
224
225
226

227
228
229
230
231
232
233

234
235
236
237
238
239
240

241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
256
257

258
259
260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275







-
+










-
+









-
+








-
+


















-
+







-
+






-
+






-
+






-
+







-
+








-
+









-
+







/*!
 * @brief Initializes an already allocated OFDataArray with an item size of 1,
 *	  containing the data of the specified file.
 *
 * @param path The path of the file
 * @return An initialized OFDataArray
 */
- initWithContentsOfFile: (OFString*)path;
- initWithContentsOfFile: (OFString *)path;
#endif

#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS)
/*!
 * @brief Initializes an already allocated OFDataArray with an item size of 1,
 *	  containing the data of the specified URL.
 *
 * @param URL The URL to the contents for the OFDataArray
 * @return A new autoreleased OFDataArray
 */
- initWithContentsOfURL: (OFURL*)URL;
- initWithContentsOfURL: (OFURL *)URL;
#endif

/*!
 * @brief Initializes an already allocated OFDataArray with an item size of 1,
 *	  containing the data of the string representation.
 *
 * @param string The string representation of the data
 * @return A new autoreleased OFDataArray
 */
- initWithStringRepresentation: (OFString*)string;
- initWithStringRepresentation: (OFString *)string;

/*!
 * @brief Initializes an already allocated OFDataArray with an item size of 1,
 *	  containing the data of the Base64-encoded string.
 *
 * @param string The string with the Base64-encoded data
 * @return An initialized OFDataArray
 */
- initWithBase64EncodedString: (OFString*)string;
- initWithBase64EncodedString: (OFString *)string;

/*!
 * @brief Returns the number of items in the OFDataArray.
 *
 * @return The number of items in the OFDataArray
 */
- (size_t)count;

/*!
 * @brief Returns all items of the OFDataArray as a C array.
 *
 * @warning The pointer is only valid until the OFDataArray is changed!
 *
 * Modifying the returned array directly is allowed and will change the contents
 * of the data array.
 *
 * @return All elements of the OFDataArray as a C array
 */
- (void*)items OF_RETURNS_INNER_POINTER;
- (void *)items OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns a specific item of the OFDataArray.
 *
 * @param index The number of the item to return
 * @return The specified item of the OFDataArray
 */
- (void*)itemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER;
- (void *)itemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns the first item of the OFDataArray.
 *
 * @return The first item of the OFDataArray or NULL
 */
- (nullable void*)firstItem OF_RETURNS_INNER_POINTER;
- (nullable void *)firstItem OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns the last item of the OFDataArray.
 *
 * @return The last item of the OFDataArray or NULL
 */
- (nullable void*)lastItem OF_RETURNS_INNER_POINTER;
- (nullable void *)lastItem OF_RETURNS_INNER_POINTER;

/*!
 * @brief Adds an item to the OFDataArray.
 *
 * @param item A pointer to an arbitrary item
 */
- (void)addItem: (const void*)item;
- (void)addItem: (const void *)item;

/*!
 * @brief Adds an item to the OFDataArray at the specified index.
 *
 * @param item A pointer to an arbitrary item
 * @param index The index where the item should be added
 */
- (void)insertItem: (const void*)item
- (void)insertItem: (const void *)item
	   atIndex: (size_t)index;

/*!
 * @brief Adds items from a C array to the OFDataArray.
 *
 * @param items A C array containing the items to add
 * @param count The number of items to add
 */
- (void)addItems: (const void*)items
- (void)addItems: (const void *)items
	   count: (size_t)count;

/*!
 * @brief Adds items from a C array to the OFDataArray at the specified index.
 *
 * @param items A C array containing the items to add
 * @param index The index where the items should be added
 * @param count The number of items to add
 */
- (void)insertItems: (const void*)items
- (void)insertItems: (const void *)items
	    atIndex: (size_t)index
	      count: (size_t)count;

/*!
 * @brief Removes the item at the specified index.
 *
 * @param index The index of the item to remove
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
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







-
+






-
+







-
+







 * @brief Returns the string representation of the data array.
 *
 * The string representation is a hex dump of the data inside the data array,
 * grouped by itemSize bytes.
 *
 * @return The string representation of the data array.
 */
- (OFString*)stringRepresentation;
- (OFString *)stringRepresentation;

/*!
 * @brief Returns a string containing the data in Base64 encoding.
 *
 * @return A string containing the data in Base64 encoding
 */
- (OFString*)stringByBase64Encoding;
- (OFString *)stringByBase64Encoding;

#ifdef OF_HAVE_FILES
/*!
 * @brief Writes the OFDataArray into the specified file.
 *
 * @param path The path of the file to write to
 */
- (void)writeToFile: (OFString*)path;
- (void)writeToFile: (OFString *)path;
#endif
@end

OF_ASSUME_NONNULL_END

#import "OFDataArray+CryptoHashing.h"
#import "OFDataArray+MessagePackValue.h"

Modified src/OFDataArray.m from [5df935f0d5] to [08874136fe].

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







-
+






-
+





-
+





-
+







			     capacity: (size_t)capacity
{
	return [[[self alloc] initWithItemSize: itemSize
				      capacity: capacity] autorelease];
}

#ifdef OF_HAVE_FILES
+ (instancetype)dataArrayWithContentsOfFile: (OFString*)path
+ (instancetype)dataArrayWithContentsOfFile: (OFString *)path
{
	return [[[self alloc] initWithContentsOfFile: path] autorelease];
}
#endif

#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS)
+ (instancetype)dataArrayWithContentsOfURL: (OFURL*)URL
+ (instancetype)dataArrayWithContentsOfURL: (OFURL *)URL
{
	return [[[self alloc] initWithContentsOfURL: URL] autorelease];
}
#endif

+ (instancetype)dataArrayWithStringRepresentation: (OFString*)string
+ (instancetype)dataArrayWithStringRepresentation: (OFString *)string
{
	return [[[self alloc]
	    initWithStringRepresentation: string] autorelease];
}

+ (instancetype)dataArrayWithBase64EncodedString: (OFString*)string
+ (instancetype)dataArrayWithBase64EncodedString: (OFString *)string
{
	return [[[self alloc] initWithBase64EncodedString: string] autorelease];
}

- init
{
	self = [super init];
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164







-
+







		@throw e;
	}

	return self;
}

#ifdef OF_HAVE_FILES
- initWithContentsOfFile: (OFString*)path
- initWithContentsOfFile: (OFString *)path
{
	@try {
		OFFile *file = [[OFFile alloc] initWithPath: path
						       mode: @"rb"];
		of_offset_t size = [[OFFileManager defaultManager]
		    sizeOfFileAtPath: path];

192
193
194
195
196
197
198
199

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

199
200
201
202
203
204
205
206







-
+







	}

	return self;
}
#endif

#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS)
- initWithContentsOfURL: (OFURL*)URL
- initWithContentsOfURL: (OFURL *)URL
{
	void *pool;
	OFString *scheme;

	pool = objc_autoreleasePoolPush();

	scheme = [URL scheme];
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286







-
+








	objc_autoreleasePoolPop(pool);

	return self;
}
#endif

- initWithStringRepresentation: (OFString*)string
- initWithStringRepresentation: (OFString *)string
{
	@try {
		const char *cString;
		size_t count;

		count = [string
		    cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII];
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
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







-
+

















-
+







		[self release];
		@throw e;
	}

	return self;
}

- initWithBase64EncodedString: (OFString*)string
- initWithBase64EncodedString: (OFString *)string
{
	self = [self initWithItemSize: 1
			     capacity: [string length] / 3];

	@try {
		if (!of_base64_decode(self, [string cStringWithEncoding:
		    OF_STRING_ENCODING_ASCII], [string
		    cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII]))
			@throw [OFInvalidFormatException exception];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	@try {
		void *pool = objc_autoreleasePoolPush();
		OFString *stringValue;

		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
370
371
372
373
374
375
376
377

378
379
380
381
382

383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398

399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
370
371
372
373
374
375
376

377
378
379
380
381

382
383
384
385
386
387
388
389

390
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
430

431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447

448
449
450
451
452
453
454
455







-
+




-
+







-
+







-
+







-
+
















-
+







-
+
















-
+







}

- (size_t)count
{
	return _count;
}

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

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

	return _items + index * _itemSize;
}

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

	return _items;
}

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

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

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

	if (_count + 1 > _capacity) {
		_items = [self resizeMemory: _items
				       size: _itemSize
				      count: _count + 1];
		_capacity = _count + 1;
	}

	memcpy(_items + _count * _itemSize, item, _itemSize);

	_count++;
}

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

- (void)addItems: (const void*)items
- (void)addItems: (const void *)items
	   count: (size_t)count
{
	if (count > SIZE_MAX - _count)
		@throw [OFOutOfRangeException exception];

	if (_count + count > _capacity) {
		_items = [self resizeMemory: _items
				       size: _itemSize
				      count: _count + count];
		_capacity = _count + count;
	}

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

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

	if (_count + count > _capacity) {
551
552
553
554
555
556
557
558

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

558
559
560
561
562
563
564
565







-
+







	OFDataArray *dataArray;
	int comparison;
	size_t count, minCount;

	if (![object isKindOfClass: [OFDataArray class]])
		@throw [OFInvalidArgumentException exception];

	dataArray = (OFDataArray*)object;
	dataArray = (OFDataArray *)object;

	if ([dataArray itemSize] != _itemSize)
		@throw [OFInvalidArgumentException exception];

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

582
583
584
585
586
587
588
589

590
591
592
593
594
595
596

597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614

615
616
617
618
619
620
621
622
623
624
625
626

627
628
629
630
631
632

633
634
635
636
637
638
639
640
641
642
643
644
645
646

647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667

668
669
670
671
672
673
674
582
583
584
585
586
587
588

589
590
591
592
593
594
595

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

614
615
616
617
618
619
620
621
622
623
624
625

626
627
628
629
630
631

632
633
634
635
636
637
638
639
640
641
642
643
644
645

646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666

667
668
669
670
671
672
673
674







-
+






-
+

















-
+











-
+





-
+













-
+




















-
+







- (uint32_t)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

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

	OF_HASH_FINALIZE(hash);

	return hash;
}

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

	for (size_t i = 0; i < _count; i++) {
		if (i > 0)
			[ret appendString: @" "];

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

	[ret appendString: @">"];

	[ret makeImmutable];
	return ret;
}

- (OFString*)stringRepresentation
- (OFString *)stringRepresentation
{
	OFMutableString *ret = [OFMutableString string];

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

	[ret makeImmutable];
	return ret;
}

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

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

	@try {
		[file writeBuffer: _items
			   length: _count * _itemSize];
	} @finally {
		[file release];
	}
}
#endif

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

	if (_itemSize != 1)
		@throw [OFInvalidArgumentException exception];

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

	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (OFDataArray*)messagePackRepresentation
- (OFDataArray *)messagePackRepresentation
{
	OFDataArray *data;

	if (_itemSize != 1)
		@throw [OFInvalidArgumentException exception];

	if (_count <= UINT8_MAX) {

Modified src/OFDate.h from [f57292fc57] to [7c2a95ab3f].

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







-
-
+
+















-
-
+
+







 *	    %%a, %%b, %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%z, %%, %%n and
 *	    %%t.
 *
 * @param string The string describing the date
 * @param format The format of the string describing the date
 * @return A new, autoreleased OFDate with the specified date and time
 */
+ (instancetype)dateWithDateString: (OFString*)string
			    format: (OFString*)format;
+ (instancetype)dateWithDateString: (OFString *)string
			    format: (OFString *)format;

/*!
 * @brief Creates a new OFDate with the specified string in the specified
 *	  format.
 *
 * See the man page for `strftime` for information on the format.
 *
 * @warning The format is currently limited to the following format specifiers:
 *	    %%a, %%b, %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%z, %%, %%n and
 *	    %%t.
 *
 * @param string The string describing the date
 * @param format The format of the string describing the date
 * @return A new, autoreleased OFDate with the specified date and time
 */
+ (instancetype)dateWithLocalDateString: (OFString*)string
				 format: (OFString*)format;
+ (instancetype)dateWithLocalDateString: (OFString *)string
				 format: (OFString *)format;

/*!
 * @brief Returns a date in the distant future.
 *
 * The date is system-dependant.
 *
 * @return A date in the distant future
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
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







-
-
+
+
















-
-
+
+







 * @warning The format is currently limited to the following format specifiers:
 *	    %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%, %%n and %%t.
 *
 * @param string The string describing the date
 * @param format The format of the string describing the date
 * @return An initialized OFDate with the specified date and time
 */
- initWithDateString: (OFString*)string
	      format: (OFString*)format;
- initWithDateString: (OFString *)string
	      format: (OFString *)format;

/*!
 * @brief Initializes an already allocated OFDate with the specified string in
 *	  the specified format.
 *
 * If no time zone is specified, local time is assumed.
 *
 * See the man page for `strftime` for information on the format.
 *
 * @warning The format is currently limited to the following format specifiers:
 *	    %%d, %%e, %%H, %%m, %%M, %%S, %%y, %%Y, %%, %%n and %%t.
 *
 * @param string The string describing the date
 * @param format The format of the string describing the date
 * @return An initialized OFDate with the specified date and time
 */
- initWithLocalDateString: (OFString*)string
		   format: (OFString*)format;
- initWithLocalDateString: (OFString *)string
		   format: (OFString *)format;

/*!
 * @brief Returns the microsecond of the date.
 *
 * @return The microsecond of the date
 */
- (uint32_t)microsecond;
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

344
345
346
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302

303
304
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

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

343
344
345
346







-
+









-
+









-
+









-
+














-
+














-
+



 * @brief Creates a string of the date with the specified format.
 *
 * See the man page for `strftime` for information on the format.
 *
 * @param format The format for the date string
 * @return A new, autoreleased OFString
 */
- (OFString*)dateStringWithFormat: (OFConstantString*)format;
- (OFString *)dateStringWithFormat: (OFConstantString *)format;

/*!
 * @brief Creates a string of the local date with the specified format.
 *
 * See the man page for `strftime` for information on the format.
 *
 * @param format The format for the date string
 * @return A new, autoreleased OFString
 */
- (OFString*)localDateStringWithFormat: (OFConstantString*)format;
- (OFString *)localDateStringWithFormat: (OFConstantString *)format;

/*!
 * @brief Returns the earlier of the two dates.
 *
 * If the argument is `nil`, it returns the receiver.
 *
 * @param otherDate Another date
 * @return The earlier date of the two dates
 */
- (OFDate*)earlierDate: (OFDate*)otherDate;
- (OFDate *)earlierDate: (OFDate *)otherDate;

/*!
 * @brief Returns the later of the two dates.
 *
 * If the argument is `nil`, it returns the receiver.
 *
 * @param otherDate Another date
 * @return The later date of the two dates
 */
- (OFDate*)laterDate: (OFDate*)otherDate;
- (OFDate *)laterDate: (OFDate *)otherDate;

/*!
 * @brief Returns the seconds since 1970-01-01T00:00:00Z.
 *
 * @return The seconds since 1970-01-01T00:00:00Z
 */
- (of_time_interval_t)timeIntervalSince1970;

/*!
 * @brief Returns the seconds the receiver is after the date.
 *
 * @param otherDate Date date to generate the difference with receiver
 * @return The seconds the receiver is after the date.
 */
- (of_time_interval_t)timeIntervalSinceDate: (OFDate*)otherDate;
- (of_time_interval_t)timeIntervalSinceDate: (OFDate *)otherDate;

/*!
 * @brief Returns the seconds the receiver is in the future.
 *
 * @return The seconds the receiver is in the future
 */
- (of_time_interval_t)timeIntervalSinceNow;

/*!
 * @brief Creates a new date with the specified time interval added.
 *
 * @param seconds The seconds after the date
 * @return A new, autoreleased OFDate
 */
- (OFDate*)dateByAddingTimeInterval: (of_time_interval_t)seconds;
- (OFDate *)dateByAddingTimeInterval: (of_time_interval_t)seconds;
@end

OF_ASSUME_NONNULL_END

Modified src/OFDate.m from [7fa6b61e6d] to [7b7d9e6713].

201
202
203
204
205
206
207
208
209


210
211
212
213
214
215
216


217
218
219
220
221
222
223
201
202
203
204
205
206
207


208
209
210
211
212
213
214


215
216
217
218
219
220
221
222
223







-
-
+
+





-
-
+
+








+ (instancetype)dateWithTimeIntervalSinceNow: (of_time_interval_t)seconds
{
	return [[[self alloc]
	    initWithTimeIntervalSinceNow: seconds] autorelease];
}

+ (instancetype)dateWithDateString: (OFString*)string
			    format: (OFString*)format
+ (instancetype)dateWithDateString: (OFString *)string
			    format: (OFString *)format
{
	return [[[self alloc] initWithDateString: string
					  format: format] autorelease];
}

+ (instancetype)dateWithLocalDateString: (OFString*)string
				 format: (OFString*)format
+ (instancetype)dateWithLocalDateString: (OFString *)string
				 format: (OFString *)format
{
	return [[[self alloc] initWithLocalDateString: string
					       format: format] autorelease];
}

+ (instancetype)distantFuture
{
259
260
261
262
263
264
265
266
267


268
269
270
271
272
273
274
259
260
261
262
263
264
265


266
267
268
269
270
271
272
273
274







-
-
+
+







	self = [self init];

	_seconds += seconds;

	return self;
}

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

	@try {
		const char *UTF8String = [string UTF8String];
		struct tm tm = { 0 };
		int16_t tz = 0;
284
285
286
287
288
289
290
291
292


293
294
295
296
297
298
299
284
285
286
287
288
289
290


291
292
293
294
295
296
297
298
299







-
-
+
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		const char *UTF8String = [string UTF8String];
		struct tm tm = { 0 };
		/*
323
324
325
326
327
328
329
330

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

330
331
332
333
334
335
336
337







-
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFString *stringValue;
		union {
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
430

431
432
433
434
435
436
437
438







-
+









-
+







-
+







- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	OFDate *otherDate;

	if (![object isKindOfClass: [OFDate class]])
		@throw [OFInvalidArgumentException exception];

	otherDate = (OFDate*)object;
	otherDate = (OFDate *)object;

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

	return OF_ORDERED_SAME;
}

- (OFString*)description
- (OFString *)description
{
	if (isinf(_seconds))
		return (_seconds > 0 ? @"Distant Future" : @"Distant Past");
	else
		return [self dateStringWithFormat: @"%Y-%m-%dT%H:%M:%SZ"];
}

- (OFXMLElement*)XMLElementBySerializing
- (OFXMLElement *)XMLElementBySerializing
{
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;
	union {
		double d;
		uint64_t u;
	} d;
527
528
529
530
531
532
533
534

535
536
537
538
539
540
541
527
528
529
530
531
532
533

534
535
536
537
538
539
540
541







-
+







}

- (uint16_t)localDayOfYear
{
	LOCALTIME_RET(tm_yday + 1)
}

- (OFString*)dateStringWithFormat: (OFConstantString*)format
- (OFString *)dateStringWithFormat: (OFConstantString *)format
{
	OFString *ret;
	time_t seconds = (time_t)_seconds;
	struct tm tm;
	size_t pageSize;
#ifndef OF_WINDOWS
	char *buffer;
587
588
589
590
591
592
593
594

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

594
595
596
597
598
599
600
601







-
+







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

	return ret;
}

- (OFString*)localDateStringWithFormat: (OFConstantString*)format
- (OFString *)localDateStringWithFormat: (OFConstantString *)format
{
	OFString *ret;
	time_t seconds = (time_t)_seconds;
	struct tm tm;
	size_t pageSize;
#ifndef OF_WINDOWS
	char *buffer;
647
648
649
650
651
652
653
654

655
656
657
658
659
660
661
662
663
664
665

666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681

682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699

700
701
702
703
647
648
649
650
651
652
653

654
655
656
657
658
659
660
661
662
663
664

665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698

699
700
701
702
703







-
+










-
+















-
+

















-
+




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

	return ret;
}

- (OFDate*)earlierDate: (OFDate*)otherDate
- (OFDate *)earlierDate: (OFDate *)otherDate
{
	if (otherDate == nil)
		return [[self retain] autorelease];

	if ([self compare: otherDate] == OF_ORDERED_DESCENDING)
		return [[otherDate retain] autorelease];

	return [[self retain] autorelease];
}

- (OFDate*)laterDate: (OFDate*)otherDate
- (OFDate *)laterDate: (OFDate *)otherDate
{
	if (otherDate == nil)
		return [[self retain] autorelease];

	if ([self compare: otherDate] == OF_ORDERED_ASCENDING)
		return [[otherDate retain] autorelease];

	return [[self retain] autorelease];
}

- (of_time_interval_t)timeIntervalSince1970
{
	return _seconds;
}

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

- (of_time_interval_t)timeIntervalSinceNow
{
	struct timeval t;
	of_time_interval_t seconds;

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

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

	return _seconds - seconds;
}

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

Modified src/OFDeflateStream.h from [0d64fa32f0] to [f5d863787a].

72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89

90
91
92
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88

89
90
91
92







-
+









-
+



/*!
 * @brief Creates a new OFDeflateStream with the specified underlying stream.
 *
 * @param stream The underlying stream to which compressed data is written or
 *		 from which compressed data is read
 * @return A new, autoreleased OFDeflateStream
 */
+ (instancetype)streamWithStream: (OFStream*)stream;
+ (instancetype)streamWithStream: (OFStream *)stream;

/*!
 * @brief Initializes an already allocated OFDeflateStream with the specified
 *	  underlying stream.
 *
 * @param stream The underlying stream to which compressed data is written or
 *		 from which compressed data is read
 * @return A initialized OFDeflateStream
 */
- initWithStream: (OFStream*)stream;
- initWithStream: (OFStream *)stream;
@end

OF_ASSUME_NONNULL_END

Modified src/OFDeflateStream.m from [459199aede] to [be9beadf26].

150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164







-
+







	ivars->savedBits = 0;
	ivars->savedBitsLength = 0;
	*bits = ret;

	return true;
}

static struct huffman_tree*
static struct huffman_tree *
newTree(void)
{
	struct huffman_tree *tree;

	if ((tree = malloc(sizeof(*tree))) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: sizeof(*tree)];
184
185
186
187
188
189
190
191

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

191
192
193
194
195
196
197
198







-
+








		tree = tree->leafs[bit];
	}

	tree->value = value;
}

static struct huffman_tree*
static struct huffman_tree *
constructTree(uint8_t lengths[], uint16_t count)
{
	struct huffman_tree *tree;
	uint16_t lengthCount[MAX_BITS + 1] = { 0 };
	uint16_t code, maxCode = 0, nextCode[MAX_BITS + 1];

	for (uint16_t i = 0; i < count; i++) {
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305







-
+









-
+







	for (uint16_t i = 0; i <= 31; i++)
		lengths[i] = 5;

	fixedDistTree = constructTree(lengths, 32);
}

#ifndef DEFLATE64
+ (instancetype)streamWithStream: (OFStream*)stream
+ (instancetype)streamWithStream: (OFStream *)stream
{
	return [[[self alloc] initWithStream: stream] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithStream: (OFStream*)stream
- initWithStream: (OFStream *)stream
{
	self = [super init];

	_stream = [stream retain];

	return self;
}
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350







-
+







#ifdef DEFLATE64
	_decompression->slidingWindowMask = 0xFFFF;
#else
	_decompression->slidingWindowMask = 0x7FFF;
#endif
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer_
- (size_t)lowlevelReadIntoBuffer: (void *)buffer_
			  length: (size_t)length
{
	struct of_deflate_stream_decompression_ivars *ivars = _decompression;
	uint8_t *buffer = buffer_;
	uint16_t bits, tmp;
	uint16_t value;
	size_t bytesWritten = 0;

Modified src/OFDictionary.h from [1ef115643a] to [5f2fde2cb0].

48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62







-
+







 *
 * Keys are copied and thus must conform to the OFCopying protocol.
 *
 * @note Fast enumeration on a dictionary enumerates through the keys of the
 *	 dictionary.
 */
#ifdef OF_HAVE_GENERICS
@interface OFDictionary <KeyType, ObjectType>:
@interface OFDictionary<KeyType, ObjectType>:
#else
# ifndef DOXYGEN
#  define KeyType id
#  define ObjectType id
# endif
@interface OFDictionary:
#endif
72
73
74
75
76
77
78
79

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


101
102
103
104
105
106
107
72
73
74
75
76
77
78

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


99
100
101
102
103
104
105
106
107







-
+



















-
-
+
+







/*!
 * @brief Creates a new OFDictionary with the specified dictionary.
 *
 * @param dictionary An OFDictionary
 * @return A new autoreleased OFDictionary
 */
+ (instancetype)dictionaryWithDictionary:
   (OFDictionary OF_GENERIC(KeyType, ObjectType)*)dictionary;
   (OFDictionary OF_GENERIC(KeyType, ObjectType) *)dictionary;

/*!
 * @brief Creates a new OFDictionary with the specified key and object.
 *
 * @param key The key
 * @param object The object
 * @return A new autoreleased OFDictionary
 */
+ (instancetype)dictionaryWithObject: (ObjectType)object
			      forKey: (KeyType)key;

/*!
 * @brief Creates a new OFDictionary with the specified keys and objects.
 *
 * @param keys An array of keys
 * @param objects An array of objects
 * @return A new autoreleased OFDictionary
 */
+ (instancetype)
    dictionaryWithObjects: (OFArray OF_GENERIC(ObjectType)*)objects
		  forKeys: (OFArray OF_GENERIC(KeyType)*)keys;
    dictionaryWithObjects: (OFArray OF_GENERIC(ObjectType) *)objects
		  forKeys: (OFArray OF_GENERIC(KeyType) *)keys;

/*!
 * @brief Creates a new OFDictionary with the specified keys and objects.
 *
 * @param keys An array of keys
 * @param objects An array of objects
 * @param count The number of objects in the arrays
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
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







+
-
+




















-
-
+
+







/*!
 * @brief Initializes an already allocated OFDictionary with the specified
 *	  OFDictionary.
 *
 * @param dictionary An OFDictionary
 * @return An initialized OFDictionary
 */
- initWithDictionary:
- initWithDictionary: (OFDictionary OF_GENERIC(KeyType, ObjectType)*)dictionary;
    (OFDictionary OF_GENERIC(KeyType, ObjectType) *)dictionary;

/*!
 * @brief Initializes an already allocated OFDictionary with the specified key
 *	  and object.
 *
 * @param key The key
 * @param object The object
 * @return An initialized OFDictionary
 */
- initWithObject: (ObjectType)object
	  forKey: (KeyType)key;

/*!
 * @brief Initializes an already allocated OFDictionary with the specified keys
 *	  and objects.
 *
 * @param keys An array of keys
 * @param objects An array of objects
 * @return An initialized OFDictionary
 */
- initWithObjects: (OFArray OF_GENERIC(ObjectType)*)objects
	  forKeys: (OFArray OF_GENERIC(KeyType)*)keys;
- initWithObjects: (OFArray OF_GENERIC(ObjectType) *)objects
	  forKeys: (OFArray OF_GENERIC(KeyType) *)keys;

/*!
 * @brief Initializes an already allocated OFDictionary with the specified keys
 *	  and objects.
 *
 * @param keys An array of keys
 * @param objects An array of objects
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236







-
+














-
+







 * `[super valueForKey:]` is called.
 * If the key does not start with an `@`, this is equivalent to
 * @ref objectForKey:.
 *
 * @param key The key whose value should be returned
 * @return The value for the given key or `nil` if the key was not found
 */
- (nullable id)valueForKey: (OFString*)key;
- (nullable id)valueForKey: (OFString *)key;

/*!
 * @brief Sets a value for a key.
 *
 * If the key starts with an `@`, the `@` is stripped and
 * `[super setValue:forKey:]` is called.
 * If the key does not start with an `@`, this is equivalent to
 * @ref setObject:forKey:. In this case, if the dictionary is immutable, an
 * @ref OFUndefinedKeyException is thrown.
 *
 * @param key The key to set
 * @param value The value to set the key to
 */
- (void)setValue: (nullable id)value
	  forKey: (OFString*)key;
	  forKey: (OFString *)key;

/*!
 * @brief Checks whether the dictionary contains an object equal to the
 *	  specified object.
 *
 * @param object The object which is checked for being in the dictionary
 * @return A boolean whether the dictionary contains the specified object
247
248
249
250
251
252
253
254

255
256
257
258
259
260
261

262
263
264
265
266
267
268

269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
248
249
250
251
252
253
254

255
256
257
258
259
260
261

262
263
264
265
266
267
268

269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
312







-
+






-
+






-
+






-
+

















-
+










-
+







- (bool)containsObjectIdenticalTo: (nullable ObjectType)object;

/*!
 * @brief Returns an array of all keys.
 *
 * @return An array of all keys
 */
- (OFArray OF_GENERIC(KeyType)*)allKeys;
- (OFArray OF_GENERIC(KeyType) *)allKeys;

/*!
 * @brief Returns an array of all objects.
 *
 * @return An array of all objects
 */
- (OFArray OF_GENERIC(ObjectType)*)allObjects;
- (OFArray OF_GENERIC(ObjectType) *)allObjects;

/*!
 * @brief Returns an OFEnumerator to enumerate through the dictionary's keys.
 *
 * @return An OFEnumerator to enumerate through the dictionary's keys
 */
- (OFEnumerator OF_GENERIC(KeyType)*)keyEnumerator;
- (OFEnumerator OF_GENERIC(KeyType) *)keyEnumerator;

/*!
 * @brief Returns an OFEnumerator to enumerate through the dictionary's objects.
 *
 * @return An OFEnumerator to enumerate through the dictionary's objects
 */
- (OFEnumerator OF_GENERIC(ObjectType)*)objectEnumerator;
- (OFEnumerator OF_GENERIC(ObjectType) *)objectEnumerator;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Executes a block for each key / object pair.
 *
 * @param block The block to execute for each key / object pair.
 */
- (void)enumerateKeysAndObjectsUsingBlock:
    (of_dictionary_enumeration_block_t)block;

/*!
 * @brief Creates a new dictionary, mapping each object using the specified
 *	  block.
 *
 * @param block A block which maps an object for each object
 * @return A new autoreleased OFDictionary
 */
- (OFDictionary OF_GENERIC(KeyType, id)*)mappedDictionaryUsingBlock:
- (OFDictionary OF_GENERIC(KeyType, id) *)mappedDictionaryUsingBlock:
    (of_dictionary_map_block_t)block;

/*!
 * @brief Creates a new dictionary, only containing the objects for which the
 *	  block returns true.
 *
 * @param block A block which determines if the object should be in the new
 *		dictionary
 * @return A new autoreleased OFDictionary
 */
- (OFDictionary OF_GENERIC(KeyType, ObjectType)*)filteredDictionaryUsingBlock:
- (OFDictionary OF_GENERIC(KeyType, ObjectType) *)filteredDictionaryUsingBlock:
    (of_dictionary_filter_block_t)block;
#endif
@end
#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN)
# undef KeyType
# undef ObjectType
#endif

Modified src/OFDictionary.m from [537dc67d0c] to [e4842b5166].

32
33
34
35
36
37
38
39

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

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


67
68
69
70
71
72
73


74
75
76
77
78
79
80
32
33
34
35
36
37
38

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

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


65
66
67
68
69
70
71


72
73
74
75
76
77
78
79
80







-
+












-
+












-
-
+
+





-
-
+
+







#import "OFUndefinedKeyException.h"

static struct {
	Class isa;
} placeholder;

@interface OFDictionary ()
- (OFString*)OF_JSONRepresentationWithOptions: (int)options
- (OFString *)OF_JSONRepresentationWithOptions: (int)options
					depth: (size_t)depth;
@end

@interface OFDictionary_placeholder: OFDictionary
@end

@implementation OFDictionary_placeholder
- init
{
	return (id)[[OFDictionary_hashtable alloc] init];
}

- initWithDictionary: (OFDictionary*)dictionary
- initWithDictionary: (OFDictionary *)dictionary
{
	return (id)[[OFDictionary_hashtable alloc]
	    initWithDictionary: dictionary];
}

- initWithObject: (id)object
	  forKey: (id)key
{
	return (id)[[OFDictionary_hashtable alloc] initWithObject: object
							   forKey: key];
}

- initWithObjects: (OFArray*)objects
	  forKeys: (OFArray*)keys
- initWithObjects: (OFArray *)objects
	  forKeys: (OFArray *)keys
{
	return (id)[[OFDictionary_hashtable alloc] initWithObjects: objects
							   forKeys: keys];
}

- initWithObjects: (id const*)objects
	  forKeys: (id const*)keys
- initWithObjects: (id const *)objects
	  forKeys: (id const *)keys
	    count: (size_t)count
{
	return (id)[[OFDictionary_hashtable alloc] initWithObjects: objects
							   forKeys: keys
							     count: count];
}

94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108







-
+







- initWithKey: (id <OFCopying>)firstKey
    arguments: (va_list)arguments
{
	return (id)[[OFDictionary_hashtable alloc] initWithKey: firstKey
						     arguments: arguments];
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFDictionary_hashtable alloc]
	    initWithSerialization: element];
}

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







-
+











-
-
+
+





-
-
+
+







}

+ (instancetype)dictionary
{
	return [[[self alloc] init] autorelease];
}

+ (instancetype)dictionaryWithDictionary: (OFDictionary*)dictionary
+ (instancetype)dictionaryWithDictionary: (OFDictionary *)dictionary
{
	return [[[self alloc] initWithDictionary: dictionary] autorelease];
}

+ (instancetype)dictionaryWithObject: (id)object
			      forKey: (id)key
{
	return [[[self alloc] initWithObject: object
				      forKey: key] autorelease];
}

+ (instancetype)dictionaryWithObjects: (OFArray*)objects
			      forKeys: (OFArray*)keys
+ (instancetype)dictionaryWithObjects: (OFArray *)objects
			      forKeys: (OFArray *)keys
{
	return [[[self alloc] initWithObjects: objects
				      forKeys: keys] autorelease];
}

+ (instancetype)dictionaryWithObjects: (id const*)objects
			      forKeys: (id const*)keys
+ (instancetype)dictionaryWithObjects: (id const *)objects
			      forKeys: (id const *)keys
		  count: (size_t)count
{
	return [[[self alloc] initWithObjects: objects
				      forKeys: keys
					count: count] autorelease];
}

197
198
199
200
201
202
203
204

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


220
221
222
223
224
225
226
197
198
199
200
201
202
203

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


218
219
220
221
222
223
224
225
226







-
+













-
-
+
+








		abort();
	}

	return [super init];
}

- initWithDictionary: (OFDictionary*)dictionary
- initWithDictionary: (OFDictionary *)dictionary
{
	OF_INVALID_INIT_METHOD
}

- initWithObject: (id)object
	  forKey: (id)key
{
	if (key == nil || object == nil)
		@throw [OFInvalidArgumentException exception];

	return [self initWithKeysAndObjects: key, object, nil];
}

- initWithObjects: (OFArray*)objects_
	  forKeys: (OFArray*)keys_
- initWithObjects: (OFArray *)objects_
	  forKeys: (OFArray *)keys_
{
	id const *objects, *keys;
	size_t count;

	@try {
		count = [objects_ count];

235
236
237
238
239
240
241
242
243


244
245
246
247
248
249
250
235
236
237
238
239
240
241


242
243
244
245
246
247
248
249
250







-
-
+
+







	}

	return [self initWithObjects: objects
			     forKeys: keys
			       count: count];
}

- initWithObjects: (id const*)objects
	  forKeys: (id const*)keys
- initWithObjects: (id const *)objects
	  forKeys: (id const *)keys
	    count: (size_t)count
{
	OF_INVALID_INIT_METHOD
}

- initWithKeysAndObjects: (id)firstKey, ...
{
261
262
263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301

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


321
322
323
324
325
326
327
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

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


319
320
321
322
323
324
325
326
327







-
+














-
+

















-
+

















-
-
+
+








- initWithKey: (id)firstKey
    arguments: (va_list)arguments
{
	OF_INVALID_INIT_METHOD
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	OF_INVALID_INIT_METHOD
}

- (id)objectForKey: (id)key
{
	OF_UNRECOGNIZED_SELECTOR
}

- (id)objectForKeyedSubscript: (id)key
{
	return [self objectForKey: key];
}

- (id)valueForKey: (OFString*)key
- (id)valueForKey: (OFString *)key
{
	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();
		id ret;

		key = [key substringWithRange: of_range(1, [key length] - 1)];
		ret = [[super valueForKey: key] retain];

		objc_autoreleasePoolPop(pool);

		return [ret autorelease];
	}

	return [self objectForKey: key];
}

- (void)setValue: (id)value
	  forKey: (OFString*)key
	  forKey: (OFString *)key
{
	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();

		key = [key substringWithRange: of_range(1, [key length] - 1)];
		[super setValue: value
			 forKey: key];

		objc_autoreleasePoolPop(pool);
		return;
	}

	if (![self isKindOfClass: [OFMutableDictionary class]])
		@throw [OFUndefinedKeyException exceptionWithObject: self
								key: key
							      value: value];

	[(OFMutableDictionary*)self setObject: value
				       forKey: key];
	[(OFMutableDictionary *)self setObject: value
					forKey: key];
}

- (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

413
414
415
416
417
418
419
420

421
422
423
424
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449

450
451
452
453
454

455
456
457
458
459
460


461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480

481
482
483
484
485
486
487
488
489
490
491
492
493
494
495

496
497
498
499
500
501
502
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

449
450
451
452
453

454
455
456
457
458


459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502







-
+











-
+
















-
+




-
+




-
-
+
+



















-
+














-
+







	}

	objc_autoreleasePoolPop(pool);

	return false;
}

- (OFArray*)allKeys
- (OFArray *)allKeys
{
	OFMutableArray *ret = [OFMutableArray arrayWithCapacity: [self count]];

	for (id key in self)
		[ret addObject: key];

	[ret makeImmutable];

	return ret;
}

- (OFArray*)allObjects
- (OFArray *)allObjects
{
	OFMutableArray *ret = [OFMutableArray arrayWithCapacity: [self count]];
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *enumerator = [self objectEnumerator];
	id object;

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

	[ret makeImmutable];

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (OFEnumerator*)keyEnumerator
- (OFEnumerator *)keyEnumerator
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFEnumerator*)objectEnumerator
- (OFEnumerator *)objectEnumerator
{
	OF_UNRECOGNIZED_SELECTOR
}

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

#ifdef OF_HAVE_BLOCKS
- (void)enumerateKeysAndObjectsUsingBlock:
    (of_dictionary_enumeration_block_t)block
{
	bool stop = false;

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

		if (stop)
			break;
	}
}

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

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

	[new makeImmutable];

	return new;
}

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

	[self enumerateKeysAndObjectsUsingBlock: ^ (id key, id object,
	    bool *stop) {
		if (block(key, object))
525
526
527
528
529
530
531
532

533
534
535
536
537
538
539
525
526
527
528
529
530
531

532
533
534
535
536
537
538
539







-
+







	}

	objc_autoreleasePoolPop(pool);

	return hash;
}

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

566
567
568
569
570
571
572
573

574
575
576
577
578
579
580
566
567
568
569
570
571
572

573
574
575
576
577
578
579
580







-
+







	[ret makeImmutable];

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (OFXMLElement*)XMLElementBySerializing
- (OFXMLElement *)XMLElementBySerializing
{
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;
	OFEnumerator *keyEnumerator, *objectEnumerator;
	id key, object;

	if ([self isKindOfClass: [OFMutableDictionary class]])
610
611
612
613
614
615
616
617

618
619
620
621
622
623

624
625
626
627
628
629

630
631
632
633
634
635
636
610
611
612
613
614
615
616

617
618
619
620
621
622

623
624
625
626
627
628

629
630
631
632
633
634
635
636







-
+





-
+





-
+







	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (OFString*)JSONRepresentation
- (OFString *)JSONRepresentation
{
	return [self OF_JSONRepresentationWithOptions: 0
						depth: 0];
}

- (OFString*)JSONRepresentationWithOptions: (int)options
- (OFString *)JSONRepresentationWithOptions: (int)options
{
	return [self OF_JSONRepresentationWithOptions: options
						depth: 0];
}

- (OFString*)OF_JSONRepresentationWithOptions: (int)options
- (OFString *)OF_JSONRepresentationWithOptions: (int)options
					depth: (size_t)depth
{
	OFMutableString *JSON = [OFMutableString stringWithString: @"{"];
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *keyEnumerator = [self keyEnumerator];
	OFEnumerator *objectEnumerator = [self objectEnumerator];
	size_t i, count = [self count];
703
704
705
706
707
708
709
710

711
712
713
714
715
716
717
703
704
705
706
707
708
709

710
711
712
713
714
715
716
717







-
+







	[JSON makeImmutable];

	objc_autoreleasePoolPop(pool);

	return JSON;
}

- (OFDataArray*)messagePackRepresentation
- (OFDataArray *)messagePackRepresentation
{
	OFDataArray *data;
	size_t i, count;
	void *pool;
	OFEnumerator *keyEnumerator, *objectEnumerator;
	id key, object;

Modified src/OFDictionary_hashtable.m from [3138cd18bb] to [0f9f60ec04].

26
27
28
29
30
31
32
33

34
35
36
37
38
39

40
41
42
43
44
45
46
26
27
28
29
30
31
32

33
34
35
36
37
38

39
40
41
42
43
44
45
46







-
+





-
+







#import "OFString.h"
#import "OFXMLElement.h"

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

static void*
static void *
copy(void *object)
{
	return [(id)object copy];
}

static void*
static void *
retain(void *object)
{
	return [(id)object retain];
}

static void
release(void *object)
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
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







-
+












-
+







		[self release];
		@throw e;
	}

	return self;
}

- initWithDictionary: (OFDictionary*)dictionary
- initWithDictionary: (OFDictionary *)dictionary
{
	size_t count;

	if (dictionary == nil)
		return [self init];

	if ([dictionary isKindOfClass: [OFDictionary_hashtable class]] ||
	    [dictionary isKindOfClass: [OFMutableDictionary_hashtable class]]) {
		self = [super init];

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

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

162
163
164
165
166
167
168
169
170


171
172
173
174
175
176
177
162
163
164
165
166
167
168


169
170
171
172
173
174
175
176
177







-
-
+
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		size_t i;

236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
236
237
238
239
240
241
242

243
244
245
246
247
248
249
250







-
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFArray *keys, *objects;
		OFEnumerator *keyEnumerator, *objectEnumerator;
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
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







-
+














-
+







{
	OFDictionary_hashtable *dictionary_;

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

	dictionary_ = (OFDictionary_hashtable*)dictionary;
	dictionary_ = (OFDictionary_hashtable *)dictionary;

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

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

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

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

	count = [_mapTable count];
	keys = [self allocMemoryWithSize: sizeof(*keys)
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
364
365
366
367
368
369
370

371
372
373
374
375
376
377
378







-
+







	} @finally {
		[self freeMemory: keys];
	}

	return ret;
}

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

	count = [_mapTable count];
	objects = [self allocMemoryWithSize: sizeof(*objects)
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413

414
415
416
417
418
419
420
421


422
423
424
425
426
427
428
399
400
401
402
403
404
405

406
407
408
409
410
411
412

413
414
415
416
417
418
419


420
421
422
423
424
425
426
427
428







-
+






-
+






-
-
+
+







	} @finally {
		[self freeMemory: objects];
	}

	return ret;
}

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

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

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

Modified src/OFEnumerator.h from [f1914c42af] to [e2784c6244].

31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73







-
+








-
+


















-
+







@protocol OFEnumerating
/*!
 * @brief Returns an OFEnumerator to enumerate through all objects of the
 *	  collection.
 *
 * @returns An OFEnumerator to enumerate through all objects of the collection
 */
- (OFEnumerator*)objectEnumerator;
- (OFEnumerator *)objectEnumerator;
@end

/*!
 * @class OFEnumerator OFEnumerator.h ObjFW/OFEnumerator.h
 *
 * @brief A class which provides methods to enumerate through collections.
 */
#ifdef OF_HAVE_GENERICS
@interface OFEnumerator <ObjectType>: OFObject
@interface OFEnumerator<ObjectType>: OFObject
#else
# ifndef DOXYGEN
#  define ObjectType id
# endif
@interface OFEnumerator: OFObject
#endif
/*!
 * @brief Returns the next object or `nil` if there is none left.
 *
 * @return The next object or `nil` if there is none left
 */
- (nullable ObjectType)nextObject;

/*!
 * @brief Returns an array of all remaining objects in the collection.
 *
 * @return An array of all remaining objects in the collection
 */
- (OFArray OF_GENERIC(ObjectType)*)allObjects;
- (OFArray OF_GENERIC(ObjectType) *)allObjects;

/*!
 * @brief Resets the enumerator, so the next call to nextObject returns the
 *	  first object again.
 */
- (void)reset;
@end
115
116
117
118
119
120
121
122

123
124
125
126
127
128
115
116
117
118
119
120
121

122
123
124
125
126
127
128







-
+






 *
 * @param state Context information for the enumeration
 * @param objects A pointer to an array where to put the objects
 * @param count The number of objects that can be stored at objects
 * @return The number of objects returned in objects or 0 when the enumeration
 *	   finished.
 */
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state
			   objects: (id __unsafe_unretained _Nonnull *_Nonnull)
					objects
			     count: (int)count;
@end

OF_ASSUME_NONNULL_END

Modified src/OFEnumerator.m from [9f42f95aec] to [73c62897f9].

38
39
40
41
42
43
44
45

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

45
46
47
48
49
50
51
52







-
+







}

- (id)nextObject
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFArray*)allObjects
- (OFArray *)allObjects
{
	OFMutableArray *ret = [OFMutableArray array];
	void *pool = objc_autoreleasePoolPush();
	id object;

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

Modified src/OFFile.h from [aa46fd0cd7] to [e4c0b1e08b].

65
66
67
68
69
70
71
72
73


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


72
73
74
75
76
77
78
79
80







-
-
+
+







 *	       `wb+` or `w+b` | read-write, create, truncate, binary
 *	       `a`            | write-only, create, append
 *	       `ab`           | write-only, create, append, binary
 *	       `a+`           | read-write, create, append
 *	       `ab+` or `a+b` | read-write, create, append, binary
 * @return A new autoreleased OFFile
 */
+ (instancetype)fileWithPath: (OFString*)path
			mode: (OFString*)mode;
+ (instancetype)fileWithPath: (OFString *)path
			mode: (OFString *)mode;

/*!
 * @brief Creates a new OFFile with the specified file descriptor.
 *
 * @param fd A file descriptor, returned from for example open().
 *	     It is not closed when the OFFile object is deallocated!
 * @return A new autoreleased OFFile
99
100
101
102
103
104
105
106
107


108
109
110
111
112
113
114
99
100
101
102
103
104
105


106
107
108
109
110
111
112
113
114







-
-
+
+







 *	       `wb+` or `w+b` | read-write, create, truncate, binary
 *	       `a`            | write-only, create, append
 *	       `ab`           | write-only, create, append, binary
 *	       `a+`           | read-write, create, append
 *	       `ab+` or `a+b` | read-write, create, append, binary
 * @return An initialized OFFile
 */
- initWithPath: (OFString*)path
	  mode: (OFString*)mode;
- initWithPath: (OFString *)path
	  mode: (OFString *)mode;

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

Modified src/OFFile.m from [c9a19755a7] to [018b6789b8].

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







-
-
+
+
















-
-
+
+







#ifdef OF_NINTENDO_DS
	if (!nitroFSInit(NULL))
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
#endif
}

+ (instancetype)fileWithPath: (OFString*)path
			mode: (OFString*)mode
+ (instancetype)fileWithPath: (OFString *)path
			mode: (OFString *)mode
{
	return [[[self alloc] initWithPath: path
				      mode: mode] autorelease];
}

+ (instancetype)fileWithFileDescriptor: (int)filedescriptor
{
	return [[[self alloc]
	    initWithFileDescriptor: filedescriptor] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

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

	@try {
		int flags;

		if ((flags = parseMode([mode UTF8String])) == -1)
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211







-
+







{
	if (_fd == -1)
		return true;

	return _atEndOfStream;
}

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

	if (_fd == -1 || _atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];
227
228
229
230
231
232
233
234

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

234
235
236
237
238
239
240
241







-
+








	if (ret == 0)
		_atEndOfStream = true;

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
- (void)lowlevelWriteBuffer: (const void *)buffer
		     length: (size_t)length
{
	if (_fd == -1 || _atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length];

#ifndef OF_WINDOWS

Modified src/OFFileManager.h from [85d228e919] to [89d56ff83d].

28
29
30
31
32
33
34
35

36
37
38
39
40
41
42

43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101

102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168


169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203


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


220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237
238
239
240
241
242
243


244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264


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

278
279
280
281
28
29
30
31
32
33
34

35
36
37
38
39
40
41

42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166


167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201


202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217


218
219
220
221
222
223
224
225
226
227

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


242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262


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

277
278
279
280
281







-
+






-
+







-
+







-
+








-
+







-
+







-
+










-
+






-
+








-
+








-
+









-
+









-
+









-
+









-
+







-
-
+
+




-
+










-
-
-
+
+
+















-
-
+
+














-
-
+
+








-
+













-
-
+
+



















-
-
+
+












-
+




 * @brief A class which provides management for files, e.g. reading contents of
 *	  directories, deleting files, renaming files, etc.
 */
@interface OFFileManager: OFObject
/*!
 * @brief Returns the default file manager.
 */
+ (OFFileManager*)defaultManager;
+ (OFFileManager *)defaultManager;

/*!
 * @brief Returns the path for the current working directory.
 *
 * @return The path of the current working directory
 */
- (OFString*)currentDirectoryPath;
- (OFString *)currentDirectoryPath;

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

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

#if defined(OF_HAVE_SYMLINK) || defined(OF_WINDOWS)
/*!
 * @brief Checks whether a symbolic link exists at the specified path.
 *
 * @param path The path to check
 * @return A boolean whether there is a symbolic link at the specified path
 */
- (bool)symbolicLinkExistsAtPath: (OFString*)path;
- (bool)symbolicLinkExistsAtPath: (OFString *)path;
#endif

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

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

/*!
 * @brief Returns an array with the items in the specified directory.
 *
 * @note `.` and `..` are not part of the returned array.
 *
 * @param path The path to the directory whose items should be returned
 * @return An array of OFString with the items in the specified directory
 */
- (OFArray OF_GENERIC(OFString*)*)contentsOfDirectoryAtPath: (OFString*)path;
- (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtPath: (OFString *)path;

/*!
 * @brief Changes the current working directory.
 *
 * @param path The new directory to change to
 */
- (void)changeCurrentDirectoryPath: (OFString*)path;
- (void)changeCurrentDirectoryPath: (OFString *)path;

/*!
 * @brief Returns the size of the specified file.
 *
 * @param path The path to the file whose size should be returned
 *
 * @return The size of the specified file
 */
- (of_offset_t)sizeOfFileAtPath: (OFString*)path;
- (of_offset_t)sizeOfFileAtPath: (OFString *)path;

/*!
 * @brief Returns the last access time of the specified item.
 *
 * @param path The path to the item whose last access time should be returned
 *
 * @return The last access time of the specified item
 */
- (OFDate*)accessTimeOfItemAtPath: (OFString*)path;
- (OFDate *)accessTimeOfItemAtPath: (OFString *)path;

/*!
 * @brief Returns the last modification time of the specified item.
 *
 * @param path The path to the item whose last modification time should be
 *	       returned
 *
 * @return The last modification time of the specified item
 */
- (OFDate*)modificationTimeOfItemAtPath: (OFString*)path;
- (OFDate *)modificationTimeOfItemAtPath: (OFString *)path;

/*!
 * @brief Returns the last status change time of the specified item.
 *
 * @param path The path to the item whose last status change time should be
 *	       returned
 *
 * @return The last status change time of the specified item
 */
- (OFDate*)statusChangeTimeOfItemAtPath: (OFString*)path;
- (OFDate *)statusChangeTimeOfItemAtPath: (OFString *)path;

#ifdef OF_HAVE_CHMOD
/*!
 * @brief Returns the permissions of the specified item.
 *
 * @param path The path to the item whose permissions should be returned
 *
 * @return The permissions of the specified item
 */
- (mode_t)permissionsOfItemAtPath: (OFString*)path;
- (mode_t)permissionsOfItemAtPath: (OFString *)path;

/*!
 * @brief Changes the permissions of an item.
 *
 * This method only changes the read-only flag on Windows.
 *
 * @param path The path to the item whose permissions should be changed
 * @param permissions The new permissions for the item
 */
- (void)changePermissionsOfItemAtPath: (OFString*)path
- (void)changePermissionsOfItemAtPath: (OFString *)path
			  permissions: (mode_t)permissions;
#endif

#ifdef OF_HAVE_CHOWN
/*!
 * @brief Get the owner and group of the specified item.
 *
 * @param owner A pointer to an OFString* to store the owner, or nil
 * @param group A pointer to an OFString* to store the group, or nil
 * @param owner A pointer to an `OFString *` to store the owner, or nil
 * @param group A pointer to an `OFString *` to store the group, or nil
 * @param path The path to the item whose owner and group should be retrieved
 */
- (void)getOwner: (OFString *__autoreleasing _Nonnull *_Nullable)owner
	   group: (OFString *__autoreleasing _Nonnull *_Nullable)group
    ofItemAtPath: (OFString*)path;
    ofItemAtPath: (OFString *)path;

/*!
 * @brief Changes the owner of an item.
 *
 * This method is not available on some systems, most notably Windows.
 *
 * @param path The path to the item whose owner should be changed
 * @param owner The new owner for the item
 * @param group The new group for the item
 */
- (void)changeOwnerOfItemAtPath: (OFString*)path
			  owner: (OFString*)owner
			  group: (OFString*)group;
- (void)changeOwnerOfItemAtPath: (OFString *)path
			  owner: (OFString *)owner
			  group: (OFString *)group;
#endif

/*!
 * @brief Copies a file, directory or symlink (if supported by the OS).
 *
 * The destination path must be a full path, which means it must include the
 * name of the item.
 *
 * If an item already exists, the copy operation fails. This is also the case
 * if a directory is copied and an item already exists in the destination
 * directory.
 *
 * @param source The file, directory or symlink to copy
 * @param destination The destination path
 */
- (void)copyItemAtPath: (OFString*)source
		toPath: (OFString*)destination;
- (void)copyItemAtPath: (OFString *)source
		toPath: (OFString *)destination;

/*!
 * @brief Moves an item.
 *
 * The destination path must be a full path, which means it must include the
 * name of the item.
 *
 * If the destination is on a different logical device, the source will be
 * copied to the destination using @ref copyItemAtPath:toPath: and the source
 * removed using @ref removeItemAtPath:.
 *
 * @param source The item to rename
 * @param destination The new name for the item
 */
- (void)moveItemAtPath: (OFString*)source
		toPath: (OFString*)destination;
- (void)moveItemAtPath: (OFString *)source
		toPath: (OFString *)destination;

/*!
 * @brief Removes the item at the specified path.
 *
 * If the item at the specified path is a directory, it is removed recursively.
 *
 * @param path The path to the item which should be removed
 */
- (void)removeItemAtPath: (OFString*)path;
- (void)removeItemAtPath: (OFString *)path;

#if defined(OF_HAVE_LINK) || defined(OF_WINDOWS)
/*!
 * @brief Creates a hard link for the specified item.
 *
 * The destination path must be a full path, which means it must include the
 * name of the item.
 *
 * This method is not available on some systems.
 *
 * @param source The path to the item for which a link should be created
 * @param destination The path to the item which should link to the source
 */
- (void)linkItemAtPath: (OFString*)source
		toPath: (OFString*)destination;
- (void)linkItemAtPath: (OFString *)source
		toPath: (OFString *)destination;
#endif

#if defined(OF_HAVE_SYMLINK) || defined(OF_WINDOWS)
/*!
 * @brief Creates a symbolic link for an item.
 *
 * The destination path must be a full path, which means it must include the
 * name of the item.
 *
 * This method is not available on some systems.
 *
 * @note On Windows, this requires at least Windows Vista and administrator
 *	 privileges!
 *
 * @param destination The path to the item which should symbolically link to the
 *		      source
 * @param source The path to the item for which a symbolic link should be
 *		 created
 */
- (void)createSymbolicLinkAtPath: (OFString*)destination
	     withDestinationPath: (OFString*)source;
- (void)createSymbolicLinkAtPath: (OFString *)destination
	     withDestinationPath: (OFString *)source;
#endif

#if defined(OF_HAVE_READLINK) || defined(OF_WINDOWS)
/*!
 * @brief Returns the destination of the symbolic link at the specified path.
 *
 * @param path The path to the symbolic link
 *
 * @note On Windows, at least Windows Vista is required.
 *
 * @return The destination of the symbolic link at the specified path
 */
- (OFString*)destinationOfSymbolicLinkAtPath: (OFString*)path;
- (OFString *)destinationOfSymbolicLinkAtPath: (OFString *)path;
#endif
@end

OF_ASSUME_NONNULL_END

Modified src/OFFileManager.m from [6f389e5f28] to [f4973b705b].

161
162
163
164
165
166
167
168

169
170
171
172
173

174
175
176
177
178
179
180
161
162
163
164
165
166
167

168
169
170
171
172

173
174
175
176
177
178
179
180







-
+




-
+







		    (WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR, DWORD))
		    GetProcAddress(module, "CreateSymbolicLinkW");
#endif

	defaultManager = [[OFFileManager alloc] init];
}

+ (OFFileManager*)defaultManager
+ (OFFileManager *)defaultManager
{
	return defaultManager;
}

- (OFString*)currentDirectoryPath
- (OFString *)currentDirectoryPath
{
	OFString *ret;
#ifndef OF_WINDOWS
	char *buffer = getcwd(NULL, 0);
#else
	wchar_t *buffer = _wgetcwd(NULL, 0);
#endif
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

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

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

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

278
279
280
281
282
283
284
190
191
192
193
194
195
196

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

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

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

277
278
279
280
281
282
283
284







-
+















-
+
















-
+















-
+














-
+















-
+







	} @finally {
		free(buffer);
	}

	return ret;
}

- (bool)fileExistsAtPath: (OFString*)path
- (bool)fileExistsAtPath: (OFString *)path
{
	of_stat_t s;

	if (path == nil)
		@throw [OFInvalidArgumentException exception];

	if (of_stat(path, &s) == -1)
		return false;

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

	return false;
}

- (bool)directoryExistsAtPath: (OFString*)path
- (bool)directoryExistsAtPath: (OFString *)path
{
	of_stat_t s;

	if (path == nil)
		@throw [OFInvalidArgumentException exception];

	if (of_stat(path, &s) == -1)
		return false;

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

	return false;
}

#if defined(OF_HAVE_SYMLINK)
- (bool)symbolicLinkExistsAtPath: (OFString*)path
- (bool)symbolicLinkExistsAtPath: (OFString *)path
{
	of_stat_t s;

	if (path == nil)
		@throw [OFInvalidArgumentException exception];

	if (of_lstat(path, &s) == -1)
		return false;

	if (S_ISLNK(s.st_mode))
		return true;

	return false;
}
#elif defined(OF_WINDOWS)
- (bool)symbolicLinkExistsAtPath: (OFString*)path
- (bool)symbolicLinkExistsAtPath: (OFString *)path
{
	WIN32_FIND_DATAW data;

	if (!FindFirstFileW([path UTF16String], &data))
		return false;

	if ((data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
	    data.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
		return true;

	return false;
}
#endif

- (void)createDirectoryAtPath: (OFString*)path
- (void)createDirectoryAtPath: (OFString *)path
{
	if (path == nil)
		@throw [OFInvalidArgumentException exception];

#ifndef OF_WINDOWS
	if (mkdir([path cStringWithEncoding: [OFLocalization encoding]],
	    DIR_MODE) != 0)
#else
	if (_wmkdir([path UTF16String]) != 0)
#endif
		@throw [OFCreateDirectoryFailedException
		    exceptionWithPath: path
				errNo: errno];
}

- (void)createDirectoryAtPath: (OFString*)path
- (void)createDirectoryAtPath: (OFString *)path
		createParents: (bool)createParents
{
	OFString *currentPath = nil;

	if (!createParents) {
		[self createDirectoryAtPath: path];
		return;
304
305
306
307
308
309
310
311

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

311
312
313
314
315
316
317
318







-
+








		objc_autoreleasePoolPop(pool);

		[currentPath autorelease];
	}
}

- (OFArray*)contentsOfDirectoryAtPath: (OFString*)path
- (OFArray *)contentsOfDirectoryAtPath: (OFString *)path
{
	OFMutableArray *files;
#ifndef OF_WINDOWS
	of_string_encoding_t encoding;
#endif

	if (path == nil)
424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468
469
470
471
472
473
474
475

476
477
478
479
480
481
482
483
484
485
486
487
488
489
490

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

507
508
509
510
511
512
513
514
515
516
517
518
519
520

521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542



543
544
545
546
547
548
549
424
425
426
427
428
429
430

431
432
433
434
435
436
437
438
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467
468
469
470
471
472
473
474

475
476
477
478
479
480
481
482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505

506
507
508
509
510
511
512
513
514
515
516
517
518
519

520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539



540
541
542
543
544
545
546
547
548
549







-
+














-
+













-
+














-
+














-
+















-
+













-
+



















-
-
-
+
+
+







#endif

	[files makeImmutable];

	return files;
}

- (void)changeCurrentDirectoryPath: (OFString*)path
- (void)changeCurrentDirectoryPath: (OFString *)path
{
	if (path == nil)
		@throw [OFInvalidArgumentException exception];

#ifndef OF_WINDOWS
	if (chdir([path cStringWithEncoding: [OFLocalization encoding]]) != 0)
#else
	if (_wchdir([path UTF16String]) != 0)
#endif
		@throw [OFChangeCurrentDirectoryPathFailedException
		    exceptionWithPath: path
				errNo: errno];
}

- (of_offset_t)sizeOfFileAtPath: (OFString*)path
- (of_offset_t)sizeOfFileAtPath: (OFString *)path
{
	of_stat_t s;

	if (path == nil)
		@throw [OFInvalidArgumentException exception];

	if (of_stat(path, &s) != 0)
		@throw [OFStatItemFailedException exceptionWithPath: path
							      errNo: errno];

	return s.st_size;
}

- (OFDate*)accessTimeOfItemAtPath: (OFString*)path
- (OFDate *)accessTimeOfItemAtPath: (OFString *)path
{
	of_stat_t s;

	if (path == nil)
		@throw [OFInvalidArgumentException exception];

	if (of_stat(path, &s) != 0)
		@throw [OFStatItemFailedException exceptionWithPath: path
							      errNo: errno];

	/* FIXME: We could be more precise on some OSes */
	return [OFDate dateWithTimeIntervalSince1970: s.st_atime];
}

- (OFDate*)modificationTimeOfItemAtPath: (OFString*)path
- (OFDate *)modificationTimeOfItemAtPath: (OFString *)path
{
	of_stat_t s;

	if (path == nil)
		@throw [OFInvalidArgumentException exception];

	if (of_stat(path, &s) != 0)
		@throw [OFStatItemFailedException exceptionWithPath: path
							      errNo: errno];

	/* FIXME: We could be more precise on some OSes */
	return [OFDate dateWithTimeIntervalSince1970: s.st_mtime];
}

- (OFDate*)statusChangeTimeOfItemAtPath: (OFString*)path
- (OFDate *)statusChangeTimeOfItemAtPath: (OFString *)path
{
	of_stat_t s;

	if (path == nil)
		@throw [OFInvalidArgumentException exception];

	if (of_stat(path, &s) != 0)
		@throw [OFStatItemFailedException exceptionWithPath: path
							      errNo: errno];

	/* FIXME: We could be more precise on some OSes */
	return [OFDate dateWithTimeIntervalSince1970: s.st_ctime];
}

#ifdef OF_HAVE_CHMOD
- (mode_t)permissionsOfItemAtPath: (OFString*)path
- (mode_t)permissionsOfItemAtPath: (OFString *)path
{
	of_stat_t s;

	if (path == nil)
		@throw [OFInvalidArgumentException exception];

	if (of_stat(path, &s) != 0)
		@throw [OFStatItemFailedException exceptionWithPath: path
							      errNo: errno];

	return s.st_mode;
}

- (void)changePermissionsOfItemAtPath: (OFString*)path
- (void)changePermissionsOfItemAtPath: (OFString *)path
			  permissions: (mode_t)permissions
{
	if (path == nil)
		@throw [OFInvalidArgumentException exception];

# ifndef OF_WINDOWS
	if (chmod([path cStringWithEncoding: [OFLocalization encoding]],
	    permissions) != 0)
# else
	if (_wchmod([path UTF16String], permissions) != 0)
# endif
		@throw [OFChangePermissionsFailedException
		    exceptionWithPath: path
			  permissions: permissions
				errNo: errno];
}
#endif

#ifdef OF_HAVE_CHOWN
- (void)getOwner: (OFString**)owner
	   group: (OFString**)group
    ofItemAtPath: (OFString*)path
- (void)getOwner: (OFString **)owner
	   group: (OFString **)group
    ofItemAtPath: (OFString *)path
{
	of_stat_t s;

	if (path == nil)
		@throw [OFInvalidArgumentException exception];

	if (of_stat(path, &s) != 0)
572
573
574
575
576
577
578
579
580
581



582
583
584
585
586
587
588
572
573
574
575
576
577
578



579
580
581
582
583
584
585
586
587
588







-
-
-
+
+
+







# ifdef OF_HAVE_THREADS
	} @finally {
		[passwdMutex unlock];
	}
#endif
}

- (void)changeOwnerOfItemAtPath: (OFString*)path
			  owner: (OFString*)owner
			  group: (OFString*)group
- (void)changeOwnerOfItemAtPath: (OFString *)path
			  owner: (OFString *)owner
			  group: (OFString *)group
{
	uid_t uid = -1;
	gid_t gid = -1;
	of_string_encoding_t encoding;

	if (path == nil || (owner == nil && group == nil))
		@throw [OFInvalidArgumentException exception];
630
631
632
633
634
635
636
637
638


639
640
641
642
643
644
645
630
631
632
633
634
635
636


637
638
639
640
641
642
643
644
645







-
-
+
+







		@throw [OFChangeOwnerFailedException exceptionWithPath: path
								 owner: owner
								 group: group
								 errNo: errno];
}
#endif

- (void)copyItemAtPath: (OFString*)source
		toPath: (OFString*)destination
- (void)copyItemAtPath: (OFString *)source
		toPath: (OFString *)destination
{
	void *pool;
	of_stat_t s;

	if (source == nil || destination == nil)
		@throw [OFInvalidArgumentException exception];

774
775
776
777
778
779
780
781
782


783
784
785
786
787
788
789
774
775
776
777
778
779
780


781
782
783
784
785
786
787
788
789







-
-
+
+







		    exceptionWithSourcePath: source
			    destinationPath: destination
				      errNo: EINVAL];

	objc_autoreleasePoolPop(pool);
}

- (void)moveItemAtPath: (OFString*)source
		toPath: (OFString*)destination
- (void)moveItemAtPath: (OFString *)source
		toPath: (OFString *)destination
{
	void *pool;
	of_stat_t s;
#ifndef OF_WINDOWS
	of_string_encoding_t encoding;
#endif

833
834
835
836
837
838
839
840

841
842
843
844
845
846
847
833
834
835
836
837
838
839

840
841
842
843
844
845
846
847







-
+







					      errNo: [e errNo]];
		}
	}

	objc_autoreleasePoolPop(pool);
}

- (void)removeItemAtPath: (OFString*)path
- (void)removeItemAtPath: (OFString *)path
{
	void *pool;
	of_stat_t s;

	if (path == nil)
		@throw [OFInvalidArgumentException exception];

902
903
904
905
906
907
908
909
910


911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932


933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953


954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975


976
977
978
979
980
981
982
902
903
904
905
906
907
908


909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930


931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951


952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973


974
975
976
977
978
979
980
981
982







-
-
+
+




















-
-
+
+



















-
-
+
+




















-
-
+
+







					errNo: errno];
	}

	objc_autoreleasePoolPop(pool);
}

#if defined(OF_HAVE_LINK)
- (void)linkItemAtPath: (OFString*)source
		toPath: (OFString*)destination
- (void)linkItemAtPath: (OFString *)source
		toPath: (OFString *)destination
{
	void *pool;
	of_string_encoding_t encoding;

	if (source == nil || destination == nil)
		@throw [OFInvalidArgumentException exception];

	pool = objc_autoreleasePoolPush();
	encoding = [OFLocalization encoding];

	if (link([source cStringWithEncoding: encoding],
	    [destination cStringWithEncoding: encoding]) != 0)
		@throw [OFLinkFailedException
		    exceptionWithSourcePath: source
			    destinationPath: destination
				      errNo: errno];

	objc_autoreleasePoolPop(pool);
}
#else
- (void)linkItemAtPath: (OFString*)source
		toPath: (OFString*)destination
- (void)linkItemAtPath: (OFString *)source
		toPath: (OFString *)destination
{
	void *pool;

	if (source == nil || destination == nil)
		@throw [OFInvalidArgumentException exception];

	pool = objc_autoreleasePoolPush();

	if (!CreateHardLinkW([destination UTF16String],
	    [source UTF16String], NULL))
		@throw [OFLinkFailedException
		    exceptionWithSourcePath: source
			    destinationPath: destination];

	objc_autoreleasePoolPop(pool);
}
#endif

#if defined(OF_HAVE_SYMLINK)
- (void)createSymbolicLinkAtPath: (OFString*)destination
	     withDestinationPath: (OFString*)source
- (void)createSymbolicLinkAtPath: (OFString *)destination
	     withDestinationPath: (OFString *)source
{
	void *pool;
	of_string_encoding_t encoding;

	if (source == nil || destination == nil)
		@throw [OFInvalidArgumentException exception];

	pool = objc_autoreleasePoolPush();
	encoding = [OFLocalization encoding];

	if (symlink([source cStringWithEncoding: encoding],
	    [destination cStringWithEncoding: encoding]) != 0)
		@throw [OFCreateSymbolicLinkFailedException
		    exceptionWithSourcePath: source
			    destinationPath: destination
				      errNo: errno];

	objc_autoreleasePoolPop(pool);
}
#elif defined(OF_WINDOWS)
- (void)createSymbolicLinkAtPath: (OFString*)destination
	     withDestinationPath: (OFString*)source
- (void)createSymbolicLinkAtPath: (OFString *)destination
	     withDestinationPath: (OFString *)source
{
	void *pool;

	if (func_CreateSymbolicLinkW == NULL)
		@throw [OFNotImplementedException exceptionWithSelector: _cmd
								 object: self];

992
993
994
995
996
997
998
999

1000
1001
1002
1003
1004
1005
1006
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
1006







-
+







			    destinationPath: destination];

	objc_autoreleasePoolPop(pool);
}
#endif

#ifdef OF_HAVE_READLINK
- (OFString*)destinationOfSymbolicLinkAtPath: (OFString*)path
- (OFString *)destinationOfSymbolicLinkAtPath: (OFString *)path
{
	char destination[PATH_MAX];
	ssize_t length;
	of_string_encoding_t encoding;

	if (path == nil)
		@throw [OFInvalidArgumentException exception];
1014
1015
1016
1017
1018
1019
1020
1021

1022
1023
1024
1025
1026
1027
1028
1014
1015
1016
1017
1018
1019
1020

1021
1022
1023
1024
1025
1026
1027
1028







-
+







							      errNo: errno];

	return [OFString stringWithCString: destination
				  encoding: encoding
				    length: length];
}
#elif defined(OF_WINDOWS)
- (OFString*)destinationOfSymbolicLinkAtPath: (OFString*)path
- (OFString *)destinationOfSymbolicLinkAtPath: (OFString *)path
{
	HANDLE handle;

	/* Check if we're on a version that actually supports symlinks. */
	if (func_CreateSymbolicLinkW == NULL)
		@throw [OFNotImplementedException exceptionWithSelector: _cmd
								 object: self];

Modified src/OFGZIPStream.h from [dc02ae5a5d] to [3b1588eaa2].

70
71
72
73
74
75
76
77
78


79
80
81
70
71
72
73
74
75
76


77
78
79
80
81







-
-
+
+



	size_t _bytesRead;
	uint8_t _buffer[4];
	OFDate *_modificationDate;
	uint16_t _extraLength;
	uint32_t _CRC32, _uncompressedSize;
}

+ (instancetype)streamWithStream: (OFStream*)stream;
- initWithStream: (OFStream*)stream;
+ (instancetype)streamWithStream: (OFStream *)stream;
- initWithStream: (OFStream *)stream;
@end

OF_ASSUME_NONNULL_END

Modified src/OFGZIPStream.m from [1c958d34d5] to [e4f1e2e6e9].

22
23
24
25
26
27
28
29

30
31
32
33
34

35
36
37
38
39
40
41
22
23
24
25
26
27
28

29
30
31
32
33

34
35
36
37
38
39
40
41







-
+




-
+








#import "crc32.h"

#import "OFChecksumFailedException.h"
#import "OFInvalidFormatException.h"

@implementation OFGZIPStream
+ (instancetype)streamWithStream: (OFStream*)stream
+ (instancetype)streamWithStream: (OFStream *)stream
{
	return [[[self alloc] initWithStream: stream] autorelease];
}

- initWithStream: (OFStream*)stream
- initWithStream: (OFStream *)stream
{
	self = [super init];

	@try {
		_stream = [stream retain];
		_CRC32 = ~0;
	} @catch (id e) {
51
52
53
54
55
56
57
58

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

58
59
60
61
62
63
64
65







-
+







	[_stream release];
	[_inflateStream release];
	[_modificationDate release];

	[super dealloc];
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer
- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	uint8_t byte;

	for (;;) {
		switch (_state) {
		case OF_GZIP_STREAM_ID1:

Modified src/OFHMAC.h from [60c34cd9f4] to [6621f48b54].

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







-
+








-
+










-
+







 * @warning This invalidates any pointer previously returned by @ref digest. If
 *	    you are still interested in the previous digest, you need to memcpy
 *	    it yourself before calling @ref setKey:length:!
 *
 * @param key The key for the HMAC
 * @param length The length of the key for the HMAC
 */
- (void)setKey: (const void*)key
- (void)setKey: (const void *)key
	length: (size_t)length;

/*!
 * @brief Adds a buffer to the HMAC to be calculated.
 *
 * @param buffer The buffer which should be included into the calculation
 * @param length The length of the buffer
 */
- (void)updateWithBuffer: (const void*)buffer
- (void)updateWithBuffer: (const void *)buffer
		  length: (size_t)length;

/*!
 * @brief Returns a buffer containing the HMAC.
 *
 * The size of the buffer depends on the hash used. The buffer is part of the
 * receiver's memory pool.
 *
 * @return A buffer containing the hash
 */
- (const unsigned char*)digest OF_RETURNS_INNER_POINTER;
- (const unsigned char *)digest OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns the size of the digest.
 *
 * @return The size of the digest.
 */
- (size_t)digestSize;

Modified src/OFHMAC.m from [2e98081b44] to [1827be5212].

42
43
44
45
46
47
48
49

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

49
50
51
52
53
54
55
56







-
+







	[_innerHash release];
	[_outerHashCopy release];
	[_innerHashCopy release];

	[super dealloc];
}

- (void)setKey: (const void*)key
- (void)setKey: (const void *)key
	length: (size_t)length
{
	void *pool = objc_autoreleasePoolPush();
	size_t blockSize = [_hashClass blockSize];
	uint8_t outerKeyPad[blockSize], innerKeyPad[blockSize];

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







-
+













-
+








	_outerHashCopy = [_outerHash copy];
	_innerHashCopy = [_innerHash copy];

	_calculated = false;
}

- (void)updateWithBuffer: (const void*)buffer
- (void)updateWithBuffer: (const void *)buffer
		  length: (size_t)length
{
	if (_innerHash == nil)
		@throw [OFInvalidArgumentException exception];

	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithObject: self];

	[_innerHash updateWithBuffer: buffer
			      length: length];
}

- (const unsigned char*)digest
- (const unsigned char *)digest
{
	if (_outerHash == nil || _innerHash == nil)
		@throw [OFInvalidArgumentException exception];

	if (_calculated)
		return [_outerHash digest];

Modified src/OFHTTPClient.h from [08ff8ce82a] to [8fd8945807].

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







-
-
-
+
+
+










-
-
+
+

-
+







 * about the certificate. Another use case is to tell the socket about a SOCKS5
 * proxy it should use for this connection.
 *
 * @param client The OFHTTPClient that created a socket
 * @param socket The socket created by the OFHTTPClient
 * @param request The request for which the socket was created
 */
-    (void)client: (OFHTTPClient*)client
  didCreateSocket: (OF_KINDOF(OFTCPSocket*))socket
	  request: (OFHTTPRequest*)request;
-    (void)client: (OFHTTPClient *)client
  didCreateSocket: (OF_KINDOF(OFTCPSocket *))socket
	  request: (OFHTTPRequest *)request;

/*!
 * @brief A callback which is called when an OFHTTPClient received headers.
 *
 * @param client The OFHTTPClient which received the headers
 * @param headers The headers received
 * @param statusCode The status code received
 * @param request The request for which the headers and status code have been
 *		  received
 */
-      (void)client: (OFHTTPClient*)client
  didReceiveHeaders: (OFDictionary OF_GENERIC(OFString*, OFString*)*)headers
-      (void)client: (OFHTTPClient *)client
  didReceiveHeaders: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headers
	 statusCode: (int)statusCode
	    request: (OFHTTPRequest*)request;
	    request: (OFHTTPRequest *)request;

/*!
 * @brief A callback which is called when an OFHTTPClient wants to follow a
 *	  redirect.
 *
 * If you want to get the headers and data for each redirect, set the number of
 * redirects to 0 and perform a new OFHTTPClient for each redirect. However,
83
84
85
86
87
88
89
90
91


92
93
94


95
96
97
98
99
100
101
83
84
85
86
87
88
89


90
91
92


93
94
95
96
97
98
99
100
101







-
-
+
+

-
-
+
+







 * @param client The OFHTTPClient which wants to follow a redirect
 * @param URL The URL to which it will follow a redirect
 * @param statusCode The status code for the redirection
 * @param request The request for which the OFHTTPClient wants to redirect
 * @param response The response indicating the redirect
 * @return A boolean whether the OFHTTPClient should follow the redirect
 */
-	  (bool)client: (OFHTTPClient*)client
  shouldFollowRedirect: (OFURL*)URL
-	  (bool)client: (OFHTTPClient *)client
  shouldFollowRedirect: (OFURL *)URL
	    statusCode: (int)statusCode
	       request: (OFHTTPRequest*)request
	      response: (OFHTTPResponse*)response;
	       request: (OFHTTPRequest *)request
	      response: (OFHTTPResponse *)response;
@end

/*!
 * @class OFHTTPClient OFHTTPClient.h ObjFW/OFHTTPClient.h
 *
 * @brief A class for performing HTTP requests.
 */
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
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







-
+










-
-
+
+








+ (instancetype)client;

/*!
 * @brief Performs the specified HTTP request and returns an OFHTTPResponse.
 *
 * @return An OFHTTPResponse with the response for the HTTP request
 */
- (OFHTTPResponse*)performRequest: (OFHTTPRequest*)request;
- (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request;

/*!
 * @brief Performs the HTTP request and returns an OFHTTPResponse.
 *
 * @param request The request to perform
 * @param redirects The maximum number of redirects after which no further
 *		    attempt is done to follow the redirect, but instead the
 *		    redirect is returned as an OFHTTPResponse
 * @return An OFHTTPResponse with the response for the HTTP request
 */
- (OFHTTPResponse*)performRequest: (OFHTTPRequest*)request
			redirects: (size_t)redirects;
- (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request
			 redirects: (size_t)redirects;

/*!
 * @brief Closes connections that are still open due to keep-alive.
 */
- (void)close;
@end

OF_ASSUME_NONNULL_END

Modified src/OFHTTPClient.m from [f34d4593a1] to [8ee3bb44d0].

40
41
42
43
44
45
46
47

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

47
48
49
50
51
52
53
54







-
+







#import "OFUnsupportedProtocolException.h"
#import "OFUnsupportedVersionException.h"
#import "OFWriteFailedException.h"

static OF_INLINE void
normalizeKey(char *str_)
{
	unsigned char *str = (unsigned char*)str_;
	unsigned char *str = (unsigned char *)str_;
	bool firstLetter = true;

	while (*str != '\0') {
		if (!of_ascii_isalpha(*str)) {
			firstLetter = true;
			str++;
			continue;
66
67
68
69
70
71
72
73

74
75
76
77
78

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

100
101
102
103
104
105
106
66
67
68
69
70
71
72

73
74
75
76
77

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

99
100
101
102
103
104
105
106







-
+




-
+




















-
+







@interface OFHTTPClientResponse: OFHTTPResponse
{
	OFTCPSocket *_socket;
	bool _hasContentLength, _chunked, _keepAlive, _atEndOfStream;
	size_t _toRead;
}

- initWithSocket: (OFTCPSocket*)socket;
- initWithSocket: (OFTCPSocket *)socket;
- (void)OF_setKeepAlive: (bool)keepAlive;
@end

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

	_socket = [socket retain];

	return self;
}

- (void)OF_setKeepAlive: (bool)keepAlive
{
	_keepAlive = keepAlive;
}

- (void)dealloc
{
	[_socket release];

	[super dealloc];
}

- (void)setHeaders: (OFDictionary*)headers
- (void)setHeaders: (OFDictionary *)headers
{
	OFString *contentLength;

	[super setHeaders: headers];

	_chunked = [[headers objectForKey: @"Transfer-Encoding"]
	    isEqual: @"chunked"];
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137







-
+







			_toRead = (size_t)toRead;
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidServerReplyException exception];
		}
	}
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer
- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	if (_atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length
							    errNo: ENOTCONN];

273
274
275
276
277
278
279
280

281
282
283
284
285
286

287
288
289
290
291
292
293
273
274
275
276
277
278
279

280
281
282
283
284
285

286
287
288
289
290
291
292
293







-
+





-
+







- (void)dealloc
{
	[self close];

	[super dealloc];
}

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

- (OFTCPSocket*)OF_closeAndCreateSocketForRequest: (OFHTTPRequest*)request
- (OFTCPSocket *)OF_closeAndCreateSocketForRequest: (OFHTTPRequest *)request
{
	OFURL *URL = [request URL];
	OFTCPSocket *socket;

	[self close];

	if ([[URL scheme] isEqual: @"https"]) {
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
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







-
-
+
+








-
+





-
+








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

	return socket;
}

- (OFHTTPResponse*)performRequest: (OFHTTPRequest*)request
			redirects: (size_t)redirects
- (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request
			 redirects: (size_t)redirects
{
	void *pool = objc_autoreleasePoolPush();
	OFURL *URL = [request URL];
	OFString *scheme = [URL scheme];
	of_http_request_method_t method = [request method];
	OFString *path;
	OFMutableString *requestString;
	OFString *user, *password;
	OFMutableDictionary OF_GENERIC(OFString*, OFString*) *headers;
	OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers;
	OFDataArray *body = [request body];
	OFTCPSocket *socket;
	OFHTTPClientResponse *response;
	OFString *line, *version, *redirect, *connectionHeader;
	bool keepAlive;
	OFMutableDictionary OF_GENERIC(OFString*, OFString*) *serverHeaders;
	OFMutableDictionary OF_GENERIC(OFString *, OFString *) *serverHeaders;
	OFEnumerator *keyEnumerator, *objectEnumerator;
	OFString *key, *object;
	int status;

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

Modified src/OFHTTPCookie.h from [4d41b6f478] to [f54859d1ab].

26
27
28
29
30
31
32
33

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

33
34
35
36
37
38
39
40







-
+







 */
@interface OFHTTPCookie: OFObject <OFCopying>
{
	OFString *_name, *_value;
	OFDate *_expires;
	OFString *_domain, *_path;
	bool _secure, _HTTPOnly;
	OFMutableArray OF_GENERIC(OFString*) *_extensions;
	OFMutableArray OF_GENERIC(OFString *) *_extensions;
}

/*!
 * The name of the cookie.
 */
@property (nonatomic, copy) OFString *name;

68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85


86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104


105
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83


84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102


103
104
105







-
+








-
-
+
+







-
+









-
-
+
+

 */
@property (getter=isHTTPOnly) bool HTTPOnly;

/*!
 * An array of other attributes.
 */
@property (readonly, nonatomic)
    OFMutableArray OF_GENERIC(OFString*) *extensions;
    OFMutableArray OF_GENERIC(OFString *) *extensions;

/*!
 * @brief Create a new cookie with the specified name and value.
 *
 * @param name The name of the cookie
 * @param value The value of the cookie
 * @return A new, autoreleased OFHTTPCookie
 */
+ (instancetype)cookieWithName: (OFString*)name
			 value: (OFString*)value;
+ (instancetype)cookieWithName: (OFString *)name
			 value: (OFString *)value;

/*!
 * @brief Parses the specified string and returns an array of cookies.
 *
 * @param string The cookie string to parse
 * @return An array of cookies
 */
+ (OFArray OF_GENERIC(OFHTTPCookie*)*)cookiesForString: (OFString*)string;
+ (OFArray OF_GENERIC(OFHTTPCookie *) *)cookiesForString: (OFString *)string;

/*!
 * @brief Initializes an already allocated new cookie with the specified name
 *	  and value.
 *
 * @param name The name of the cookie
 * @param value The value of the cookie
 * @return An initialized OFHTTPCookie
 */
- initWithName: (OFString*)name
	 value: (OFString*)value;
- initWithName: (OFString *)name
	 value: (OFString *)value;
@end

Modified src/OFHTTPCookie.m from [ee6a333bc6] to [ef24e84f97].

53
54
55
56
57
58
59
60
61


62
63
64
65
66
67

68
69

70
71
72
73
74
75
76
53
54
55
56
57
58
59


60
61
62
63
64
65
66

67
68

69
70
71
72
73
74
75
76







-
-
+
+





-
+

-
+







}

@implementation OFHTTPCookie
@synthesize name = _name, value = _value, expires = _expires, domain = _domain;
@synthesize path = _path, secure = _secure, HTTPOnly = _HTTPOnly;
@synthesize extensions = _extensions;

+ (instancetype)cookieWithName: (OFString*)name
			 value: (OFString*)value
+ (instancetype)cookieWithName: (OFString *)name
			 value: (OFString *)value
{
	return [[[self alloc] initWithName: name
				     value: value] autorelease];
}

+ (OFArray OF_GENERIC(OFHTTPCookie*)*)cookiesForString: (OFString*)string
+ (OFArray OF_GENERIC(OFHTTPCookie *) *)cookiesForString: (OFString *)string
{
	OFMutableArray OF_GENERIC(OFHTTPCookie*) *ret = [OFMutableArray array];
	OFMutableArray OF_GENERIC(OFHTTPCookie *) *ret = [OFMutableArray array];
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [string characters];
	size_t length = [string length], last = 0;
	enum {
		STATE_PRE_NAME,
		STATE_NAME,
		STATE_EXPECT_VALUE,
245
246
247
248
249
250
251
252
253


254
255
256
257
258
259
260
245
246
247
248
249
250
251


252
253
254
255
256
257
258
259
260







-
-
+
+







}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithName: (OFString*)name
	 value: (OFString*)value
- initWithName: (OFString *)name
	 value: (OFString *)value
{
	self = [super init];

	@try {
		_name = [name copy];
		_value = [value copy];
		_extensions = [[OFMutableArray alloc] init];
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357







-
+







		[copy release];
		@throw e;
	}

	return copy;
}

- (OFString*)description
- (OFString *)description
{
	OFMutableString *ret = [OFMutableString
	    stringWithFormat: @"%@=%@", _name, _value];
	void *pool = objc_autoreleasePoolPush();

	if (_expires != nil)
		[ret appendString:

Modified src/OFHTTPRequest.h from [116a255b13] to [f3657b719a].

72
73
74
75
76
77
78
79
80


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

100
101
102
103
104
105

106
107
108
109
110
111
112
72
73
74
75
76
77
78


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

99
100
101
102
103
104

105
106
107
108
109
110
111
112







-
-
+
+


















-
+





-
+







 * @brief A class for storing HTTP requests.
 */
@interface OFHTTPRequest: OFObject <OFCopying>
{
	OFURL *_URL;
	of_http_request_method_t _method;
	of_http_request_protocol_version_t _protocolVersion;
	OFDictionary OF_GENERIC(OFString*, OFString*) *_headers;
	OFArray OF_GENERIC(OFHTTPCookie*) *_cookies;
	OFDictionary OF_GENERIC(OFString *, OFString *) *_headers;
	OFArray OF_GENERIC(OFHTTPCookie *) *_cookies;
	OFDataArray *_body;
	OFString *_remoteAddress;
}

/*!
 * The URL of the HTTP request.
 */
@property (nonatomic, copy) OFURL *URL;

/*!
 * The request method of the HTTP request.
 */
@property of_http_request_method_t method;

/*!
 * The headers for the HTTP request.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, copy)
    OFDictionary OF_GENERIC(OFString*, OFString*) *headers;
    OFDictionary OF_GENERIC(OFString *, OFString *) *headers;

/*!
 * The cookies for the HTTP request.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, copy)
    OFArray OF_GENERIC(OFHTTPCookie*) *cookies;
    OFArray OF_GENERIC(OFHTTPCookie *) *cookies;

/*!
 * The entity body of the HTTP request.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, retain) OFDataArray *body;

/*!
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145







-
+







-
+








/*!
 * @brief Creates a new OFHTTPRequest with the specified URL.
 *
 * @param URL The URL for the request
 * @return A new, autoreleased OFHTTPRequest
 */
+ (instancetype)requestWithURL: (OFURL*)URL;
+ (instancetype)requestWithURL: (OFURL *)URL;

/*!
 * @brief Initializes an already allocated OFHTTPRequest with the specified URL.
 *
 * @param URL The URL for the request
 * @return An initialized OFHTTPRequest
 */
- initWithURL: (OFURL*)URL;
- initWithURL: (OFURL *)URL;

/*!
 * @brief Sets the protocol version of the HTTP request.
 *
 * @param protocolVersion The protocol version of the HTTP request
 */
- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion;
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
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







-
+






-
+







-
+








-
+








/*!
 * @brief Sets the protocol version of the HTTP request to the version
 *	  described by the specified string.
 *
 * @param string A string describing an HTTP version
 */
- (void)setProtocolVersionFromString: (OFString*)string;
- (void)setProtocolVersionFromString: (OFString *)string;

/*!
 * @brief Returns the protocol version of the HTTP request as a string.
 *
 * @return The protocol version of the HTTP request as a string
 */
- (OFString*)protocolVersionString;
- (OFString *)protocolVersionString;

/*!
 * @brief Sets the entity body of the HTTP request to the specified string
 *	  encoded in UTF-8.
 *
 * @param string The string to use for the entity body
 */
- (void)setBodyFromString: (nullable OFString*)string;
- (void)setBodyFromString: (nullable OFString *)string;

/*!
 * @brief Sets the entity body of the HTTP request to the specified string
 *	  encoded in the specified encoding.
 *
 * @param string The string to use for the entity body
 * @param encoding The encoding to encode the string with
 */
- (void)setBodyFromString: (nullable OFString*)string
- (void)setBodyFromString: (nullable OFString *)string
		 encoding: (of_string_encoding_t)encoding;
@end

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

Modified src/OFHTTPRequest.m from [2083545dd2] to [c7f95080da].

25
26
27
28
29
30
31
32

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

32
33
34
35
36
37
38
39







-
+







#import "OFDataArray.h"
#import "OFArray.h"

#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"
#import "OFUnsupportedVersionException.h"

const char*
const char *
of_http_request_method_to_string(of_http_request_method_t method)
{
	switch (method) {
	case OF_HTTP_REQUEST_METHOD_OPTIONS:
		return "OPTIONS";
	case OF_HTTP_REQUEST_METHOD_GET:
		return "GET";
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
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







-
+















-
+







@synthesize cookies = _cookies, body = _body, remoteAddress = _remoteAddress;

+ (instancetype)request
{
	return [[[self alloc] init] autorelease];
}

+ (instancetype)requestWithURL: (OFURL*)URL
+ (instancetype)requestWithURL: (OFURL *)URL
{
	return [[[self alloc] initWithURL: URL] autorelease];
}

- init
{
	self = [super init];

	_method = OF_HTTP_REQUEST_METHOD_GET;
	_protocolVersion.major = 1;
	_protocolVersion.minor = 1;

	return self;
}

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

	@try {
		[self setURL: URL];
	} @catch (id e) {
		[self release];
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212







-
+







}

- (of_http_request_protocol_version_t)protocolVersion
{
	return _protocolVersion;
}

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

	if ([components count] != 2)
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236

237
238
239
240
241
242

243
244
245
246
247
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
222
223
224
225
226
227
228

229
230
231
232
233
234
235

236
237
238
239
240
241

242
243
244
245
246
247
248
249
250
251
252
253
254

255
256
257
258
259
260
261
262







-
+






-
+





-
+












-
+







	protocolVersion.minor = (uint8_t)minor;

	[self setProtocolVersion: protocolVersion];

	objc_autoreleasePoolPop(pool);
}

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

- (void)setBodyFromString: (OFString*)string
- (void)setBodyFromString: (OFString *)string
{
	[self setBodyFromString: string
		       encoding: OF_STRING_ENCODING_UTF_8];
}

- (void)setBodyFromString: (OFString*)string
- (void)setBodyFromString: (OFString *)string
		 encoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFDataArray *body = [OFDataArray dataArray];

	[body addItems: [string cStringWithEncoding: encoding]
		 count: [string cStringLengthWithEncoding: encoding]];
	[self setBody: body];

	objc_autoreleasePoolPop(pool);
}

- (OFString*)description
- (OFString *)description
{
	void *pool = objc_autoreleasePoolPush();
	const char *method = of_http_request_method_to_string(_method);
	OFString *indentedHeaders, *indentedBody, *ret;

	indentedHeaders = [[_headers description]
	    stringByReplacingOccurrencesOfString: @"\n"

Modified src/OFHTTPResponse.h from [8b2b368da6] to [88ee04dd60].

28
29
30
31
32
33
34
35
36


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

49
50
51
52
53
54

55
56
57
58
59
60
61
28
29
30
31
32
33
34


35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53

54
55
56
57
58
59
60
61







-
-
+
+











-
+





-
+







 *
 * @brief A class for representing an HTTP request reply as a stream.
 */
@interface OFHTTPResponse: OFStream
{
	of_http_request_protocol_version_t _protocolVersion;
	short _statusCode;
	OFDictionary OF_GENERIC(OFString*, OFString*) *_headers;
	OFArray OF_GENERIC(OFHTTPCookie*) *_cookies;
	OFDictionary OF_GENERIC(OFString *, OFString *) *_headers;
	OFArray OF_GENERIC(OFHTTPCookie *) *_cookies;
}

/*!
 * The status code of the reply to the HTTP request.
 */
@property short statusCode;

/*!
 * The headers of the reply to the HTTP request.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, copy)
    OFDictionary OF_GENERIC(OFString*, OFString*) *headers;
    OFDictionary OF_GENERIC(OFString *, OFString *) *headers;

/*!
 * The cookies to set of the reply to the HTTP request.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, copy)
    OFArray OF_GENERIC(OFHTTPCookie*) *cookies;
    OFArray OF_GENERIC(OFHTTPCookie *) *cookies;

/*!
 * @brief Sets the protocol version of the HTTP request reply.
 *
 * @param protocolVersion The protocol version of the HTTP request reply
 */
- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion;
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
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







-
+






-
+






-
+







-
+




/*!
 * @brief Sets the protocol version of the HTTP request reply to the version
 *	  described by the specified string.
 *
 * @param string A string describing an HTTP version
 */
- (void)setProtocolVersionFromString: (OFString*)string;
- (void)setProtocolVersionFromString: (OFString *)string;

/*!
 * @brief Returns the protocol version of the HTTP request reply as a string.
 *
 * @return The protocol version of the HTTP request reply as a string
 */
- (OFString*)protocolVersionString;
- (OFString *)protocolVersionString;

/*!
 * @brief Returns the reply as a string, trying to detect the encoding.
 *
 * @return The reply as a string
 */
- (OFString*)string;
- (OFString *)string;

/*!
 * @brief Returns the reply as a string, trying to detect the encoding and
 *	  falling back to the specified encoding if not detectable.
 *
 * @return The reply as a string
 */
- (OFString*)stringWithEncoding: (of_string_encoding_t)encoding;
- (OFString *)stringWithEncoding: (of_string_encoding_t)encoding;
@end

OF_ASSUME_NONNULL_END

Modified src/OFHTTPResponse.m from [ae2e00de64] to [b039102173].

166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180







-
+







}

- (of_http_request_protocol_version_t)protocolVersion
{
	return _protocolVersion;
}

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

	if ([components count] != 2)
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204

205
206
207
208
209

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
190
191
192
193
194
195
196

197
198
199
200
201
202
203

204
205
206
207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244







-
+






-
+




-
+


















-
+








-
+







	protocolVersion.minor = (uint8_t)minor;

	[self setProtocolVersion: protocolVersion];

	objc_autoreleasePoolPop(pool);
}

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

- (OFString*)string
- (OFString *)string
{
	return [self stringWithEncoding: OF_STRING_ENCODING_AUTODETECT];
}

- (OFString*)stringWithEncoding: (of_string_encoding_t)encoding
- (OFString *)stringWithEncoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFString *contentType, *contentLength, *ret;
	OFDataArray *data;

	if (encoding == OF_STRING_ENCODING_AUTODETECT &&
	    (contentType = [_headers objectForKey: @"Content-Type"]) != nil)
		encoding = encodingForContentType(contentType);

	if (encoding == OF_STRING_ENCODING_AUTODETECT)
		encoding = OF_STRING_ENCODING_UTF_8;

	data = [self readDataArrayTillEndOfStream];

	if ((contentLength = [_headers objectForKey: @"Content-Length"]) != nil)
		if ([data count] != (size_t)[contentLength decimalValue])
			@throw [OFTruncatedDataException exception];

	ret = [[OFString alloc] initWithCString: (char*)[data items]
	ret = [[OFString alloc] initWithCString: (char *)[data items]
				       encoding: encoding
					 length: [data count]];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

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

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

Modified src/OFHTTPServer.h from [8ee31cc729] to [7497041027].

38
39
40
41
42
43
44
45
46
47



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81




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

102
103
104
105
106
107
108
38
39
40
41
42
43
44



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


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




78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108







-
-
-
+
+
+













-
-
+
+















-
-
-
-
+
+
+
+



















-
+







 * @brief This method is called when the HTTP server received a request from a
 *	  client.
 *
 * @param server The HTTP server which received the request
 * @param request The request the HTTP server received
 * @param response The response the server will send to the client
 */
-      (void)server: (OFHTTPServer*)server
  didReceiveRequest: (OFHTTPRequest*)request
	   response: (OFHTTPResponse*)response;
-      (void)server: (OFHTTPServer *)server
  didReceiveRequest: (OFHTTPRequest *)request
	   response: (OFHTTPResponse *)response;

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

/*!
 * @brief This method is called when a client socket encountered an exception.
 *
 * This can happen when the OFHTTPServer tries to properly close the
 * connection. If no headers have been sent yet, it will send headers, and if
 * chunked transfer encoding was used, it will send a chunk of size 0. However,
 * if the other end already closed the connection before that, this will raise
 * an exception.
 *
 * @param server The HTTP server which encountered an exception
 * @param response The response for which the exception occurred
 * @param request The request for the response for which the exception occurred
 * @param exception The exception which occurred
 */
-		    (void)server: (OFHTTPServer*)server
  didReceiveExceptionForResponse: (OFHTTPResponse*)response
			 request: (OFHTTPRequest*)request
		       exception: (OFException*)exception;
-		    (void)server: (OFHTTPServer *)server
  didReceiveExceptionForResponse: (OFHTTPResponse *)response
			 request: (OFHTTPRequest *)request
		       exception: (OFException *)exception;
@end

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

/*!
 * The host on which the HTTP server will listen.
 */
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString* host;
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *host;

/*!
 * The port on which the HTTP server will listen.
 */
@property uint16_t port;

/*!

Modified src/OFHTTPServer.m from [84e4421360] to [6f3529bdbf].

43
44
45
46
47
48
49
50
51
52



53
54
55

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



50
51
52
53
54

55
56
57
58
59
60
61
62







-
-
-
+
+
+


-
+








/*
 * FIXME: Key normalization replaces headers like "DNT" with "Dnt".
 * FIXME: Errors are not reported to the user.
 */

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

static const char*
static const char *
statusCodeToString(short code)
{
	switch (code) {
	case 100:
		return "Continue";
	case 101:
		return "Switching Protocols";
137
138
139
140
141
142
143
144

145
146
147
148

149
150
151
152
153
154
155
137
138
139
140
141
142
143

144
145
146
147

148
149
150
151
152
153
154
155







-
+



-
+







	case 505:
		return "HTTP Version Not Supported";
	default:
		return NULL;
	}
}

static OF_INLINE OFString*
static OF_INLINE OFString *
normalizedKey(OFString *key)
{
	char *cString = of_strdup([key UTF8String]);
	unsigned char *tmp = (unsigned char*)cString;
	unsigned char *tmp = (unsigned char *)cString;
	bool firstLetter = true;

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

	while (*tmp != '\0') {
175
176
177
178
179
180
181
182
183
184



185
186
187
188
189
190



191
192
193
194
195
196
197
175
176
177
178
179
180
181



182
183
184
185
186
187



188
189
190
191
192
193
194
195
196
197







-
-
-
+
+
+



-
-
-
+
+
+







{
	OFTCPSocket *_socket;
	OFHTTPServer *_server;
	OFHTTPRequest *_request;
	bool _chunked, _headersSent;
}

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

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

	_statusCode = 500;
	_socket = [socket retain];
	_server = [server retain];
	_request = [request retain];
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223







-
+








	[super dealloc];
}

- (void)OF_sendHeaders
{
	void *pool = objc_autoreleasePoolPush();
	OFMutableDictionary OF_GENERIC(OFString*, OFString*) *headers;
	OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers;
	OFEnumerator *keyEnumerator, *valueEnumerator;
	OFString *key, *value;

	[_socket writeFormat: @"HTTP/%@ %d %s\r\n",
			      [self protocolVersionString], _statusCode,
			      statusCodeToString(_statusCode)];

250
251
252
253
254
255
256
257

258
259
260
261
262
263
264
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264







-
+







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

	objc_autoreleasePoolPop(pool);
}

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

	if (_socket == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

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







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

-
+





-
-
+
+







	OFString *_host, *_path;
	uint16_t _port;
	OFMutableDictionary *_headers;
	size_t _contentLength;
	OFDataArray *_body;
}

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

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

	@try {
		_socket = [socket retain];
		_server = [server retain];
		_timer = [[OFTimer
389
390
391
392
393
394
395
396
397
398



399
400
401
402
403
404
405
389
390
391
392
393
394
395



396
397
398
399
400
401
402
403
404
405







-
-
-
+
+
+







	[_path release];
	[_headers release];
	[_body release];

	[super dealloc];
}

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

	@try {
		switch (_state) {
		case AWAITING_PROLOG:
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
420
421
422
423
424
425
426

427
428
429
430
431
432
433
434







-
+







	} @catch (OFWriteFailedException *e) {
		return false;
	}

	OF_ENSURE(0);
}

- (bool)parseProlog: (OFString*)line
- (bool)parseProlog: (OFString *)line
{
	OFString *method;
	OFMutableString *path;
	size_t pos;

	@try {
		OFString *version = [line
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
479
480
481
482
483
484
485

486
487
488
489
490
491
492
493







-
+







	_headers = [[OFMutableDictionary alloc] init];
	_path = [path copy];
	_state = PARSING_HEADERS;

	return true;
}

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

	if ([line length] == 0) {
		intmax_t contentLength;

567
568
569
570
571
572
573
574
575


576
577

578
579
580
581
582
583
584
567
568
569
570
571
572
573


574
575
576

577
578
579
580
581
582
583
584







-
-
+
+

-
+







			_port = 80;
		}
	}

	return true;
}

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

	[_body addItems: buffer
		  count: length];

727
728
729
730
731
732
733
734
735
736



737
738
739
740
741
742
743
727
728
729
730
731
732
733



734
735
736
737
738
739
740
741
742
743







-
-
-
+
+
+







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

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

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

Modified src/OFINICategory+Private.h from [ba852f9a21] to [3108b44cc4].

19
20
21
22
23
24
25
26
27


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


26
27
28
29
30
31
32







-
-
+
+






OF_ASSUME_NONNULL_BEGIN

@class OFStream;

@interface OFINICategory ()
- (instancetype)OF_init;
- (void)OF_parseLine: (OFString*)line;
- (bool)OF_writeToStream: (OFStream*)stream
- (void)OF_parseLine: (OFString *)line;
- (bool)OF_writeToStream: (OFStream *)stream
		encoding: (of_string_encoding_t)encoding
		   first: (bool)first;
@end

OF_ASSUME_NONNULL_END

Modified src/OFINICategory.h from [1a4f4e7d5d] to [3e2b10c31b].

46
47
48
49
50
51
52
53

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


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

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

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

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

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


154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216


217
218
219
220
221
222
223
224
225
226

227
228
229
46
47
48
49
50
51
52

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


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

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

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

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151


152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210
211
212
213
214


215
216
217
218
219
220
221
222
223
224
225

226
227
228
229







-
+













-
-
+
+













-
+














-
+














-
+














-
+













-
+










-
-
+
+











-
+











-
+











-
+











-
+













-
-
+
+









-
+



 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is returned.
 *
 * @param key The key for which the string value should be returned
 * @return The string value for the specified key, or `nil` if it does not exist
 */
- (nullable OFString*)stringForKey: (OFString*)key;
- (nullable OFString *)stringForKey: (OFString *)key;

/*!
 * @brief Returns the string value for the specified key or the specified
 *	  default value if it does not exist.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is returned.
 *
 * @param key The key for which the string value should be returned
 * @param defaultValue The value to return if the key does not exist
 * @return The string value for the specified key or the specified default
 *	   value if it does not exist
 */
- (nullable OFString*)stringForKey: (OFString*)key
		      defaultValue: (nullable OFString*)defaultValue;
- (nullable OFString *)stringForKey: (OFString *)key
		       defaultValue: (nullable OFString *)defaultValue;

/*!
 * @brief Returns the integer value for the specified key or the specified
 *	  default value if it does not exist.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is returned.
 *
 * @param key The key for which the integer value should be returned
 * @param defaultValue The value to return if the key does not exist
 * @return The integer value for the specified key or the specified default
 *	   value if it does not exist
 */
- (intmax_t)integerForKey: (OFString*)key
- (intmax_t)integerForKey: (OFString *)key
	     defaultValue: (intmax_t)defaultValue;

/*!
 * @brief Returns the bool value for the specified key or the specified default
 *	  value if it does not exist.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is returned.
 *
 * @param key The key for which the bool value should be returned
 * @param defaultValue The value to return if the key does not exist
 * @return The bool value for the specified key or the specified default value
 *	   if it does not exist
 */
- (bool)boolForKey: (OFString*)key
- (bool)boolForKey: (OFString *)key
      defaultValue: (bool)defaultValue;

/*!
 * @brief Returns the float value for the specified key or the specified
 *	  default value if it does not exist.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is returned.
 *
 * @param key The key for which the float value should be returned
 * @param defaultValue The value to return if the key does not exist
 * @return The float value for the specified key or the specified default value
 *	   if it does not exist
 */
- (float)floatForKey: (OFString*)key
- (float)floatForKey: (OFString *)key
	defaultValue: (float)defaultValue;

/*!
 * @brief Returns the double value for the specified key or the specified
 *	  default value if it does not exist.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is returned.
 *
 * @param key The key for which the double value should be returned
 * @param defaultValue The value to return if the key does not exist
 * @return The double value for the specified key or the specified default
 *	   value if it does not exist
 */
- (double)doubleForKey: (OFString*)key
- (double)doubleForKey: (OFString *)key
	  defaultValue: (double)defaultValue;

/*!
 * @brief Returns an array of string values for the specified multi-key, or an
 *	  empty array if the key does not exist.
 *
 * A multi-key is a key which exists several times in the same category. Each
 * occurrence of the key/value pair adds the respective value to the array.
 *
 * @param key The multi-key for which the array should be returned
 * @return The array for the specified key, or an empty array if it does not
 *	   exist
 */
- (OFArray OF_GENERIC(OFString*)*)arrayForKey: (OFString*)key;
- (OFArray OF_GENERIC(OFString *) *)arrayForKey: (OFString *)key;

/*!
 * @brief Sets the value of the specified key to the specified string.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is changed.
 *
 * @param string The string to which the value of the key should be set
 * @param key The key for which the new value should be set
 */
- (void)setString: (OFString*)string
	   forKey: (OFString*)key;
- (void)setString: (OFString *)string
	   forKey: (OFString *)key;

/*!
 * @brief Sets the value of the specified key to the specified integer.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is changed.
 *
 * @param integer The integer to which the value of the key should be set
 * @param key The key for which the new value should be set
 */
- (void)setInteger: (intmax_t)integer
	    forKey: (OFString*)key;
	    forKey: (OFString *)key;

/*!
 * @brief Sets the value of the specified key to the specified bool.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is changed.
 *
 * @param bool_ The bool to which the value of the key should be set
 * @param key The key for which the new value should be set
 */
- (void)setBool: (bool)bool_
	 forKey: (OFString*)key;
	 forKey: (OFString *)key;

/*!
 * @brief Sets the value of the specified key to the specified float.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is changed.
 *
 * @param float_ The float to which the value of the key should be set
 * @param key The key for which the new value should be set
 */
- (void)setFloat: (float)float_
	  forKey: (OFString*)key;
	  forKey: (OFString *)key;

/*!
 * @brief Sets the value of the specified key to the specified double.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is changed.
 *
 * @param double_ The double to which the value of the key should be set
 * @param key The key for which the new value should be set
 */
- (void)setDouble: (double)double_
	   forKey: (OFString*)key;
	   forKey: (OFString *)key;

/*!
 * @brief Sets the specified multi-key to the specified array of strings.
 *
 * It replaces the first occurrence of the multi-key with several key/value
 * pairs and removes all following occurrences. If the multi-key does not exist
 * yet, it is appended to the section.
 *
 * See also @ref arrayForKey: for more information about multi-keys.
 *
 * @param array The array of strings to which the multi-key should be set
 * @param key The multi-key for which the new values should be set
 */
- (void)setArray: (OFArray OF_GENERIC(OFString*)*)array
	  forKey: (OFString*)key;
- (void)setArray: (OFArray OF_GENERIC(OFString *) *)array
	  forKey: (OFString *)key;

/*!
 * @brief Removes the value for the specified key
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), all key/value
 * pairs matching the specified key are removed.
 *
 * @param key The key of the value to remove
 */
- (void)removeValueForKey: (OFString*)key;
- (void)removeValueForKey: (OFString *)key;
@end

OF_ASSUME_NONNULL_END

Modified src/OFINICategory.m from [6aba1314ef] to [0b4fba9171].

35
36
37
38
39
40
41
42

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

42
43
44
45
46
47
48
49







-
+







@interface OFINICategory_Comment: OFObject
{
@public
	OFString *_comment;
}
@end

static OFString*
static OFString *
escapeString(OFString *string)
{
	OFMutableString *mutableString;

	/* FIXME: Optimize */
	if (![string hasPrefix: @" "] && ![string hasPrefix: @"\t"] &&
	    ![string hasPrefix: @"\f"] && ![string hasSuffix: @" "] &&
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82







-
+







	[mutableString appendString: @"\""];

	[mutableString makeImmutable];

	return mutableString;
}

static OFString*
static OFString *
unescapeString(OFString *string)
{
	OFMutableString *mutableString;

	if (![string hasPrefix: @"\""] || ![string hasSuffix: @"\""])
		return string;

144
145
146
147
148
149
150
151

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

151
152
153
154
155
156
157
158







-
+







{
	[_name release];
	[_lines release];

	[super dealloc];
}

- (void)OF_parseLine: (OFString*)line
- (void)OF_parseLine: (OFString *)line
{
	if (![line hasPrefix: @";"]) {
		OFINICategory_Pair *pair =
		    [[[OFINICategory_Pair alloc] init] autorelease];
		OFString *key, *value;
		size_t pos;

179
180
181
182
183
184
185
186

187
188
189
190
191
192
193


194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
179
180
181
182
183
184
185

186
187
188
189
190
191


192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
238







-
+





-
-
+
+
















-
+




















-
+








		comment->_comment = [line copy];

		[_lines addObject: comment];
	}
}

- (OFString*)stringForKey: (OFString*)key
- (OFString *)stringForKey: (OFString *)key
{
	return [self stringForKey: key
		     defaultValue: nil];
}

- (OFString*)stringForKey: (OFString*)key
	     defaultValue: (OFString*)defaultValue
- (OFString *)stringForKey: (OFString *)key
	      defaultValue: (OFString *)defaultValue
{
	for (id line in _lines) {
		OFINICategory_Pair *pair;

		if (![line isKindOfClass: [OFINICategory_Pair class]])
			continue;

		pair = line;

		if ([pair->_key isEqual: key])
			return [[pair->_value copy] autorelease];
	}

	return defaultValue;
}

- (intmax_t)integerForKey: (OFString*)key
- (intmax_t)integerForKey: (OFString *)key
	     defaultValue: (intmax_t)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *value = [self stringForKey: key
				defaultValue: nil];
	intmax_t ret;

	if (value != nil) {
		if ([value hasPrefix: @"0x"] || [value hasPrefix: @"$"])
			ret = [value hexadecimalValue];
		else
			ret = [value decimalValue];
	} else
		ret = defaultValue;

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (bool)boolForKey: (OFString*)key
- (bool)boolForKey: (OFString *)key
      defaultValue: (bool)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *value = [self stringForKey: key
				defaultValue: nil];
	bool ret;

247
248
249
250
251
252
253
254

255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297







-
+

















-
+

















-
+







		ret = defaultValue;

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (float)floatForKey: (OFString*)key
- (float)floatForKey: (OFString *)key
	defaultValue: (float)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *value = [self stringForKey: key
				defaultValue: nil];
	float ret;

	if (value != nil)
		ret = [value floatValue];
	else
		ret = defaultValue;

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (double)doubleForKey: (OFString*)key
- (double)doubleForKey: (OFString *)key
	  defaultValue: (double)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *value = [self stringForKey: key
				defaultValue: nil];
	double ret;

	if (value != nil)
		ret = [value doubleValue];
	else
		ret = defaultValue;

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (OFArray*)arrayForKey: (OFString*)key
- (OFArray *)arrayForKey: (OFString *)key
{
	OFMutableArray *ret = [OFMutableArray array];
	void *pool = objc_autoreleasePoolPush();

	for (id line in _lines) {
		OFINICategory_Pair *pair;

307
308
309
310
311
312
313
314
315


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


314
315
316
317
318
319
320
321
322







-
-
+
+







	objc_autoreleasePoolPop(pool);

	[ret makeImmutable];

	return ret;
}

- (void)setString: (OFString*)string
	   forKey: (OFString*)key
- (void)setString: (OFString *)string
	   forKey: (OFString *)key
{
	void *pool = objc_autoreleasePoolPush();
	OFINICategory_Pair *pair;

	for (id line in _lines) {
		if (![line isKindOfClass: [OFINICategory_Pair class]])
			continue;
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374

375
376
377
378
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394
395
396


397
398
399
400
401
402
403
349
350
351
352
353
354
355

356
357
358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373

374
375
376
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392
393
394


395
396
397
398
399
400
401
402
403







-
+










-
+






-
+










-
+









-
-
+
+







		@throw e;
	}

	objc_autoreleasePoolPop(pool);
}

- (void)setInteger: (intmax_t)integer
	    forKey: (OFString*)key
	    forKey: (OFString *)key
{
	void *pool = objc_autoreleasePoolPush();

	[self setString: [OFString stringWithFormat: @"%jd", integer]
		 forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setBool: (bool)bool_
	 forKey: (OFString*)key
	 forKey: (OFString *)key
{
	[self setString: (bool_ ? @"true" : @"false")
		 forKey: key];
}

- (void)setFloat: (float)float_
	  forKey: (OFString*)key
	  forKey: (OFString *)key
{
	void *pool = objc_autoreleasePoolPush();

	[self setString: [OFString stringWithFormat: @"%g", float_]
		 forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setDouble: (double)double_
	   forKey: (OFString*)key
	   forKey: (OFString *)key
{
	void *pool = objc_autoreleasePoolPush();

	[self setString: [OFString stringWithFormat: @"%g", double_]
		 forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setArray: (OFArray*)array
	  forKey: (OFString*)key
- (void)setArray: (OFArray *)array
	  forKey: (OFString *)key
{
	void *pool;
	OFMutableArray *pairs;
	id const *lines;
	size_t count;
	bool replaced;

457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471







-
+








	if (!replaced)
		[_lines addObjectsFromArray: pairs];

	objc_autoreleasePoolPop(pool);
}

- (void)removeValueForKey: (OFString*)key
- (void)removeValueForKey: (OFString *)key
{
	void *pool = objc_autoreleasePoolPush();
	id const *lines = [_lines objects];
	size_t count = [_lines count];

	for (size_t i = 0; i < count; i++) {
		OFINICategory_Pair *pair;
485
486
487
488
489
490
491
492

493
494
495
496
497
498
499
485
486
487
488
489
490
491

492
493
494
495
496
497
498
499







-
+







			continue;
		}
	}

	objc_autoreleasePoolPop(pool);
}

- (bool)OF_writeToStream: (OFStream*)stream
- (bool)OF_writeToStream: (OFStream *)stream
		encoding: (of_string_encoding_t)encoding
		   first: (bool)first
{
	if ([_lines count] == 0)
		return false;

	if (first)

Modified src/OFINIFile.h from [1a37c007aa] to [233379f0e4].

25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
103

104
105
106
107
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102

103
104
105
106
107







-
+









-
+










-
+










-
+










-
+











-
+






-
+








-
+




/*!
 * @class OFINIFile OFINIFile.h ObjFW/OFINIFile.h
 *
 * @brief A class for reading, creating and modifying INI files.
 */
@interface OFINIFile: OFObject
{
	OFMutableArray OF_GENERIC(OFINICategory*) *_categories;
	OFMutableArray OF_GENERIC(OFINICategory *) *_categories;
}

/*!
 * @brief Creates a new OFINIFile with the contents of the specified file.
 *
 * @param path The path to the file whose contents the OFINIFile should contain
 *
 * @return A new, autoreleased OFINIFile with the contents of the specified file
 */
+ (instancetype)fileWithPath: (OFString*)path;
+ (instancetype)fileWithPath: (OFString *)path;

/*!
 * @brief Creates a new OFINIFile with the contents of the specified file in
 *	  the specified encoding.
 *
 * @param path The path to the file whose contents the OFINIFile should contain
 * @param encoding The encoding of the specified file
 *
 * @return A new, autoreleased OFINIFile with the contents of the specified file
 */
+ (instancetype)fileWithPath: (OFString*)path
+ (instancetype)fileWithPath: (OFString *)path
		    encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Initializes an already allocated OFINIFile with the contents of the
 *	  specified file.
 *
 * @param path The path to the file whose contents the OFINIFile should contain
 *
 * @return An initialized OFINIFile with the contents of the specified file
 */
- initWithPath: (OFString*)path;
- initWithPath: (OFString *)path;

/*!
 * @brief Initializes an already allocated OFINIFile with the contents of the
 *	  specified file in the specified encoding.
 *
 * @param path The path to the file whose contents the OFINIFile should contain
 * @param encoding The encoding of the specified file
 *
 * @return An initialized OFINIFile with the contents of the specified file
 */
- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
      encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Returns an @ref OFINICategory for the category with the specified
 *	  name.
 *
 * @param name The name of the category for which an @ref OFINICategory should
 *	       be returned
 *
 * @return An @ref OFINICategory for the category with the specified name
 */
- (OFINICategory*)categoryForName: (OFString*)name;
- (OFINICategory *)categoryForName: (OFString *)name;

/*!
 * @brief Writes the contents of the OFINIFile to a file.
 *
 * @param path The path of the file to write to
 */
- (void)writeToFile: (OFString*)path;
- (void)writeToFile: (OFString *)path;

/*!
 * @brief Writes the contents of the OFINIFile to a file in the specified
 *	  encoding.
 *
 * @param path The path of the file to write to
 * @param encoding The encoding to use
 */
- (void)writeToFile: (OFString*)path
- (void)writeToFile: (OFString *)path
	   encoding: (of_string_encoding_t)encoding;
@end

OF_ASSUME_NONNULL_END

Modified src/OFINIFile.m from [33a908e3eb] to [3398a352d7].

25
26
27
28
29
30
31
32

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

32
33
34
35
36
37
38
39







-
+







#import "OFINICategory.h"
#import "OFINICategory+Private.h"

#import "OFInvalidFormatException.h"
#import "OFOpenItemFailedException.h"

@interface OFINIFile ()
- (void)OF_parseFile: (OFString*)path
- (void)OF_parseFile: (OFString *)path
	    encoding: (of_string_encoding_t)encoding;
@end

static bool
isWhitespaceLine(OFString *line)
{
	const char *cString = [line UTF8String];
51
52
53
54
55
56
57
58

59
60
61
62
63

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

76
77
78
79
80
81

82
83
84
85
86
87
88
51
52
53
54
55
56
57

58
59
60
61
62

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

75
76
77
78
79
80

81
82
83
84
85
86
87
88







-
+




-
+











-
+





-
+







		}
	}

	return true;
}

@implementation OFINIFile
+ (instancetype)fileWithPath: (OFString*)path
+ (instancetype)fileWithPath: (OFString *)path
{
	return [[[self alloc] initWithPath: path] autorelease];
}

+ (instancetype)fileWithPath: (OFString*)path
+ (instancetype)fileWithPath: (OFString *)path
		    encoding: (of_string_encoding_t)encoding
{
	return [[[self alloc] initWithPath: path
				  encoding: encoding] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
{
	return [self initWithPath: path
			 encoding: OF_STRING_ENCODING_UTF_8];
}

- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
      encoding: (of_string_encoding_t)encoding
{
	self = [super init];

	@try {
		_categories = [[OFMutableArray alloc] init];

99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113







-
+







- (void)dealloc
{
	[_categories release];

	[super dealloc];
}

- (OFINICategory*)categoryForName: (OFString*)name
- (OFINICategory *)categoryForName: (OFString *)name
{
	void *pool = objc_autoreleasePoolPush();
	OFINICategory *category;

	for (category in _categories) {
		if ([[category name] isEqual: name]) {
			OFINICategory *ret = [category retain];
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139







-
+







	[category retain];

	objc_autoreleasePoolPop(pool);

	return [category autorelease];
}

- (void)OF_parseFile: (OFString*)path
- (void)OF_parseFile: (OFString *)path
	    encoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFFile *file;
	OFINICategory *category = nil;
	OFString *line;

172
173
174
175
176
177
178
179

180
181
182
183
184
185

186
187
188
189
190
191
192
172
173
174
175
176
177
178

179
180
181
182
183
184

185
186
187
188
189
190
191
192







-
+





-
+







			[category OF_parseLine: line];
		}
	}

	objc_autoreleasePoolPop(pool);
}

- (void)writeToFile: (OFString*)path
- (void)writeToFile: (OFString *)path
{
	[self writeToFile: path
		 encoding: OF_STRING_ENCODING_UTF_8];
}

- (void)writeToFile: (OFString*)path
- (void)writeToFile: (OFString *)path
	   encoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFFile *file = [OFFile fileWithPath: path
				       mode: @"w"];
	bool first = true;

Modified src/OFIntrospection.h from [07598bfdef] to [fb7189fbfa].

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







-
-
-
-
+
+
+
+





-
+




-
+







/*!
 * @class OFIntrospection OFIntrospection.h ObjFW/OFIntrospection.h
 *
 * @brief A class for introspecting classes.
 */
@interface OFIntrospection: OFObject
{
	OFMutableArray OF_GENERIC(OFMethod*) *_classMethods;
	OFMutableArray OF_GENERIC(OFMethod*) *_instanceMethods;
	OFMutableArray OF_GENERIC(OFProperty*) *_properties;
	OFMutableArray OF_GENERIC(OFInstanceVariable*) *_instanceVariables;
	OFMutableArray OF_GENERIC(OFMethod *) *_classMethods;
	OFMutableArray OF_GENERIC(OFMethod *) *_instanceMethods;
	OFMutableArray OF_GENERIC(OFProperty *) *_properties;
	OFMutableArray OF_GENERIC(OFInstanceVariable *) *_instanceVariables;
}

/*!
 * The class methods of the class.
 */
@property (readonly, nonatomic) OFArray OF_GENERIC(OFMethod*) *classMethods;
@property (readonly, nonatomic) OFArray OF_GENERIC(OFMethod *) *classMethods;

/*!
 * The instance methods of the class.
 */
@property (readonly, nonatomic) OFArray OF_GENERIC(OFMethod*) *instanceMethods;
@property (readonly, nonatomic) OFArray OF_GENERIC(OFMethod *) *instanceMethods;

/*!
 * The properties of the class.
 *
 * @warning **Do not rely on this, as this behaves differently depending on the
 *	    compiler and ABI used!**
 *
179
180
181
182
183
184
185
186

187
188
189
190
191
192

193
194
195
196
197
198
199
179
180
181
182
183
184
185

186
187
188
189
190
191

192
193
194
195
196
197
198
199







-
+





-
+







 *	    introspection for every property that has been declared using
 *	    `@``property`, even if no `@``synchronize` or `@``dynamic` has been
 *	    used.
 *
 * @warning GCC does not emit any data for property introspection for the GNU
 *	    ABI.
 */
@property (readonly, nonatomic) OFArray OF_GENERIC(OFProperty*) *properties;
@property (readonly, nonatomic) OFArray OF_GENERIC(OFProperty *) *properties;

/*!
 * The instance variables of the class.
 */
@property (readonly, nonatomic)
    OFArray OF_GENERIC(OFInstanceVariable*) *instanceVariables;
    OFArray OF_GENERIC(OFInstanceVariable *) *instanceVariables;

/* TODO: protocols */

/*!
 * @brief Creates a new introspection for the specified class.
 *
 * @return A new, autoreleased introspection for the specified class

Modified src/OFIntrospection.m from [3b325f542e] to [1afb80a6b9].

24
25
26
27
28
29
30
31

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

31
32
33
34
35
36
37
38







-
+








#import "OFInitializationFailedException.h"

@implementation OFMethod
@synthesize selector = _selector, name = _name, typeEncoding = _typeEncoding;

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

	@try {
		_selector = (SEL)&method->sel;
		_name = [[OFString alloc]
		    initWithUTF8String: sel_getName(_selector)];
73
74
75
76
77
78
79
80

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

80
81
82
83
84
85
86
87







-
+







- (void)dealloc
{
	[_name release];

	[super dealloc];
}

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

- (bool)isEqual: (id)object
{
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145







-
+







@end

@implementation OFProperty
@synthesize name = _name, attributes = _attributes;
@synthesize getter = _getter, setter = _setter;

#if defined(OF_OBJFW_RUNTIME)
- (instancetype)OF_initWithProperty: (struct objc_property*)property
- (instancetype)OF_initWithProperty: (struct objc_property *)property
{
	self = [super init];

	@try {
		_name = [[OFString alloc] initWithUTF8String: property->name];
		_attributes =
		    property->attributes | (property->extended_attributes << 8);
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311







-
+







	[_name release];
	[_getter release];
	[_setter release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString
	    stringWithFormat: @"<%@: %@\n"
			      @"\tAttributes = 0x%03X\n"
			      @"\tGetter = %@\n"
			      @"\tSetter = %@\n"
			      @">",
352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366







-
+







}
@end

@implementation OFInstanceVariable
@synthesize name = _name, offset = _offset, typeEncoding = _typeEncoding;

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

	@try {
		_name = [[OFString alloc] initWithUTF8String: ivar->name];
		_typeEncoding = ivar->type;
		_offset = ivar->offset;
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414







-
+







- (void)dealloc
{
	[_name release];

	[super dealloc];
}

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

Modified src/OFJSONRepresentation.h from [d6d76264fc] to [e14744365e].

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







-
+













-
+



 */
@protocol OFJSONRepresentation
/*!
 * @brief Returns the JSON representation of the object as a string.
 *
 * @return The JSON representation of the object as a string
 */
- (OFString*)JSONRepresentation;
- (OFString *)JSONRepresentation;

/*!
 * @brief Returns the JSON representation of the object as a string.
 *
 * @param options The options to use when creating a JSON representation.@n
 *		  Possible values are:
 *		  Value                           | Description
 *		  --------------------------------|-------------------------
 *		  `OF_JSON_REPRESENTATION_PRETTY` | Optimize for readability
 *		  `OF_JSON_REPRESENTATION_JSON5`  | Generate JSON5
 *
 * @return The JSON representation of the object as a string
 */
- (OFString*)JSONRepresentationWithOptions: (int)options;
- (OFString *)JSONRepresentationWithOptions: (int)options;
@end

OF_ASSUME_NONNULL_END

Modified src/OFKernelEventObserver.h from [316e90db78] to [e653f3b4a2].

196
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211
212
213
214
215
196
197
198
199
200
201
202

203
204
205
206
207
208
209
210
211
212
213
214
215







-
+













/*!
 * @brief Observes all objects until an event happens on an object or the
 *	  specified date is reached.
 *
 * @param date The until which to observe
 */
- (void)observeUntilDate: (OFDate*)date;
- (void)observeUntilDate: (OFDate *)date;

/*!
 * @brief Cancels the currently blocking observe call.
 *
 * This is automatically done when a new object is added or removed by another
 * thread, but in some circumstances, it might be desirable for a thread to
 * manually stop the observe running in another thread.
 */
- (void)cancel;
@end

OF_ASSUME_NONNULL_END

Modified src/OFKernelEventObserver.m from [02536e25d0] to [687f558fe2].

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







-
+





-
-
+
+











-
+
+







		_cancelAddr.sin_port = 0;
		_cancelAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
# ifdef OF_WII
		_cancelAddr.sin_len = 8;
# endif

# if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
		if (bind(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
		if (bind(_cancelFD[0], (struct sockaddr *)&_cancelAddr,
		    sizeof(_cancelAddr)) != 0)
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		cancelAddrLen = sizeof(_cancelAddr);
		if (of_getsockname(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
		    &cancelAddrLen) != 0)
		if (of_getsockname(_cancelFD[0],
		    (struct sockaddr *)&_cancelAddr, &cancelAddrLen) != 0)
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];
# else
		for (;;) {
			uint16_t rnd = 0;
			int ret;

			while (rnd < 1024)
				rnd = (uint16_t)rand();

			_cancelAddr.sin_port = OF_BSWAP16_IF_LE(rnd);
			ret = bind(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
			ret = bind(_cancelFD[0],
			    (struct sockaddr *)&_cancelAddr,
			    sizeof(_cancelAddr));

			if (ret == 0)
				break;

			if (of_socket_errno() != EADDRINUSE)
				@throw [OFInitializationFailedException
397
398
399
400
401
402
403
404

405
406
407
408
409
410
411
412
413
414
415
416

417
418
419

420
421
422
423
398
399
400
401
402
403
404

405
406
407
408
409
410
411
412
413
414
415
416

417
418
419

420
421
422
423
424







-
+











-
+


-
+




}

- (void)observeForTimeInterval: (of_time_interval_t)timeInterval
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)observeUntilDate: (OFDate*)date
- (void)observeUntilDate: (OFDate *)date
{
	[self observeForTimeInterval: [date timeIntervalSinceNow]];
}

- (void)cancel
{
#ifdef OF_HAVE_PIPE
	OF_ENSURE(write(_cancelFD[1], "", 1) > 0);
#else
# ifndef OF_WII
	OF_ENSURE(sendto(_cancelFD[1], "", 1, 0,
	    (struct sockaddr*)&_cancelAddr, sizeof(_cancelAddr)) > 0);
	    (struct sockaddr *)&_cancelAddr, sizeof(_cancelAddr)) > 0);
# else
	OF_ENSURE(sendto(_cancelFD[1], "", 1, 0,
	    (struct sockaddr*)&_cancelAddr, 8) > 0);
	    (struct sockaddr *)&_cancelAddr, 8) > 0);
# endif
#endif
}
@end

Modified src/OFKernelEventObserver_epoll.m from [7c101cdbc0] to [662ee50aca].

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







-
+










-
-
+
+









-
+








-
+












-
-
+
+







      fileDescriptor: (int)fd
	      events: (int)addEvents
{
	struct epoll_event event;
	intptr_t events;

	events = (intptr_t)[_FDToEvents
	    objectForKey: (void*)((intptr_t)fd + 1)];
	    objectForKey: (void *)((intptr_t)fd + 1)];

	memset(&event, 0, sizeof(event));
	event.events = (int)events | addEvents;
	event.data.ptr = object;

	if (epoll_ctl(_epfd, (events == 0 ? EPOLL_CTL_ADD : EPOLL_CTL_MOD),
	    fd, &event) == -1)
		@throw [OFObserveFailedException exceptionWithObserver: self
								 errNo: errno];

	[_FDToEvents setObject: (void*)(events | addEvents)
			forKey: (void*)((intptr_t)fd + 1)];
	[_FDToEvents setObject: (void *)(events | addEvents)
			forKey: (void *)((intptr_t)fd + 1)];
}

- (void)OF_removeObject: (id)object
	 fileDescriptor: (int)fd
		 events: (int)removeEvents
{
	intptr_t events;

	events = (intptr_t)[_FDToEvents
	    objectForKey: (void*)((intptr_t)fd + 1)];
	    objectForKey: (void *)((intptr_t)fd + 1)];
	events &= ~removeEvents;

	if (events == 0) {
		if (epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, NULL) == -1)
			@throw [OFObserveFailedException
			    exceptionWithObserver: self
					    errNo: errno];

		[_FDToEvents removeObjectForKey: (void*)((intptr_t)fd + 1)];
		[_FDToEvents removeObjectForKey: (void *)((intptr_t)fd + 1)];
	} else {
		struct epoll_event event;

		memset(&event, 0, sizeof(event));
		event.events = (int)events;
		event.data.ptr = object;

		if (epoll_ctl(_epfd, EPOLL_CTL_MOD, fd, &event) == -1)
			@throw [OFObserveFailedException
			    exceptionWithObserver: self
					    errNo: errno];

		[_FDToEvents setObject: (void*)events
				forKey: (void*)((intptr_t)fd + 1)];
		[_FDToEvents setObject: (void *)events
				forKey: (void *)((intptr_t)fd + 1)];
	}
}

- (void)OF_addObjectForReading: (id <OFReadyForReadingObserving>)object
{
	[self OF_addObject: object
	    fileDescriptor: [object fileDescriptorForReading]

Modified src/OFKeyValueCoding.h from [7617e632ed] to [f12732c01d].

31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58

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

71
72
73
74
75
76
77
78
79
80

81
82
83
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57

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

70
71
72
73
74
75
76
77
78
79

80
81
82
83







-
+










-
+








-
+











-
+









-
+



@protocol OFKeyValueCoding
/*!
 * @brief Returns the value for the specified key
 *
 * @param key The key of the value to return
 * @return The value for the specified key
 */
- (nullable id)valueForKey: (OFString*)key;
- (nullable id)valueForKey: (OFString *)key;

/*!
 * @brief This is called by @ref valueForKey: if the specified key does not
 *	  exist.
 *
 * By default, this throws an @ref OFUndefinedKeyException.
 *
 * @param key The undefined key of the value to return
 * @return The value for the specified undefined key
 */
- (nullable id)valueForUndefinedKey: (OFString*)key;
- (nullable id)valueForUndefinedKey: (OFString *)key;

/*!
 * @brief Set the value for the specified key
 *
 * @param value The value for the specified key
 * @param key The key of the value to set
 */
- (void)setValue: (nullable id)value
	  forKey: (OFString*)key;
	  forKey: (OFString *)key;

/*!
 * @brief This is called by @ref setValue:forKey: if the specified key does not
 *	  exist.
 *
 * By default, this throws an @ref OFUndefinedKeyException.
 *
 * @param value The value for the specified undefined key
 * @param key The undefined key of the value to set
 */
-  (void)setValue: (nullable id)value
  forUndefinedKey: (OFString*)key;
  forUndefinedKey: (OFString *)key;

/*!
 * @brief This is called by @ref setValue:forKey: if the specified key is a
 *	  scalar, but the value specified is `nil`.
 *
 * By default, this throws an @ref OFInvalidArgumentException.
 *
 * @param key The key for which the value `nil` was specified
 */
- (void)setNilValueForKey: (OFString*)key;
- (void)setNilValueForKey: (OFString *)key;
@end

OF_ASSUME_NONNULL_END

Modified src/OFList.h from [f3204f0892] to [feabf2e6ec].

41
42
43
44
45
46
47
48

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

48
49
50
51
52
53
54
55







-
+








/*!
 * @class OFList OFList.h ObjFW/OFList.h
 *
 * @brief A class which provides easy to use double-linked lists.
 */
#ifdef OF_HAVE_GENERICS
@interface OFList <ObjectType>:
@interface OFList<ObjectType>:
#else
# ifndef DOXYGEN
#  define ObjectType id
# endif
@interface OFList:
#endif
    OFObject <OFCopying, OFCollection, OFSerialization>
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111


112
113
114
115
116
117
118
119
120
121
122
123
124


125
126
127
128
129
130
131

132
133
134
135
136
137
138
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109


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


123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138







-
+









-
+











-
-
+
+











-
-
+
+






-
+







 * @brief Appends an object to the list.
 *
 * @param object The object to append
 * @return An of_list_object_t, needed to identify the object inside the list.
 *	   For example, if you want to remove an object from the list, you need
 *	   its of_list_object_t.
 */
- (of_list_object_t*)appendObject: (ObjectType)object;
- (of_list_object_t *)appendObject: (ObjectType)object;

/*!
 * @brief Prepends an object to the list.
 *
 * @param object The object to prepend
 * @return An of_list_object_t, needed to identify the object inside the list.
 *	   For example, if you want to remove an object from the list, you need
 *	   its of_list_object_t.
 */
- (of_list_object_t*)prependObject: (ObjectType)object;
- (of_list_object_t *)prependObject: (ObjectType)object;

/*!
 * @brief Inserts an object before another list object.
 *
 * @param object The object to insert
 * @param listObject The of_list_object_t of the object before which it should
 *	  be inserted
 * @return An of_list_object_t, needed to identify the object inside the list.
 *	   For example, if you want to remove an object from the list, you need
 *	   its of_list_object_t.
 */
- (of_list_object_t*)insertObject: (ObjectType)object
		 beforeListObject: (of_list_object_t*)listObject;
- (of_list_object_t *)insertObject: (ObjectType)object
		  beforeListObject: (of_list_object_t *)listObject;

/*!
 * @brief Inserts an object after another list object.
 *
 * @param object The object to insert
 * @param listObject The of_list_object_t of the object after which it should be
 *	  inserted
 * @return An of_list_object_t, needed to identify the object inside the list.
 *	   For example, if you want to remove an object from the list, you need
 *	   its of_list_object_t.
 */
- (of_list_object_t*)insertObject: (ObjectType)object
		  afterListObject: (of_list_object_t*)listObject;
- (of_list_object_t *)insertObject: (ObjectType)object
		   afterListObject: (of_list_object_t *)listObject;

/*!
 * @brief Removes the object with the specified list object from the list.
 *
 * @param listObject The list object returned by append / prepend
 */
- (void)removeListObject: (of_list_object_t*)listObject;
- (void)removeListObject: (of_list_object_t *)listObject;

/*!
 * @brief Checks whether the list contains an object equal to the specified
 *	  object.
 *
 * @param object The object which is checked for being in the list
 * @return A boolean whether the list contains the specified object
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163







-
+







- (bool)containsObjectIdenticalTo: (nullable ObjectType)object;

/*!
 * @brief Returns an OFEnumerator to enumerate through all objects of the list.
 *
 * @returns An OFEnumerator to enumerate through all objects of the list
 */
- (OFEnumerator OF_GENERIC(ObjectType)*)objectEnumerator;
- (OFEnumerator OF_GENERIC(ObjectType) *)objectEnumerator;

/*!
 * @brief Returns the first object of the list or `nil`.
 *
 * @warning The returned object is *not* retained and autoreleased for
 *	    performance reasons!
 *
188
189
190
191
192
193
194
195
196


197
198
199
188
189
190
191
192
193
194


195
196
197
198
199







-
-
+
+



{
	OFList		 *_list;
	of_list_object_t *_current;
	unsigned long	 _mutations;
	unsigned long	 *_mutationsPtr;
}

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

OF_ASSUME_NONNULL_END

Modified src/OFList.m from [064f669702] to [e2872c89cd].

32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46







-
+







@synthesize lastListObject = _lastListObject;

+ (instancetype)list
{
	return [[[self alloc] init] autorelease];
}

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

	@try {
		void *pool = objc_autoreleasePoolPush();

		if (![[element name] isEqual: [self className]] ||
70
71
72
73
74
75
76
77

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

77
78
79
80
81
82
83
84







-
+







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

	[super dealloc];
}

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

	listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	listObject->object = [object retain];
	listObject->next = NULL;
	listObject->previous = _lastListObject;
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106







-
+








	_count++;
	_mutations++;

	return listObject;
}

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

	listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	listObject->object = [object retain];
	listObject->next = _firstListObject;
	listObject->previous = NULL;
114
115
116
117
118
119
120
121
122


123
124
125
126
127
128
129
114
115
116
117
118
119
120


121
122
123
124
125
126
127
128
129







-
-
+
+








	_count++;
	_mutations++;

	return listObject;
}

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

	newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	newListObject->object = [object retain];
	newListObject->next = listObject;
	newListObject->previous = listObject->previous;
138
139
140
141
142
143
144
145
146


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


145
146
147
148
149
150
151
152
153







-
-
+
+








	_count++;
	_mutations++;

	return newListObject;
}

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

	newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	newListObject->object = [object retain];
	newListObject->next = listObject->next;
	newListObject->previous = listObject;
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176







-
+








	_count++;
	_mutations++;

	return newListObject;
}

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

	if (_firstListObject == listObject)
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
315
316
317
318
319
320
321

322
323
324
325
326
327
328
329







-
+







		OF_HASH_ADD_HASH(hash, [iter->object hash]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

- (OFString*)description
- (OFString *)description
{
	OFMutableString *ret;

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

	ret = [OFMutableString stringWithString: @"[\n"];
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
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







-
+

















-
-
+
+







	[ret appendString: @"\n]"];

	[ret makeImmutable];

	return ret;
}

- (OFXMLElement*)XMLElementBySerializing
- (OFXMLElement *)XMLElementBySerializing
{
	OFXMLElement *element =
	    [OFXMLElement elementWithName: [self className]
				namespace: OF_SERIALIZATION_NS];

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

		[element addChild: [iter->object XMLElementBySerializing]];

		objc_autoreleasePoolPop(pool);
	}

	return element;
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state
			   objects: (id *)objects
			     count: (int)count
{
	of_list_object_t *listObject;

	memcpy(&listObject, state->extra, sizeof(listObject));

	state->itemsPtr = objects;
391
392
393
394
395
396
397
398

399
400
401
402
403
404
405
406
407
408


409
410
411
412
413
414
415
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405
406


407
408
409
410
411
412
413
414
415







-
+








-
-
+
+







	}

	memcpy(state->extra, &listObject, sizeof(listObject));

	return count;
}

- (OFEnumerator*)objectEnumerator
- (OFEnumerator *)objectEnumerator
{
	return [[[OFListEnumerator alloc]
		initWithList: self
	    mutationsPointer: &_mutations] autorelease];
}
@end

@implementation OFListEnumerator
-     initWithList: (OFList*)list
  mutationsPointer: (unsigned long*)mutationsPtr
-     initWithList: (OFList *)list
  mutationsPointer: (unsigned long *)mutationsPtr
{
	self = [super init];

	_list = [list retain];
	_current = [list firstListObject];
	_mutations = *mutationsPtr;
	_mutationsPtr = mutationsPtr;

Modified src/OFLocalization.h from [5268bd2a18] to [368d40b91d].

36
37
38
39
40
41
42
43

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

43
44
45
46
47
48
49
50







-
+







 */
@interface OFLocalization: OFObject
{
	OFString *_language;
	OFString *_territory;
	of_string_encoding_t _encoding;
	OFString *_decimalPoint;
	OFMutableArray OF_GENERIC(OFDictionary OF_GENERIC(OFString*, id)*)
	OFMutableArray OF_GENERIC(OFDictionary OF_GENERIC(OFString *, id) *)
	    *_localizedStrings;
}

/**
 * The language of the locale for messages.
 *
 * If the language is unknown, it is `nil`.
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
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







-
+








-
+


















-
+







-
+




















-
+




















-
-
+
+
+







/**
 * @brief Returns the language of the locale.
 *
 * If the language is unknown, `nil` is returned.
 *
 * @return The language of the locale.
 */
+ (nullable OFString*)language;
+ (nullable OFString *)language;

/*!
 * @brief Returns the territory of the locale.
 *
 * If the territory is unknown, `nil` is returned.
 *
 * @return The territory of the locale.
 */
+ (nullable OFString*)territory;
+ (nullable OFString *)territory;

/*!
 * @brief Returns the native 8-bit string encoding for the locale.
 *
 * This is useful to encode strings correctly for passing them to operating
 * system calls.
 *
 * If the native 8-bit encoding is unknown, UTF-8 is assumed.
 *
 * @return The native 8-bit string encoding for the locale
 */
+ (of_string_encoding_t)encoding;

/*!
 * @brief Returns the decimal point of the system's locale.
 *
 * @return The decimal point of the system's locale
 */
+ (OFString*)decimalPoint;
+ (OFString *)decimalPoint;

#ifdef OF_HAVE_FILES
/*!
 * @brief Adds a directory to scan for language files.
 *
 * @param path The path to the directory to scan for language files
 */
+ (void)addLanguageDirectory: (OFString*)path;
+ (void)addLanguageDirectory: (OFString *)path;
#endif

/*!
 * @brief Initializes the OFLocalization singleton with the specified locale.
 *
 * @warning This sets the locale via `setlocale()`!
 *
 * @warning You should never call this yourself, except if you do not use
 *	    @ref OFApplication. In this case, you need to allocate exactly one
 *	    instance of OFLocalization, which will be come the singleton, and
 *	    call this method.
 */
- init;

#ifdef OF_HAVE_FILES
/*!
 * @brief Adds a directory to scan for language files.
 *
 * @param path The path to the directory to scan for language files
 */
- (void)addLanguageDirectory: (OFString*)path;
- (void)addLanguageDirectory: (OFString *)path;
#endif

/*!
 * @brief Returns the localized string for the specified ID, using the fallback
 *	  string if it cannot be looked up or is missing.
 *
 * @note This takes a variadic argument, terminated by `nil`, that consists of
 *	 pairs of variable names and variable values, which will be replaced
 *	 inside the localized string. For example, you can pass
 *	 `@"name", @"foo", nil`, causing `%[name]` to be replaced with `foo` in
 *	 the localized string.
 *
 * @note Generally, you want to use @ref OF_LOCALIZED instead, which also takes
 *	 care of the `nil` sentinel automatically.
 *
 * @param ID The ID for the localized string
 * @param fallback The fallback to use in case the localized string cannot be
 *		   looked up or is missing
 * @return The localized string
 */
- (OFString*)localizedStringForID: (OFConstantString*)ID
			 fallback: (OFConstantString*)fallback, ... OF_SENTINEL;
- (OFString *)localizedStringForID: (OFConstantString *)ID
			  fallback: (OFConstantString *)fallback, ...
				    OF_SENTINEL;

/**
 * @brief Returns the localized string for the specified ID, using the fallback
 *	  string if it cannot be looked up or is missing.
 *
 * @note This takes a variadic argument, terminated by `nil` and passed as
 *	 va_list, that consists of pairs of variable names and variable values,
189
190
191
192
193
194
195
196
197
198



199
200
201
190
191
192
193
194
195
196



197
198
199
200
201
202







-
-
-
+
+
+



 * @param fallback The fallback to use in case the localized string cannot be
 *		   looked up or is missing
 * @param arguments A va_list of arguments, consisting of pairs of variable
 *		    names and values to replace in the localized string,
 *		    terminated with `nil`
 * @return The localized string
 */
- (OFString*)localizedStringForID: (OFConstantString*)ID
			 fallback: (OFConstantString*)fallback
			arguments: (va_list)arguments;
- (OFString *)localizedStringForID: (OFConstantString *)ID
			  fallback: (OFConstantString *)fallback
			 arguments: (va_list)arguments;
@end

OF_ASSUME_NONNULL_END

Modified src/OFLocalization.m from [306b376984] to [39c2a63182].

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







-
+




-
+









-
+





-
+







@synthesize decimalPoint = _decimalPoint;

+ (instancetype)sharedLocalization
{
	return sharedLocalization;
}

+ (OFString*)language
+ (OFString *)language
{
	return [sharedLocalization language];
}

+ (OFString*)territory
+ (OFString *)territory
{
	return [sharedLocalization territory];
}

+ (of_string_encoding_t)encoding
{
	return [sharedLocalization encoding];
}

+ (OFString*)decimalPoint
+ (OFString *)decimalPoint
{
	return [sharedLocalization decimalPoint];
}

#ifdef OF_HAVE_FILES
+ (void)addLanguageDirectory: (OFString*)path
+ (void)addLanguageDirectory: (OFString *)path
{
	[sharedLocalization addLanguageDirectory: path];
}
#endif

- init
{
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173







-
+







	[_decimalPoint release];
	[_localizedStrings release];

	[super dealloc];
}

#ifdef OF_HAVE_FILES
- (void)addLanguageDirectory: (OFString*)path
- (void)addLanguageDirectory: (OFString *)path
{
	void *pool;
	OFString *mapPath, *language, *territory, *languageFile;
	OFDictionary *map;

	if (_language == nil)
		return;
199
200
201
202
203
204
205
206
207


208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223



224
225
226
227
228
229
230
199
200
201
202
203
204
205


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



221
222
223
224
225
226
227
228
229
230







-
-
+
+













-
-
-
+
+
+







	[_localizedStrings addObject:
	    [[OFString stringWithContentsOfFile: languageFile] JSONValue]];

	objc_autoreleasePoolPop(pool);
}
#endif

- (OFString*)localizedStringForID: (OFConstantString*)ID
			 fallback: (OFConstantString*)fallback, ...
- (OFString *)localizedStringForID: (OFConstantString *)ID
			  fallback: (OFConstantString *)fallback, ...
{
	OFString *ret;
	va_list args;

	va_start(args, fallback);
	ret = [self localizedStringForID: ID
				fallback: fallback
			       arguments: args];
	va_end(args);

	return ret;
}

- (OFString*)localizedStringForID: (OFConstantString*)ID
			 fallback: (OFConstantString*)fallback
			arguments: (va_list)arguments
- (OFString *)localizedStringForID: (OFConstantString *)ID
			  fallback: (OFConstantString *)fallback
			 arguments: (va_list)arguments
{
	OFMutableString *ret = [OFMutableString string];
	void *pool = objc_autoreleasePoolPush();
	const char *UTF8String = NULL;
	size_t last, UTF8StringLength;
	int state = 0;

281
282
283
284
285
286
287
288

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

288
289
290
291
292
293
294
295







-
+







				/*
				 * We loop, as most of the time, we only have
				 * one or maybe two variables, meaning looping
				 * is faster than constructing a dictionary.
				 */
				va_copy(argsCopy, arguments);
				while ((name = va_arg(argsCopy,
				    OFConstantString*)) != nil) {
				    OFConstantString *)) != nil) {
					id value = va_arg(argsCopy, id);

					if (value == nil)
						@throw
						    [OFInvalidArgumentException
						    exception];

Modified src/OFLocking.h from [1787b597ed] to [484f458e2d].

47
48
49
50
51
52
53
54

55
56
57
58
59
60
61

62
63
64
47
48
49
50
51
52
53

54
55
56
57
58
59
60

61
62
63
64







-
+






-
+



- (void)unlock;

/*!
 * @brief Sets a name for the lock.
 *
 * @param name The name for the lock
 */
- (void)setName: (nullable OFString*)name;
- (void)setName: (nullable OFString *)name;

/*!
 * @brief Returns the name for the lock.
 *
 * @return The name for the lock
 */
- (nullable OFString*)name;
- (nullable OFString *)name;
@end

OF_ASSUME_NONNULL_END

Modified src/OFMD5Hash.m from [43550851b7] to [003b801911].

163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177







-
+







{
	_state[0] = 0x67452301;
	_state[1] = 0xEFCDAB89;
	_state[2] = 0x98BADCFE;
	_state[3] = 0x10325476;
}

- (void)updateWithBuffer: (const void*)buffer_
- (void)updateWithBuffer: (const void *)buffer_
		  length: (size_t)length
{
	const uint8_t *buffer = buffer_;

	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithObject: self];
193
194
195
196
197
198
199
200

201
202
203

204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229
230
231
232
193
194
195
196
197
198
199

200
201
202

203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232







-
+


-
+

















-
+











		if (_bufferLength == 64) {
			processBlock(_state, _buffer.words);
			_bufferLength = 0;
		}
	}
}

- (const unsigned char*)digest
- (const unsigned char *)digest
{
	if (_calculated)
		return (const uint8_t*)_state;
		return (const uint8_t *)_state;

	_buffer.bytes[_bufferLength] = 0x80;
	memset(_buffer.bytes + _bufferLength + 1, 0, 64 - _bufferLength - 1);

	if (_bufferLength >= 56) {
		processBlock(_state, _buffer.words);
		memset(_buffer.bytes, 0, 64);
	}

	_buffer.words[14] = OF_BSWAP32_IF_BE((uint32_t)(_bits & 0xFFFFFFFF));
	_buffer.words[15] = OF_BSWAP32_IF_BE((uint32_t)(_bits >> 32));

	processBlock(_state, _buffer.words);
	memset(&_buffer, 0, sizeof(_buffer));
	byteSwapVectorIfBE(_state, 4);
	_calculated = true;

	return (const uint8_t*)_state;
	return (const uint8_t *)_state;
}

- (void)reset
{
	[self OF_resetState];
	_bits = 0;
	memset(&_buffer, 0, sizeof(_buffer));
	_bufferLength = 0;
	_calculated = false;
}
@end

Modified src/OFMapTable+Private.h from [075d4c6ae4] to [4526b06ac3].

20
21
22
23
24
25
26
27

28
29
30
31
20
21
22
23
24
25
26

27
28
29
30
31







-
+





@interface OFMapTable_EnumeratorWrapper: OFEnumerator
{
	OFMapTableEnumerator *_enumerator;
	id _object;
}

- initWithEnumerator: (OFMapTableEnumerator*)enumerator
- initWithEnumerator: (OFMapTableEnumerator *)enumerator
	      object: (id)object;
@end

OF_ASSUME_NONNULL_END

Modified src/OFMapTable.h from [68e1c948c0] to [1bd4f42cb6].

146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162


163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160


161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216







-
+







-
-
+
+






-
+













-
+









-
+







-
+







-
+








/*!
 * @brief Returns the object for the given key or NULL if the key was not found.
 *
 * @param key The key whose object should be returned
 * @return The object for the given key or NULL if the key was not found
 */
- (nullable void*)objectForKey: (void*)key;
- (nullable void *)objectForKey: (void *)key;

/*!
 * @brief Sets an object for a key.
 *
 * @param key The key to set
 * @param object The object to set the key to
 */
- (void)setObject: (void*)object
	   forKey: (void*)key;
- (void)setObject: (void *)object
	   forKey: (void *)key;

/*!
 * @brief Removes the object for the specified key from the map table.
 *
 * @param key The key whose object should be removed
 */
- (void)removeObjectForKey: (void*)key;
- (void)removeObjectForKey: (void *)key;

/*!
 * @brief Removes all objects.
 */
- (void)removeAllObjects;

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

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

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

/*!
 * @brief Returns an OFMapTableEnumerator to enumerate through the map table's
 *	  objects.
 *
 * @return An OFMapTableEnumerator to enumerate through the map table's objects
 */
- (OFMapTableEnumerator*)objectEnumerator;
- (OFMapTableEnumerator *)objectEnumerator;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Executes a block for each key / object pair.
 *
 * @param block The block to execute for each key / object pair.
 */
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259







-
+









}

/*!
 * @brief Returns the next object.
 *
 * @return The next object
 */
- (void*)nextObject;
- (void *)nextObject;

/*!
 * @brief Resets the enumerator, so the next call to @ref nextKey returns the
 *	  first key again.
 */
- (void)reset;
@end

OF_ASSUME_NONNULL_END

Modified src/OFMapTable.m from [69937f5d0f] to [0faf59214b].

33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47







-
+








struct of_map_table_bucket {
	void *key, *object;
	uint32_t hash;
};
static struct of_map_table_bucket deleted = { 0 };

static void*
static void *
defaultRetain(void *object)
{
	return object;
}

static void
defaultRelease(void *object)
57
58
59
60
61
62
63
64
65


66
67
68
69
70
71


72
73

74
75
76
77
78
79
80
57
58
59
60
61
62
63


64
65
66
67
68
69


70
71
72

73
74
75
76
77
78
79
80







-
-
+
+




-
-
+
+

-
+







static bool
defaultEqual(void *object1, void *object2)
{
	return (object1 == object2);
}

@interface OFMapTable ()
- (void)OF_setObject: (void*)object
	      forKey: (void*)key
- (void)OF_setObject: (void *)object
	      forKey: (void *)key
		hash: (uint32_t)hash;
@end

@interface OFMapTableEnumerator ()
- (instancetype)OF_initWithMapTable: (OFMapTable*)mapTable
			    buckets: (struct of_map_table_bucket**)buckets
- (instancetype)OF_initWithMapTable: (OFMapTable *)mapTable
			    buckets: (struct of_map_table_bucket **)buckets
			   capacity: (uint32_t)capacity
		   mutationsPointer: (unsigned long*)mutationsPtr;
		   mutationsPointer: (unsigned long *)mutationsPtr;
@end

@interface OFMapTableKeyEnumerator: OFMapTableEnumerator
@end

@interface OFMapTableObjectEnumerator: OFMapTableEnumerator
@end
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271







-
+







}

- (size_t)count
{
	return _count;
}

- (void*)objectForKey: (void*)key
- (void *)objectForKey: (void *)key
{
	uint32_t i, hash, last;

	if (key == NULL)
		@throw [OFInvalidArgumentException exception];

	hash = OF_ROL(_keyFunctions.hash(key), _rotate);
353
354
355
356
357
358
359
360
361


362
363
364
365
366
367
368
353
354
355
356
357
358
359


360
361
362
363
364
365
366
367
368







-
-
+
+







	}

	[self freeMemory: _buckets];
	_buckets = buckets;
	_capacity = capacity;
}

- (void)OF_setObject: (void*)object
	      forKey: (void*)key
- (void)OF_setObject: (void *)object
	      forKey: (void *)key
		hash: (uint32_t)hash
{
	uint32_t i, last;
	void *old;

	if (key == NULL || object == NULL)
		@throw [OFInvalidArgumentException exception];
441
442
443
444
445
446
447
448
449


450
451
452
453
454
455
456

457
458
459
460
461
462
463
441
442
443
444
445
446
447


448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463







-
-
+
+






-
+







	}

	old = _buckets[i]->object;
	_buckets[i]->object = _objectFunctions.retain(object);
	_objectFunctions.release(old);
}

- (void)setObject: (void*)object
	   forKey: (void*)key
- (void)setObject: (void *)object
	   forKey: (void *)key
{
	[self OF_setObject: object
		    forKey: key
		      hash: _keyFunctions.hash(key)];
}

- (void)removeObjectForKey: (void*)key
- (void)removeObjectForKey: (void *)key
{
	uint32_t i, hash, last;

	if (key == NULL)
		@throw [OFInvalidArgumentException exception];

	hash = OF_ROL(_keyFunctions.hash(key), _rotate);
542
543
544
545
546
547
548
549

550
551
552
553
554
555
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570
571
572
573
574
575

576
577
578
579
580
581
582
583
584

585
586
587
588
589
590
591
592
593
594


595
596
597
598
599
600
601
542
543
544
545
546
547
548

549
550
551
552
553
554
555
556
557
558
559
560
561

562
563
564
565
566
567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
582
583

584
585
586
587
588
589
590
591
592


593
594
595
596
597
598
599
600
601







-
+












-
+












-
+








-
+








-
-
+
+







#elif defined(HAVE_RANDOM)
		_rotate = random() & 31;
#else
		_rotate = rand() & 31;
#endif
}

- (bool)containsObject: (void*)object
- (bool)containsObject: (void *)object
{
	if (object == NULL || _count == 0)
		return false;

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

	return false;
}

- (bool)containsObjectIdenticalTo: (void*)object
- (bool)containsObjectIdenticalTo: (void *)object
{
	if (object == NULL || _count == 0)
		return false;

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

	return false;
}

- (OFMapTableEnumerator*)keyEnumerator
- (OFMapTableEnumerator *)keyEnumerator
{
	return [[[OFMapTableKeyEnumerator alloc]
	    OF_initWithMapTable: self
			buckets: _buckets
		       capacity: _capacity
	       mutationsPointer: &_mutations] autorelease];
}

- (OFMapTableEnumerator*)objectEnumerator
- (OFMapTableEnumerator *)objectEnumerator
{
	return [[[OFMapTableObjectEnumerator alloc]
	    OF_initWithMapTable: self
			buckets: _buckets
		       capacity: _capacity
	       mutationsPointer: &_mutations] autorelease];
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state
			   objects: (id *)objects
			     count: (int)count
{
	uint32_t j = (uint32_t)state->state;
	int i;

	for (i = 0; i < count; i++) {
		for (; j < _capacity && (_buckets[j] == NULL ||
661
662
663
664
665
666
667
668
669


670
671

672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691

692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707

708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724

725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741

742
743
744
745
746
747
748
661
662
663
664
665
666
667


668
669
670

671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706

707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
748







-
-
+
+

-
+



















-
+















-
+
















-
+
















-
+








@implementation OFMapTableEnumerator
- init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)OF_initWithMapTable: (OFMapTable*)mapTable
			    buckets: (struct of_map_table_bucket**)buckets
- (instancetype)OF_initWithMapTable: (OFMapTable *)mapTable
			    buckets: (struct of_map_table_bucket **)buckets
			   capacity: (uint32_t)capacity
		   mutationsPointer: (unsigned long*)mutationsPtr
		   mutationsPointer: (unsigned long *)mutationsPtr
{
	self = [super init];

	_mapTable = [mapTable retain];
	_buckets = buckets;
	_capacity = capacity;
	_mutations = *mutationsPtr;
	_mutationsPtr = mutationsPtr;

	return self;
}

- (void)dealloc
{
	[_mapTable release];

	[super dealloc];
}

- (void*)nextObject
- (void *)nextObject
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)reset
{
	if (*_mutationsPtr != _mutations)
		@throw [OFEnumerationMutationException
		    exceptionWithObject: _mapTable];

	_position = 0;
}
@end

@implementation OFMapTableKeyEnumerator
- (void*)nextObject
- (void *)nextObject
{
	if (*_mutationsPtr != _mutations)
		@throw [OFEnumerationMutationException
		    exceptionWithObject: _mapTable];

	for (; _position < _capacity && (_buckets[_position] == NULL ||
	    _buckets[_position] == &deleted); _position++);

	if (_position < _capacity)
		return _buckets[_position++]->key;
	else
		return NULL;
}
@end

@implementation OFMapTableObjectEnumerator
- (void*)nextObject
- (void *)nextObject
{
	if (*_mutationsPtr != _mutations)
		@throw [OFEnumerationMutationException
		    exceptionWithObject: _mapTable];

	for (; _position < _capacity && (_buckets[_position] == NULL ||
	    _buckets[_position] == &deleted); _position++);

	if (_position < _capacity)
		return _buckets[_position++]->object;
	else
		return NULL;
}
@end

@implementation OFMapTable_EnumeratorWrapper
- initWithEnumerator: (OFMapTableEnumerator*)enumerator
- initWithEnumerator: (OFMapTableEnumerator *)enumerator
	      object: (id)object
{
	self = [super init];

	_enumerator = [enumerator retain];
	_object = [object retain];

Modified src/OFMessagePackExtension.h from [386dd06c1d] to [834b809fc0].

49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67

68
69
70
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66

67
68
69
70







-
+










-
+



 *	  data.
 *
 * @param type The MessagePack extension type
 * @param data The data for the extension
 * @return A new, autoreleased OFMessagePackRepresentation
 */
+ (instancetype)extensionWithType: (int8_t)type
			     data: (OFDataArray*)data;
			     data: (OFDataArray *)data;

/*!
 * @brief Initializes an already allocated OFMessagePackRepresentation with the
 *	  specified type and data.
 *
 * @param type The MessagePack extension type
 * @param data The data for the extension
 * @return An initialized OFMessagePackRepresentation
 */
- initWithType: (int8_t)type
	  data: (OFDataArray*)data;
	  data: (OFDataArray *)data;
@end

OF_ASSUME_NONNULL_END

Modified src/OFMessagePackExtension.m from [06108912c2] to [d56d43685b].

22
23
24
25
26
27
28
29

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

42
43
44
45
46
47
48
22
23
24
25
26
27
28

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

41
42
43
44
45
46
47
48







-
+











-
+








#import "OFInvalidArgumentException.h"

@implementation OFMessagePackExtension
@synthesize type = _type, data = _data;

+ (instancetype)extensionWithType: (int8_t)type
			     data: (OFDataArray*)data
			     data: (OFDataArray *)data
{
	return [[[self alloc] initWithType: type
				      data: data] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithType: (int8_t)type
	  data: (OFDataArray*)data
	  data: (OFDataArray *)data
{
	self = [super init];

	@try {
		if (data == nil || [data itemSize] != 1)
			@throw [OFInvalidArgumentException exception];

59
60
61
62
63
64
65
66

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

66
67
68
69
70
71
72
73







-
+







- (void)dealloc
{
	[_data release];

	[super dealloc];
}

- (OFDataArray*)messagePackRepresentation
- (OFDataArray *)messagePackRepresentation
{
	OFDataArray *ret;
	uint8_t prefix;
	size_t count = [_data count];

	if (count == 1) {
		ret = [OFDataArray dataArrayWithCapacity: 3];
146
147
148
149
150
151
152
153

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

153
154
155
156
157
158
159
160







-
+








	[ret addItems: [_data items]
		count: [_data count]];

	return ret;
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFMessagePackExtension: %d, %@>",
					   _type, _data];
}

- (bool)isEqual: (id)object
{

Modified src/OFMessagePackRepresentation.h from [4a497d828e] to [3af5c96964].

30
31
32
33
34
35
36
37

38
39
40
30
31
32
33
34
35
36

37
38
39
40







-
+



@protocol OFMessagePackRepresentation
/*!
 * @brief Returns the MessagePack representation of the object as an
 *	  OFDataArray.
 *
 * @return The MessagePack representation of the object as an OFDataArray.
 */
- (OFDataArray*)messagePackRepresentation;
- (OFDataArray *)messagePackRepresentation;
@end

OF_ASSUME_NONNULL_END

Modified src/OFMutableArray.h from [d3ea586b43] to [d8a00e107e].

34
35
36
37
38
39
40
41

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

41
42
43
44
45
46
47
48







-
+







/*!
 * @class OFMutableArray OFArray.h ObjFW/OFArray.h
 *
 * @brief An abstract class for storing, adding and removing objects in an
 *	  array.
 */
#ifdef OF_HAVE_GENERICS
@interface OFMutableArray <ObjectType>: OFArray <ObjectType>
@interface OFMutableArray<ObjectType>: OFArray<ObjectType>
#else
# ifndef DOXYGEN
#  define ObjectType id
# endif
@interface OFMutableArray: OFArray
#endif
/*!
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
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







-
+
















-
+







- (void)addObject: (ObjectType)object;

/*!
 * @brief Adds the objects from the specified OFArray to the end of the array.
 *
 * @param array An array of objects to add
 */
- (void)addObjectsFromArray: (OFArray OF_GENERIC(ObjectType)*)array;
- (void)addObjectsFromArray: (OFArray OF_GENERIC(ObjectType) *)array;

/*!
 * @brief Inserts an object to the OFArray at the specified index.
 *
 * @param object An object to add
 * @param index The index where the object should be inserted
 */
- (void)insertObject: (ObjectType)object
	     atIndex: (size_t)index;

/*!
 * @brief Inserts the objects from the specified OFArray at the specified index.
 *
 * @param array An array of objects
 * @param index The index where the objects should be inserted
 */
- (void)insertObjectsFromArray: (OFArray OF_GENERIC(ObjectType)*)array
- (void)insertObjectsFromArray: (OFArray OF_GENERIC(ObjectType) *)array
		       atIndex: (size_t)index;

/*!
 * @brief Replaces the first object equivalent to the specified object with the
 *	  other specified object.
 *
 * @param oldObject The object to replace

Modified src/OFMutableArray.m from [e9c73ad6de] to [f7473af41f].

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







-
+




-
+






-
+







- initWithObject: (id)firstObject
       arguments: (va_list)arguments
{
	return (id)[[OFMutableArray_adjacent alloc] initWithObject: firstObject
							 arguments: arguments];
}

- initWithArray: (OFArray*)array
- initWithArray: (OFArray *)array
{
	return (id)[[OFMutableArray_adjacent alloc] initWithArray: array];
}

- initWithObjects: (id const*)objects
- initWithObjects: (id const *)objects
	    count: (size_t)count
{
	return (id)[[OFMutableArray_adjacent alloc] initWithObjects: objects
							      count: count];
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFMutableArray_adjacent alloc]
	    initWithSerialization: element];
}

- retain
{
199
200
201
202
203
204
205
206

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

219
220
221
222
223
224
225
199
200
201
202
203
204
205

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

218
219
220
221
222
223
224
225







-
+











-
+








- (void)addObject: (id)object
{
	[self insertObject: object
		   atIndex: [self count]];
}

- (void)addObjectsFromArray: (OFArray*)array
- (void)addObjectsFromArray: (OFArray *)array
{
	[self insertObjectsFromArray: array
			     atIndex: [self count]];
}

- (void)insertObject: (id)object
	     atIndex: (size_t)index
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)insertObjectsFromArray: (OFArray*)array
- (void)insertObjectsFromArray: (OFArray *)array
		       atIndex: (size_t)index
{
	size_t i = 0;

	for (id object in array)
		[self insertObject: object
			   atIndex: index + i++];

Modified src/OFMutableArray_adjacent.m from [55b87bb47c] to [6496c63550].

72
73
74
75
76
77
78
79

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

79
80
81
82
83
84
85
86







-
+







		@throw [OFOutOfRangeException exception];
	}
	[object retain];

	_mutations++;
}

- (void)insertObjectsFromArray: (OFArray*)array
- (void)insertObjectsFromArray: (OFArray *)array
		       atIndex: (size_t)index
{
	id const *objects = [array objects];
	size_t count = [array count];

	@try {
		[_array insertItems: objects
294
295
296
297
298
299
300
301
302


303
304
305
306
307
308
309
294
295
296
297
298
299
300


301
302
303
304
305
306
307
308
309







-
-
+
+







	for (i = 0, j = count - 1; i < j; i++, j--) {
		id tmp = objects[i];
		objects[i] = objects[j];
		objects[j] = tmp;
	}
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state
			   objects: (id *)objects
			     count: (int)count_
{
	size_t count = [_array count];

	if (count > INT_MAX) {
		/*
		 * Use the implementation from OFArray (OFMutableArray does not
323
324
325
326
327
328
329
330

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

330
331
332
333
334
335
336
337







-
+







	state->state = (unsigned long)count;
	state->itemsPtr = [_array items];
	state->mutationsPtr = &_mutations;

	return (int)count;
}

- (OFEnumerator*)objectEnumerator
- (OFEnumerator *)objectEnumerator
{
	return [[[OFArrayEnumerator alloc]
	    initWithArray: self
	     mutationsPtr: &_mutations] autorelease];
}

#ifdef OF_HAVE_BLOCKS

Modified src/OFMutableDictionary.h from [98bf6cee07] to [50af542eae].

33
34
35
36
37
38
39
40
41


42
43
44
45
46
47
48
33
34
35
36
37
38
39


40
41
42
43
44
45
46
47
48







-
-
+
+








/*!
 * @class OFMutableDictionary OFDictionary.h ObjFW/OFDictionary.h
 *
 * @brief An abstract class for storing and changing objects in a dictionary.
 */
#ifdef OF_HAVE_GENERICS
@interface OFMutableDictionary <KeyType, ObjectType>:
    OFDictionary <KeyType, ObjectType>
@interface OFMutableDictionary<KeyType, ObjectType>:
    OFDictionary<KeyType, ObjectType>
#else
# ifndef DOXYGEN
#  define KeyType id
#  define ObjectType id
# endif
@interface OFMutableDictionary: OFDictionary
#endif

Modified src/OFMutableDictionary.m from [8cacd80133] to [63b8a9aaca].

31
32
33
34
35
36
37
38

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


53
54
55
56
57
58
59
60


61
62
63
64
65
66
67
31
32
33
34
35
36
37

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


51
52
53
54
55
56
57
58


59
60
61
62
63
64
65
66
67







-
+












-
-
+
+






-
-
+
+








@implementation OFMutableDictionary_placeholder
- init
{
	return (id)[[OFMutableDictionary_hashtable alloc] init];
}

- initWithDictionary: (OFDictionary*)dictionary
- initWithDictionary: (OFDictionary *)dictionary
{
	return (id)[[OFMutableDictionary_hashtable alloc]
	    initWithDictionary: dictionary];
}

- initWithObject: (id)object
	  forKey: (id)key
{
	return (id)[[OFMutableDictionary_hashtable alloc] initWithObject: object
								  forKey: key];
}

- initWithObjects: (OFArray*)objects
	  forKeys: (OFArray*)keys
- initWithObjects: (OFArray *)objects
	  forKeys: (OFArray *)keys
{
	return (id)[[OFMutableDictionary_hashtable alloc]
	    initWithObjects: objects
		    forKeys: keys];
}

- initWithObjects: (id const*)objects
	  forKeys: (id const*)keys
- initWithObjects: (id const *)objects
	  forKeys: (id const *)keys
	    count: (size_t)count
{
	return (id)[[OFMutableDictionary_hashtable alloc]
	    initWithObjects: objects
		    forKeys: keys
		      count: count];
}
84
85
86
87
88
89
90
91

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

91
92
93
94
95
96
97
98







-
+







    arguments: (va_list)arguments
{
	return (id)[[OFMutableDictionary_hashtable alloc]
	    initWithKey: firstKey
	      arguments: arguments];
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFMutableDictionary_hashtable alloc]
	    initWithSerialization: element];
}

- initWithCapacity: (size_t)capacity
{

Modified src/OFMutableDictionary_hashtable.m from [6a515f0f03] to [57fa2b9adf].

50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64







-
+







}

#ifdef OF_HAVE_BLOCKS
- (void)replaceObjectsUsingBlock: (of_dictionary_replace_block_t)block
{
	@try {
		[_mapTable replaceObjectsUsingBlock:
		    ^ void* (void *key, void *object) {
		    ^ void *(void *key, void *object) {
			return block(key, object);
		}];
	} @catch (OFEnumerationMutationException *e) {
		@throw [OFEnumerationMutationException
		    exceptionWithObject: self];
	}
}

Modified src/OFMutableSet.h from [0f0aec6a5e] to [95746eb4fa].

20
21
22
23
24
25
26
27

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

27
28
29
30
31
32
33
34







-
+








/*!
 * @class OFMutableSet OFSet.h ObjFW/OFSet.h
 *
 * @brief An abstract class for a mutable unordered set of unique objects.
 */
#ifdef OF_HAVE_GENERICS
@interface OFMutableSet <ObjectType>: OFSet <ObjectType>
@interface OFMutableSet<ObjectType>: OFSet<ObjectType>
#else
# ifndef DOXYGEN
#  define ObjectType id
# endif
@interface OFMutableSet: OFSet
#endif
/*!
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
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







-
+







-
+






-
+











- (void)removeObject: (ObjectType)object;

/*!
 * @brief Removes all objects from the receiver which are in the specified set.
 *
 * @param set The set whose objects will be removed from the receiver
 */
- (void)minusSet: (OFSet OF_GENERIC(ObjectType)*)set;
- (void)minusSet: (OFSet OF_GENERIC(ObjectType) *)set;

/*!
 * @brief Removes all objects from the receiver which are not in the specified
 *	  set.
 *
 * @param set The set to intersect with
 */
- (void)intersectSet: (OFSet OF_GENERIC(ObjectType)*)set;
- (void)intersectSet: (OFSet OF_GENERIC(ObjectType) *)set;

/*!
 * @brief Creates a union of the receiver and the specified set.
 *
 * @param set The set to create the union with
 */
- (void)unionSet: (OFSet OF_GENERIC(ObjectType)*)set;
- (void)unionSet: (OFSet OF_GENERIC(ObjectType) *)set;

/*!
 * @brief Converts the mutable set to an immutable set.
 */
- (void)makeImmutable;
@end
#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN)
# undef ObjectType
#endif

OF_ASSUME_NONNULL_END

Modified src/OFMutableSet.m from [3bdd110505] to [be0ab30e62].

32
33
34
35
36
37
38
39

40
41
42
43
44

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

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

77
78
79
80
81
82
83
32
33
34
35
36
37
38

39
40
41
42
43

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

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

76
77
78
79
80
81
82
83







-
+




-
+

















-
+













-
+








@implementation OFMutableSet_placeholder
- init
{
	return (id)[[OFMutableSet_hashtable alloc] init];
}

- initWithSet: (OFSet*)set
- initWithSet: (OFSet *)set
{
	return (id)[[OFMutableSet_hashtable alloc] initWithSet: set];
}

- initWithArray: (OFArray*)array
- initWithArray: (OFArray *)array
{
	return (id)[[OFMutableSet_hashtable alloc] initWithArray: array];
}

- initWithObjects: (id)firstObject, ...
{
	id ret;
	va_list arguments;

	va_start(arguments, firstObject);
	ret = [[OFMutableSet_hashtable alloc] initWithObject: firstObject
						   arguments: arguments];
	va_end(arguments);

	return ret;
}

- initWithObjects: (id const*)objects
- initWithObjects: (id const *)objects
	    count: (size_t)count
{
	return (id)[[OFMutableSet_hashtable alloc] initWithObjects: objects
							     count: count];
}

- initWithObject: (id)firstObject
       arguments: (va_list)arguments
{
	return (id)[[OFMutableSet_hashtable alloc] initWithObject: firstObject
							arguments: arguments];
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFMutableSet_hashtable alloc]
	    initWithSerialization: element];
}

- initWithCapacity: (size_t)capacity
{
150
151
152
153
154
155
156
157

158
159
160
161
162
163

164
165
166
167
168
169
170
150
151
152
153
154
155
156

157
158
159
160
161
162

163
164
165
166
167
168
169
170







-
+





-
+







}

- (void)removeObject: (id)object
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)minusSet: (OFSet*)set
- (void)minusSet: (OFSet *)set
{
	for (id object in set)
		[self removeObject: object];
}

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

	cArray = [self allocMemoryWithSize: sizeof(id)
				     count: count];
184
185
186
187
188
189
190
191

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

191
192
193
194
195
196
197
198
199
200







-
+









	} @finally {
		[self freeMemory: cArray];
	}

	objc_autoreleasePoolPop(pool);
}

- (void)unionSet: (OFSet*)set
- (void)unionSet: (OFSet *)set
{
	for (id object in set)
		[self addObject: object];
}

- (void)makeImmutable
{
}
@end

Modified src/OFMutableSet_hashtable.m from [cf2eb9bd94] to [6a9e638b4e].

25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
25
26
27
28
29
30
31

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







-
+













{
	if (self == [OFMutableSet_hashtable class])
		[self inheritMethodsFromClass: [OFSet_hashtable class]];
}

- (void)addObject: (id)object
{
	[_mapTable setObject: (void*)1
	[_mapTable setObject: (void *)1
		      forKey: object];
}

- (void)removeObject: (id)object
{
	[_mapTable removeObjectForKey: object];
}

- (void)makeImmutable
{
	object_setClass(self, [OFSet_hashtable class]);
}
@end

Modified src/OFMutableString.h from [d140645479] to [8880ebe178].

34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95

96
97
98
99

100
101
102
103
104
105



106
107
108
109
110

111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94

95
96
97
98

99
100
101
102
103


104
105
106
107
108
109
110

111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126







-
+







-
+







-
+








-
+








-
+










-
+








-
+



-
+




-
-
+
+
+




-
+







-
+







	     atIndex: (size_t)index;

/*!
 * @brief Appends another OFString to the OFMutableString.
 *
 * @param string An OFString to append
 */
- (void)appendString: (OFString*)string;
- (void)appendString: (OFString *)string;

/*!
 * @brief Appends the specified characters to the OFMutableString.
 *
 * @param characters An array of characters to append
 * @param length The length of the array of characters
 */
- (void)appendCharacters: (const of_unichar_t*)characters
- (void)appendCharacters: (const of_unichar_t *)characters
		  length: (size_t)length;

/*!
 * @brief Appends a UTF-8 encoded C string to the OFMutableString.
 *
 * @param UTF8String A UTF-8 encoded C string to append
 */
- (void)appendUTF8String: (const char*)UTF8String;
- (void)appendUTF8String: (const char *)UTF8String;

/*!
 * @brief Appends a UTF-8 encoded C string with the specified length to the
 *	  OFMutableString.
 *
 * @param UTF8String A UTF-8 encoded C string to append
 * @param UTF8StringLength The length of the UTF-8 encoded C string
 */
- (void)appendUTF8String: (const char*)UTF8String
- (void)appendUTF8String: (const char *)UTF8String
		  length: (size_t)UTF8StringLength;

/*!
 * @brief Appends a C string with the specified encoding to the OFMutableString.
 *
 * @param cString A C string to append
 * @param encoding The encoding of the C string
 */
- (void)appendCString: (const char*)cString
- (void)appendCString: (const char *)cString
	     encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Appends a C string with the specified encoding and length to the
 *	  OFMutableString.
 *
 * @param cString A C string to append
 * @param encoding The encoding of the C string
 * @param cStringLength The length of the UTF-8 encoded C string
 */
- (void)appendCString: (const char*)cString
- (void)appendCString: (const char *)cString
	     encoding: (of_string_encoding_t)encoding
	       length: (size_t)cStringLength;

/*!
 * @brief Appends a formatted string to the OFMutableString.
 *
 * See `printf` for the format syntax. As an addition, `%@` is available as
 * format specifier for objects, `%C` for `of_unichar_t` and `%S` for
 * `const of_unichar_t*`.
 * `const of_unichar_t *`.
 *
 * @param format A format string which generates the string to append
 */
- (void)appendFormat: (OFConstantString*)format, ...;
- (void)appendFormat: (OFConstantString *)format, ...;

/*!
 * @brief Appends a formatted string to the OFMutableString.
 *
 * See printf for the format syntax. As an addition, %@ is available as format
 * specifier for objects, %C for of_unichar_t and %S for const of_unichar_t*.
 * See printf for the format syntax. As an addition, `%@` is available as
 * format specifier for objects, `%C` for `of_unichar_t` and `%S` for
 * `const of_unichar_t *`.
 *
 * @param format A format string which generates the string to append
 * @param arguments The arguments used in the format string
 */
- (void)appendFormat: (OFConstantString*)format
- (void)appendFormat: (OFConstantString *)format
	   arguments: (va_list)arguments;

/*!
 * @brief Prepends another OFString to the OFMutableString.
 *
 * @param string An OFString to prepend
 */
- (void)prependString: (OFString*)string;
- (void)prependString: (OFString *)string;

/*!
 * @brief Reverses the string.
 */
- (void)reverse;

/*!
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
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







-
+
















-
+







-
-
+
+











-
-
+
+








/*!
 * @brief Inserts a string at the specified index.
 *
 * @param string The string to insert
 * @param index The index
 */
- (void)insertString: (OFString*)string
- (void)insertString: (OFString *)string
	     atIndex: (size_t)index;

/*!
 * @brief Deletes the characters at the specified range.
 *
 * @param range The range of the characters which should be removed
 */
- (void)deleteCharactersInRange: (of_range_t)range;

/*!
 * @brief Replaces the characters at the specified range.
 *
 * @param range The range of the characters which should be replaced
 * @param replacement The string to the replace the characters with
 */
- (void)replaceCharactersInRange: (of_range_t)range
		      withString: (OFString*)replacement;
		      withString: (OFString *)replacement;

/*!
 * @brief Replaces all occurrences of a string with another string.
 *
 * @param string The string to replace
 * @param replacement The string with which it should be replaced
 */
- (void)replaceOccurrencesOfString: (OFString*)string
			withString: (OFString*)replacement;
- (void)replaceOccurrencesOfString: (OFString *)string
			withString: (OFString *)replacement;

/*!
 * @brief Replaces all occurrences of a string in the specified range with
 *	  another string.
 *
 * @param string The string to replace
 * @param replacement The string with which it should be replaced
 * @param options Options modifying search behaviour
 *		  Possible values: None yet
 * @param range The range in which the string should be replaced
 */
- (void)replaceOccurrencesOfString: (OFString*)string
			withString: (OFString*)replacement
- (void)replaceOccurrencesOfString: (OFString *)string
			withString: (OFString *)replacement
			   options: (int)options
			     range: (of_range_t)range;

/*!
 * @brief Deletes all whitespaces at the beginning of the string.
 */
- (void)deleteLeadingWhitespaces;

Modified src/OFMutableString.m from [3e71679146] to [8db593635a].

41
42
43
44
45
46
47
48

49
50
51
52
53
54

55
56
57
58
59
60
61
62

63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79

80
81
82
83
84

85
86
87
88
89
90
91

92
93
94
95
96

97
98
99
100
101
102
103

104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121

122
123
124
125
126

127
128
129
130
131
132
133

134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172

173
174
175
176
177

178
179
180
181
182
183
184
185
186
187

188
189
190
191
192

193
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
41
42
43
44
45
46
47

48
49
50
51
52
53

54
55
56
57
58
59
60
61

62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78

79
80
81
82
83

84
85
86
87
88
89
90

91
92
93
94
95

96
97
98
99
100
101
102

103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120

121
122
123
124
125

126
127
128
129
130
131
132

133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171

172
173
174
175
176

177
178
179
180
181
182
183
184
185
186

187
188
189
190
191

192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208







-
+





-
+







-
+






-
+









-
+




-
+






-
+




-
+






-
+







-
+









-
+




-
+






-
+







-
+









-
+












-
+







-
+




-
+









-
+




-
+








-
+








@implementation OFMutableString_placeholder
- init
{
	return (id)[[OFMutableString_UTF8 alloc] init];
}

- initWithUTF8String: (const char*)UTF8String
- initWithUTF8String: (const char *)UTF8String
{
	return (id)[[OFMutableString_UTF8 alloc]
	    initWithUTF8String: UTF8String];
}

- initWithUTF8String: (const char*)UTF8String
- initWithUTF8String: (const char *)UTF8String
	      length: (size_t)UTF8StringLength
{
	return (id)[[OFMutableString_UTF8 alloc]
	    initWithUTF8String: UTF8String
			length: UTF8StringLength];
}

- initWithCString: (const char*)cString
- initWithCString: (const char *)cString
	 encoding: (of_string_encoding_t)encoding
{
	return (id)[[OFMutableString_UTF8 alloc] initWithCString: cString
							encoding: encoding];
}

- initWithCString: (const char*)cString
- initWithCString: (const char *)cString
	 encoding: (of_string_encoding_t)encoding
	   length: (size_t)cStringLength
{
	return (id)[[OFMutableString_UTF8 alloc]
	    initWithCString: cString
		   encoding: encoding
		     length: cStringLength];
}

- initWithString: (OFString*)string
- initWithString: (OFString *)string
{
	return (id)[[OFMutableString_UTF8 alloc] initWithString: string];
}

- initWithCharacters: (const of_unichar_t*)characters
- initWithCharacters: (const of_unichar_t *)characters
	      length: (size_t)length
{
	return (id)[[OFMutableString_UTF8 alloc] initWithCharacters: characters
							     length: length];
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
{
	return (id)[[OFMutableString_UTF8 alloc] initWithUTF16String: string];
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	       length: (size_t)length
{
	return (id)[[OFMutableString_UTF8 alloc] initWithUTF16String: string
							      length: length];
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	    byteOrder: (of_byte_order_t)byteOrder
{
	return (id)[[OFMutableString_UTF8 alloc]
	    initWithUTF16String: string
		      byteOrder: byteOrder];
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	return (id)[[OFMutableString_UTF8 alloc]
	    initWithUTF16String: string
			 length: length
		      byteOrder: byteOrder];
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
{
	return (id)[[OFMutableString_UTF8 alloc] initWithUTF32String: string];
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	       length: (size_t)length
{
	return (id)[[OFMutableString_UTF8 alloc] initWithUTF32String: string
							      length: length];
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	    byteOrder: (of_byte_order_t)byteOrder
{
	return (id)[[OFMutableString_UTF8 alloc]
	    initWithUTF32String: string
		      byteOrder: byteOrder];
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	return (id)[[OFMutableString_UTF8 alloc]
	    initWithUTF32String: string
			 length: length
		      byteOrder: byteOrder];
}

- initWithFormat: (OFConstantString*)format, ...
- initWithFormat: (OFConstantString *)format, ...
{
	id ret;
	va_list arguments;

	va_start(arguments, format);
	ret = [[OFMutableString_UTF8 alloc] initWithFormat: format
						 arguments: arguments];
	va_end(arguments);

	return ret;
}

- initWithFormat: (OFConstantString*)format
- initWithFormat: (OFConstantString *)format
       arguments: (va_list)arguments
{
	return (id)[[OFMutableString_UTF8 alloc] initWithFormat: format
						      arguments: arguments];
}

#ifdef OF_HAVE_FILES
- initWithContentsOfFile: (OFString*)path
- initWithContentsOfFile: (OFString *)path
{
	return (id)[[OFMutableString_UTF8 alloc] initWithContentsOfFile: path];
}

- initWithContentsOfFile: (OFString*)path
- initWithContentsOfFile: (OFString *)path
		encoding: (of_string_encoding_t)encoding
{
	return (id)[[OFMutableString_UTF8 alloc]
	    initWithContentsOfFile: path
			  encoding: encoding];
}
#endif

#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS)
- initWithContentsOfURL: (OFURL*)URL
- initWithContentsOfURL: (OFURL *)URL
{
	return (id)[[OFMutableString_UTF8 alloc] initWithContentsOfURL: URL];
}

- initWithContentsOfURL: (OFURL*)URL
- initWithContentsOfURL: (OFURL *)URL
	       encoding: (of_string_encoding_t)encoding
{
	return (id)[[OFMutableString_UTF8 alloc]
	    initWithContentsOfURL: URL
			 encoding: encoding];
}
#endif

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFMutableString_UTF8 alloc]
	    initWithSerialization: element];
}

- retain
{
328
329
330
331
332
333
334
335

336
337
338
339
340
341

342
343
344
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360
361

362
363
364
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380
381
382
383

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

397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
328
329
330
331
332
333
334

335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379
380
381
382

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

396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426

427
428
429
430
431
432
433
434







-
+





-
+










-
+








-
+










-
+










-
+












-
+









-
+




















-
+








	[self replaceCharactersInRange: of_range(index, 1)
			    withString: string];

	objc_autoreleasePoolPop(pool);
}

- (void)appendString: (OFString*)string
- (void)appendString: (OFString *)string
{
	[self insertString: string
		   atIndex: [self length]];
}

- (void)appendCharacters: (const of_unichar_t*)characters
- (void)appendCharacters: (const of_unichar_t *)characters
		  length: (size_t)length
{
	void *pool = objc_autoreleasePoolPush();

	[self appendString: [OFString stringWithCharacters: characters
						    length: length]];

	objc_autoreleasePoolPop(pool);
}

- (void)appendUTF8String: (const char*)UTF8String
- (void)appendUTF8String: (const char *)UTF8String
{
	void *pool = objc_autoreleasePoolPush();

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

	objc_autoreleasePoolPop(pool);
}

- (void)appendUTF8String: (const char*)UTF8String
- (void)appendUTF8String: (const char *)UTF8String
		  length: (size_t)UTF8StringLength
{
	void *pool = objc_autoreleasePoolPush();

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

	objc_autoreleasePoolPop(pool);
}

- (void)appendCString: (const char*)cString
- (void)appendCString: (const char *)cString
	     encoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();

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

	objc_autoreleasePoolPop(pool);
}

- (void)appendCString: (const char*)cString
- (void)appendCString: (const char *)cString
	     encoding: (of_string_encoding_t)encoding
	       length: (size_t)cStringLength
{
	void *pool = objc_autoreleasePoolPush();

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

	objc_autoreleasePoolPop(pool);
}

- (void)appendFormat: (OFConstantString*)format, ...
- (void)appendFormat: (OFConstantString *)format, ...
{
	va_list arguments;

	va_start(arguments, format);
	[self appendFormat: format
		 arguments: arguments];
	va_end(arguments);
}

- (void)appendFormat: (OFConstantString*)format
- (void)appendFormat: (OFConstantString *)format
	   arguments: (va_list)arguments
{
	char *UTF8String;
	int UTF8StringLength;

	if (format == nil)
		@throw [OFInvalidArgumentException exception];

	if ((UTF8StringLength = of_vasprintf(&UTF8String, [format UTF8String],
	    arguments)) == -1)
		@throw [OFInvalidFormatException exception];

	@try {
		[self appendUTF8String: UTF8String
				length: UTF8StringLength];
	} @finally {
		free(UTF8String);
	}
}

- (void)prependString: (OFString*)string
- (void)prependString: (OFString *)string
{
	[self insertString: string
		   atIndex: 0];
}

- (void)reverse
{
483
484
485
486
487
488
489
490

491
492
493
494
495
496
497
498
499
500
501
502
503
504

505
506
507
508
509
510


511
512
513
514
515
516
517
518
519


520
521
522
523
524
525
526
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497
498
499
500
501
502
503

504
505
506
507
508


509
510
511
512
513
514
515
516
517


518
519
520
521
522
523
524
525
526







-
+













-
+




-
-
+
+







-
-
+
+







- (void)capitalize
{
	[self OF_convertWithWordStartFunction: of_ascii_toupper
			   wordMiddleFunction: of_ascii_tolower];
}
#endif

- (void)insertString: (OFString*)string
- (void)insertString: (OFString *)string
	     atIndex: (size_t)index
{
	[self replaceCharactersInRange: of_range(index, 0)
			    withString: string];
}

- (void)deleteCharactersInRange: (of_range_t)range
{
	[self replaceCharactersInRange: range
			    withString: @""];
}

- (void)replaceCharactersInRange: (of_range_t)range
		      withString: (OFString*)replacement
		      withString: (OFString *)replacement
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)replaceOccurrencesOfString: (OFString*)string
			withString: (OFString*)replacement
- (void)replaceOccurrencesOfString: (OFString *)string
			withString: (OFString *)replacement
{
	[self replaceOccurrencesOfString: string
			      withString: replacement
				 options: 0
				   range: of_range(0, [self length])];
}

- (void)replaceOccurrencesOfString: (OFString*)string
			withString: (OFString*)replacement
- (void)replaceOccurrencesOfString: (OFString *)string
			withString: (OFString *)replacement
			   options: (int)options
			     range: (of_range_t)range
{
	void *pool = objc_autoreleasePoolPush(), *pool2;
	const of_unichar_t *characters;
	const of_unichar_t *searchCharacters = [string characters];
	size_t searchLength = [string length];

Modified src/OFMutableString_UTF8.m from [b3fb2f4d74] to [841b1b06a7].

37
38
39
40
41
42
43
44

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

44
45
46
47
48
49
50
51







-
+







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

- initWithUTF8StringNoCopy: (char*)UTF8String
- initWithUTF8StringNoCopy: (char *)UTF8String
	      freeWhenDone: (bool)freeWhenDone
{
	@try {
		self = [self initWithUTF8String: UTF8String];
	} @finally {
		if (freeWhenDone)
			free(UTF8String);
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281







-
+







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

- (void)appendUTF8String: (const char*)UTF8String
- (void)appendUTF8String: (const char *)UTF8String
{
	size_t UTF8StringLength = strlen(UTF8String);
	size_t length;

	if (UTF8StringLength >= 3 &&
	    memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) {
		UTF8String += 3;
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311







-
+







	memcpy(_s->cString + _s->cStringLength, UTF8String,
	    UTF8StringLength + 1);

	_s->cStringLength += UTF8StringLength;
	_s->length += length;
}

- (void)appendUTF8String: (const char*)UTF8String
- (void)appendUTF8String: (const char *)UTF8String
		  length: (size_t)UTF8StringLength
{
	size_t length;

	if (UTF8StringLength >= 3 &&
	    memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) {
		UTF8String += 3;
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
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







-
+







-
+


















-
+








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

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

- (void)appendCString: (const char*)cString
- (void)appendCString: (const char *)cString
	     encoding: (of_string_encoding_t)encoding
{
	[self appendCString: cString
		   encoding: encoding
		     length: strlen(cString)];
}

- (void)appendCString: (const char*)cString
- (void)appendCString: (const char *)cString
	     encoding: (of_string_encoding_t)encoding
	       length: (size_t)cStringLength
{
	if (encoding == OF_STRING_ENCODING_UTF_8)
		[self appendUTF8String: cString
				length: cStringLength];
	else {
		void *pool = objc_autoreleasePoolPush();

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

		objc_autoreleasePoolPop(pool);
	}
}

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

	if (string == nil)
		@throw [OFInvalidArgumentException exception];

	UTF8StringLength = [string UTF8StringLength];
378
379
380
381
382
383
384
385

386
387
388
389
390
391

392
393
394
395
396
397
398
378
379
380
381
382
383
384

385
386
387
388
389
390

391
392
393
394
395
396
397
398







-
+





-
+







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

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

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

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

	tmp = [self allocMemoryWithSize: (length * 4) + 1];
	@try {
		size_t j = 0;
424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
424
425
426
427
428
429
430

431
432
433
434
435
436
437
438







-
+







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

- (void)appendFormat: (OFConstantString*)format
- (void)appendFormat: (OFConstantString *)format
	   arguments: (va_list)arguments
{
	char *UTF8String;
	int UTF8StringLength;

	if (format == nil)
		@throw [OFInvalidArgumentException exception];
525
526
527
528
529
530
531
532

533
534
535
536
537
538
539
525
526
527
528
529
530
531

532
533
534
535
536
537
538
539







-
+







		}

		/* UTF-8 does not allow more than 4 bytes per character */
		@throw [OFInvalidEncodingException exception];
	}
}

- (void)insertString: (OFString*)string
- (void)insertString: (OFString *)string
	     atIndex: (size_t)index
{
	size_t newCStringLength;

	if (index > _s->length)
		@throw [OFOutOfRangeException exception];

553
554
555
556
557
558
559
560

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

560
561
562
563
564
565
566
567







-
+







	_s->cString[newCStringLength] = '\0';

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

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

- (void)deleteCharactersInRange: (of_range_t)range
{
590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
590
591
592
593
594
595
596

597
598
599
600
601
602
603
604







-
+







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

- (void)replaceCharactersInRange: (of_range_t)range
		      withString: (OFString*)replacement
		      withString: (OFString *)replacement
{
	size_t start = range.location;
	size_t end = range.location + range.length;
	size_t newCStringLength, newLength;

	if (replacement == nil)
		@throw [OFInvalidArgumentException exception];
646
647
648
649
650
651
652
653

654
655
656
657
658
659
660


661
662
663
664
665
666
667
646
647
648
649
650
651
652

653
654
655
656
657
658


659
660
661
662
663
664
665
666
667







-
+





-
-
+
+







					    size: newCStringLength + 1];

	_s->cStringLength = newCStringLength;
	_s->length = newLength;

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

- (void)replaceOccurrencesOfString: (OFString*)string
			withString: (OFString*)replacement
- (void)replaceOccurrencesOfString: (OFString *)string
			withString: (OFString *)replacement
			   options: (int)options
			     range: (of_range_t)range
{
	const char *searchString = [string UTF8String];
	const char *replacementString = [replacement UTF8String];
	size_t searchLength = [string UTF8StringLength];
	size_t replacementLength = [replacement UTF8StringLength];
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
733
734
735
736
737
738
739

740
741
742
743
744
745
746
747







-
+







	_s->hashed = false;
	_s->cString = newCString;
	_s->cStringLength = newCStringLength;
	_s->length = newLength;

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

- (void)deleteLeadingWhitespaces
{

Modified src/OFMutex.m from [a5b00a027c] to [fcee48ecda].

71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86







-
+









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

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

	return [OFString stringWithFormat: @"<%@: %@>",
					   [self className], _name];
}
@end

Modified src/OFNull.h from [a1cf765408] to [a98530e584].

30
31
32
33
34
35
36
37

38
39
40
30
31
32
33
34
35
36

37
38
39
40







-
+



@interface OFNull: OFObject <OFCopying, OFSerialization, OFJSONRepresentation,
    OFMessagePackRepresentation>
/*!
 * @brief Returns an OFNull singleton.
 *
 * @return An OFNull singleton
 */
+ (OFNull*)null;
+ (OFNull *)null;
@end

OF_ASSUME_NONNULL_END

Modified src/OFNull.m from [3b65b7b5aa] to [8d2ffd1fab].

20
21
22
23
24
25
26
27
28


29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44

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

62
63
64
65
66
67
68
69
70
71

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

87
88
89
90
91
92

93
94
95
96
97
98

99
100
101
102
103
104

105
106
107
108
109
110
111
20
21
22
23
24
25
26


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

39
40
41
42
43

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

61
62
63
64
65
66
67
68
69
70

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

86
87
88
89
90
91

92
93
94
95
96
97

98
99
100
101
102
103

104
105
106
107
108
109
110
111







-
-
+
+










-
+




-
+
















-
+









-
+














-
+





-
+





-
+





-
+







#import "OFString.h"
#import "OFXMLElement.h"
#import "OFDataArray.h"

#import "OFInvalidArgumentException.h"

@interface OFNull ()
- (OFString*)OF_JSONRepresentationWithOptions: (int)options
					depth: (size_t)depth;
- (OFString *)OF_JSONRepresentationWithOptions: (int)options
					 depth: (size_t)depth;
@end

static OFNull *null = nil;

@implementation OFNull
+ (void)initialize
{
	null = [[self alloc] init];
}

+ (OFNull*)null
+ (OFNull *)null
{
	return null;
}

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

	[self release];

	pool = objc_autoreleasePoolPush();

	if (![[element name] isEqual: [self className]] ||
	    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
		@throw [OFInvalidArgumentException exception];

	objc_autoreleasePoolPop(pool);

	return [OFNull null];
}

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

- copy
{
	return self;
}

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

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

	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (OFString*)JSONRepresentation
- (OFString *)JSONRepresentation
{
	return [self OF_JSONRepresentationWithOptions: 0
						depth: 0];
}

- (OFString*)JSONRepresentationWithOptions: (int)options
- (OFString *)JSONRepresentationWithOptions: (int)options
{
	return [self OF_JSONRepresentationWithOptions: options
						depth: 0];
}

- (OFString*)OF_JSONRepresentationWithOptions: (int)options
- (OFString *)OF_JSONRepresentationWithOptions: (int)options
					depth: (size_t)depth
{
	return @"null";
}

- (OFDataArray*)messagePackRepresentation
- (OFDataArray *)messagePackRepresentation
{
	OFDataArray *data = [OFDataArray dataArrayWithItemSize: 1
						      capacity: 1];
	uint8_t type = 0xC0;

	[data addItem: &type];

Modified src/OFNumber.m from [5681aa0f6b] to [97313fd44a].

88
89
90
91
92
93
94
95
96


97
98
99
100
101
102
103
88
89
90
91
92
93
94


95
96
97
98
99
100
101
102
103







-
-
+
+







	case OF_NUMBER_TYPE_DOUBLE:					\
		return (t)_value.double_;				\
	default:							\
		@throw [OFInvalidFormatException exception];		\
	}

@interface OFNumber ()
- (OFString*)OF_JSONRepresentationWithOptions: (int)options
					depth: (size_t)depth;
- (OFString *)OF_JSONRepresentationWithOptions: (int)options
					 depth: (size_t)depth;
@end

@implementation OFNumber
@synthesize type = _type;

+ (instancetype)numberWithBool: (bool)bool_
{
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534







-
+








	_value.double_ = double_;
	_type = OF_NUMBER_TYPE_DOUBLE;

	return self;
}

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

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

761
762
763
764
765
766
767
768

769
770
771
772
773
774
775
761
762
763
764
765
766
767

768
769
770
771
772
773
774
775







-
+







- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	OFNumber *number;

	if (![object isKindOfClass: [OFNumber class]])
		@throw [OFInvalidArgumentException exception];

	number = (OFNumber*)object;
	number = (OFNumber *)object;

	if (_type & OF_NUMBER_TYPE_FLOAT ||
	    number->_type & OF_NUMBER_TYPE_FLOAT) {
		double double1 = [self doubleValue];
		double double2 = [number doubleValue];

		if (double1 > double2)
865
866
867
868
869
870
871
872

873
874
875
876
877
878
879
865
866
867
868
869
870
871

872
873
874
875
876
877
878
879







-
+







}

- copy
{
	return [self retain];
}

- (OFString*)description
- (OFString *)description
{
	OFMutableString *ret;

	switch (_type) {
	case OF_NUMBER_TYPE_BOOL:
		return (_value.bool_ ? @"true" : @"false");
	case OF_NUMBER_TYPE_UCHAR:
922
923
924
925
926
927
928
929

930
931
932
933
934
935
936
922
923
924
925
926
927
928

929
930
931
932
933
934
935
936







-
+








		return ret;
	default:
		@throw [OFInvalidFormatException exception];
	}
}

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

	element = [OFXMLElement elementWithName: [self className]
				      namespace: OF_SERIALIZATION_NS
				    stringValue: [self description]];
1006
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017
1018
1019

1020
1021
1022
1023
1024
1025
1026


1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047

1048
1049
1050
1051
1052
1053
1054
1006
1007
1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018

1019
1020
1021
1022
1023
1024


1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046

1047
1048
1049
1050
1051
1052
1053
1054







-
+





-
+





-
-
+
+




















-
+







	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (OFString*)JSONRepresentation
- (OFString *)JSONRepresentation
{
	return [self OF_JSONRepresentationWithOptions: 0
						depth: 0];
}

- (OFString*)JSONRepresentationWithOptions: (int)options
- (OFString *)JSONRepresentationWithOptions: (int)options
{
	return [self OF_JSONRepresentationWithOptions: options
						depth: 0];
}

- (OFString*)OF_JSONRepresentationWithOptions: (int)options
					depth: (size_t)depth
- (OFString *)OF_JSONRepresentationWithOptions: (int)options
					 depth: (size_t)depth
{
	double doubleValue;

	if (_type == OF_NUMBER_TYPE_BOOL)
		return (_value.bool_ ? @"true" : @"false");

	doubleValue = [self doubleValue];
	if (isinf(doubleValue)) {
		if (options & OF_JSON_REPRESENTATION_JSON5) {
			if (doubleValue > 0)
				return @"Infinity";
			else
				return @"-Infinity";
		} else
			@throw [OFInvalidArgumentException exception];
	}

	return [self description];
}

- (OFDataArray*)messagePackRepresentation
- (OFDataArray *)messagePackRepresentation
{
	OFDataArray *data;

	if (_type == OF_NUMBER_TYPE_BOOL) {
		uint8_t type;

		data = [OFDataArray dataArrayWithItemSize: 1

Modified src/OFObject+KeyValueCoding.m from [d4b85d6121] to [30955b0805].

37
38
39
40
41
42
43
44

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

44
45
46
47
48
49
50
51







-
+







	while (**typeEncoding >= '0' && **typeEncoding <= '9')
		(*typeEncoding)++;

	return ret;
}

@implementation OFObject (KeyValueCoding)
- (id)valueForKey: (OFString*)key
- (id)valueForKey: (OFString *)key
{
	SEL selector = sel_registerName([key UTF8String]);
	const char *typeEncoding = [self typeEncodingForSelector: selector];
	id ret;

	if (typeEncoding == NULL) {
		size_t keyLength;
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95







-
+







	case '@':
	case '#':
		ret = [self performSelector: selector];
		break;
#define CASE(encoding, type, method)					  \
	case encoding:							  \
		{							  \
			type (*getter)(id, SEL) = (type(*)(id, SEL))	  \
			type (*getter)(id, SEL) = (type (*)(id, SEL))	  \
			    [self methodForSelector: selector];		  \
			ret = [OFNumber method getter(self, selector)]; \
		}							  \
		break;
	CASE('B', bool, numberWithBool:)
	CASE('c', char, numberWithChar:)
	CASE('s', short, numberWithShort:)
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125

126
127
128
129
130
131
132
111
112
113
114
115
116
117

118
119
120
121
122
123
124

125
126
127
128
129
130
131
132







-
+






-
+







	if (nextType(&typeEncoding) != '@' || nextType(&typeEncoding) != ':' ||
	    *typeEncoding != 0)
		return [self valueForUndefinedKey: key];

	return ret;
}

- (id)valueForUndefinedKey: (OFString*)key
- (id)valueForUndefinedKey: (OFString *)key
{
	@throw [OFUndefinedKeyException exceptionWithObject: self
							key: key];
}

- (void)setValue: (id)value
	  forKey: (OFString*)key
	  forKey: (OFString *)key
{
	size_t keyLength;
	char *name;
	SEL selector;
	const char *typeEncoding;
	char valueType;

174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197







-
+








-
+







		return;
	}

	switch (valueType) {
	case '@':
	case '#':
		{
			void (*setter)(id, SEL, id) = (void(*)(id, SEL, id))
			void (*setter)(id, SEL, id) = (void (*)(id, SEL, id))
			    [self methodForSelector: selector];
			setter(self, selector, value);
		}
		break;
#define CASE(encoding, type, method) \
	case encoding:						\
		{						\
			void (*setter)(id, SEL, type) =		\
			    (void(*)(id, SEL, type))		\
			    (void (*)(id, SEL, type))		\
			    [self methodForSelector: selector];	\
			setter(self, selector, [value method]);	\
		}						\
		break;
	CASE('B', bool, boolValue)
	CASE('c', char, charValue)
	CASE('s', short, shortValue)
210
211
212
213
214
215
216
217

218
219
220
221
222
223
224

225
226
227
228
210
211
212
213
214
215
216

217
218
219
220
221
222
223

224
225
226
227
228







-
+






-
+




		[self    setValue: value
		  forUndefinedKey: key];
		return;
	}
}

-  (void)setValue: (id)value
  forUndefinedKey: (OFString*)key
  forUndefinedKey: (OFString *)key
{
	@throw [OFUndefinedKeyException exceptionWithObject: self
							key: key
						      value: value];
}

- (void)setNilValueForKey: (OFString*)key
- (void)setNilValueForKey: (OFString *)key
{
	@throw [OFInvalidArgumentException exception];
}
@end

Modified src/OFObject+Serialization.h from [befa28a78f] to [26f370712f].

30
31
32
33
34
35
36
37

38
39
40
30
31
32
33
34
35
36

37
38
39
40







-
+




@interface OFObject (OFSerialization)
/*!
 * @brief Creates a string by serializing the receiver.
 *
 * @return The object serialized as a string
 */
- (OFString*)stringBySerializing;
- (OFString *)stringBySerializing;
@end

OF_ASSUME_NONNULL_END

Modified src/OFObject+Serialization.m from [2df11c40e9] to [7c7cd74965].

23
24
25
26
27
28
29
30

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

30
31
32
33
34
35
36
37







-
+







#import "OFSerialization.h"
#import "OFString.h"
#import "OFXMLElement.h"

int _OFObject_Serialization_reference;

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

	if (![self conformsToProtocol: @protocol(OFSerialization)]) {

Modified src/OFObject.h from [292119d486] to [6e202ea9b1].

227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257







-
+















-
+








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

/*!
 * @brief Returns the implementation for the specified selector.
 *
 * @param selector The selector for which the method should be returned
 * @return The implementation for the specified selector
 */
- (nullable IMP)methodForSelector: (SEL)selector;

/*!
 * @brief Returns the type encoding for the specified selector.
 *
 * @param selector The selector for which the type encoding should be returned
 * @return The type encoding for the specified selector
 */
- (nullable const char*)typeEncodingForSelector: (SEL)selector;
- (nullable const char *)typeEncodingForSelector: (SEL)selector;

/*!
 * @brief Performs the specified selector.
 *
 * @param selector The selector to perform
 * @return The object returned by the method specified by the selector
 */
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
441
442
443
444
445
446
447

448
449
450
451
452
453
454
455







-
+







+ (Class)class;

/*!
 * @brief Returns the name of the class as a string.
 *
 * @return The name of the class as a string
 */
+ (OFString*)className;
+ (OFString *)className;

/*!
 * @brief Returns a boolean whether the class is a subclass of the specified
 *	  class.
 *
 * @param class_ The class which is checked for being a superclass
 * @return A boolean whether the class is a subclass of the specified class
474
475
476
477
478
479
480
481

482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500

501
502
503
504
505
506
507
508
509

510
511
512
513
514
515
516
474
475
476
477
478
479
480

481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499

500
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516







-
+


















-
+








-
+








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

/*!
 * @brief Returns the implementation of the instance method for the specified
 *	  selector.
 *
 * @param selector The selector for which the method should be returned
 * @return The implementation of the instance method for the specified selector
 *	   or `nil` if it isn't implemented
 */
+ (nullable IMP)instanceMethodForSelector: (SEL)selector;

/*!
 * @brief Returns the type encoding of the instance method for the specified
 *	  selector.
 *
 * @param selector The selector for which the type encoding should be returned
 * @return The type encoding of the instance method for the specified selector
 */
+ (nullable const char*)typeEncodingForInstanceSelector: (SEL)selector;
+ (nullable const char *)typeEncodingForInstanceSelector: (SEL)selector;

/*!
 * @brief Returns a description for the class, which is usually the class name.
 *
 * This is mostly for debugging purposes.
 *
 * @return A description for the class, which is usually the class name
 */
+ (OFString*)description;
+ (OFString *)description;

/*!
 * @brief Replaces a class method with a class method from another class.
 *
 * @param selector The selector of the class method to replace
 * @param class_ The class from which the new class method should be taken
 * @return The old implementation
539
540
541
542
543
544
545
546

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

563
564
565
566
567
568
569
539
540
541
542
543
544
545

546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561

562
563
564
565
566
567
568
569







-
+















-
+







 * @param selector The selector for the new method
 * @param implementation The implementation for the new method
 * @param typeEncoding The type encoding for the new method
 * @return The old implementation or `nil` if the method was added
 */
+ (nullable IMP)replaceClassMethod: (SEL)selector
		withImplementation: (IMP)implementation
		      typeEncoding: (const char*)typeEncoding;
		      typeEncoding: (const char *)typeEncoding;

/*!
 * @brief Replaces or adds an instance method.
 *
 * If the method already exists, it is replaced and the old implementation
 * returned. If the method does not exist, it is added with the specified type
 * encoding.
 *
 * @param selector The selector for the new method
 * @param implementation The implementation for the new method
 * @param typeEncoding The type encoding for the new method
 * @return The old implementation or `nil` if the method was added
 */
+ (nullable IMP)replaceInstanceMethod: (SEL)selector
		   withImplementation: (IMP)implementation
			 typeEncoding: (const char*)typeEncoding;
			 typeEncoding: (const char *)typeEncoding;

/*!
 * @brief Adds all methods from the specified class to the class that is the
 *	  receiver.
 *
 * Methods implemented by the receiving class itself will not be overridden,
 * however methods implemented by its superclass will. Therefore it behaves
627
628
629
630
631
632
633
634

635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
651
652
653

654
655
656
657
658
659
660
661
662
663
664
665
666


667
668
669
670
671
672
673
674
675
676
677
678
679


680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695



696
697
698
699
700
701
702
703
704

705
706
707
708
709
710
711
627
628
629
630
631
632
633

634
635
636
637
638
639
640
641
642

643
644
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659
660
661
662
663
664


665
666
667
668
669
670
671
672
673
674
675
676
677


678
679
680
681
682
683
684
685
686
687
688
689
690
691
692



693
694
695
696
697
698
699
700
701
702
703

704
705
706
707
708
709
710
711







-
+








-
+









-
+











-
-
+
+











-
-
+
+













-
-
-
+
+
+








-
+







- init;

/*!
 * @brief Returns the name of the object's class.
 *
 * @return The name of the object's class
 */
- (OFString*)className;
- (OFString *)className;

/*!
 * @brief Returns a description for the object.
 *
 * This is mostly for debugging purposes.
 *
 * @return A description for the object
 */
- (OFString*)description;
- (OFString *)description;

/*!
 * @brief Allocates memory and stores it in the object's memory pool.
 *
 * It will be freed automatically when the object is deallocated.
 *
 * @param size The size of the memory to allocate
 * @return A pointer to the allocated memory
 */
- (void*)allocMemoryWithSize: (size_t)size;
- (void *)allocMemoryWithSize: (size_t)size;

/*!
 * @brief Allocates memory for the specified number of items and stores it in
 *	  the object's memory pool.
 *
 * It will be freed automatically when the object is deallocated.
 *
 * @param size The size of each item to allocate
 * @param count The number of items to allocate
 * @return A pointer to the allocated memory
 */
- (void*)allocMemoryWithSize: (size_t)size
		       count: (size_t)count;
- (void *)allocMemoryWithSize: (size_t)size
			count: (size_t)count;

/*!
 * @brief Resizes memory in the object's memory pool to the specified size.
 *
 * If the pointer is NULL, this is equivalent to allocating memory.
 * If the size is 0, this is equivalent to freeing memory.
 *
 * @param pointer A pointer to the already allocated memory
 * @param size The new size for the memory chunk
 * @return A pointer to the resized memory chunk
 */
- (nullable void*)resizeMemory: (nullable void*)pointer
			  size: (size_t)size;
- (nullable void *)resizeMemory: (nullable void *)pointer
			   size: (size_t)size;

/*!
 * @brief Resizes memory in the object's memory pool to the specific number of
 *	  items of the specified size.
 *
 * If the pointer is NULL, this is equivalent to allocating memory.
 * If the size or number of items is 0, this is equivalent to freeing memory.
 *
 * @param pointer A pointer to the already allocated memory
 * @param size The size of each item to resize to
 * @param count The number of items to resize to
 * @return A pointer to the resized memory chunk
 */
- (nullable void*)resizeMemory: (nullable void*)pointer
			  size: (size_t)size
			 count: (size_t)count;
- (nullable void *)resizeMemory: (nullable void *)pointer
			   size: (size_t)size
			  count: (size_t)count;

/*!
 * @brief Frees allocated memory and removes it from the object's memory pool.
 *
 * Does nothing if the pointer is NULL.
 *
 * @param pointer A pointer to the allocated memory
 */
- (void)freeMemory: (nullable void*)pointer;
- (void)freeMemory: (nullable void *)pointer;

/*!
 * @brief Deallocates the object.
 *
 * It is automatically called when the retain count reaches zero.
 *
 * This also frees all memory in its memory pool.
755
756
757
758
759
760
761
762

763
764
765
766
767
768
769
770
771
772
773
774
775
776

777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793

794
795
796
797
798
799
800
755
756
757
758
759
760
761

762
763
764
765
766
767
768
769
770
771
772
773
774
775

776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792

793
794
795
796
797
798
799
800







-
+













-
+
















-
+







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

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

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

/*!
 * @brief Performs the specified selector on the main thread.
 *
838
839
840
841
842
843
844
845

846
847
848
849
850
851
852
853
854
855
856
857
858
859

860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876

877
878
879
880
881
882
883
838
839
840
841
842
843
844

845
846
847
848
849
850
851
852
853
854
855
856
857
858

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875

876
877
878
879
880
881
882
883







-
+













-
+
















-
+







 *	  specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	       onThread: (OFThread *)thread
	     afterDelay: (of_time_interval_t)delay;

/*!
 * @brief Performs the specified selector on the specified thread with the
 *	  specified object after the specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param object The object that is passed to the method specified by the
 *		 selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object
	     afterDelay: (of_time_interval_t)delay;

/*!
 * @brief Performs the specified selector on the specified thread with the
 *	  specified objects after the specified delay.
 *
 * @param selector The selector to perform
 * @param thread The thread on which to perform the selector
 * @param object1 The first object that is passed to the method specified by the
 *		 selector
 * @param object2 The second object that is passed to the method specified by
 *		  the selector
 * @param delay The delay after which the selector will be performed
 */
- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     afterDelay: (of_time_interval_t)delay;
#endif

/*!
 * @brief This method is called when @ref resolveClassMethod: or

Modified src/OFObject.m from [3768fd3a96] to [3eb86842c6].

83
84
85
86
87
88
89
90

91
92
93
94

95
96
97
98
99
100
101
83
84
85
86
87
88
89

90
91
92
93

94
95
96
97
98
99
100
101







-
+



-
+







struct pre_mem {
	struct pre_mem *prev, *next;
	id owner;
};

#define PRE_IVARS_ALIGN ((sizeof(struct pre_ivar) + \
    (OF_BIGGEST_ALIGNMENT - 1)) & ~(OF_BIGGEST_ALIGNMENT - 1))
#define PRE_IVARS ((struct pre_ivar*)(void*)((char*)self - PRE_IVARS_ALIGN))
#define PRE_IVARS ((struct pre_ivar *)(void *)((char *)self - PRE_IVARS_ALIGN))

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

static struct {
	Class isa;
} allocFailedException;

uint32_t of_hash_seed;

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







-
-
-
+
+
+



-
+






-
+




-
+





-
+




-
+







	    extraAlignment + extraSize);

	if OF_UNLIKELY (instance == nil) {
		allocFailedException.isa = [OFAllocFailedException class];
		@throw (id)&allocFailedException;
	}

	((struct pre_ivar*)instance)->retainCount = 1;
	((struct pre_ivar*)instance)->firstMem = NULL;
	((struct pre_ivar*)instance)->lastMem = NULL;
	((struct pre_ivar *)instance)->retainCount = 1;
	((struct pre_ivar *)instance)->firstMem = NULL;
	((struct pre_ivar *)instance)->lastMem = NULL;

#if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS)
	if OF_UNLIKELY (!of_spinlock_new(
	    &((struct pre_ivar*)instance)->retainCountSpinlock)) {
	    &((struct pre_ivar *)instance)->retainCountSpinlock)) {
		free(instance);
		@throw [OFInitializationFailedException
		    exceptionWithClass: class];
	}
#endif

	instance = (OFObject*)((char*)instance + PRE_IVARS_ALIGN);
	instance = (OFObject *)(void *)((char *)instance + PRE_IVARS_ALIGN);

	memset(instance, 0, instanceSize);

	if (!objc_constructInstance(class, instance)) {
		free((char*)instance - PRE_IVARS_ALIGN);
		free((char *)instance - PRE_IVARS_ALIGN);
		@throw [OFInitializationFailedException
		    exceptionWithClass: class];
	}

	if OF_UNLIKELY (extra != NULL)
		*extra = (char*)instance + instanceSize + extraAlignment;
		*extra = (char *)instance + instanceSize + extraAlignment;

	return instance;
}

const char*
const char *
_NSPrintForDebugger(id object)
{
	return [[object description]
	    cStringWithEncoding: [OFLocalization encoding]];
}

/* References for static linking */
226
227
228
229
230
231
232
233
234


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


233
234
235
236
237
238
239
240
241







-
-
+
+







	 * handler on load, we should not set ours, as this will break
	 * Foundation.
	 *
	 * Unfortunately, there is no way to check if a forward handler has
	 * already been set, so this is the best we can do.
	 */
	if (&NSFoundationVersionNumber == NULL)
		objc_setForwardHandler((void*)&of_forward,
		    (void*)&of_forward_stret);
		objc_setForwardHandler((void *)&of_forward,
		    (void *)&of_forward_stret);
#else
	objc_setForwardHandler((IMP)&of_forward, (IMP)&of_forward_stret);
#endif

	objc_setEnumerationMutationHandler(enumerationMutationHandler);

	of_hash_seed = 0;
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290







-
+







}

+ (Class)class
{
	return self;
}

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

+ (bool)isSubclassOfClass: (Class)class
{
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
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







-
+















-
+













-
+







}

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

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

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

	return false;
}

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

+ (const char*)typeEncodingForInstanceSelector: (SEL)selector
+ (const char *)typeEncodingForInstanceSelector: (SEL)selector
{
#if defined(OF_OBJFW_RUNTIME)
	return class_getMethodTypeEncoding(self, selector);
#else
	Method m;

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

	return method_getTypeEncoding(m);
#endif
}

+ (OFString*)description
+ (OFString *)description
{
	return [self className];
}

+ (IMP)replaceClassMethod: (SEL)selector
      withMethodFromClass: (Class)class
{
366
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388







-
+







-
+







	return [self replaceInstanceMethod: selector
			withImplementation: newImp
			      typeEncoding: typeEncoding];
}

+ (IMP)replaceInstanceMethod: (SEL)selector
	  withImplementation: (IMP)implementation
		typeEncoding: (const char*)typeEncoding
		typeEncoding: (const char *)typeEncoding
{
	return class_replaceMethod(self, selector, implementation,
	    typeEncoding);
}

+ (IMP)replaceClassMethod: (SEL)selector
       withImplementation: (IMP)implementation
	     typeEncoding: (const char*)typeEncoding
	     typeEncoding: (const char *)typeEncoding
{
	return class_replaceMethod(object_getClass(self), selector,
	    implementation, typeEncoding);
}

+ (void)inheritMethodsFromClass: (Class)class
{
497
498
499
500
501
502
503
504

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

504
505
506
507
508
509
510
511







-
+







}

- (Class)superclass
{
	return class_getSuperclass(object_getClass(self));
}

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

- (bool)isKindOfClass: (Class)class
{
523
524
525
526
527
528
529
530

531
532
533
534
535
536
537
538
539
540
541
542
543

544
545

546
547
548
549
550
551
552
553
554
555
556

557
558

559
560
561
562
563
564
565
566
567
568
569
570

571
572

573
574
575
576
577
578
579
523
524
525
526
527
528
529

530
531
532
533
534
535
536
537
538
539
540
541
542

543
544

545
546
547
548
549
550
551
552
553
554
555

556
557

558
559
560
561
562
563
564
565
566
567
568
569

570
571

572
573
574
575
576
577
578
579







-
+












-
+

-
+










-
+

-
+











-
+

-
+







}

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

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

- (IMP)methodForSelector: (SEL)selector
{
	return class_getMethodImplementation(object_getClass(self), selector);
}

- (id)performSelector: (SEL)selector
{
#if defined(OF_OBJFW_RUNTIME)
	id (*imp)(id, SEL) = (id(*)(id, SEL))objc_msg_lookup(self, selector);
	id (*imp)(id, SEL) = (id (*)(id, SEL))objc_msg_lookup(self, selector);
#elif defined(OF_APPLE_RUNTIME)
	id (*imp)(id, SEL) = (id(*)(id, SEL))objc_msgSend;
	id (*imp)(id, SEL) = (id (*)(id, SEL))objc_msgSend;
#endif

	return imp(self, selector);
}

- (id)performSelector: (SEL)selector
	   withObject: (id)object
{
#if defined(OF_OBJFW_RUNTIME)
	id (*imp)(id, SEL, id) =
	    (id(*)(id, SEL, id))objc_msg_lookup(self, selector);
	    (id (*)(id, SEL, id))objc_msg_lookup(self, selector);
#elif defined(OF_APPLE_RUNTIME)
	id (*imp)(id, SEL, id) = (id(*)(id, SEL, id))objc_msgSend;
	id (*imp)(id, SEL, id) = (id (*)(id, SEL, id))objc_msgSend;
#endif

	return imp(self, selector, object);
}

- (id)performSelector: (SEL)selector
	   withObject: (id)object1
	   withObject: (id)object2
{
#if defined(OF_OBJFW_RUNTIME)
	id (*imp)(id, SEL, id, id) =
	    (id(*)(id, SEL, id, id))objc_msg_lookup(self, selector);
	    (id (*)(id, SEL, id, id))objc_msg_lookup(self, selector);
#elif defined(OF_APPLE_RUNTIME)
	id (*imp)(id, SEL, id, id) = (id(*)(id, SEL, id, id))objc_msgSend;
	id (*imp)(id, SEL, id, id) = (id (*)(id, SEL, id, id))objc_msgSend;
#endif

	return imp(self, selector, object1, object2);
}

- (void)performSelector: (SEL)selector
	     afterDelay: (of_time_interval_t)delay
618
619
620
621
622
623
624
625

626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642

643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661

662
663
664
665
666
667
668
618
619
620
621
622
623
624

625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641

642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660

661
662
663
664
665
666
667
668







-
+
















-
+


















-
+







					repeats: false];

	objc_autoreleasePoolPop(pool);
}

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

	if (waitUntilDone)
		[timer waitUntilDone];

	objc_autoreleasePoolPop(pool);
}

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

	if (waitUntilDone)
		[timer waitUntilDone];

	objc_autoreleasePoolPop(pool);
}

- (void)performSelector: (SEL)selector
	       onThread: (OFThread*)thread
	       onThread: (OFThread *)thread
	     withObject: (id)object1
	     withObject: (id)object2
	  waitUntilDone: (bool)waitUntilDone
{
	void *pool = objc_autoreleasePoolPush();
	OFTimer *timer = [OFTimer timerWithTimeInterval: 0
						 target: self
729
730
731
732
733
734
735
736

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

751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

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

785
786
787
788
789
790
791
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743
744
745
746
747
748
749

750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

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

784
785
786
787
788
789
790
791







-
+













-
+















-
+

















-
+







	if (waitUntilDone)
		[timer waitUntilDone];

	objc_autoreleasePoolPop(pool);
}

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

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

	objc_autoreleasePoolPop(pool);
}

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

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

	objc_autoreleasePoolPop(pool);
}

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

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

	objc_autoreleasePoolPop(pool);
}
#endif

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

	if ((m = class_getInstanceMethod(object_getClass(self),
814
815
816
817
818
819
820
821

822
823
824
825
826
827
828

829
830
831
832
833
834
835
814
815
816
817
818
819
820

821
822
823
824
825
826
827

828
829
830
831
832
833
834
835







-
+






-
+







	}

	OF_HASH_FINALIZE(hash);

	return hash;
}

- (OFString*)description
- (OFString *)description
{
	/* Classes containing data should reimplement this! */

	return [OFString stringWithFormat: @"<%@>", [self className]];
}

- (void*)allocMemoryWithSize: (size_t)size
- (void *)allocMemoryWithSize: (size_t)size
{
	void *pointer;
	struct pre_mem *preMem;

	if OF_UNLIKELY (size == 0)
		return NULL;

848
849
850
851
852
853
854
855

856
857
858
859


860
861
862
863
864
865
866
867
868


869
870
871
872
873
874
875
848
849
850
851
852
853
854

855
856
857


858
859
860
861
862
863
864
865
866


867
868
869
870
871
872
873
874
875







-
+


-
-
+
+







-
-
+
+







	if OF_LIKELY (PRE_IVARS->lastMem != NULL)
		PRE_IVARS->lastMem->next = preMem;

	if OF_UNLIKELY (PRE_IVARS->firstMem == NULL)
		PRE_IVARS->firstMem = preMem;
	PRE_IVARS->lastMem = preMem;

	return (char*)pointer + PRE_MEM_ALIGN;
	return (char *)pointer + PRE_MEM_ALIGN;
}

- (void*)allocMemoryWithSize: (size_t)size
		       count: (size_t)count
- (void *)allocMemoryWithSize: (size_t)size
			count: (size_t)count
{
	if OF_UNLIKELY (count > SIZE_MAX / size)
		@throw [OFOutOfRangeException exception];

	return [self allocMemoryWithSize: size * count];
}

- (void*)resizeMemory: (void*)pointer
		 size: (size_t)size
- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
{
	void *new;
	struct pre_mem *preMem;

	if OF_UNLIKELY (pointer == NULL)
		return [self allocMemoryWithSize: size];

897
898
899
900
901
902
903
904

905
906
907
908
909



910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927

928
929
930
931
932
933
934
897
898
899
900
901
902
903

904
905
906



907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926

927
928
929
930
931
932
933
934







-
+


-
-
-
+
+
+

















-
+








		if OF_UNLIKELY (PRE_IVARS->firstMem == PRE_MEM(pointer))
			PRE_IVARS->firstMem = preMem;
		if OF_UNLIKELY (PRE_IVARS->lastMem == PRE_MEM(pointer))
			PRE_IVARS->lastMem = preMem;
	}

	return (char*)new + PRE_MEM_ALIGN;
	return (char *)new + PRE_MEM_ALIGN;
}

- (void*)resizeMemory: (void*)pointer
		 size: (size_t)size
		count: (size_t)count
- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
		 count: (size_t)count
{
	if OF_UNLIKELY (pointer == NULL)
		return [self allocMemoryWithSize: size
					   count: count];

	if OF_UNLIKELY (size == 0 || count == 0) {
		[self freeMemory: pointer];
		return NULL;
	}

	if OF_UNLIKELY (count > SIZE_MAX / size)
		@throw [OFOutOfRangeException exception];

	return [self resizeMemory: pointer
			     size: size * count];
}

- (void)freeMemory: (void*)pointer
- (void)freeMemory: (void *)pointer
{
	if OF_UNLIKELY (pointer == NULL)
		return;

	if OF_UNLIKELY (PRE_MEM(pointer)->owner != self)
		@throw [OFMemoryNotPartOfObjectException
		    exceptionWithPointer: pointer
1046
1047
1048
1049
1050
1051
1052
1053

1054
1055
1056
1057

1058
1059
1060
1061
1062
1063
1064
1065
1066
1067

1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081

1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093


1094
1095
1096
1097
1098
1099
1100



1101
1102
1103
1104
1105

1106
1107
1108
1109
1110
1111
1112
1046
1047
1048
1049
1050
1051
1052

1053
1054
1055
1056

1057
1058
1059
1060
1061
1062
1063
1064
1065
1066

1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080

1081
1082
1083
1084
1085

1086
1087
1088
1089
1090
1091


1092
1093
1094
1095
1096
1097



1098
1099
1100
1101
1102
1103
1104

1105
1106
1107
1108
1109
1110
1111
1112







-
+



-
+









-
+













-
+




-
+





-
-
+
+




-
-
-
+
+
+




-
+







		OF_ENSURE(iter->owner == self);

		free(iter);

		iter = next;
	}

	free((char*)self - PRE_IVARS_ALIGN);
	free((char *)self - PRE_IVARS_ALIGN);
}

/* Required to use properties with the Apple runtime */
- copyWithZone: (void*)zone
- copyWithZone: (void *)zone
{
	if OF_UNLIKELY (zone != NULL) {
		[self doesNotRecognizeSelector: _cmd];
		abort();
	}

	return [(id)self copy];
}

- mutableCopyWithZone: (void*)zone
- mutableCopyWithZone: (void *)zone
{
	if OF_UNLIKELY (zone != NULL) {
		[self doesNotRecognizeSelector: _cmd];
		abort();
	}

	return [(id)self mutableCopy];
}

/*
 * Those are needed as the root class is the superclass of the root class's
 * metaclass and thus instance methods can be sent to class objects as well.
 */
+ (void*)allocMemoryWithSize: (size_t)size
+ (void *)allocMemoryWithSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (void*)allocMemoryWithSize: (size_t)size
+ (void *)allocMemoryWithSize: (size_t)size
		       count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (void*)resizeMemory: (void*)pointer
		 size: (size_t)size
+ (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (void*)resizeMemory: (void*)pointer
		 size: (size_t)size
		count: (size_t)count
+ (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
		 count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (void)freeMemory: (void*)pointer
+ (void)freeMemory: (void *)pointer
{
	OF_UNRECOGNIZED_SELECTOR
}

+ retain
{
	return self;
1132
1133
1134
1135
1136
1137
1138
1139

1140
1141
1142
1143
1144
1145

1146
1147
1148
1149
1150
1151
1152
1153
1154
1132
1133
1134
1135
1136
1137
1138

1139
1140
1141
1142
1143
1144

1145
1146
1147
1148
1149
1150
1151
1152
1153
1154







-
+





-
+









}

+ copy
{
	return self;
}

+ mutableCopyWithZone: (void*)zone
+ mutableCopyWithZone: (void *)zone
{
	OF_UNRECOGNIZED_SELECTOR
}

/* Required to use ObjFW from Swift */
+ allocWithZone: (void*)zone
+ allocWithZone: (void *)zone
{
	if OF_UNLIKELY (zone != NULL) {
		[self doesNotRecognizeSelector: _cmd];
		abort();
	}

	return [self alloc];
}
@end

Modified src/OFOptionsParser.h from [06c158db08] to [faec9b2ba6].

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







-
-
+
+













-
+







	/*!
	 * An optional pointer to a bool that is set to whether the option has
	 * been specified.
	 */
	bool *_Nullable isSpecifiedPtr;

	/*!
	 * An optional pointer to an @ref OFString* that is set to the argument
	 * specified for the option or `nil` for no argument.
	 * An optional pointer to an @ref OFString * that is set to the
	 * argument specified for the option or `nil` for no argument.
	 */
	OFString *__autoreleasing _Nullable *_Nullable argumentPtr;
} of_options_parser_option_t;

/*!
 * @class OFOptionsParser OFOptionsParser.h ObjFW/OFOptionsParser.h
 *
 * @brief A class for parsing the program options specified on the command line.
 */
@interface OFOptionsParser: OFObject
{
	of_options_parser_option_t *_options;
	OFMapTable *_longOptions;
	OFArray OF_GENERIC(OFString*) *_arguments;
	OFArray OF_GENERIC(OFString *) *_arguments;
	size_t _index, _subIndex;
	of_unichar_t _lastOption;
	OFString *_lastLongOption, *_argument;
	bool _done;
}

/*!
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
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







-
+











-
+







 *
 * @param options An array of @ref of_options_parser_option_t specifying all
 *		  accepted options, terminated with an option whose short
 *		  option is `\0` and long option is `nil`.
 *
 * @return A new, autoreleased OFOptionsParser
 */
+ (instancetype)parserWithOptions: (const of_options_parser_option_t*)options;
+ (instancetype)parserWithOptions: (const of_options_parser_option_t *)options;

/*!
 * @brief Initializes an already allocated OFOptionsParser so that it accepts
 *	  the specified options.
 *
 * @param options An array of @ref of_options_parser_option_t specifying all
 *		  accepted options, terminated with an option whose short
 *		  option is `\0` and long option is `nil`.
 *
 * @return An initialized OFOptionsParser
 */
- initWithOptions: (const of_options_parser_option_t*)options;
- initWithOptions: (const of_options_parser_option_t *)options;

/*!
 * @brief Returns the next option.
 *
 * If the option is only available as a long option, `-` is returned.
 * Otherwise, the short option is returned, even if it was specified as a long
 * option.@n
153
154
155
156
157
158
159
160

161
162
163
153
154
155
156
157
158
159

160
161
162
163







-
+



- (of_unichar_t)nextOption;

/*!
 * @brief Returns the arguments following the last option.
 *
 * @return The arguments following the last option
 */
- (OFArray OF_GENERIC(OFString*)*)remainingArguments;
- (OFArray OF_GENERIC(OFString *) *)remainingArguments;
@end

OF_ASSUME_NONNULL_END

Modified src/OFOptionsParser.m from [03713bc866] to [f1e270d342].

22
23
24
25
26
27
28
29

30
31
32
33
34
35

36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
22
23
24
25
26
27
28

29
30
31
32
33
34

35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59







-
+





-
+






-
+









-
+







#import "OFMapTable.h"

#import "OFInvalidArgumentException.h"

static uint32_t
stringHash(void *object)
{
	return [(OFString*)object hash];
	return [(OFString *)object hash];
}

static bool
stringEqual(void *object1, void *object2)
{
	return [(OFString*)object1 isEqual: (OFString*)object2];
	return [(OFString *)object1 isEqual: (OFString *)object2];
}

@implementation OFOptionsParser
@synthesize lastOption = _lastOption, lastLongOption = _lastLongOption;
@synthesize argument = _argument;

+ (instancetype)parserWithOptions: (const of_options_parser_option_t*)options
+ (instancetype)parserWithOptions: (const of_options_parser_option_t *)options
{
	return [[[self alloc] initWithOptions: options] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithOptions: (const of_options_parser_option_t*)options
- initWithOptions: (const of_options_parser_option_t *)options
{
	self = [super init];

	@try {
		size_t count = 0;
		const of_options_parser_option_t *iter;
		of_options_parser_option_t *iter2;
271
272
273
274
275
276
277
278

279
280
281
282
283
271
272
273
274
275
276
277

278
279
280
281
282
283







-
+





			return _lastOption;
		}
	}

	return '?';
}

- (OFArray*)remainingArguments
- (OFArray *)remainingArguments
{
	return [_arguments objectsInRange:
	    of_range(_index, [_arguments count] - _index)];
}
@end

Modified src/OFPlugin.h from [776ab43e02] to [c055a2fd0c].

18
19
20
21
22
23
24
25

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

25
26
27
28
29
30
31
32







-
+








@class OFString;

#ifndef OF_WINDOWS
# include <dlfcn.h>
# define OF_RTLD_LAZY RTLD_LAZY
# define OF_RTLD_NOW  RTLD_NOW
typedef void* of_plugin_handle_t;
typedef void *of_plugin_handle_t;
#else
# include <windows.h>
# define OF_RTLD_LAZY 0
# define OF_RTLD_NOW  0
typedef HMODULE of_plugin_handle_t;
#endif

44
45
46
47
48
49
50
51

52
53
54
55
56
57
58

59
60
61
62
63
64
44
45
46
47
48
49
50

51
52
53
54
55
56
57

58
59
60
61
62
63
64







-
+






-
+







/*!
 * @brief Loads a plugin from a file.
 *
 * @param path Path to the plugin file. The suffix is appended automatically.
 * @return The loaded plugin
 */
+ (OF_KINDOF(OFPlugin*))pluginFromFile: (OFString*)path;
+ (OF_KINDOF(OFPlugin *))pluginFromFile: (OFString *)path;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern of_plugin_handle_t of_dlopen(OFString *path, int flags);
extern void* of_dlsym(of_plugin_handle_t handle, const char *symbol);
extern void *of_dlsym(of_plugin_handle_t handle, const char *symbol);
extern void of_dlclose(of_plugin_handle_t handle);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFPlugin.m from [c0e1766901] to [5175fba523].

25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

49
50
51
52
53
54

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

70
71
72
73
74
75
76
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53

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

69
70
71
72
73
74
75
76







-
+















-
+





-
+














-
+








#import "OFPlugin.h"
#import "OFString.h"
#import "OFLocalization.h"

#import "OFInitializationFailedException.h"

typedef OFPlugin* (*init_plugin_t)(void);
typedef OFPlugin *(*init_plugin_t)(void);

of_plugin_handle_t
of_dlopen(OFString *path, int flags)
{
#ifndef OF_WINDOWS
	return dlopen([path cStringWithEncoding: [OFLocalization encoding]],
	    flags);
#else
	if (path == nil)
		return GetModuleHandle(NULL);

	return LoadLibraryW([path UTF16String]);
#endif
}

void*
void *
of_dlsym(of_plugin_handle_t handle, const char *symbol)
{
#ifndef OF_WINDOWS
	return dlsym(handle, symbol);
#else
	return (void*)(uintptr_t)GetProcAddress(handle, symbol);
	return (void *)(uintptr_t)GetProcAddress(handle, symbol);
#endif
}

void
of_dlclose(of_plugin_handle_t handle)
{
#ifndef OF_WINDOWS
	dlclose(handle);
#else
	FreeLibrary(handle);
#endif
}

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

	path = [path stringByAppendingString: @PLUGIN_SUFFIX];

Modified src/OFProcess.h from [d3d4d0056c] to [d13a85d5ee].

56
57
58
59
60
61
62
63

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


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113



114
115

116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
136
137


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



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172



173
174

175
176
177
178
179
180
181
182
183
184
185
186
56
57
58
59
60
61
62

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


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110



111
112
113
114

115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135


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



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169



170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186







-
+











-
-
+
+













-
-
-
+
+
+


















-
-
-
+
+
+

-
+









-
+










-
-
+
+












-
-
-
+
+
+

















-
-
-
+
+
+

-
+












 * @brief Creates a new OFProcess with the specified program and invokes the
 *	  program.
 *
 * @param program The program to execute. If it does not start with a slash, the
 *		  search path specified in PATH is used.
 * @return A new, autoreleased OFProcess.
 */
+ (instancetype)processWithProgram: (OFString*)program;
+ (instancetype)processWithProgram: (OFString *)program;

/*!
 * @brief Creates a new OFProcess with the specified program and arguments and
 *	  invokes the program.
 *
 * @param program The program to execute. If it does not start with a slash, the
 *		  search path specified in PATH is used.
 * @param arguments The arguments to pass to the program, or `nil`
 * @return A new, autoreleased OFProcess.
 */
+ (instancetype)
    processWithProgram: (OFString*)program
	     arguments: (nullable OFArray OF_GENERIC(OFString*)*)arguments;
    processWithProgram: (OFString *)program
	     arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments;

/*!
 * @brief Creates a new OFProcess with the specified program, program name and
 *	  arguments and invokes the program.
 *
 * @param program The program to execute. If it does not start with a slash, the
 *		  search path specified in PATH is used.
 * @param programName The program name for the program to invoke (argv[0]).
 *		      Usually, this is equal to program.
 * @param arguments The arguments to pass to the program, or `nil`
 * @return A new, autoreleased OFProcess.
 */
+ (instancetype)
    processWithProgram: (OFString*)program
	   programName: (OFString*)programName
	     arguments: (nullable OFArray OF_GENERIC(OFString*)*)arguments;
    processWithProgram: (OFString *)program
	   programName: (OFString *)programName
	     arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments;

/*!
 * @brief Creates a new OFProcess with the specified program, program name,
 *	  arguments and environment and invokes the program.
 *
 * @param program The program to execute. If it does not start with a slash, the
 *		  search path specified in PATH is used.
 * @param programName The program name for the program to invoke (argv[0]).
 *		      Usually, this is equal to program.
 * @param arguments The arguments to pass to the program, or `nil`
 * @param environment The environment to pass to the program, or `nil`. If it
 *		      is not `nil`, the passed dictionary will be used to
 *		      override the environment. If you want to add to the
 *		      existing environment, you need to get the existing
 *		      environment first, copy it, modify it and then pass it.
 * @return A new, autoreleased OFProcess.
 */
+ (instancetype)
    processWithProgram: (OFString*)program
	   programName: (OFString*)programName
	     arguments: (nullable OFArray OF_GENERIC(OFString*)*)arguments
    processWithProgram: (OFString *)program
	   programName: (OFString *)programName
	     arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments
	   environment: (nullable OFDictionary
			    OF_GENERIC(OFString*, OFString*)*)environment;
			    OF_GENERIC(OFString *, OFString *) *)environment;

/*!
 * @brief Initializes an already allocated OFProcess with the specified program
 *	  and invokes the program.
 *
 * @param program The program to execute. If it does not start with a slash, the
 *		  search path specified in PATH is used.
 * @return An initialized OFProcess.
 */
- initWithProgram: (OFString*)program;
- initWithProgram: (OFString *)program;

/*!
 * @brief Initializes an already allocated OFProcess with the specified program
 *	  and arguments and invokes the program.
 *
 * @param program The program to execute. If it does not start with a slash, the
 *		  search path specified in PATH is used.
 * @param arguments The arguments to pass to the program, or `nil`
 * @return An initialized OFProcess.
 */
- initWithProgram: (OFString*)program
	arguments: (nullable OFArray OF_GENERIC(OFString*)*)arguments;
- initWithProgram: (OFString *)program
	arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments;

/*!
 * @brief Initializes an already allocated OFProcess with the specified program,
 *	  program name and arguments and invokes the program.
 *
 * @param program The program to execute. If it does not start with a slash, the
 *		  search path specified in PATH is used.
 * @param programName The program name for the program to invoke (argv[0]).
 *		      Usually, this is equal to program.
 * @param arguments The arguments to pass to the program, or `nil`
 * @return An initialized OFProcess.
 */
- initWithProgram: (OFString*)program
      programName: (OFString*)programName
	arguments: (nullable OFArray OF_GENERIC(OFString*)*)arguments;
- initWithProgram: (OFString *)program
      programName: (OFString *)programName
	arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments;

/*!
 * @brief Initializes an already allocated OFProcess with the specified program,
 *	  program name, arguments and environment and invokes the program.
 *
 * @param program The program to execute. If it does not start with a slash, the
 *		  search path specified in PATH is used.
 * @param programName The program name for the program to invoke (argv[0]).
 *		      Usually, this is equal to program.
 * @param arguments The arguments to pass to the program, or `nil`
 * @param environment The environment to pass to the program, or `nil`. If it
 *		      is not `nil`, the passed dictionary will be used to
 *		      override the environment. If you want to add to the
 *		      existing environment, you need to get the existing
 *		      environment first, copy it, modify it and then pass it.
 * @return An initialized OFProcess.
 */
- initWithProgram: (OFString*)program
      programName: (OFString*)programName
	arguments: (nullable OFArray OF_GENERIC(OFString*)*)arguments
- initWithProgram: (OFString *)program
      programName: (OFString *)programName
	arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments
      environment: (nullable OFDictionary
		       OF_GENERIC(OFString*, OFString*)*)environment;
		       OF_GENERIC(OFString *, OFString *) *)environment;

/*!
 * @brief Closes the write direction of the process.
 *
 * This method needs to be called for some programs before data can be read,
 * since some programs don't start processing before the write direction is
 * closed.
 */
- (void)closeForWriting;
@end

OF_ASSUME_NONNULL_END

Modified src/OFProcess.m from [e88047c399] to [08732d57f8].

54
55
56
57
58
59
60
61
62
63
64




65
66

67
68
69
70
71

72
73
74
75
76
77


78
79
80
81
82
83
84
85



86
87
88
89
90
91
92
93
94
95




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

109
110
111
112
113
114
115
116
117


118
119
120
121
122
123
124
125
126
127



128
129
130
131
132
133
134
135
136
137
138




139
140
141
142
143
144
145
54
55
56
57
58
59
60




61
62
63
64
65

66
67
68
69
70

71
72
73
74
75


76
77
78
79
80
81
82



83
84
85
86
87
88
89
90
91




92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115


116
117
118
119
120
121
122
123
124



125
126
127
128
129
130
131
132
133
134




135
136
137
138
139
140
141
142
143
144
145







-
-
-
-
+
+
+
+

-
+




-
+




-
-
+
+





-
-
-
+
+
+






-
-
-
-
+
+
+
+












-
+







-
-
+
+







-
-
-
+
+
+







-
-
-
-
+
+
+
+








#if !defined(OF_WINDOWS) && !defined(HAVE_POSIX_SPAWNP)
extern char **environ;
#endif

@interface OFProcess ()
#ifndef OF_WINDOWS
- (void)OF_getArgV: (char***)argv
    forProgramName: (OFString*)programName
      andArguments: (OFArray*)arguments;
- (char**)OF_environmentForDictionary: (OFDictionary*)dictionary;
- (void)OF_getArgV: (char ***)argv
    forProgramName: (OFString *)programName
      andArguments: (OFArray *)arguments;
- (char **)OF_environmentForDictionary: (OFDictionary *)dictionary;
#else
- (of_char16_t*)OF_environmentForDictionary: (OFDictionary*)dictionary;
- (of_char16_t *)OF_environmentForDictionary: (OFDictionary *)dictionary;
#endif
@end

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

+ (instancetype)processWithProgram: (OFString*)program
			 arguments: (OFArray*)arguments
+ (instancetype)processWithProgram: (OFString *)program
			 arguments: (OFArray *)arguments
{
	return [[[self alloc] initWithProgram: program
				    arguments: arguments] autorelease];
}

+ (instancetype)processWithProgram: (OFString*)program
		       programName: (OFString*)programName
			 arguments: (OFArray*)arguments
+ (instancetype)processWithProgram: (OFString *)program
		       programName: (OFString *)programName
			 arguments: (OFArray *)arguments
{
	return [[[self alloc] initWithProgram: program
				  programName: programName
				    arguments: arguments] autorelease];
}

+ (instancetype)processWithProgram: (OFString*)program
		       programName: (OFString*)programName
			 arguments: (OFArray*)arguments
		       environment: (OFDictionary*)environment
+ (instancetype)processWithProgram: (OFString *)program
		       programName: (OFString *)programName
			 arguments: (OFArray *)arguments
		       environment: (OFDictionary *)environment
{
	return [[[self alloc] initWithProgram: program
				  programName: programName
				    arguments: arguments
				  environment: environment] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithProgram: (OFString*)program
- initWithProgram: (OFString *)program
{
	return [self initWithProgram: program
			 programName: program
			   arguments: nil
			 environment: nil];
}

- initWithProgram: (OFString*)program
	arguments: (OFArray*)arguments
- initWithProgram: (OFString *)program
	arguments: (OFArray *)arguments
{
	return [self initWithProgram: program
			 programName: program
			   arguments: arguments
			 environment: nil];
}

- initWithProgram: (OFString*)program
      programName: (OFString*)programName
	arguments: (OFArray*)arguments
- initWithProgram: (OFString *)program
      programName: (OFString *)programName
	arguments: (OFArray *)arguments
{
	return [self initWithProgram: program
			 programName: program
			   arguments: arguments
			 environment: nil];
}

- initWithProgram: (OFString*)program
      programName: (OFString*)programName
	arguments: (OFArray*)arguments
      environment: (OFDictionary*)environment
- initWithProgram: (OFString *)program
      programName: (OFString *)programName
	arguments: (OFArray *)arguments
      environment: (OFDictionary *)environment
{
	self = [super init];

	@try {
#ifndef OF_WINDOWS
		void *pool = objc_autoreleasePoolPush();
		const char *path;
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
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







-
-
-
+
+
+





-
+




-
+



-
+




-
+












-
+







{
	[self close];

	[super dealloc];
}

#ifndef OF_WINDOWS
- (void)OF_getArgV: (char***)argv
    forProgramName: (OFString*)programName
      andArguments: (OFArray*)arguments
- (void)OF_getArgV: (char ***)argv
    forProgramName: (OFString *)programName
      andArguments: (OFArray *)arguments
{
	OFString *const *objects = [arguments objects];
	size_t i, count = [arguments count];
	of_string_encoding_t encoding;

	*argv = [self allocMemoryWithSize: sizeof(char*)
	*argv = [self allocMemoryWithSize: sizeof(char *)
				    count: count + 2];

	encoding = [OFLocalization encoding];

	(*argv)[0] = (char*)[programName cStringWithEncoding: encoding];
	(*argv)[0] = (char *)[programName cStringWithEncoding: encoding];

	for (i = 0; i < count; i++)
		(*argv)[i + 1] =
		    (char*)[objects[i] cStringWithEncoding: encoding];
		    (char *)[objects[i] cStringWithEncoding: encoding];

	(*argv)[i + 1] = NULL;
}

- (char**)OF_environmentForDictionary: (OFDictionary*)environment
- (char **)OF_environmentForDictionary: (OFDictionary *)environment
{
	OFEnumerator *keyEnumerator, *objectEnumerator;
	char **envp;
	size_t i, count;
	of_string_encoding_t encoding;

	if (environment == nil)
		return NULL;

	encoding = [OFLocalization encoding];

	count = [environment count];
	envp = [self allocMemoryWithSize: sizeof(char*)
	envp = [self allocMemoryWithSize: sizeof(char *)
				   count: count + 1];

	keyEnumerator = [environment keyEnumerator];
	objectEnumerator = [environment objectEnumerator];

	for (i = 0; i < count; i++) {
		OFString *key;
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414







-
+







	}

	envp[i] = NULL;

	return envp;
}
#else
- (of_char16_t*)OF_environmentForDictionary: (OFDictionary*)environment
- (of_char16_t *)OF_environmentForDictionary: (OFDictionary *)environment
{
	OFDataArray *env;
	OFEnumerator *keyEnumerator, *objectEnumerator;
	OFString *key, *object;
	const of_char16_t equal = '=';
	const of_char16_t zero[2] = { 0, 0 };

445
446
447
448
449
450
451
452

453
454
455
456
457
458
459
445
446
447
448
449
450
451

452
453
454
455
456
457
458
459







-
+







	if (_readPipe[0] == NULL)
#endif
		return true;

	return _atEndOfStream;
}

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

	if (_readPipe[0] == -1 || _atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
486
487
488
489
490
491
492
493

494
495
496
497
498
499
500
486
487
488
489
490
491
492

493
494
495
496
497
498
499
500







-
+








	if (ret == 0)
		_atEndOfStream = true;

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
- (void)lowlevelWriteBuffer: (const void *)buffer
		     length: (size_t)length
{
#ifndef OF_WINDOWS
	if (_writePipe[1] == -1 || _atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length];

Modified src/OFRIPEMD160Hash.m from [c9c8fa689f] to [eb95ce0800].

178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192







-
+







	_state[0] = 0x67452301;
	_state[1] = 0xEFCDAB89;
	_state[2] = 0x98BADCFE;
	_state[3] = 0x10325476;
	_state[4] = 0xC3D2E1F0;
}

- (void)updateWithBuffer: (const void*)buffer_
- (void)updateWithBuffer: (const void *)buffer_
		  length: (size_t)length
{
	const uint8_t *buffer = buffer_;

	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithObject: self];
208
209
210
211
212
213
214
215

216
217
218

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
208
209
210
211
212
213
214

215
216
217

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245
246
247







-
+


-
+

















-
+











		if (_bufferLength == 64) {
			processBlock(_state, _buffer.words);
			_bufferLength = 0;
		}
	}
}

- (const unsigned char*)digest
- (const unsigned char *)digest
{
	if (_calculated)
		return (const uint8_t*)_state;
		return (const uint8_t *)_state;

	_buffer.bytes[_bufferLength] = 0x80;
	memset(_buffer.bytes + _bufferLength + 1, 0, 64 - _bufferLength - 1);

	if (_bufferLength >= 56) {
		processBlock(_state, _buffer.words);
		memset(_buffer.bytes, 0, 64);
	}

	_buffer.words[14] = OF_BSWAP32_IF_BE((uint32_t)(_bits & 0xFFFFFFFF));
	_buffer.words[15] = OF_BSWAP32_IF_BE((uint32_t)(_bits >> 32));

	processBlock(_state, _buffer.words);
	memset(&_buffer, 0, sizeof(_buffer));
	byteSwapVectorIfBE(_state, 5);
	_calculated = true;

	return (const uint8_t*)_state;
	return (const uint8_t *)_state;
}

- (void)reset
{
	[self OF_resetState];
	_bits = 0;
	memset(&_buffer, 0, sizeof(_buffer));
	_bufferLength = 0;
	_calculated = false;
}
@end

Modified src/OFRecursiveMutex.m from [cf1fc36f57] to [5791a36f8a].

71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86







-
+









- (void)unlock
{
	if (!of_rmutex_unlock(&_rmutex))
		@throw [OFUnlockFailedException exceptionWithLock: self];
}

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

	return [OFString stringWithFormat: @"<%@: %@>",
					   [self className], _name];
}
@end

Modified src/OFRunLoop+Private.h from [e29afe9906] to [a788ecb156].

19
20
21
22
23
24
25
26

27
28
29


30
31
32
33
34


35
36
37
38

39
40
41
42

43
44
45
46


47
48
49
50
51
52


53
54
55
56


57
58
59

60
61
62

63
64
65
66


67
68
69
70
71
72
73

74
75
76
19
20
21
22
23
24
25

26
27


28
29
30
31
32


33
34
35
36
37

38
39
40
41

42
43
44


45
46
47
48
49
50


51
52
53
54


55
56
57
58

59
60
61

62
63
64


65
66
67
68
69
70
71
72

73
74
75
76







-
+

-
-
+
+



-
-
+
+



-
+



-
+


-
-
+
+




-
-
+
+


-
-
+
+


-
+


-
+


-
-
+
+






-
+



#ifdef OF_HAVE_SOCKETS
# import "OFUDPSocket.h"
#endif

OF_ASSUME_NONNULL_BEGIN

@interface OFRunLoop ()
+ (void)OF_setMainRunLoop: (OFRunLoop*)runLoop;
+ (void)OF_setMainRunLoop: (OFRunLoop *)runLoop;
#ifdef OF_HAVE_SOCKETS
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
+ (void)OF_addAsyncReadForStream: (OFStream *)stream
			  buffer: (void *)buffer
			  length: (size_t)length
			  target: (id)target
			selector: (SEL)selector;
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
+ (void)OF_addAsyncReadForStream: (OFStream *)stream
			  buffer: (void *)buffer
		     exactLength: (size_t)length
			  target: (id)target
			selector: (SEL)selector;
+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
+ (void)OF_addAsyncReadLineForStream: (OFStream *)stream
			    encoding: (of_string_encoding_t)encoding
			      target: (id)target
			    selector: (SEL)selector;
+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)socket
+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket *)socket
			       target: (id)target
			     selector: (SEL)selector;
+ (void)OF_addAsyncReceiveForUDPSocket: (OFUDPSocket*)socket
				buffer: (void*)buffer
+ (void)OF_addAsyncReceiveForUDPSocket: (OFUDPSocket *)socket
				buffer: (void *)buffer
				length: (size_t)length
				target: (id)target
			      selector: (SEL)selector;
# ifdef OF_HAVE_BLOCKS
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
+ (void)OF_addAsyncReadForStream: (OFStream *)stream
			  buffer: (void *)buffer
			  length: (size_t)length
			   block: (of_stream_async_read_block_t)block;
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
+ (void)OF_addAsyncReadForStream: (OFStream *)stream
			  buffer: (void *)buffer
		     exactLength: (size_t)length
			   block: (of_stream_async_read_block_t)block;
+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
+ (void)OF_addAsyncReadLineForStream: (OFStream *)stream
			    encoding: (of_string_encoding_t)encoding
			       block: (of_stream_async_read_line_block_t)block;
+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)socket
+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket *)socket
				block: (of_tcp_socket_async_accept_block_t)
					   block;
+ (void)OF_addAsyncReceiveForUDPSocket: (OFUDPSocket*)socket
				buffer: (void*)buffer
+ (void)OF_addAsyncReceiveForUDPSocket: (OFUDPSocket *)socket
				buffer: (void *)buffer
				length: (size_t)length
				 block: (of_udp_socket_async_receive_block_t)
					    block;
# endif
+ (void)OF_cancelAsyncRequestsForObject: (id)object;
#endif
- (void)OF_removeTimer: (OFTimer*)timer;
- (void)OF_removeTimer: (OFTimer *)timer;
@end

OF_ASSUME_NONNULL_END

Modified src/OFRunLoop.h from [fc59a05cee] to [584523a360].

57
58
59
60
61
62
63
64

65
66
67
68
69
70
71

72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
57
58
59
60
61
62
63

64
65
66
67
68
69
70

71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99







-
+






-
+






-
+











-
+









}

/*!
 * @brief Returns the run loop for the main thread.
 *
 * @return The run loop for the main thread
 */
+ (OFRunLoop*)mainRunLoop;
+ (OFRunLoop *)mainRunLoop;

/*!
 * @brief Returns the run loop for the current thread.
 *
 * @return The run loop for the current thread
 */
+ (OFRunLoop*)currentRunLoop;
+ (OFRunLoop *)currentRunLoop;

/*!
 * @brief Adds an OFTimer to the run loop.
 *
 * @param timer The timer to add
 */
- (void)addTimer: (OFTimer*)timer;
- (void)addTimer: (OFTimer *)timer;

/*!
 * @brief Starts the run loop.
 */
- (void)run;

/*!
 * @brief Run the run loop until the specified deadline.
 *
 * @param deadline The date until which the run loop should run
 */
- (void)runUntilDate: (nullable OFDate*)deadline;
- (void)runUntilDate: (nullable OFDate *)deadline;

/*!
 * @brief Stops the run loop. If there is still an operation being executed, it
 *	  is finished before the run loop stops.
 */
- (void)stop;
@end

OF_ASSUME_NONNULL_END

Modified src/OFRunLoop.m from [af29aae29a] to [f31ca790af].

128
129
130
131
132
133
134
135
136



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


135
136
137
138
139
140
141
142
143
144







-
-
+
+
+







	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, _buffer, length, exception);
	else {
# endif
		bool (*func)(id, SEL, OFStream*, void*, size_t, OFException*) =
		    (bool(*)(id, SEL, OFStream*, void*, size_t, OFException*))
		bool (*func)(id, SEL, OFStream *, void *, size_t,
		    OFException *) = (bool (*)(id, SEL, OFStream *, void *,
		    size_t, OFException *))
		    [_target methodForSelector: _selector];

		return func(_target, _selector, object, _buffer, length,
		    exception);
# ifdef OF_HAVE_BLOCKS
	}
# endif
156
157
158
159
160
161
162
163

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

164
165
166
167
168
169
170
171







-
+







@implementation OFRunLoop_ExactReadQueueItem
- (bool)handleForObject: (id)object
{
	size_t length;
	OFException *exception = nil;

	@try {
		length = [object readIntoBuffer: (char*)_buffer + _readLength
		length = [object readIntoBuffer: (char *)_buffer + _readLength
					 length: _exactLength - _readLength];
	} @catch (OFException *e) {
		length = 0;
		exception = e;
	}

	_readLength += length;
178
179
180
181
182
183
184
185
186



187
188
189
190
191
192
193
179
180
181
182
183
184
185


186
187
188
189
190
191
192
193
194
195







-
-
+
+
+







		if (!_block(object, _buffer, _readLength, exception))
			return false;

		_readLength = 0;
		return true;
	} else {
# endif
		bool (*func)(id, SEL, OFStream*, void*, size_t, OFException*) =
		    (bool(*)(id, SEL, OFStream*, void*, size_t, OFException*))
		bool (*func)(id, SEL, OFStream *, void *, size_t,
		    OFException *) = (bool (*)(id, SEL, OFStream *, void *,
		    size_t, OFException *))
		    [_target methodForSelector: _selector];

		if (!func(_target, _selector, object, _buffer, _readLength,
		    exception))
			return false;

		_readLength = 0;
224
225
226
227
228
229
230
231
232


233
234
235
236
237
238
239
226
227
228
229
230
231
232


233
234
235
236
237
238
239
240
241







-
-
+
+







		return true;

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, line, exception);
	else {
# endif
		bool (*func)(id, SEL, OFStream*, OFString*, OFException*) =
		    (bool(*)(id, SEL, OFStream*, OFString*, OFException*))
		bool (*func)(id, SEL, OFStream *, OFString *, OFException *) =
		    (bool (*)(id, SEL, OFStream *, OFString *, OFException *))
		    [_target methodForSelector: _selector];

		return func(_target, _selector, object, line, exception);
# ifdef OF_HAVE_BLOCKS
	}
# endif
}
262
263
264
265
266
267
268
269
270
271



272
273
274
275
276
277
278
264
265
266
267
268
269
270



271
272
273
274
275
276
277
278
279
280







-
-
-
+
+
+







	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, newSocket, exception);
	else {
# endif
		bool (*func)(id, SEL, OFTCPSocket*, OFTCPSocket*,
		    OFException*) =
		    (bool(*)(id, SEL, OFTCPSocket*, OFTCPSocket*, OFException*))
		bool (*func)(id, SEL, OFTCPSocket *, OFTCPSocket *,
		    OFException *) = (bool (*)(id, SEL, OFTCPSocket *,
		    OFTCPSocket *, OFException *))
		    [_target methodForSelector: _selector];

		return func(_target, _selector, object, newSocket, exception);
# ifdef OF_HAVE_BLOCKS
	}
# endif
}
304
305
306
307
308
309
310
311
312
313
314




315
316
317
318
319
320
321
306
307
308
309
310
311
312




313
314
315
316
317
318
319
320
321
322
323







-
-
-
-
+
+
+
+







	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, _buffer, length, address, exception);
	else {
# endif
		bool (*func)(id, SEL, OFUDPSocket*, void*, size_t,
		    of_udp_socket_address_t address, OFException*) =
		    (bool(*)(id, SEL, OFUDPSocket*, void*, size_t,
		    of_udp_socket_address_t, OFException*))
		bool (*func)(id, SEL, OFUDPSocket *, void *, size_t,
		    of_udp_socket_address_t address, OFException *) =
		    (bool (*)(id, SEL, OFUDPSocket *, void *, size_t,
		    of_udp_socket_address_t, OFException *))
		    [_target methodForSelector: _selector];

		return func(_target, _selector, object, _buffer, length,
		    address, exception);
# ifdef OF_HAVE_BLOCKS
	}
# endif
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
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







-
+




-
+








-
+







	[super dealloc];
}
# endif
@end
#endif

@implementation OFRunLoop
+ (OFRunLoop*)mainRunLoop
+ (OFRunLoop *)mainRunLoop
{
	return [[mainRunLoop retain] autorelease];
}

+ (OFRunLoop*)currentRunLoop
+ (OFRunLoop *)currentRunLoop
{
#ifdef OF_HAVE_THREADS
	return [[OFThread currentThread] runLoop];
#else
	return [self mainRunLoop];
#endif
}

+ (void)OF_setMainRunLoop: (OFRunLoop*)runLoop
+ (void)OF_setMainRunLoop: (OFRunLoop *)runLoop
{
	mainRunLoop = [runLoop retain];
}

#ifdef OF_HAVE_SOCKETS
# define ADD_READ(type, object, code)					\
	void *pool = objc_autoreleasePoolPush();			\
371
372
373
374
375
376
377
378
379


380
381
382
383
384
385
386
387
388
389
390
391
392
393


394
395
396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426
427
428
429


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


445
446
447
448
449
450
451
452
453
454
455
456


457
458
459
460
461
462
463
464
465
466
467

468
469
470
471
472
473
474
475
476
477

478
479
480
481
482
483
484
485
486


487
488
489
490
491
492
493
373
374
375
376
377
378
379


380
381
382
383
384
385
386
387
388
389
390
391
392
393


394
395
396
397
398
399
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429


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


445
446
447
448
449
450
451
452
453
454
455
456


457
458
459
460
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486


487
488
489
490
491
492
493
494
495







-
-
+
+












-
-
+
+












-
+











-
+









-
-
+
+













-
-
+
+










-
-
+
+










-
+









-
+







-
-
+
+







									\
	queueItem = [[[type alloc] init] autorelease];			\
	code								\
	[queue appendObject: queueItem];				\
									\
	objc_autoreleasePoolPop(pool);

+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
+ (void)OF_addAsyncReadForStream: (OFStream *)stream
			  buffer: (void *)buffer
			  length: (size_t)length
			  target: (id)target
			selector: (SEL)selector
{
	ADD_READ(OFRunLoop_ReadQueueItem, stream, {
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
		queueItem->_buffer = buffer;
		queueItem->_length = length;
	})
}

+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
+ (void)OF_addAsyncReadForStream: (OFStream *)stream
			  buffer: (void *)buffer
		     exactLength: (size_t)exactLength
			  target: (id)target
			selector: (SEL)selector
{
	ADD_READ(OFRunLoop_ExactReadQueueItem, stream, {
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
		queueItem->_buffer = buffer;
		queueItem->_exactLength = exactLength;
	})
}

+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
+ (void)OF_addAsyncReadLineForStream: (OFStream *)stream
			    encoding: (of_string_encoding_t)encoding
			      target: (id)target
			    selector: (SEL)selector
{
	ADD_READ(OFRunLoop_ReadLineQueueItem, stream, {
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
		queueItem->_encoding = encoding;
	})
}

+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)stream
+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket *)stream
			       target: (id)target
			     selector: (SEL)selector
{
	ADD_READ(OFRunLoop_AcceptQueueItem, stream, {
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
	})
}

+ (void)OF_addAsyncReceiveForUDPSocket: (OFUDPSocket*)socket
				buffer: (void*)buffer
+ (void)OF_addAsyncReceiveForUDPSocket: (OFUDPSocket *)socket
				buffer: (void *)buffer
				length: (size_t)length
				target: (id)target
			      selector: (SEL)selector
{
	ADD_READ(OFRunLoop_UDPReceiveQueueItem, socket, {
		queueItem->_buffer = buffer;
		queueItem->_length = length;
		queueItem->_target = [target retain];
		queueItem->_selector = selector;
	})
}

# ifdef OF_HAVE_BLOCKS
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
+ (void)OF_addAsyncReadForStream: (OFStream *)stream
			  buffer: (void *)buffer
			  length: (size_t)length
			   block: (of_stream_async_read_block_t)block
{
	ADD_READ(OFRunLoop_ReadQueueItem, stream, {
		queueItem->_block = [block copy];
		queueItem->_buffer = buffer;
		queueItem->_length = length;
	})
}

+ (void)OF_addAsyncReadForStream: (OFStream*)stream
			  buffer: (void*)buffer
+ (void)OF_addAsyncReadForStream: (OFStream *)stream
			  buffer: (void *)buffer
		     exactLength: (size_t)exactLength
			   block: (of_stream_async_read_block_t)block
{
	ADD_READ(OFRunLoop_ExactReadQueueItem, stream, {
		queueItem->_block = [block copy];
		queueItem->_buffer = buffer;
		queueItem->_exactLength = exactLength;
	})
}

+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
+ (void)OF_addAsyncReadLineForStream: (OFStream *)stream
			    encoding: (of_string_encoding_t)encoding
			       block: (of_stream_async_read_line_block_t)block
{
	ADD_READ(OFRunLoop_ReadLineQueueItem, stream, {
		queueItem->_block = [block copy];
		queueItem->_encoding = encoding;
	})
}

+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)stream
+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket *)stream
				block: (of_tcp_socket_async_accept_block_t)block
{
	ADD_READ(OFRunLoop_AcceptQueueItem, stream, {
		queueItem->_block = [block copy];
	})
}

+ (void)OF_addAsyncReceiveForUDPSocket: (OFUDPSocket*)socket
				buffer: (void*)buffer
+ (void)OF_addAsyncReceiveForUDPSocket: (OFUDPSocket *)socket
				buffer: (void *)buffer
				length: (size_t)length
				 block: (of_udp_socket_async_receive_block_t)
					    block
{
	ADD_READ(OFRunLoop_UDPReceiveQueueItem, socket, {
		queueItem->_buffer = buffer;
		queueItem->_length = length;
558
559
560
561
562
563
564
565

566
567
568
569
570
571
572
560
561
562
563
564
565
566

567
568
569
570
571
572
573
574







-
+







#elif defined(OF_HAVE_THREADS)
	[_condition release];
#endif

	[super dealloc];
}

- (void)addTimer: (OFTimer*)timer
- (void)addTimer: (OFTimer *)timer
{
#ifdef OF_HAVE_THREADS
	[_timersQueueLock lock];
	@try {
#endif
		[_timersQueue insertObject: timer];
#ifdef OF_HAVE_THREADS
580
581
582
583
584
585
586
587

588
589
590
591
592
593
594
582
583
584
585
586
587
588

589
590
591
592
593
594
595
596







-
+







#if defined(OF_HAVE_SOCKETS)
	[_kernelEventObserver cancel];
#elif defined(OF_HAVE_THREADS)
	[_condition signal];
#endif
}

- (void)OF_removeTimer: (OFTimer*)timer
- (void)OF_removeTimer: (OFTimer *)timer
{
#ifdef OF_HAVE_THREADS
	[_timersQueueLock lock];
	@try {
#endif
		of_list_object_t *iter;

609
610
611
612
613
614
615
616

617
618
619
620
621
622
623
611
612
613
614
615
616
617

618
619
620
621
622
623
624
625







-
+







#ifdef OF_HAVE_SOCKETS
- (void)objectIsReadyForReading: (id)object
{
	/*
	 * Retain the queue so that it doesn't disappear from us because the
	 * handler called -[cancelAsyncRequests].
	 */
	OFList OF_GENERIC(OF_KINDOF(OFRunLoop_ReadQueueItem*)) *queue =
	OFList OF_GENERIC(OF_KINDOF(OFRunLoop_ReadQueueItem *)) *queue =
	    [[_readQueues objectForKey: object] retain];

	assert(queue != nil);

	@try {
		if (![[queue firstObject] handleForObject: object]) {
			of_list_object_t *listObject = [queue firstListObject];
645
646
647
648
649
650
651
652

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

654
655
656
657
658
659
660
661







-
+







#endif

- (void)run
{
	[self runUntilDate: nil];
}

- (void)runUntilDate: (OFDate*)deadline
- (void)runUntilDate: (OFDate *)deadline
{
	_stop = false;

	for (;;) {
		void *pool = objc_autoreleasePoolPush();
		OFDate *now = [OFDate date];
		OFDate *nextTimer;

Modified src/OFSHA1Hash.m from [4360879e92] to [766775fc8c].

138
139
140
141
142
143
144
145

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

145
146
147
148
149
150
151
152







-
+







	_state[0] = 0x67452301;
	_state[1] = 0xEFCDAB89;
	_state[2] = 0x98BADCFE;
	_state[3] = 0x10325476;
	_state[4] = 0xC3D2E1F0;
}

- (void)updateWithBuffer: (const void*)buffer_
- (void)updateWithBuffer: (const void *)buffer_
		  length: (size_t)length
{
	const uint8_t *buffer = buffer_;

	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithObject: self];
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
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







-
+


-
+

















-
+











		if (_bufferLength == 64) {
			processBlock(_state, _buffer.words);
			_bufferLength = 0;
		}
	}
}

- (const unsigned char*)digest
- (const unsigned char *)digest
{
	if (_calculated)
		return (const uint8_t*)_state;
		return (const uint8_t *)_state;

	_buffer.bytes[_bufferLength] = 0x80;
	memset(_buffer.bytes + _bufferLength + 1, 0, 64 - _bufferLength - 1);

	if (_bufferLength >= 56) {
		processBlock(_state, _buffer.words);
		memset(_buffer.bytes, 0, 64);
	}

	_buffer.words[14] = OF_BSWAP32_IF_LE((uint32_t)(_bits >> 32));
	_buffer.words[15] = OF_BSWAP32_IF_LE((uint32_t)(_bits & 0xFFFFFFFF));

	processBlock(_state, _buffer.words);
	memset(&_buffer, 0, sizeof(_buffer));
	byteSwapVectorIfLE(_state, 5);
	_calculated = true;

	return (const uint8_t*)_state;
	return (const uint8_t *)_state;
}

- (void)reset
{
	[self OF_resetState];
	_bits = 0;
	memset(&_buffer, 0, sizeof(_buffer));
	_bufferLength = 0;
	_calculated = false;
}
@end

Modified src/OFSHA224Or256Hash.m from [fb3b52794b] to [07e1179a49].

161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175







-
+







	memcpy(&copy->_buffer, &_buffer, sizeof(_buffer));
	copy->_bufferLength = _bufferLength;
	copy->_calculated = _calculated;

	return copy;
}

- (void)updateWithBuffer: (const void*)buffer_
- (void)updateWithBuffer: (const void *)buffer_
		  length: (size_t)length
{
	const uint8_t *buffer = buffer_;

	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithObject: self];
191
192
193
194
195
196
197
198

199
200
201

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
191
192
193
194
195
196
197

198
199
200

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226







-
+


-
+

















-
+







		if (_bufferLength == 64) {
			processBlock(_state, _buffer.words);
			_bufferLength = 0;
		}
	}
}

- (const unsigned char*)digest
- (const unsigned char *)digest
{
	if (_calculated)
		return (const uint8_t*)_state;
		return (const uint8_t *)_state;

	_buffer.bytes[_bufferLength] = 0x80;
	memset(_buffer.bytes + _bufferLength + 1, 0, 64 - _bufferLength - 1);

	if (_bufferLength >= 56) {
		processBlock(_state, _buffer.words);
		memset(_buffer.bytes, 0, 64);
	}

	_buffer.words[14] = OF_BSWAP32_IF_LE((uint32_t)(_bits >> 32));
	_buffer.words[15] = OF_BSWAP32_IF_LE((uint32_t)(_bits & 0xFFFFFFFF));

	processBlock(_state, _buffer.words);
	memset(&_buffer, 0, sizeof(_buffer));
	byteSwapVectorIfLE(_state, 8);
	_calculated = true;

	return (const uint8_t*)_state;
	return (const uint8_t *)_state;
}

- (void)reset
{
	[self OF_resetState];
	_bits = 0;
	memset(&_buffer, 0, sizeof(_buffer));

Modified src/OFSHA384Or512Hash.m from [51d3c14901] to [d5b60b898c].

172
173
174
175
176
177
178
179

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

179
180
181
182
183
184
185
186







-
+







	memcpy(&copy->_buffer, &_buffer, sizeof(_buffer));
	copy->_bufferLength = _bufferLength;
	copy->_calculated = _calculated;

	return copy;
}

- (void)updateWithBuffer: (const void*)buffer_
- (void)updateWithBuffer: (const void *)buffer_
		  length: (size_t)length
{
	const uint8_t *buffer = buffer_;

	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithObject: self];
204
205
206
207
208
209
210
211

212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
204
205
206
207
208
209
210

211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239







-
+


-
+

















-
+







		if (_bufferLength == 128) {
			processBlock(_state, _buffer.words);
			_bufferLength = 0;
		}
	}
}

- (const unsigned char*)digest
- (const unsigned char *)digest
{
	if (_calculated)
		return (const uint8_t*)_state;
		return (const uint8_t *)_state;

	_buffer.bytes[_bufferLength] = 0x80;
	memset(_buffer.bytes + _bufferLength + 1, 0, 128 - _bufferLength - 1);

	if (_bufferLength >= 112) {
		processBlock(_state, _buffer.words);
		memset(_buffer.bytes, 0, 128);
	}

	_buffer.words[14] = OF_BSWAP64_IF_LE(_bits[1]);
	_buffer.words[15] = OF_BSWAP64_IF_LE(_bits[0]);

	processBlock(_state, _buffer.words);
	memset(&_buffer, 0, sizeof(_buffer));
	byteSwapVectorIfLE(_state, 8);
	_calculated = true;

	return (const uint8_t*)_state;
	return (const uint8_t *)_state;
}

- (void)reset
{
	[self OF_resetState];
	memset(_bits, 0, sizeof(_bits));
	memset(&_buffer, 0, sizeof(_buffer));

Modified src/OFSandbox.h from [f00e17ef0d] to [caa850467d].

132
133
134
135
136
137
138
139

140
141
142
143
132
133
134
135
136
137
138

139
140
141
142
143







-
+





#ifdef OF_HAVE_PLEDGE
/*!
 * @brief Returns the string for OpenBSD's pledge() call.
 *
 * @warning Only available on systems with the pledge() call!
 */
- (OFString*)pledgeString;
- (OFString *)pledgeString;
#endif
@end

OF_ASSUME_NONNULL_END

Modified src/OFSandbox.m from [d7f3bcd0a9] to [3da3a171ab].

201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215







-
+








	OF_HASH_FINALIZE(hash);

	return hash;
}

#ifdef OF_HAVE_PLEDGE
- (OFString*)pledgeString
- (OFString *)pledgeString
{
	void *pool = objc_autoreleasePoolPush();
	OFMutableArray *pledges = [OFMutableArray array];
	OFString *ret;

	if (_allowsStdIO)
		[pledges addObject: @"stdio"];

Modified src/OFSerialization.h from [e6befb1e9b] to [140cf6aa4f].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44

45
46
47
30
31
32
33
34
35
36

37
38
39
40
41
42
43

44
45
46
47







-
+






-
+



@protocol OFSerialization
/*!
 * @brief Initializes the object with the specified XML element serialization.
 *
 * @param element An OFXMLElement with the serialized object
 * @return An initialized object
 */
- initWithSerialization: (OFXMLElement*)element;
- initWithSerialization: (OFXMLElement *)element;

/*!
 * @brief Serializes the object into an XML element.
 *
 * @return The object serialized into an XML element
 */
- (OFXMLElement*)XMLElementBySerializing;
- (OFXMLElement *)XMLElementBySerializing;
@end

OF_ASSUME_NONNULL_END

Modified src/OFSet.h from [0fe90e5221] to [48306f95d4].

57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100







-
+




















-
+







-
+







 *
 * @brief An abstract class for an unordered set of unique objects.
 *
 * @warning Do not mutate objects that are in a set! Changing the hash of
 *	    objects in a set breaks the internal representation of the set!
 */
#ifdef OF_HAVE_GENERICS
@interface OFSet <ObjectType>:
@interface OFSet<ObjectType>:
#else
# ifndef DOXYGEN
#  define ObjectType id
# endif
@interface OFSet:
#endif
    OFObject <OFCollection, OFCopying, OFMutableCopying, OFSerialization>
/*!
 * @brief Creates a new set.
 *
 * @return A new, autoreleased set
 */
+ (instancetype)set;

/*!
 * @brief Creates a new set with the specified set.
 *
 * @param set The set to initialize the set with
 * @return A new, autoreleased set with the specified set
 */
+ (instancetype)setWithSet: (OFSet OF_GENERIC(ObjectType)*)set;
+ (instancetype)setWithSet: (OFSet OF_GENERIC(ObjectType) *)set;

/*!
 * @brief Creates a new set with the specified array.
 *
 * @param array The array to initialize the set with
 * @return A new, autoreleased set with the specified array
 */
+ (instancetype)setWithArray: (OFArray OF_GENERIC(ObjectType)*)array;
+ (instancetype)setWithArray: (OFArray OF_GENERIC(ObjectType) *)array;

/*!
 * @brief Creates a new set with the specified objects.
 *
 * @param firstObject The first object for the set
 * @return A new, autoreleased set with the specified objects
 */
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134







-
+







-
+








/*!
 * @brief Initializes an already allocated set with the specified set.
 *
 * @param set The set to initialize the set with
 * @return An initialized set with the specified set
 */
- initWithSet: (OFSet OF_GENERIC(ObjectType)*)set;
- initWithSet: (OFSet OF_GENERIC(ObjectType) *)set;

/*!
 * @brief Initializes an already allocated set with the specified array.
 *
 * @param array The array to initialize the set with
 * @return An initialized set with the specified array
 */
- initWithArray: (OFArray OF_GENERIC(ObjectType)*)array;
- initWithArray: (OFArray OF_GENERIC(ObjectType) *)array;

/*!
 * @brief Initializes an already allocated set with the specified objects.
 *
 * @param firstObject The first object for the set
 * @return An initialized set with the specified objects
 */
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181


182
183
184
185
186
187
188
189
190


191
192
193
194
195
196
197
198
199


200
201
202
203
204
205
206

207
208
209
210
211
212
213
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179


180
181
182
183
184
185
186
187
188


189
190
191
192
193
194
195
196
197


198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213







-
+








-
+







-
-
+
+







-
-
+
+







-
-
+
+






-
+







       arguments: (va_list)arguments;

/*!
 * @brief Returns whether the receiver is a subset of the specified set.
 *
 * @return Whether the receiver is a subset of the specified set
 */
- (bool)isSubsetOfSet: (OFSet OF_GENERIC(ObjectType)*)set;
- (bool)isSubsetOfSet: (OFSet OF_GENERIC(ObjectType) *)set;

/*!
 * @brief Returns whether the receiver and the specified set have at least one
 *	  object in common.
 *
 * @return Whether the receiver and the specified set have at least one object
 *	   in common
 */
- (bool)intersectsSet: (OFSet OF_GENERIC(ObjectType)*)set;
- (bool)intersectsSet: (OFSet OF_GENERIC(ObjectType) *)set;

/*!
 * @brief Creates a new set which contains the objects which are in the
 *	  receiver, but not in the specified set.
 *
 * @param set The set whose objects will not be in the new set
 */
- (OFSet OF_GENERIC(ObjectType)*)setBySubtractingSet:
    (OFSet OF_GENERIC(ObjectType)*)set;
- (OFSet OF_GENERIC(ObjectType) *)setBySubtractingSet:
    (OFSet OF_GENERIC(ObjectType) *)set;

/*!
 * @brief Creates a new set by creating the intersection of the receiver and
 *	  the specified set.
 *
 * @param set The set to intersect with
 */
- (OFSet OF_GENERIC(ObjectType)*)setByIntersectingWithSet:
    (OFSet OF_GENERIC(ObjectType)*)set;
- (OFSet OF_GENERIC(ObjectType) *)setByIntersectingWithSet:
    (OFSet OF_GENERIC(ObjectType) *)set;

/*!
 * @brief Creates a new set by creating the union of the receiver and the
 *	  specified set.
 *
 * @param set The set to create the union with
 */
- (OFSet OF_GENERIC(ObjectType)*)setByAddingSet:
    (OFSet OF_GENERIC(ObjectType)*)set;
- (OFSet OF_GENERIC(ObjectType) *)setByAddingSet:
    (OFSet OF_GENERIC(ObjectType) *)set;

/*!
 * @brief Returns an array of all objects in the set.
 *
 * @return An array of all objects in the set
 */
- (OFArray OF_GENERIC(ObjectType)*)allObjects;
- (OFArray OF_GENERIC(ObjectType) *)allObjects;

/*!
 * @brief Returns an arbitrary object in the set.
 *
 * @return An arbitrary object in the set
 */
- (ObjectType)anyObject;
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260

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

278
279
280
281
282
283
284
285
286
287
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

253
254
255
256
257
258
259

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

277
278
279
280
281
282
283
284
285
286
287







-
+















-
+






-
+
















-
+










 * specified key for each object is returned.
 *
 * @note Unlike with @ref OFArray, any nil values are removed!
 *
 * @param key The key of the value to return
 * @return The value for the specified key
 */
- (nullable id)valueForKey: (OFString*)key;
- (nullable id)valueForKey: (OFString *)key;

/*!
 * @brief Set the value for the specified key
 *
 * If the key starts with an `@`, the `@` is stripped and
 * `[super setValue:forKey:]` is called.
 * If the key does not start with an `@`, @ref setValue:forKey: is called for
 * each object.
 *
 * @note A @ref OFNull value is translated to nil!
 *
 * @param value The value for the specified key
 * @param key The key of the value to set
 */
- (void)setValue: (nullable id)value
	  forKey: (OFString*)key;
	  forKey: (OFString *)key;

/*!
 * @brief Returns an OFEnumerator to enumerate through all objects of the set.
 *
 * @returns An OFEnumerator to enumerate through all objects of the set
 */
- (OFEnumerator OF_GENERIC(ObjectType)*)objectEnumerator;
- (OFEnumerator OF_GENERIC(ObjectType) *)objectEnumerator;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Executes a block for each object in the set.
 *
 * @param block The block to execute for each object in the set
 */
- (void)enumerateObjectsUsingBlock: (of_set_enumeration_block_t)block;

/*!
 * @brief Creates a new set, only containing the objects for which the block
 *	  returns true.
 *
 * @param block A block which determines if the object should be in the new set
 * @return A new, autoreleased OFSet
 */
- (OFSet OF_GENERIC(ObjectType)*)filteredSetUsingBlock:
- (OFSet OF_GENERIC(ObjectType) *)filteredSetUsingBlock:
    (of_set_filter_block_t)block;
#endif
@end
#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN)
# undef ObjectType
#endif

OF_ASSUME_NONNULL_END

#import "OFMutableSet.h"

Modified src/OFSet.m from [4282ae8fc5] to [62db370766].

34
35
36
37
38
39
40
41

42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

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

79
80
81
82
83
84
85
34
35
36
37
38
39
40

41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

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

78
79
80
81
82
83
84
85







-
+




-
+

















-
+













-
+








@implementation OFSet_placeholder
- init
{
	return (id)[[OFSet_hashtable alloc] init];
}

- initWithSet: (OFSet*)set
- initWithSet: (OFSet *)set
{
	return (id)[[OFSet_hashtable alloc] initWithSet: set];
}

- initWithArray: (OFArray*)array
- initWithArray: (OFArray *)array
{
	return (id)[[OFSet_hashtable alloc] initWithArray: array];
}

- initWithObjects: (id)firstObject, ...
{
	id ret;
	va_list arguments;

	va_start(arguments, firstObject);
	ret = [[OFSet_hashtable alloc] initWithObject: firstObject
					    arguments: arguments];
	va_end(arguments);

	return ret;
}

- initWithObjects: (id const*)objects
- initWithObjects: (id const *)objects
	    count: (size_t)count
{
	return (id)[[OFSet_hashtable alloc] initWithObjects: objects
						      count: count];
}

- initWithObject: (id)firstObject
       arguments: (va_list)arguments
{
	return (id)[[OFSet_hashtable alloc] initWithObject: firstObject
						 arguments: arguments];
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFSet_hashtable alloc] initWithSerialization: element];
}

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







-
+




-
+

















-
+







}

+ (instancetype)set
{
	return [[[self alloc] init] autorelease];
}

+ (instancetype)setWithSet: (OFSet*)set
+ (instancetype)setWithSet: (OFSet *)set
{
	return [[[self alloc] initWithSet: set] autorelease];
}

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

+ (instancetype)setWithObjects: (id)firstObject, ...
{
	id ret;
	va_list arguments;

	va_start(arguments, firstObject);
	ret = [[[self alloc] initWithObject: firstObject
				  arguments: arguments] autorelease];
	va_end(arguments);

	return ret;
}

+ (instancetype)setWithObjects: (id const*)objects
+ (instancetype)setWithObjects: (id const *)objects
			 count: (size_t)count
{
	return [[[self alloc] initWithObjects: objects
					count: count] autorelease];
}

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







-
+




-
+




-
+








		abort();
	}

	return [super init];
}

- initWithSet: (OFSet*)set
- initWithSet: (OFSet *)set
{
	OF_INVALID_INIT_METHOD
}

- initWithArray: (OFArray*)array
- initWithArray: (OFArray *)array
{
	OF_INVALID_INIT_METHOD
}

- initWithObjects: (id const*)objects
- initWithObjects: (id const *)objects
	    count: (size_t)count
{
	OF_INVALID_INIT_METHOD
}

- (id)initWithObjects: (id)firstObject, ...
{
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221







-
+









-
+








- initWithObject: (id)firstObject
       arguments: (va_list)arguments
{
	OF_INVALID_INIT_METHOD
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	OF_INVALID_INIT_METHOD
}

- (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (id)valueForKey: (OFString*)key
- (id)valueForKey: (OFString *)key
{
	OFMutableSet *ret;

	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();
		id ret;

238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252







-
+








	[ret makeImmutable];

	return ret;
}

- (void)setValue: (id)value
	  forKey: (OFString*)key
	  forKey: (OFString *)key
{
	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();

		key = [key substringWithRange: of_range(1, [key length] - 1)];
		[super setValue: value
			 forKey: key];
264
265
266
267
268
269
270
271

272
273
274
275
276
277


278
279
280
281
282
283
284
264
265
266
267
268
269
270

271
272
273
274
275


276
277
278
279
280
281
282
283
284







-
+




-
-
+
+







}

- (bool)containsObject: (id)object
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFEnumerator*)objectEnumerator
- (OFEnumerator *)objectEnumerator
{
	OF_UNRECOGNIZED_SELECTOR
}

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

- (bool)isEqual: (id)object
{
304
305
306
307
308
309
310
311

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

311
312
313
314
315
316
317
318







-
+







		hash += [object hash];

	objc_autoreleasePoolPop(pool);

	return hash;
}

- (OFString*)description
- (OFString *)description
{
	void *pool;
	OFMutableString *ret;
	size_t i, count = [self count];

	if (count == 0)
		return @"{()}";
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
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







-
+








-
+








-
+







}

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

- (bool)isSubsetOfSet: (OFSet*)set
- (bool)isSubsetOfSet: (OFSet *)set
{
	for (id object in self)
		if (![set containsObject: object])
			return false;

	return true;
}

- (bool)intersectsSet: (OFSet*)set
- (bool)intersectsSet: (OFSet *)set
{
	for (id object in self)
		if ([set containsObject: object])
			return true;

	return false;
}

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

	if ([self isKindOfClass: [OFMutableSet class]])
		element = [OFXMLElement elementWithName: @"OFMutableSet"
					      namespace: OF_SERIALIZATION_NS];
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423
424
425

426
427
428
429
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444







-
+











-
+











-
+











-
+







	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (OFSet*)setBySubtractingSet: (OFSet*)set
- (OFSet *)setBySubtractingSet: (OFSet *)set
{
	OFMutableSet *new;

	new = [[self mutableCopy] autorelease];
	[new minusSet: set];

	[new makeImmutable];

	return new;
}

- (OFSet*)setByIntersectingWithSet: (OFSet*)set
- (OFSet *)setByIntersectingWithSet: (OFSet *)set
{
	OFMutableSet *new;

	new = [[self mutableCopy] autorelease];
	[new intersectSet: set];

	[new makeImmutable];

	return new;
}

- (OFSet*)setByAddingSet: (OFSet*)set
- (OFSet *)setByAddingSet: (OFSet *)set
{
	OFMutableSet *new;

	new = [[self mutableCopy] autorelease];
	[new unionSet: set];

	[new makeImmutable];

	return new;
}

- (OFArray*)allObjects
- (OFArray *)allObjects
{
	void *pool = objc_autoreleasePoolPush();
	OFArray *ret = [[[self objectEnumerator] allObjects] retain];
	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
461
462
463
464
465
466
467

468
469
470
471
472
473
474
475







-
+







		block(object, &stop);

		if (stop)
			break;
	}
}

- (OFSet*)filteredSetUsingBlock: (of_set_filter_block_t)block
- (OFSet *)filteredSetUsingBlock: (of_set_filter_block_t)block
{
	OFMutableSet *ret = [OFMutableSet set];

	[self enumerateObjectsUsingBlock: ^ (id object, bool *stop) {
		if (block(object))
			[ret addObject: object];
	}];

Modified src/OFSet_hashtable.m from [2668790787] to [84c4225949].

24
25
26
27
28
29
30
31

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

31
32
33
34
35
36
37
38







-
+







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

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

static void*
static void *
retain(void *object)
{
	return [(id)object retain];
}

static void
release(void *object)
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149

150
151
152
153
154
155
156
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148

149
150
151
152
153
154
155
156







-
+

















-
+









-
+

















-
+









-
+






-
+







		[self release];
		@throw e;
	}

	return self;
}

- initWithSet: (OFSet*)set
- initWithSet: (OFSet *)set
{
	size_t count;

	if (set == nil)
		return [self init];

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

	self = [self initWithCapacity: count];

	@try {
		for (id object in set)
			[_mapTable setObject: (void*)1
			[_mapTable setObject: (void *)1
				      forKey: object];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithArray: (OFArray*)array
- initWithArray: (OFArray *)array
{
	size_t count;

	if (array == nil)
		return self;

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

	self = [self initWithCapacity: count];

	@try {
		for (id object in array)
			[_mapTable setObject: (void*)1
			[_mapTable setObject: (void *)1
				      forKey: object];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		for (size_t i = 0; i < count; i++)
			[_mapTable setObject: (void*)1
			[_mapTable setObject: (void *)1
				      forKey: objects[i]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
171
172
173
174
175
176
177
178

179
180
181
182

183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
171
172
173
174
175
176
177

178
179
180
181

182
183
184
185
186
187
188
189
190
191

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

208
209
210
211
212
213
214
215







-
+



-
+









-
+















-
+







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

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

		[_mapTable setObject: (void*)1
		[_mapTable setObject: (void *)1
			      forKey: firstObject];

		while ((object = va_arg(arguments, id)) != nil)
			[_mapTable setObject: (void*)1
			[_mapTable setObject: (void *)1
				      forKey: object];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		void *pool = objc_autoreleasePoolPush();

		if ((![[element name] isEqual: @"OFSet"] &&
		    ![[element name] isEqual: @"OFMutableSet"]) ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException exception];

		for (OFXMLElement *child in
		    [element elementsForNamespace: OF_SERIALIZATION_NS]) {
			void *pool2  = objc_autoreleasePoolPush();

			[_mapTable setObject: (void*)1
			[_mapTable setObject: (void *)1
				      forKey: [child objectByDeserializing]];

			objc_autoreleasePoolPop(pool2);
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278


279
280
281
282
283
284
285
263
264
265
266
267
268
269

270
271
272
273
274
275
276


277
278
279
280
281
282
283
284
285







-
+






-
-
+
+







	object = [object retain];

	objc_autoreleasePoolPop(pool);

	return [object autorelease];
}

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

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

Modified src/OFSettings.h from [da0012a76b] to [7549ee6aeb].

46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117


118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137


138
139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188
189
190

191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70


71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115


116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135


136
137
138
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210







-
+









-
+







-
-
+
+








-
+








-
+








-
+








-
+







-
-
+
+








-
+









-
-
+
+









-
+










-
+










-
+










-
+









-
+






-
+













 * @brief Create a new OFSettings instance for the application with the
 *	  specified name.
 *
 * @param applicationName The name of the application whose settings should be
 *			  accessed
 * @return A new, autoreleased OFSettings instance
 */
+ (instancetype)settingsWithApplicationName: (OFString*)applicationName;
+ (instancetype)settingsWithApplicationName: (OFString *)applicationName;

/*!
 * @brief Initializes an already allocated OFSettings instance with the
 *	  specified application name.
 *
 * @param applicationName The name of the application whose settings should be
 *			  accessed
 * @return An initialized OFSettings instance
 */
- initWithApplicationName: (OFString*)applicationName;
- initWithApplicationName: (OFString *)applicationName;

/*!
 * @brief Sets the specified path to the specified string.
 *
 * @param string The string to set
 * @param path The path to store the string at
 */
- (void)setString: (OFString*)string
	  forPath: (OFString*)path;
- (void)setString: (OFString *)string
	  forPath: (OFString *)path;

/*!
 * @brief Sets the specified path to the specified integer.
 *
 * @param integer The integer to set
 * @param path The path to store the integer at
 */
- (void)setInteger: (intmax_t)integer
	   forPath: (OFString*)path;
	   forPath: (OFString *)path;

/*!
 * @brief Sets the specified path to the specified bool.
 *
 * @param bool_ The bool to set
 * @param path The path to store the bool at
 */
- (void)setBool: (bool)bool_
	forPath: (OFString*)path;
	forPath: (OFString *)path;

/*!
 * @brief Sets the specified path to the specified float.
 *
 * @param float_ The float to set
 * @param path The path to store the float at
 */
- (void)setFloat: (float)float_
	 forPath: (OFString*)path;
	 forPath: (OFString *)path;

/*!
 * @brief Sets the specified path to the specified double.
 *
 * @param double_ The double to set
 * @param path The path to store the double at
 */
- (void)setDouble: (double)double_
	  forPath: (OFString*)path;
	  forPath: (OFString *)path;

/*!
 * @brief Sets the specified path to the specified array of strings.
 *
 * @param array The array of strings to set
 * @param path The path to store the array of strings at
 */
- (void)setArray: (OFArray OF_GENERIC(OFString*)*)array
	 forPath: (OFString*)path;
- (void)setArray: (OFArray OF_GENERIC(OFString *) *)array
	 forPath: (OFString *)path;

/*!
 * @brief Returns the string for the specified path, or `nil` if the path does
 *	  not exist.
 *
 * @param path The path for which the string value should be returned
 * @return The string value of the specified path
 */
- (nullable OFString*)stringForPath: (OFString*)path;
- (nullable OFString *)stringForPath: (OFString *)path;

/*!
 * @brief Returns the string for the specified path, or the default value if
 *	  the path does not exist.
 *
 * @param path The path for which the string value should be returned
 * @param defaultValue The default value to return if the path does not exist
 * @return The string value of the specified path
 */
- (nullable OFString*)stringForPath: (OFString*)path
		       defaultValue: (nullable OFString*)defaultValue;
- (nullable OFString *)stringForPath: (OFString *)path
			defaultValue: (nullable OFString *)defaultValue;

/*!
 * @brief Returns the integer for the specified path, or the default value if
 *	  the path does not exist.
 *
 * @param path The path for which the integer value should be returned
 * @param defaultValue The default value to return if the path does not exist
 * @return The integer value of the specified path
 */
- (intmax_t)integerForPath: (OFString*)path
- (intmax_t)integerForPath: (OFString *)path
	      defaultValue: (intmax_t)defaultValue;

/*!
 * @brief Returns the bool for the specified path, or the default value if the
 *	  path does not exist.
 *
 * @param path The path for which the bool value should be returned
 * @param defaultValue The default value to return if the path does not exist
 * @return The bool value of the specified path
 */
- (bool)boolForPath: (OFString*)path
- (bool)boolForPath: (OFString *)path
       defaultValue: (bool)defaultValue;

/*!
 * @brief Returns the float for the specified path, or the default value if the
 *	  path does not exist.
 *
 * @param path The path for which the float value should be returned
 * @param defaultValue The default value to return if the path does not exist
 * @return The float value of the specified path
 */
- (float)floatForPath: (OFString*)path
- (float)floatForPath: (OFString *)path
	 defaultValue: (float)defaultValue;

/*!
 * @brief Returns the double for the specified path, or the default value if
 *	  the path does not exist.
 *
 * @param path The path for which the double value should be returned
 * @param defaultValue The default value to return if the path does not exist
 * @return The double value of the specified path
 */
- (double)doubleForPath: (OFString*)path
- (double)doubleForPath: (OFString *)path
	   defaultValue: (double)defaultValue;

/*!
 * @brief Returns the array of strings for the specified path, or an empty
 *	  array if the path does not exist.
 *
 * @param path The path for which the array of strings should be returned
 * @return The array of strings of the specified path
 */
- (OFArray OF_GENERIC(OFString*)*)arrayForPath: (OFString*)path;
- (OFArray OF_GENERIC(OFString *) *)arrayForPath: (OFString *)path;

/*!
 * @brief Removes the value for the specified path.
 *
 * @param path The path for which the value should be removed
 */
- (void)removeValueForPath: (OFString*)path;
- (void)removeValueForPath: (OFString *)path;

/*!
 * @brief Saves the settings to disk.
 *
 * @warning Some backends might save the settings instantly, others might not
 *	    save them before calling this method for performance reasons. You
 *	    should always call this method after doing a bunch of changes, no
 *	    matter which backend is used!
 */
- (void)save;
@end

OF_ASSUME_NONNULL_END

Modified src/OFSettings.m from [b539c0b572] to [a8dee6588b].

27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67


68
69
70
71
72
73

74
75
76
77
78
79

80
81
82
83
84
85

86
87
88
89
90
91

92
93
94
95
96
97


98
99
100
101
102

103
104
105
106
107
108
109


110
111
112
113
114

115
116
117
118
119
120

121
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
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65


66
67
68
69
70
71
72

73
74
75
76
77
78

79
80
81
82
83
84

85
86
87
88
89
90

91
92
93
94
95


96
97
98
99
100
101

102
103
104
105
106
107


108
109
110
111
112
113

114
115
116
117
118
119

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







-
+










-
+




















-
-
+
+





-
+





-
+





-
+





-
+




-
-
+
+




-
+





-
-
+
+




-
+





-
+





-
+





-
+





-
+




-
+









{
	if (self == [OFSettings class])
		return [OFSettings_INIFile alloc];

	return [super alloc];
}

+ (instancetype)settingsWithApplicationName: (OFString*)applicationName
+ (instancetype)settingsWithApplicationName: (OFString *)applicationName
{
	return [[[self alloc]
	    initWithApplicationName: applicationName] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithApplicationName: (OFString*)applicationName
- initWithApplicationName: (OFString *)applicationName
{
	self = [super init];

	@try {
		_applicationName = [applicationName copy];
	} @catch (id e) {
		@throw e;
		[self release];
	}

	return self;
}

- (void)dealloc
{
	[_applicationName release];

	[super dealloc];
}

- (void)setString: (OFString*)string
	  forPath: (OFString*)path
- (void)setString: (OFString *)string
	  forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setInteger: (intmax_t)integer
	   forPath: (OFString*)path
	   forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setBool: (bool)bool_
	forPath: (OFString*)path
	forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setFloat: (float)float_
	 forPath: (OFString*)path
	 forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setDouble: (double)double_
	  forPath: (OFString*)path
	  forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setArray: (OFArray*)array
	 forPath: (OFString*)path
- (void)setArray: (OFArray *)array
	 forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFString*)stringForPath: (OFString*)path
- (OFString *)stringForPath: (OFString *)path
{
	return [self stringForPath: path
		      defaultValue: nil];
}

- (OFString*)stringForPath: (OFString*)path
	      defaultValue: (OFString*)defaultValue
- (OFString *)stringForPath: (OFString *)path
	       defaultValue: (OFString *)defaultValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (intmax_t)integerForPath: (OFString*)path
- (intmax_t)integerForPath: (OFString *)path
	      defaultValue: (intmax_t)defaultValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (bool)boolForPath: (OFString*)path
- (bool)boolForPath: (OFString *)path
       defaultValue: (bool)defaultValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (float)floatForPath: (OFString*)path
- (float)floatForPath: (OFString *)path
	 defaultValue: (float)defaultValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (double)doubleForPath: (OFString*)path
- (double)doubleForPath: (OFString *)path
	   defaultValue: (double)defaultValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFArray*)arrayForPath: (OFString*)path
- (OFArray *)arrayForPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)removeValueForPath: (OFString*)path
- (void)removeValueForPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)save
{
	OF_UNRECOGNIZED_SELECTOR
}
@end

Modified src/OFSettings_INIFile.m from [9b36d2589e] to [4485c04494].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







#import "OFSettings_INIFile.h"
#import "OFString.h"
#import "OFArray.h"
#import "OFINIFile.h"
#import "OFSystemInfo.h"

@implementation OFSettings_INIFile
- initWithApplicationName: (OFString*)applicationName
- initWithApplicationName: (OFString *)applicationName
{
	self = [super initWithApplicationName: applicationName];

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

49
50
51
52
53
54
55
56
57
58



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


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

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

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

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


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


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

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265

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

283
284
285
286
287
288
289
49
50
51
52
53
54
55



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


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

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

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

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


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


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

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264

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

282
283
284
285
286
287
288
289







-
-
-
+
+
+















-
-
+
+















-
+















-
+















-
+















-
+














-
-
+
+














-
-
+
+
















-
+



















-
+


















-
+


















-
+


















-
+
















-
+







{
	[_filePath release];
	[_INIFile release];

	[super dealloc];
}

- (void)OF_getCategory: (OFString**)category
		andKey: (OFString**)key
	       forPath: (OFString*)path
- (void)OF_getCategory: (OFString **)category
		andKey: (OFString **)key
	       forPath: (OFString *)path
{
	size_t pos = [path rangeOfString: @"."
				 options: OF_STRING_SEARCH_BACKWARDS].location;

	if (pos == OF_NOT_FOUND) {
		*category = @"";
		*key = path;
		return;
	}

	*category = [path substringWithRange: of_range(0, pos)];
	*key = [path substringWithRange:
	    of_range(pos + 1, [path length] - pos - 1)];
}

- (void)setString: (OFString*)string
	  forPath: (OFString*)path
- (void)setString: (OFString *)string
	  forPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	[[_INIFile categoryForName: category] setString: string
						 forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setInteger: (intmax_t)integer
	   forPath: (OFString*)path
	   forPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	[[_INIFile categoryForName: category] setInteger: integer
						  forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setBool: (bool)bool_
	forPath: (OFString*)path
	forPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	[[_INIFile categoryForName: category] setBool: bool_
					       forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setFloat: (float)float_
	 forPath: (OFString*)path
	 forPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	[[_INIFile categoryForName: category] setFloat: float_
						forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setDouble: (double)double_
	  forPath: (OFString*)path
	  forPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	[[_INIFile categoryForName: category] setDouble: double_
						 forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setArray: (OFArray*)array
	 forPath: (OFString*)path
- (void)setArray: (OFArray *)array
	 forPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	[[_INIFile categoryForName: category] setArray: array
						forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (OFString*)stringForPath: (OFString*)path
	      defaultValue: (OFString*)defaultValue
- (OFString *)stringForPath: (OFString *)path
	       defaultValue: (OFString *)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key, *ret;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	ret = [[_INIFile categoryForName: category] stringForKey: key
						    defaultValue: defaultValue];

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

- (intmax_t)integerForPath: (OFString*)path
- (intmax_t)integerForPath: (OFString *)path
	      defaultValue: (intmax_t)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;
	intmax_t ret;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	ret = [[_INIFile categoryForName: category]
	    integerForKey: key
	     defaultValue: defaultValue];

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (bool)boolForPath: (OFString*)path
- (bool)boolForPath: (OFString *)path
       defaultValue: (bool)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;
	bool ret;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	ret = [[_INIFile categoryForName: category] boolForKey: key
						  defaultValue: defaultValue];

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (float)floatForPath: (OFString*)path
- (float)floatForPath: (OFString *)path
	 defaultValue: (float)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;
	float ret;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	ret = [[_INIFile categoryForName: category] floatForKey: key
						   defaultValue: defaultValue];

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (double)doubleForPath: (OFString*)path
- (double)doubleForPath: (OFString *)path
	   defaultValue: (double)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;
	double ret;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	ret = [[_INIFile categoryForName: category] doubleForKey: key
						    defaultValue: defaultValue];

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (OFArray*)arrayForPath: (OFString*)path
- (OFArray *)arrayForPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;
	OFArray *ret;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

	ret = [[_INIFile categoryForName: category] arrayForKey: key];

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

- (void)removeValueForPath: (OFString*)path
- (void)removeValueForPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;

	[self OF_getCategory: &category
		      andKey: &key
		     forPath: path];

Modified src/OFSortedList.h from [9c95c8a311] to [8dc81e5c1a].

23
24
25
26
27
28
29
30

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

44
45
46
47
48
49
23
24
25
26
27
28
29

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

43
44
45
46
47
48
49







-
+












-
+






 *
 * @brief A class which provides easy to use sorted double-linked lists.
 *
 * @warning Because the list is sorted, all methods inserting an object at a
 *	    specific place are unavailable, even though they exist in OFList!
 */
#ifdef OF_HAVE_GENERICS
@interface OFSortedList <ObjectType>: OFList <ObjectType>
@interface OFSortedList<ObjectType>: OFList<ObjectType>
#else
# ifndef DOXYGEN
#  define ObjectType id
# endif
@interface OFSortedList: OFList
#endif
/*!
 * @brief Inserts the object to the list while keeping the list sorted.
 *
 * @param object The object to insert
 * @return The list object for the object just added
 */
- (of_list_object_t*)insertObject: (ObjectType <OFComparing>)object;
- (of_list_object_t *)insertObject: (ObjectType <OFComparing>)object;
@end
#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN)
# undef ObjectType
#endif

OF_ASSUME_NONNULL_END

Modified src/OFSortedList.m from [dace74b703] to [5ca59cf2d2].

15
16
17
18
19
20
21
22






23
24
25
26
27


28
29
30
31
32
33


34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31

32
33
34
35
36
37


38
39
40
41
42
43







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







-
+
+
+
+
+
+




-
+
+




-
-
+
+




-
-
-
-
-
-
-
+












 */

#include "config.h"

#import "OFSortedList.h"

@implementation OFSortedList
- (of_list_object_t*)appendObject: (id)object
- (of_list_object_t *)appendObject: (id)object
{
	OF_UNRECOGNIZED_SELECTOR
}

- (of_list_object_t *)prependObject: (id)object
{
	OF_UNRECOGNIZED_SELECTOR
}

- (of_list_object_t*)prependObject: (id)object
- (of_list_object_t *)insertObject: (id)object
		  beforeListObject: (of_list_object_t *)listObject
{
	OF_UNRECOGNIZED_SELECTOR
}

- (of_list_object_t*)insertObject: (id)object
		 beforeListObject: (of_list_object_t*)listObject
- (of_list_object_t *)insertObject: (id)object
		   afterListObject: (of_list_object_t *)listObject
{
	OF_UNRECOGNIZED_SELECTOR
}

- (of_list_object_t*)insertObject: (id)object
		  afterListObject: (of_list_object_t*)listObject
{
	OF_UNRECOGNIZED_SELECTOR
}

- (of_list_object_t*)insertObject: (id <OFComparing>)object
- (of_list_object_t *)insertObject: (id <OFComparing>)object
{
	of_list_object_t *iter;

	for (iter = _lastListObject; iter != NULL; iter = iter->previous) {
		if ([object compare: iter->object] != OF_ORDERED_ASCENDING)
			return [super insertObject: object
				   afterListObject: iter];
	}

	return [super prependObject: object];
}
@end

Modified src/OFStdIOStream.h from [529708bf9f] to [a701818e89].

68
69
70
71
72
73
74
75

76
77
78
79
80
68
69
70
71
72
73
74

75
76
77
78
79
80







-
+





extern OFStdIOStream *_Nullable of_stdout;

/*!
 * @brief The standard error as an OFStream.
 */
extern OFStdIOStream *_Nullable of_stderr;

extern void of_log(OFConstantString*, ...);
extern void of_log(OFConstantString *, ...);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFStdIOStream.m from [ed72626b27] to [5324fa0d07].

108
109
110
111
112
113
114
115

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

115
116
117
118
119
120
121
122







-
+







{
	if (_fd == -1)
		return true;

	return _atEndOfStream;
}

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

	if (_fd == -1 || _atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];
138
139
140
141
142
143
144
145

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

145
146
147
148
149
150
151
152







-
+








	if (ret == 0)
		_atEndOfStream = true;

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
- (void)lowlevelWriteBuffer: (const void *)buffer
		     length: (size_t)length
{
	if (_fd == -1 || _atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length];

#ifndef OF_WINDOWS

Modified src/OFStdIOStream_Win32Console.m from [7220727656] to [7f3fc13f71].

96
97
98
99
100
101
102
103

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

103
104
105
106
107
108
109
110







-
+







		[self release];
		@throw e;
	}

	return self;
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer_
- (size_t)lowlevelReadIntoBuffer: (void *)buffer_
			  length: (size_t)length
{
	void *pool = objc_autoreleasePoolPush();
	char *buffer = buffer_;
	of_char16_t *UTF16;
	size_t j = 0;

212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226







-
+







	}

	objc_autoreleasePoolPop(pool);

	return j;
}

- (void)lowlevelWriteBuffer: (const void*)buffer_
- (void)lowlevelWriteBuffer: (const void *)buffer_
		     length: (size_t)length
{
	const char *buffer = buffer_;
	of_char16_t *tmp;
	size_t i = 0, j = 0;

	if (length > SIZE_MAX / 2)

Modified src/OFStream.h from [a07511dad6] to [dce22ba2cb].

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







-
+

















-
+







 * check @ref isAtEndOfStream.
 *
 * @param buffer The buffer into which the data is read
 * @param length The length of the data that should be read at most.
 *		 The buffer *must* be *at least* this big!
 * @return The number of bytes read
 */
- (size_t)readIntoBuffer: (void*)buffer
- (size_t)readIntoBuffer: (void *)buffer
		  length: (size_t)length;

/*!
 * @brief Reads exactly the specified length bytes from the stream into a
 *	  buffer.
 *
 * Unlike @ref readIntoBuffer:length:, this method does not return when less
 * than the specified length has been read - instead, it waits until it got
 * exactly the specified length.
 *
 * @warning Only call this when you know that specified amount of data is
 *	    available! Otherwise you will get an exception!
 *
 * @param buffer The buffer into which the data is read
 * @param length The length of the data that should be read.
 *		 The buffer *must* be *at least* this big!
 */
 - (void)readIntoBuffer: (void*)buffer
 - (void)readIntoBuffer: (void *)buffer
	    exactLength: (size_t)length;

#ifdef OF_HAVE_SOCKETS
/*!
 * @brief Asynchronously reads *at most* size bytes from the stream into a
 *	  buffer.
 *
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181







-
+







 *		 data has been received. If you want the next method in the
 *		 queue to handle the data received next, you need to return
 *		 false from the method.
 * @param selector The selector to call on the target. The signature must be
 *		   `bool (OFStream *stream, void *buffer, size_t length,
 *		   OFException *exception)`.
 */
- (void)asyncReadIntoBuffer: (void*)buffer
- (void)asyncReadIntoBuffer: (void *)buffer
		     length: (size_t)length
		     target: (id)target
		   selector: (SEL)selector;

/*!
 * @brief Asynchronously reads exactly the specified length bytes from the
 *	  stream into a buffer.
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211







-
+







 *		 data has been received. If you want the next method in the
 *		 queue to handle the data received next, you need to return
 *		 false from the method.
 * @param selector The selector to call on the target. The signature must be
 *		   `bool (OFStream *stream, void *buffer, size_t size,
 *		   OFException *exception)`.
 */
- (void)asyncReadIntoBuffer: (void*)buffer
- (void)asyncReadIntoBuffer: (void *)buffer
		exactLength: (size_t)length
		     target: (id)target
		   selector: (SEL)selector;

# ifdef OF_HAVE_BLOCKS
/*!
 * @brief Asynchronously reads *at most* ref size bytes from the stream into a
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240







-
+







 *		 The buffer *must* be *at least* this big!
 * @param block The block to call when the data has been received.
 *		If the block returns true, it will be called again with the same
 *		buffer and maximum length when more data has been received. If
 *		you want the next block in the queue to handle the data
 *		received next, you need to return false from the block.
 */
- (void)asyncReadIntoBuffer: (void*)buffer
- (void)asyncReadIntoBuffer: (void *)buffer
		     length: (size_t)length
		      block: (of_stream_async_read_block_t)block;

/*!
 * @brief Asynchronously reads exactly the specified length bytes from the
 *	  stream into a buffer.
 *
251
252
253
254
255
256
257
258

259
260
261
262
263
264
265
251
252
253
254
255
256
257

258
259
260
261
262
263
264
265







-
+







 *		 The buffer *must* be *at least* this big!
 * @param block The block to call when the data has been received.
 *		If the block returns true, it will be called again with the same
 *		buffer and exact length when more data has been received. If
 *		you want the next block in the queue to handle the data
 *		received next, you need to return false from the block.
 */
 - (void)asyncReadIntoBuffer: (void*)buffer
 - (void)asyncReadIntoBuffer: (void *)buffer
		 exactLength: (size_t)length
		       block: (of_stream_async_read_block_t)block;
# endif
#endif

/*!
 * @brief Reads a uint8_t from the stream.
329
330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

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

397
398
399
400
401
402
403
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403







-
+














-
+














-
+














-
+














-
+







 *	    Otherwise you will get an exception!
 *
 * @param buffer A buffer of sufficient size to store the specified number of
 *		 uint16_ts
 * @param count The number of uint16_ts to read
 * @return The number of bytes read
 */
- (size_t)readBigEndianInt16sIntoBuffer: (uint16_t*)buffer
- (size_t)readBigEndianInt16sIntoBuffer: (uint16_t *)buffer
				  count: (size_t)count;

/*!
 * @brief Reads the specified number of uint32_ts from the stream which are
 *	  encoded in big endian.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param buffer A buffer of sufficient size to store the specified number of
 *		 uint32_ts
 * @param count The number of uint32_ts to read
 * @return The number of bytes read
 */
- (size_t)readBigEndianInt32sIntoBuffer: (uint32_t*)buffer
- (size_t)readBigEndianInt32sIntoBuffer: (uint32_t *)buffer
				  count: (size_t)count;

/*!
 * @brief Reads the specified number of uint64_ts from the stream which are
 *	  encoded in big endian.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param buffer A buffer of sufficient size to store the specified number of
 *		 uint64_ts
 * @param count The number of uint64_ts to read
 * @return The number of bytes read
 */
- (size_t)readBigEndianInt64sIntoBuffer: (uint64_t*)buffer
- (size_t)readBigEndianInt64sIntoBuffer: (uint64_t *)buffer
				  count: (size_t)count;

/*!
 * @brief Reads the specified number of floats from the stream which are encoded
 *	  in big endian.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param buffer A buffer of sufficient size to store the specified number of
 *		 floats
 * @param count The number of floats to read
 * @return The number of bytes read
 */
- (size_t)readBigEndianFloatsIntoBuffer: (float*)buffer
- (size_t)readBigEndianFloatsIntoBuffer: (float *)buffer
				  count: (size_t)count;

/*!
 * @brief Reads the specified number of doubles from the stream which are
 *	  encoded in big endian.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param buffer A buffer of sufficient size to store the specified number of
 *		 doubles
 * @param count The number of doubles to read
 * @return The number of bytes read
 */
- (size_t)readBigEndianDoublesIntoBuffer: (double*)buffer
- (size_t)readBigEndianDoublesIntoBuffer: (double *)buffer
				   count: (size_t)count;

/*!
 * @brief Reads a uint16_t from the stream which is encoded in little endian.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469
470
471
472
473
474
475
476

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

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

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529
530
531
532
533
534

535
536
537
538
539
540
541
542
543
544
545
546
547
548


549
550
551
552
553
554
555
556

557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572

573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590


591
592
593
594
595
596
597
598

599
600
601
602
603
604
605
606
607
608

609
610
611
612
613
614
615
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468
469
470
471
472
473
474
475

476
477
478
479
480
481
482
483
484
485
486
487
488
489
490

491
492
493
494
495
496
497
498
499
500
501
502
503
504
505

506
507
508
509
510
511
512
513
514
515
516
517
518
519
520

521
522
523
524
525
526
527
528
529
530
531
532
533

534
535
536
537
538
539
540
541
542
543
544
545
546


547
548
549
550
551
552
553
554
555

556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571

572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588


589
590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607

608
609
610
611
612
613
614
615







-
+














-
+














-
+














-
+














-
+












-
+












-
-
+
+







-
+















-
+
















-
-
+
+







-
+









-
+







 *	    Otherwise you will get an exception!
 *
 * @param buffer A buffer of sufficient size to store the specified number of
 *		 uint16_ts
 * @param count The number of uint16_ts to read
 * @return The number of bytes read
 */
- (size_t)readLittleEndianInt16sIntoBuffer: (uint16_t*)buffer
- (size_t)readLittleEndianInt16sIntoBuffer: (uint16_t *)buffer
				     count: (size_t)count;

/*!
 * @brief Reads the specified number of uint32_ts from the stream which are
 *	  encoded in little endian.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param buffer A buffer of sufficient size to store the specified number of
 *		 uint32_ts
 * @param count The number of uint32_ts to read
 * @return The number of bytes read
 */
- (size_t)readLittleEndianInt32sIntoBuffer: (uint32_t*)buffer
- (size_t)readLittleEndianInt32sIntoBuffer: (uint32_t *)buffer
				     count: (size_t)count;

/*!
 * @brief Reads the specified number of uint64_ts from the stream which are
 *	  encoded in little endian.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param buffer A buffer of sufficient size to store the specified number of
 *		 uint64_ts
 * @param count The number of uint64_ts to read
 * @return The number of bytes read
 */
- (size_t)readLittleEndianInt64sIntoBuffer: (uint64_t*)buffer
- (size_t)readLittleEndianInt64sIntoBuffer: (uint64_t *)buffer
				     count: (size_t)count;

/*!
 * @brief Reads the specified number of floats from the stream which are
 *	  encoded in little endian.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param buffer A buffer of sufficient size to store the specified number of
 *		 floats
 * @param count The number of floats to read
 * @return The number of bytes read
 */
- (size_t)readLittleEndianFloatsIntoBuffer: (float*)buffer
- (size_t)readLittleEndianFloatsIntoBuffer: (float *)buffer
				     count: (size_t)count;

/*!
 * @brief Reads the specified number of doubles from the stream which are
 *	  encoded in little endian.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param buffer A buffer of sufficient size to store the specified number of
 *		 doubles
 * @param count The number of doubles to read
 * @return The number of bytes read
 */
- (size_t)readLittleEndianDoublesIntoBuffer: (double*)buffer
- (size_t)readLittleEndianDoublesIntoBuffer: (double *)buffer
				      count: (size_t)count;

/*!
 * @brief Reads the specified number of items with an item size of 1 from the
 *	  stream and returns them in an OFDataArray.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param count The number of items to read
 * @return An OFDataArray with count items.
 */
- (OFDataArray*)readDataArrayWithCount: (size_t)count;
- (OFDataArray *)readDataArrayWithCount: (size_t)count;

/*!
 * @brief Reads the specified number of items with the specified item size from
 *	  the stream and returns them in an OFDataArray.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param itemSize The size of each item
 * @param count The number of items to read
 * @return An OFDataArray with count items.
 */
- (OFDataArray*)readDataArrayWithItemSize: (size_t)itemSize
				    count: (size_t)count;
- (OFDataArray *)readDataArrayWithItemSize: (size_t)itemSize
				     count: (size_t)count;

/*!
 * @brief Returns an OFDataArray with all the remaining data of the stream.
 *
 * @return An OFDataArray with an item size of 1 with all the data of the
 *	   stream until the end of the stream is reached.
 */
- (OFDataArray*)readDataArrayTillEndOfStream;
- (OFDataArray *)readDataArrayTillEndOfStream;

/*!
 * @brief Reads a string with the specified length from the stream.
 *
 * If `\0` appears in the stream, the string will be truncated at the `\0` and
 * the rest of the bytes of the string will be lost. This way, reading from the
 * stream will not break because of a `\0` because the specified number of
 * bytes is still being read and only the string gets truncated.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param length The length (in bytes) of the string to read from the stream
 * @return A string with the specified length
 */
- (OFString*)readStringWithLength: (size_t)length;
- (OFString *)readStringWithLength: (size_t)length;

/*!
 * @brief Reads a string with the specified encoding and length from the stream.
 *
 * If a `\0` appears in the stream, the string will be truncated at the `\0`
 * and the rest of the bytes of the string will be lost. This way, reading from
 * the stream will not break because of a `\0` because the specified number of
 * bytes is still being read and only the string gets truncated.
 *
 * @warning Only call this when you know that enough data is available!
 *	    Otherwise you will get an exception!
 *
 * @param encoding The encoding of the string to read from the stream
 * @param length The length (in bytes) of the string to read from the stream
 * @return A string with the specified length
 */
- (OFString*)readStringWithLength: (size_t)length
			 encoding: (of_string_encoding_t)encoding;
- (OFString *)readStringWithLength: (size_t)length
			  encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Reads until a newline, `\0` or end of stream occurs.
 *
 * @return The line that was read, autoreleased, or `nil` if the end of the
 *	   stream has been reached.
 */
- (nullable OFString*)readLine;
- (nullable OFString *)readLine;

/*!
 * @brief Reads with the specified encoding until a newline, `\0` or end of
 *	  stream occurs.
 *
 * @param encoding The encoding used by the stream
 * @return The line that was read, autoreleased, or `nil` if the end of the
 *	   stream has been reached.
 */
- (nullable OFString*)readLineWithEncoding: (of_string_encoding_t)encoding;
- (nullable OFString *)readLineWithEncoding: (of_string_encoding_t)encoding;

#ifdef OF_HAVE_SOCKETS
/*!
 * @brief Asynchronously reads until a newline, `\0`, end of stream or an
 *	  exception occurs.
 *
 * @note The stream must implement @ref fileDescriptorForReading and return a
686
687
688
689
690
691
692
693

694
695
696
697
698
699
700
701
702
703
704

705
706
707
708
709
710
711
712
713
714

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


727
728
729
730
731
732
733
734
735
736
737

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


751
752
753
754
755
756
757
686
687
688
689
690
691
692

693
694
695
696
697
698
699
700
701
702
703

704
705
706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
721
722
723
724


725
726
727
728
729
730
731
732
733
734
735
736

737
738
739
740
741
742
743
744
745
746
747
748


749
750
751
752
753
754
755
756
757







-
+










-
+









-
+










-
-
+
+










-
+











-
-
+
+







/*!
 * @brief Tries to read a line from the stream (see @ref readLine) and returns
 *	  `nil` if no complete line has been received yet.
 *
 * @return The line that was read, autoreleased, or `nil` if the line is not
 *	   complete yet
 */
- (nullable OFString*)tryReadLine;
- (nullable OFString *)tryReadLine;

/*!
 * @brief Tries to read a line from the stream with the specified encoding (see
 *	  @ref readLineWithEncoding:) and returns `nil` if no complete line has
 *	  been received yet.
 *
 * @param encoding The encoding used by the stream
 * @return The line that was read, autoreleased, or `nil` if the line is not
 *	   complete yet
 */
- (nullable OFString*)tryReadLineWithEncoding: (of_string_encoding_t)encoding;
- (nullable OFString *)tryReadLineWithEncoding: (of_string_encoding_t)encoding;

/*!
 * @brief Reads until the specified string or `\0` is found or the end of
 *	  stream occurs.
 *
 * @param delimiter The delimiter
 * @return The line that was read, autoreleased, or `nil` if the end of the
 *	   stream has been reached.
 */
- (nullable OFString*)readTillDelimiter: (OFString*)delimiter;
- (nullable OFString *)readTillDelimiter: (OFString *)delimiter;

/*!
 * @brief Reads until the specified string or `\0` is found or the end of
 *	  stream occurs.
 *
 * @param delimiter The delimiter
 * @param encoding The encoding used by the stream
 * @return The line that was read, autoreleased, or `nil` if the end of the
 *	   stream has been reached.
 */
- (nullable OFString*)readTillDelimiter: (OFString*)delimiter
			       encoding: (of_string_encoding_t)encoding;
- (nullable OFString *)readTillDelimiter: (OFString *)delimiter
				encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Tries to reads until the specified string or `\0` is found or the end
 *	  of stream (see @ref readTillDelimiter:) and returns `nil` if not
 *	  enough data has been received yet.
 *
 * @param delimiter The delimiter
 * @return The line that was read, autoreleased, or `nil` if the end of the
 *	   stream has been reached.
 */
- (nullable OFString*)tryReadTillDelimiter: (OFString*)delimiter;
- (nullable OFString *)tryReadTillDelimiter: (OFString *)delimiter;

/*!
 * @brief Tries to read until the specified string or `\0` is found or the end
 *	  of stream occurs (see @ref readTillDelimiter:encoding:) and returns
 *	  `nil` if not enough data has been received yet.
 *
 * @param delimiter The delimiter
 * @param encoding The encoding used by the stream
 * @return The line that was read, autoreleased, or `nil` if the end of the
 *	   stream has been reached.
 */
- (nullable OFString*)tryReadTillDelimiter: (OFString*)delimiter
				  encoding: (of_string_encoding_t)encoding;
- (nullable OFString *)tryReadTillDelimiter: (OFString *)delimiter
				   encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Returns a boolean whether writes are buffered.
 *
 * @return A boolean whether writes are buffered
 */
- (bool)isWriteBuffered;
770
771
772
773
774
775
776
777

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

777
778
779
780
781
782
783
784







-
+








/*!
 * @brief Writes from a buffer into the stream.
 *
 * @param buffer The buffer from which the data is written to the stream
 * @param length The length of the data that should be written
 */
- (void)writeBuffer: (const void*)buffer
- (void)writeBuffer: (const void *)buffer
	     length: (size_t)length;

/*!
 * @brief Writes a uint8_t into the stream.
 *
 * @param int8 A uint8_t
 */
824
825
826
827
828
829
830
831

832
833
834
835
836
837
838
839
840
841
842
843

844
845
846
847
848
849
850
851
852
853
854
855

856
857
858
859
860
861
862
863
864
865
866
867

868
869
870
871
872
873
874
875
876
877
878
879

880
881
882
883
884
885
886
824
825
826
827
828
829
830

831
832
833
834
835
836
837
838
839
840
841
842

843
844
845
846
847
848
849
850
851
852
853
854

855
856
857
858
859
860
861
862
863
864
865
866

867
868
869
870
871
872
873
874
875
876
877
878

879
880
881
882
883
884
885
886







-
+











-
+











-
+











-
+











-
+







 *	  big endian.
 *
 * @param buffer The buffer from which the data is written to the stream after
 *		 it has been byte swapped if necessary
 * @param count The number of uint16_ts to write
 * @return The number of bytes written to the stream
 */
- (size_t)writeBigEndianInt16s: (const uint16_t*)buffer
- (size_t)writeBigEndianInt16s: (const uint16_t *)buffer
			 count: (size_t)count;

/*!
 * @brief Writes the specified number of uint32_ts into the stream, encoded in
 *	  big endian.
 *
 * @param buffer The buffer from which the data is written to the stream after
 *		 it has been byte swapped if necessary
 * @param count The number of uint32_ts to write
 * @return The number of bytes written to the stream
 */
- (size_t)writeBigEndianInt32s: (const uint32_t*)buffer
- (size_t)writeBigEndianInt32s: (const uint32_t *)buffer
			 count: (size_t)count;

/*!
 * @brief Writes the specified number of uint64_ts into the stream, encoded in
 *	  big endian.
 *
 * @param buffer The buffer from which the data is written to the stream after
 *		 it has been byte swapped if necessary
 * @param count The number of uint64_ts to write
 * @return The number of bytes written to the stream
 */
- (size_t)writeBigEndianInt64s: (const uint64_t*)buffer
- (size_t)writeBigEndianInt64s: (const uint64_t *)buffer
			 count: (size_t)count;

/*!
 * @brief Writes the specified number of floats into the stream, encoded in big
 *	  endian.
 *
 * @param buffer The buffer from which the data is written to the stream after
 *		 it has been byte swapped if necessary
 * @param count The number of floats to write
 * @return The number of bytes written to the stream
 */
- (size_t)writeBigEndianFloats: (const float*)buffer
- (size_t)writeBigEndianFloats: (const float *)buffer
			 count: (size_t)count;

/*!
 * @brief Writes the specified number of doubles into the stream, encoded in
 *	  big endian.
 *
 * @param buffer The buffer from which the data is written to the stream after
 *		 it has been byte swapped if necessary
 * @param count The number of doubles to write
 * @return The number of bytes written to the stream
 */
- (size_t)writeBigEndianDoubles: (const double*)buffer
- (size_t)writeBigEndianDoubles: (const double *)buffer
			  count: (size_t)count;

/*!
 * @brief Writes a uint16_t into the stream, encoded in little endian.
 *
 * @param int16 A uint16_t
 */
919
920
921
922
923
924
925
926

927
928
929
930
931
932
933
934
935
936
937
938

939
940
941
942
943
944
945
946
947
948
949
950

951
952
953
954
955
956
957
958
959
960
961
962

963
964
965
966
967
968
969
970
971
972
973
974

975
976
977
978
979
980
981
982
983

984
985
986
987
988
989
990
991

992
993
994
995
996
997
998
999
1000
1001

1002
1003
1004
1005
1006
1007
1008
1009
1010

1011
1012
1013
1014
1015
1016
1017
1018
1019
1020

1021
1022
1023
1024
1025
1026
1027



1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038



1039
1040
1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
919
920
921
922
923
924
925

926
927
928
929
930
931
932
933
934
935
936
937

938
939
940
941
942
943
944
945
946
947
948
949

950
951
952
953
954
955
956
957
958
959
960
961

962
963
964
965
966
967
968
969
970
971
972
973

974
975
976
977
978
979
980
981
982

983
984
985
986
987
988
989
990

991
992
993
994
995
996
997
998
999
1000

1001
1002
1003
1004
1005
1006
1007
1008
1009

1010
1011
1012
1013
1014
1015
1016
1017
1018
1019

1020
1021
1022
1023
1024
1025


1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037


1038
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050
1051
1052
1053







-
+











-
+











-
+











-
+











-
+








-
+







-
+









-
+








-
+









-
+





-
-
+
+
+




-
+




-
-
+
+
+





-
+







 *	  little endian.
 *
 * @param buffer The buffer from which the data is written to the stream after
 *		 it has been byte swapped if necessary
 * @param count The number of uint16_ts to write
 * @return The number of bytes written to the stream
 */
- (size_t)writeLittleEndianInt16s: (const uint16_t*)buffer
- (size_t)writeLittleEndianInt16s: (const uint16_t *)buffer
			    count: (size_t)count;

/*!
 * @brief Writes the specified number of uint32_ts into the stream, encoded in
 *	  little endian.
 *
 * @param count The number of uint32_ts to write
 * @param buffer The buffer from which the data is written to the stream after
 *		 it has been byte swapped if necessary
 * @return The number of bytes written to the stream
 */
- (size_t)writeLittleEndianInt32s: (const uint32_t*)buffer
- (size_t)writeLittleEndianInt32s: (const uint32_t *)buffer
			    count: (size_t)count;

/*!
 * @brief Writes the specified number of uint64_ts into the stream, encoded in
 *	  little endian.
 *
 * @param buffer The buffer from which the data is written to the stream after
 *		 it has been byte swapped if necessary
 * @param count The number of uint64_ts to write
 * @return The number of bytes written to the stream
 */
- (size_t)writeLittleEndianInt64s: (const uint64_t*)buffer
- (size_t)writeLittleEndianInt64s: (const uint64_t *)buffer
			    count: (size_t)count;

/*!
 * @brief Writes the specified number of floats into the stream, encoded in
 *	  little endian.
 *
 * @param buffer The buffer from which the data is written to the stream after
 *		 it has been byte swapped if necessary
 * @param count The number of floats to write
 * @return The number of bytes written to the stream
 */
- (size_t)writeLittleEndianFloats: (const float*)buffer
- (size_t)writeLittleEndianFloats: (const float *)buffer
			    count: (size_t)count;

/*!
 * @brief Writes the specified number of doubles into the stream, encoded in
 *	  little endian.
 *
 * @param buffer The buffer from which the data is written to the stream after
 *		 it has been byte swapped if necessary
 * @param count The number of doubles to write
 * @return The number of bytes written to the stream
 */
- (size_t)writeLittleEndianDoubles: (const double*)buffer
- (size_t)writeLittleEndianDoubles: (const double *)buffer
			     count: (size_t)count;

/*!
 * @brief Writes from an OFDataArray into the stream.
 *
 * @param dataArray The OFDataArray to write into the stream
 * @return The number of bytes written
 */
- (size_t)writeDataArray: (OFDataArray*)dataArray;
- (size_t)writeDataArray: (OFDataArray *)dataArray;

/*!
 * @brief Writes a string into the stream, without the trailing zero.
 *
 * @param string The string from which the data is written to the stream
 * @return The number of bytes written
 */
- (size_t)writeString: (OFString*)string;
- (size_t)writeString: (OFString *)string;

/*!
 * @brief Writes a string into the stream in the specified encoding, without
 *	  the trailing zero.
 *
 * @param string The string from which the data is written to the stream
 * @param encoding The encoding in which to write the string to the stream
 * @return The number of bytes written
 */
- (size_t)writeString: (OFString*)string
- (size_t)writeString: (OFString *)string
	     encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Writes a string into the stream with a trailing newline.
 *
 * @param string The string from which the data is written to the stream
 * @return The number of bytes written
 */
- (size_t)writeLine: (OFString*)string;
- (size_t)writeLine: (OFString *)string;

/*!
 * @brief Writes a string into the stream in the specified encoding with a
 *	  trailing newline.
 *
 * @param string The string from which the data is written to the stream
 * @param encoding The encoding in which to write the string to the stream
 * @return The number of bytes written
 */
- (size_t)writeLine: (OFString*)string
- (size_t)writeLine: (OFString *)string
	   encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Writes a formatted string into the stream.
 *
 * See printf for the format syntax. As an addition, %@ is available as format
 * specifier for objects, %C for of_unichar_t and %S for const of_unichar_t*.
 * See printf for the format syntax. As an addition, `%@` is available as
 * format specifier for objects, `%C` for `of_unichar_t` and `%S` for
 * `const of_unichar_t *`.
 *
 * @param format A string used as format
 * @return The number of bytes written
 */
- (size_t)writeFormat: (OFConstantString*)format, ...;
- (size_t)writeFormat: (OFConstantString *)format, ...;

/*!
 * @brief Writes a formatted string into the stream.
 *
 * See printf for the format syntax. As an addition, %@ is available as format
 * specifier for objects, %C for of_unichar_t and %S for const of_unichar_t*.
 * See printf for the format syntax. As an addition, `%@` is available as
 * format specifier for objects, `%C` for `of_unichar_t` and `%S` for
 * `const of_unichar_t *`.
 *
 * @param format A string used as format
 * @param arguments The arguments used in the format string
 * @return The number of bytes written
 */
- (size_t)writeFormat: (OFConstantString*)format
- (size_t)writeFormat: (OFConstantString *)format
	    arguments: (va_list)arguments;

/*!
 * @brief Returns whether data is present in the internal read buffer.
 *
 * @return Whether data is present in the internal read buffer
 */
1106
1107
1108
1109
1110
1111
1112
1113

1114
1115
1116
1117
1118
1119
1120
1108
1109
1110
1111
1112
1113
1114

1115
1116
1117
1118
1119
1120
1121
1122







-
+







 *
 * If the stream is seekable, a seek operation will discard any data which was
 * unread.
 *
 * @param buffer The buffer to unread
 * @param length The length of the buffer to unread
 */
- (void)unreadFromBuffer: (const void*)buffer
- (void)unreadFromBuffer: (const void *)buffer
		  length: (size_t)length;

/*!
 * @brief Closes the stream.
 *
 * @note If you override this, make sure to call `[super close]`!
 */
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
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







-
+













-
+







 * @note Override this method with your actual read implementation when
 *	 subclassing!
 *
 * @param buffer The buffer for the data to read
 * @param length The length of the buffer
 * @return The number of bytes read
 */
- (size_t)lowlevelReadIntoBuffer: (void*)buffer
- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length;

/*!
 * @brief Performs a lowlevel write.
 *
 * @warning Do not call this directly!
 *
 * @note Override this method with your actual write implementation when
 *	 subclassing!
 *
 * @param buffer The buffer with the data to write
 * @param length The length of the data to write
 */
- (void)lowlevelWriteBuffer: (const void*)buffer
- (void)lowlevelWriteBuffer: (const void *)buffer
		     length: (size_t)length;

/*!
 * @brief Returns whether the lowlevel is at the end of the stream.
 *
 * @warning Do not call this directly!
 *

Modified src/OFStream.m from [553fc37056] to [257a9e5027].

84
85
86
87
88
89
90
91

92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
84
85
86
87
88
89
90

91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123







-
+





-
+


















-
+







}

- (bool)lowlevelIsAtEndOfStream
{
	OF_UNRECOGNIZED_SELECTOR
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer
- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	OF_UNRECOGNIZED_SELECTOR
}

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

- copy
{
	return [self retain];
}

- (bool)isAtEndOfStream
{
	if (_readBufferLength > 0)
		return false;

	return [self lowlevelIsAtEndOfStream];
}

- (size_t)readIntoBuffer: (void*)buffer
- (size_t)readIntoBuffer: (void *)buffer
		  length: (size_t)length
{
	if (_readBufferLength == 0) {
		/*
		 * For small sizes, it is cheaper to read more and cache the
		 * remainder - even if that means more copying of data - than
		 * to do a syscall for every read.
167
168
169
170
171
172
173
174

175
176
177
178
179
180

181
182
183
184
185

186
187
188
189
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

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

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

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

357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394
395
396

397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416

417
418
419
420
421
422

423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438

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

455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470

471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502

503
504
505
506
507
508
509


510
511
512
513
514
515
516
167
168
169
170
171
172
173

174
175
176
177
178
179

180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219

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

236
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

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

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

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

356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421

422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437

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

454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485

486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501

502
503
504
505
506
507


508
509
510
511
512
513
514
515
516







-
+





-
+




-
+











-
+












-
+









-
+















-
+









-
+









-
+









-
+









-
+









-
+





-
+















-
+















-
+















-
+















-
+



















-
+









-
+









-
+









-
+









-
+





-
+















-
+















-
+















-
+















-
+















-
+





-
-
+
+







		_readBuffer += length;
		_readBufferLength -= length;

		return length;
	}
}

- (void)readIntoBuffer: (void*)buffer
- (void)readIntoBuffer: (void *)buffer
	   exactLength: (size_t)length
{
	size_t readLength = 0;

	while (readLength < length)
		readLength += [self readIntoBuffer: (char*)buffer + readLength
		readLength += [self readIntoBuffer: (char *)buffer + readLength
					    length: length - readLength];
}

#ifdef OF_HAVE_SOCKETS
- (void)asyncReadIntoBuffer: (void*)buffer
- (void)asyncReadIntoBuffer: (void *)buffer
		     length: (size_t)length
		     target: (id)target
		   selector: (SEL)selector
{
	[OFRunLoop OF_addAsyncReadForStream: self
				     buffer: buffer
				     length: length
				     target: target
				   selector: selector];
}

- (void)asyncReadIntoBuffer: (void*)buffer
- (void)asyncReadIntoBuffer: (void *)buffer
		exactLength: (size_t)length
		     target: (id)target
		   selector: (SEL)selector
{
	[OFRunLoop OF_addAsyncReadForStream: self
				     buffer: buffer
				exactLength: length
				     target: target
				   selector: selector];
}

# ifdef OF_HAVE_BLOCKS
- (void)asyncReadIntoBuffer: (void*)buffer
- (void)asyncReadIntoBuffer: (void *)buffer
		     length: (size_t)length
		      block: (of_stream_async_read_block_t)block
{
	[OFRunLoop OF_addAsyncReadForStream: self
				     buffer: buffer
				     length: length
				      block: block];
}

- (void)asyncReadIntoBuffer: (void*)buffer
- (void)asyncReadIntoBuffer: (void *)buffer
		exactLength: (size_t)length
		      block: (of_stream_async_read_block_t)block
{
	[OFRunLoop OF_addAsyncReadForStream: self
				     buffer: buffer
				exactLength: length
				      block: block];
}
# endif
#endif

- (uint8_t)readInt8
{
	uint8_t ret;

	[self readIntoBuffer: (char*)&ret
	[self readIntoBuffer: (char *)&ret
		 exactLength: 1];

	return ret;
}

- (uint16_t)readBigEndianInt16
{
	uint16_t ret;

	[self readIntoBuffer: (char*)&ret
	[self readIntoBuffer: (char *)&ret
		 exactLength: 2];

	return OF_BSWAP16_IF_LE(ret);
}

- (uint32_t)readBigEndianInt32
{
	uint32_t ret;

	[self readIntoBuffer: (char*)&ret
	[self readIntoBuffer: (char *)&ret
		 exactLength: 4];

	return OF_BSWAP32_IF_LE(ret);
}

- (uint64_t)readBigEndianInt64
{
	uint64_t ret;

	[self readIntoBuffer: (char*)&ret
	[self readIntoBuffer: (char *)&ret
		 exactLength: 8];

	return OF_BSWAP64_IF_LE(ret);
}

- (float)readBigEndianFloat
{
	float ret;

	[self readIntoBuffer: (char*)&ret
	[self readIntoBuffer: (char *)&ret
		 exactLength: 4];

	return OF_BSWAP_FLOAT_IF_LE(ret);
}

- (double)readBigEndianDouble
{
	double ret;

	[self readIntoBuffer: (char*)&ret
	[self readIntoBuffer: (char *)&ret
		 exactLength: 8];

	return OF_BSWAP_DOUBLE_IF_LE(ret);
}

- (size_t)readBigEndianInt16sIntoBuffer: (uint16_t*)buffer
- (size_t)readBigEndianInt16sIntoBuffer: (uint16_t *)buffer
				  count: (size_t)count
{
	size_t size = count * sizeof(uint16_t);

	[self readIntoBuffer: buffer
		 exactLength: size];

#ifndef OF_BIG_ENDIAN
	for (size_t i = 0; i < count; i++)
		buffer[i] = OF_BSWAP16(buffer[i]);
#endif

	return size;
}

- (size_t)readBigEndianInt32sIntoBuffer: (uint32_t*)buffer
- (size_t)readBigEndianInt32sIntoBuffer: (uint32_t *)buffer
				  count: (size_t)count
{
	size_t size = count * sizeof(uint32_t);

	[self readIntoBuffer: buffer
		 exactLength: size];

#ifndef OF_BIG_ENDIAN
	for (size_t i = 0; i < count; i++)
		buffer[i] = OF_BSWAP32(buffer[i]);
#endif

	return size;
}

- (size_t)readBigEndianInt64sIntoBuffer: (uint64_t*)buffer
- (size_t)readBigEndianInt64sIntoBuffer: (uint64_t *)buffer
				  count: (size_t)count
{
	size_t size = count * sizeof(uint64_t);

	[self readIntoBuffer: buffer
		 exactLength: size];

#ifndef OF_BIG_ENDIAN
	for (size_t i = 0; i < count; i++)
		buffer[i] = OF_BSWAP64(buffer[i]);
#endif

	return size;
}

- (size_t)readBigEndianFloatsIntoBuffer: (float*)buffer
- (size_t)readBigEndianFloatsIntoBuffer: (float *)buffer
				  count: (size_t)count
{
	size_t size = count * sizeof(float);

	[self readIntoBuffer: buffer
		 exactLength: size];

#ifndef OF_FLOAT_BIG_ENDIAN
	for (size_t i = 0; i < count; i++)
		buffer[i] = OF_BSWAP_FLOAT(buffer[i]);
#endif

	return size;
}

- (size_t)readBigEndianDoublesIntoBuffer: (double*)buffer
- (size_t)readBigEndianDoublesIntoBuffer: (double *)buffer
				   count: (size_t)count
{
	size_t size = count * sizeof(double);

	[self readIntoBuffer: buffer
		 exactLength: size];

#ifndef OF_FLOAT_BIG_ENDIAN
	for (size_t i = 0; i < count; i++)
		buffer[i] = OF_BSWAP_DOUBLE(buffer[i]);
#endif

	return size;
}

- (uint16_t)readLittleEndianInt16
{
	uint16_t ret;

	[self readIntoBuffer: (char*)&ret
	[self readIntoBuffer: (char *)&ret
		 exactLength: 2];

	return OF_BSWAP16_IF_BE(ret);
}

- (uint32_t)readLittleEndianInt32
{
	uint32_t ret;

	[self readIntoBuffer: (char*)&ret
	[self readIntoBuffer: (char *)&ret
		 exactLength: 4];

	return OF_BSWAP32_IF_BE(ret);
}

- (uint64_t)readLittleEndianInt64
{
	uint64_t ret;

	[self readIntoBuffer: (char*)&ret
	[self readIntoBuffer: (char *)&ret
		 exactLength: 8];

	return OF_BSWAP64_IF_BE(ret);
}

- (float)readLittleEndianFloat
{
	float ret;

	[self readIntoBuffer: (char*)&ret
	[self readIntoBuffer: (char *)&ret
		 exactLength: 4];

	return OF_BSWAP_FLOAT_IF_BE(ret);
}

- (double)readLittleEndianDouble
{
	double ret;

	[self readIntoBuffer: (char*)&ret
	[self readIntoBuffer: (char *)&ret
		 exactLength: 8];

	return OF_BSWAP_DOUBLE_IF_BE(ret);
}

- (size_t)readLittleEndianInt16sIntoBuffer: (uint16_t*)buffer
- (size_t)readLittleEndianInt16sIntoBuffer: (uint16_t *)buffer
				     count: (size_t)count
{
	size_t size = count * sizeof(uint16_t);

	[self readIntoBuffer: buffer
		 exactLength: size];

#ifdef OF_BIG_ENDIAN
	for (size_t i = 0; i < count; i++)
		buffer[i] = OF_BSWAP16(buffer[i]);
#endif

	return size;
}

- (size_t)readLittleEndianInt32sIntoBuffer: (uint32_t*)buffer
- (size_t)readLittleEndianInt32sIntoBuffer: (uint32_t *)buffer
				     count: (size_t)count
{
	size_t size = count * sizeof(uint32_t);

	[self readIntoBuffer: buffer
		 exactLength: size];

#ifdef OF_BIG_ENDIAN
	for (size_t i = 0; i < count; i++)
		buffer[i] = OF_BSWAP32(buffer[i]);
#endif

	return size;
}

- (size_t)readLittleEndianInt64sIntoBuffer: (uint64_t*)buffer
- (size_t)readLittleEndianInt64sIntoBuffer: (uint64_t *)buffer
				     count: (size_t)count
{
	size_t size = count * sizeof(uint64_t);

	[self readIntoBuffer: buffer
		 exactLength: size];

#ifdef OF_BIG_ENDIAN
	for (size_t i = 0; i < count; i++)
		buffer[i] = OF_BSWAP64(buffer[i]);
#endif

	return size;
}

- (size_t)readLittleEndianFloatsIntoBuffer: (float*)buffer
- (size_t)readLittleEndianFloatsIntoBuffer: (float *)buffer
				     count: (size_t)count
{
	size_t size = count * sizeof(float);

	[self readIntoBuffer: buffer
		 exactLength: size];

#ifdef OF_FLOAT_BIG_ENDIAN
	for (size_t i = 0; i < count; i++)
		buffer[i] = OF_BSWAP_FLOAT(buffer[i]);
#endif

	return size;
}

- (size_t)readLittleEndianDoublesIntoBuffer: (double*)buffer
- (size_t)readLittleEndianDoublesIntoBuffer: (double *)buffer
				      count: (size_t)count
{
	size_t size = count * sizeof(double);

	[self readIntoBuffer: buffer
		 exactLength: size];

#ifdef OF_FLOAT_BIG_ENDIAN
	for (size_t i = 0; i < count; i++)
		buffer[i] = OF_BSWAP_DOUBLE(buffer[i]);
#endif

	return size;
}

- (OFDataArray*)readDataArrayWithCount: (size_t)count
- (OFDataArray *)readDataArrayWithCount: (size_t)count
{
	return [self readDataArrayWithItemSize: 1
					 count: count];
}

- (OFDataArray*)readDataArrayWithItemSize: (size_t)itemSize
				    count: (size_t)count
- (OFDataArray *)readDataArrayWithItemSize: (size_t)itemSize
				     count: (size_t)count
{
	OFDataArray *dataArray;
	char *tmp;

	dataArray = [OFDataArray dataArrayWithItemSize: itemSize];
	tmp = [self allocMemoryWithSize: itemSize
				  count: count];
524
525
526
527
528
529
530
531

532
533
534
535
536
537
538
524
525
526
527
528
529
530

531
532
533
534
535
536
537
538







-
+







	} @finally {
		[self freeMemory: tmp];
	}

	return dataArray;
}

- (OFDataArray*)readDataArrayTillEndOfStream
- (OFDataArray *)readDataArrayTillEndOfStream
{
	OFDataArray *dataArray;
	size_t pageSize;
	char *buffer;

	dataArray = [OFDataArray dataArray];
	pageSize = [OFSystemInfo pageSize];
550
551
552
553
554
555
556
557

558
559
560
561
562
563
564


565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583

584
585
586
587
588
589
590
550
551
552
553
554
555
556

557
558
559
560
561
562


563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582

583
584
585
586
587
588
589
590







-
+





-
-
+
+


















-
+







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

	return dataArray;
}

- (OFString*)readStringWithLength: (size_t)length
- (OFString *)readStringWithLength: (size_t)length
{
	return [self readStringWithLength: length
				 encoding: OF_STRING_ENCODING_UTF_8];
}

- (OFString*)readStringWithLength: (size_t)length
			 encoding: (of_string_encoding_t)encoding
- (OFString *)readStringWithLength: (size_t)length
			  encoding: (of_string_encoding_t)encoding
{
	OFString *ret;
	char *buffer = [self allocMemoryWithSize: length + 1];
	buffer[length] = 0;

	@try {
		[self readIntoBuffer: buffer
			 exactLength: length];

		ret = [OFString stringWithCString: buffer
					 encoding: encoding];
	} @finally {
		[self freeMemory: buffer];
	}

	return ret;
}

- (OFString*)tryReadLineWithEncoding: (of_string_encoding_t)encoding
- (OFString *)tryReadLineWithEncoding: (of_string_encoding_t)encoding
{
	size_t pageSize, bufferLength, retLength;
	char *retCString, *buffer, *readBuffer;
	OFString *ret;

	/* Look if there's a line or \0 in our buffer */
	if (!_waitingForDelimiter && _readBuffer != NULL) {
729
730
731
732
733
734
735
736

737
738
739
740
741

742
743
744
745
746
747
748
729
730
731
732
733
734
735

736
737
738
739
740

741
742
743
744
745
746
747
748







-
+




-
+







		[self freeMemory: buffer];
	}

	_waitingForDelimiter = true;
	return nil;
}

- (OFString*)readLine
- (OFString *)readLine
{
	return [self readLineWithEncoding: OF_STRING_ENCODING_UTF_8];
}

- (OFString*)readLineWithEncoding: (of_string_encoding_t)encoding
- (OFString *)readLineWithEncoding: (of_string_encoding_t)encoding
{
	OFString *line = nil;

	while ((line = [self tryReadLineWithEncoding: encoding]) == nil)
		if ([self isAtEndOfStream])
			return nil;

781
782
783
784
785
786
787
788

789
790
791
792
793
794


795
796
797
798
799
800
801
781
782
783
784
785
786
787

788
789
790
791
792


793
794
795
796
797
798
799
800
801







-
+




-
-
+
+







	[OFRunLoop OF_addAsyncReadLineForStream: self
				       encoding: encoding
					  block: block];
}
# endif
#endif

- (OFString*)tryReadLine
- (OFString *)tryReadLine
{
	return [self tryReadLineWithEncoding: OF_STRING_ENCODING_UTF_8];
}

- (OFString*)tryReadTillDelimiter: (OFString*)delimiter
			 encoding: (of_string_encoding_t)encoding
- (OFString *)tryReadTillDelimiter: (OFString *)delimiter
			  encoding: (of_string_encoding_t)encoding
{
	const char *delimiterCString;
	size_t j, delimiterLength, pageSize, bufferLength, retLength;
	char *retCString, *buffer, *readBuffer;
	OFString *ret;

	delimiterCString = [delimiter cStringWithEncoding: encoding];
925
926
927
928
929
930
931
932

933
934
935
936
937
938
939


940
941
942
943
944
945
946
947
948
949
950
951
952

953
954
955
956
957
958
959
925
926
927
928
929
930
931

932
933
934
935
936
937


938
939
940
941
942
943
944
945
946
947
948
949
950
951

952
953
954
955
956
957
958
959







-
+





-
-
+
+












-
+







	}

	_waitingForDelimiter = true;
	return nil;
}


- (OFString*)readTillDelimiter: (OFString*)delimiter
- (OFString *)readTillDelimiter: (OFString *)delimiter
{
	return [self readTillDelimiter: delimiter
			      encoding: OF_STRING_ENCODING_UTF_8];
}

- (OFString*)readTillDelimiter: (OFString*)delimiter
		      encoding: (of_string_encoding_t)encoding
- (OFString *)readTillDelimiter: (OFString *)delimiter
		       encoding: (of_string_encoding_t)encoding
{
	OFString *ret = nil;


	while ((ret = [self tryReadTillDelimiter: delimiter
					encoding: encoding]) == nil)
		if ([self isAtEndOfStream])
			return nil;

	return ret;
}

- (OFString*)tryReadTillDelimiter: (OFString*)delimiter
- (OFString *)tryReadTillDelimiter: (OFString *)delimiter
{
	return [self tryReadTillDelimiter: delimiter
				 encoding: OF_STRING_ENCODING_UTF_8];
}

- (bool)isWriteBuffered
{
974
975
976
977
978
979
980
981

982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997

998
999
1000
1001
1002
1003
1004
1005

1006
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017
1018
1019
1020
1021

1022
1023
1024
1025
1026
1027
1028
1029

1030
1031
1032
1033
1034
1035
1036
1037

1038
1039
1040
1041

1042
1043
1044
1045
1046
1047
1048
974
975
976
977
978
979
980

981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996

997
998
999
1000
1001
1002
1003
1004

1005
1006
1007
1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
1020

1021
1022
1023
1024
1025
1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
1036

1037
1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
1048







-
+















-
+







-
+







-
+







-
+







-
+







-
+



-
+







			   length: _writeBufferLength];

	[self freeMemory: _writeBuffer];
	_writeBuffer = NULL;
	_writeBufferLength = 0;
}

- (void)writeBuffer: (const void*)buffer
- (void)writeBuffer: (const void *)buffer
	     length: (size_t)length
{
	if (!_writeBuffered)
		[self lowlevelWriteBuffer: buffer
				   length: length];
	else {
		_writeBuffer = [self resizeMemory: _writeBuffer
					     size: _writeBufferLength + length];
		memcpy(_writeBuffer + _writeBufferLength, buffer, length);
		_writeBufferLength += length;
	}
}

- (void)writeInt8: (uint8_t)int8
{
	[self writeBuffer: (char*)&int8
	[self writeBuffer: (char *)&int8
		   length: 1];
}

- (void)writeBigEndianInt16: (uint16_t)int16
{
	int16 = OF_BSWAP16_IF_LE(int16);

	[self writeBuffer: (char*)&int16
	[self writeBuffer: (char *)&int16
		   length: 2];
}

- (void)writeBigEndianInt32: (uint32_t)int32
{
	int32 = OF_BSWAP32_IF_LE(int32);

	[self writeBuffer: (char*)&int32
	[self writeBuffer: (char *)&int32
		   length: 4];
}

- (void)writeBigEndianInt64: (uint64_t)int64
{
	int64 = OF_BSWAP64_IF_LE(int64);

	[self writeBuffer: (char*)&int64
	[self writeBuffer: (char *)&int64
		   length: 8];
}

- (void)writeBigEndianFloat: (float)float_
{
	float_ = OF_BSWAP_FLOAT_IF_LE(float_);

	[self writeBuffer: (char*)&float_
	[self writeBuffer: (char *)&float_
		   length: 4];
}

- (void)writeBigEndianDouble: (double)double_
{
	double_ = OF_BSWAP_DOUBLE_IF_LE(double_);

	[self writeBuffer: (char*)&double_
	[self writeBuffer: (char *)&double_
		   length: 8];
}

- (size_t)writeBigEndianInt16s: (const uint16_t*)buffer
- (size_t)writeBigEndianInt16s: (const uint16_t *)buffer
			 count: (size_t)count
{
	size_t size = count * sizeof(uint16_t);

#ifdef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
1060
1061
1062
1063
1064
1065
1066
1067

1068
1069
1070
1071
1072
1073
1074
1060
1061
1062
1063
1064
1065
1066

1067
1068
1069
1070
1071
1072
1073
1074







-
+







		[self freeMemory: tmp];
	}
#endif

	return size;
}

- (size_t)writeBigEndianInt32s: (const uint32_t*)buffer
- (size_t)writeBigEndianInt32s: (const uint32_t *)buffer
			 count: (size_t)count
{
	size_t size = count * sizeof(uint32_t);

#ifdef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
1086
1087
1088
1089
1090
1091
1092
1093

1094
1095
1096
1097
1098
1099
1100
1086
1087
1088
1089
1090
1091
1092

1093
1094
1095
1096
1097
1098
1099
1100







-
+







		[self freeMemory: tmp];
	}
#endif

	return size;
}

- (size_t)writeBigEndianInt64s: (const uint64_t*)buffer
- (size_t)writeBigEndianInt64s: (const uint64_t *)buffer
			 count: (size_t)count
{
	size_t size = count * sizeof(uint64_t);

#ifdef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
1112
1113
1114
1115
1116
1117
1118
1119

1120
1121
1122
1123
1124
1125
1126
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1126







-
+







		[self freeMemory: tmp];
	}
#endif

	return size;
}

- (size_t)writeBigEndianFloats: (const float*)buffer
- (size_t)writeBigEndianFloats: (const float *)buffer
			 count: (size_t)count
{
	size_t size = count * sizeof(float);

#ifdef OF_FLOAT_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
1138
1139
1140
1141
1142
1143
1144
1145

1146
1147
1148
1149
1150
1151
1152
1138
1139
1140
1141
1142
1143
1144

1145
1146
1147
1148
1149
1150
1151
1152







-
+







		[self freeMemory: tmp];
	}
#endif

	return size;
}

- (size_t)writeBigEndianDoubles: (const double*)buffer
- (size_t)writeBigEndianDoubles: (const double *)buffer
			  count: (size_t)count
{
	size_t size = count * sizeof(double);

#ifdef OF_FLOAT_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
1168
1169
1170
1171
1172
1173
1174
1175

1176
1177
1178
1179
1180
1181
1182
1183

1184
1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195
1196
1197
1198
1199

1200
1201
1202
1203
1204
1205
1206
1207

1208
1209
1210
1211

1212
1213
1214
1215
1216
1217
1218
1168
1169
1170
1171
1172
1173
1174

1175
1176
1177
1178
1179
1180
1181
1182

1183
1184
1185
1186
1187
1188
1189
1190

1191
1192
1193
1194
1195
1196
1197
1198

1199
1200
1201
1202
1203
1204
1205
1206

1207
1208
1209
1210

1211
1212
1213
1214
1215
1216
1217
1218







-
+







-
+







-
+







-
+







-
+



-
+







	return size;
}

- (void)writeLittleEndianInt16: (uint16_t)int16
{
	int16 = OF_BSWAP16_IF_BE(int16);

	[self writeBuffer: (char*)&int16
	[self writeBuffer: (char *)&int16
		   length: 2];
}

- (void)writeLittleEndianInt32: (uint32_t)int32
{
	int32 = OF_BSWAP32_IF_BE(int32);

	[self writeBuffer: (char*)&int32
	[self writeBuffer: (char *)&int32
		   length: 4];
}

- (void)writeLittleEndianInt64: (uint64_t)int64
{
	int64 = OF_BSWAP64_IF_BE(int64);

	[self writeBuffer: (char*)&int64
	[self writeBuffer: (char *)&int64
		   length: 8];
}

- (void)writeLittleEndianFloat: (float)float_
{
	float_ = OF_BSWAP_FLOAT_IF_BE(float_);

	[self writeBuffer: (char*)&float_
	[self writeBuffer: (char *)&float_
		   length: 4];
}

- (void)writeLittleEndianDouble: (double)double_
{
	double_ = OF_BSWAP_DOUBLE_IF_BE(double_);

	[self writeBuffer: (char*)&double_
	[self writeBuffer: (char *)&double_
		   length: 8];
}

- (size_t)writeLittleEndianInt16s: (const uint16_t*)buffer
- (size_t)writeLittleEndianInt16s: (const uint16_t *)buffer
			    count: (size_t)count
{
	size_t size = count * sizeof(uint16_t);

#ifndef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
1230
1231
1232
1233
1234
1235
1236
1237

1238
1239
1240
1241
1242
1243
1244
1230
1231
1232
1233
1234
1235
1236

1237
1238
1239
1240
1241
1242
1243
1244







-
+







		[self freeMemory: tmp];
	}
#endif

	return size;
}

- (size_t)writeLittleEndianInt32s: (const uint32_t*)buffer
- (size_t)writeLittleEndianInt32s: (const uint32_t *)buffer
			    count: (size_t)count
{
	size_t size = count * sizeof(uint32_t);

#ifndef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
1256
1257
1258
1259
1260
1261
1262
1263

1264
1265
1266
1267
1268
1269
1270
1256
1257
1258
1259
1260
1261
1262

1263
1264
1265
1266
1267
1268
1269
1270







-
+







		[self freeMemory: tmp];
	}
#endif

	return size;
}

- (size_t)writeLittleEndianInt64s: (const uint64_t*)buffer
- (size_t)writeLittleEndianInt64s: (const uint64_t *)buffer
			    count: (size_t)count
{
	size_t size = count * sizeof(uint64_t);

#ifndef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
1282
1283
1284
1285
1286
1287
1288
1289

1290
1291
1292
1293
1294
1295
1296
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296







-
+







		[self freeMemory: tmp];
	}
#endif

	return size;
}

- (size_t)writeLittleEndianFloats: (const float*)buffer
- (size_t)writeLittleEndianFloats: (const float *)buffer
			    count: (size_t)count
{
	size_t size = count * sizeof(float);

#ifndef OF_FLOAT_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
1308
1309
1310
1311
1312
1313
1314
1315

1316
1317
1318
1319
1320
1321
1322
1308
1309
1310
1311
1312
1313
1314

1315
1316
1317
1318
1319
1320
1321
1322







-
+







		[self freeMemory: tmp];
	}
#endif

	return size;
}

- (size_t)writeLittleEndianDoubles: (const double*)buffer
- (size_t)writeLittleEndianDoubles: (const double *)buffer
			     count: (size_t)count
{
	size_t size = count * sizeof(double);

#ifndef OF_FLOAT_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
1334
1335
1336
1337
1338
1339
1340
1341

1342
1343
1344
1345
1346
1347
1348
1349
1350
1351

1352
1353
1354
1355
1356
1357

1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368

1369
1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380
1381
1334
1335
1336
1337
1338
1339
1340

1341
1342
1343
1344
1345
1346
1347
1348
1349
1350

1351
1352
1353
1354
1355
1356

1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367

1368
1369
1370
1371
1372
1373

1374
1375
1376
1377
1378
1379
1380
1381







-
+









-
+





-
+










-
+





-
+







		[self freeMemory: tmp];
	}
#endif

	return size;
}

- (size_t)writeDataArray: (OFDataArray*)dataArray
- (size_t)writeDataArray: (OFDataArray *)dataArray
{
	size_t length = [dataArray count] * [dataArray itemSize];

	[self writeBuffer: [dataArray items]
		   length: length];

	return length;
}

- (size_t)writeString: (OFString*)string
- (size_t)writeString: (OFString *)string
{
	return [self writeString: string
			encoding: OF_STRING_ENCODING_UTF_8];
}

- (size_t)writeString: (OFString*)string
- (size_t)writeString: (OFString *)string
	     encoding: (of_string_encoding_t)encoding
{
	size_t length = [string cStringLengthWithEncoding: encoding];

	[self writeBuffer: [string cStringWithEncoding: encoding]
		   length: length];

	return length;
}

- (size_t)writeLine: (OFString*)string
- (size_t)writeLine: (OFString *)string
{
	return [self writeLine: string
		      encoding: OF_STRING_ENCODING_UTF_8];
}

- (size_t)writeLine: (OFString*)string
- (size_t)writeLine: (OFString *)string
	   encoding: (of_string_encoding_t)encoding
{
	size_t stringLength = [string cStringLengthWithEncoding: encoding];
	char *buffer;

	buffer = [self allocMemoryWithSize: stringLength + 1];

1389
1390
1391
1392
1393
1394
1395
1396

1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409

1410
1411
1412
1413
1414
1415
1416
1389
1390
1391
1392
1393
1394
1395

1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408

1409
1410
1411
1412
1413
1414
1415
1416







-
+












-
+







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

	return stringLength + 1;
}

- (size_t)writeFormat: (OFConstantString*)format, ...
- (size_t)writeFormat: (OFConstantString *)format, ...
{
	va_list arguments;
	size_t ret;

	va_start(arguments, format);
	ret = [self writeFormat: format
		      arguments: arguments];
	va_end(arguments);

	return ret;
}

- (size_t)writeFormat: (OFConstantString*)format
- (size_t)writeFormat: (OFConstantString *)format
	    arguments: (va_list)arguments
{
	char *UTF8String;
	int length;

	if (format == nil)
		@throw [OFInvalidArgumentException exception];
1517
1518
1519
1520
1521
1522
1523
1524

1525
1526
1527
1528
1529
1530
1531
1517
1518
1519
1520
1521
1522
1523

1524
1525
1526
1527
1528
1529
1530
1531







-
+







#ifdef OF_HAVE_SOCKETS
- (void)cancelAsyncRequests
{
	[OFRunLoop OF_cancelAsyncRequestsForObject: self];
}
#endif

- (void)unreadFromBuffer: (const void*)buffer
- (void)unreadFromBuffer: (const void *)buffer
		  length: (size_t)length
{
	char *readBuffer;

	if (length > SIZE_MAX - _readBufferLength)
		@throw [OFOutOfRangeException exception];

Modified src/OFStreamSocket.m from [196ec0c55f] to [d2e763431e].

49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63







-
+







}

- (bool)lowlevelIsAtEndOfStream
{
	return _atEndOfStream;
}

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

	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

85
86
87
88
89
90
91
92

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

92
93
94
95
96
97
98
99







-
+








	if (ret == 0)
		_atEndOfStream = true;

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
- (void)lowlevelWriteBuffer: (const void *)buffer
		     length: (size_t)length
{
	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self

Modified src/OFString+CryptoHashing.h from [3e61516736] to [f63a3a4a9b].

28
29
30
31
32
33
34
35

36
37
38
39
40
41
42

43
44
45
46
47
48
49

50
51
52
53
54
55
56

57
58
59
60
61
62
63

64
65
66
67
68
69
70

71
72
73
74
75
76
77

78
79
80
28
29
30
31
32
33
34

35
36
37
38
39
40
41

42
43
44
45
46
47
48

49
50
51
52
53
54
55

56
57
58
59
60
61
62

63
64
65
66
67
68
69

70
71
72
73
74
75
76

77
78
79
80







-
+






-
+






-
+






-
+






-
+






-
+






-
+




@interface OFString (CryptoHashing)
/*!
 * @brief Returns the MD5 hash of the string as an autoreleased OFString.
 *
 * @return The MD5 hash of the string as an autoreleased OFString
 */
- (OFString*)MD5Hash;
- (OFString *)MD5Hash;

/*!
 * @brief Returns the RIPEMD-160 hash of the string as an autoreleased OFString.
 *
 * @return The RIPEMD-160 hash of the string as an autoreleased OFString
 */
- (OFString*)RIPEMD160Hash;
- (OFString *)RIPEMD160Hash;

/*!
 * @brief Returns the SHA-1 hash of the string as an autoreleased OFString.
 *
 * @return The SHA-1 hash of the string as an autoreleased OFString
 */
- (OFString*)SHA1Hash;
- (OFString *)SHA1Hash;

/*!
 * @brief Returns the SHA-224 hash of the string as an autoreleased OFString.
 *
 * @return The SHA-224 hash of the string as an autoreleased OFString
 */
- (OFString*)SHA224Hash;
- (OFString *)SHA224Hash;

/*!
 * @brief Returns the SHA-256 hash of the string as an autoreleased OFString.
 *
 * @return The SHA-256 hash of the string as an autoreleased OFString
 */
- (OFString*)SHA256Hash;
- (OFString *)SHA256Hash;

/*!
 * @brief Returns the SHA-384 hash of the string as an autoreleased OFString.
 *
 * @return The SHA-384 hash of the string as an autoreleased OFString
 */
- (OFString*)SHA384Hash;
- (OFString *)SHA384Hash;

/*!
 * @brief Returns the SHA-512 hash of the string as an autoreleased OFString.
 *
 * @return The SHA-512 hash of the string as an autoreleased OFString
 */
- (OFString*)SHA512Hash;
- (OFString *)SHA512Hash;
@end

OF_ASSUME_NONNULL_END

Modified src/OFString+CryptoHashing.m from [2a2048b5b4] to [78fa704049].

25
26
27
28
29
30
31
32

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

32
33
34
35
36
37
38
39







-
+







#import "OFSHA256Hash.h"
#import "OFSHA384Hash.h"
#import "OFSHA512Hash.h"

int _OFString_CryptoHashing_reference;

@implementation OFString (CryptoHashing)
- (OFString*)OF_cryptoHashWithClass: (Class <OFCryptoHash>)class
- (OFString *)OF_cryptoHashWithClass: (Class <OFCryptoHash>)class
{
	void *pool = objc_autoreleasePoolPush();
	id <OFCryptoHash> hash = [class cryptoHash];
	size_t digestSize = [class digestSize];
	const unsigned char *digest;
	char cString[digestSize * 2];

54
55
56
57
58
59
60
61

62
63
64
65
66

67
68
69
70
71

72
73
74
75
76

77
78
79
80
81

82
83
84
85
86

87
88
89
90
91

92
93
94
95
54
55
56
57
58
59
60

61
62
63
64
65

66
67
68
69
70

71
72
73
74
75

76
77
78
79
80

81
82
83
84
85

86
87
88
89
90

91
92
93
94
95







-
+




-
+




-
+




-
+




-
+




-
+




-
+




	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: digestSize * 2];
}

- (OFString*)MD5Hash
- (OFString *)MD5Hash
{
	return [self OF_cryptoHashWithClass: [OFMD5Hash class]];
}

- (OFString*)RIPEMD160Hash
- (OFString *)RIPEMD160Hash
{
	return [self OF_cryptoHashWithClass: [OFRIPEMD160Hash class]];
}

- (OFString*)SHA1Hash
- (OFString *)SHA1Hash
{
	return [self OF_cryptoHashWithClass: [OFSHA1Hash class]];
}

- (OFString*)SHA224Hash
- (OFString *)SHA224Hash
{
	return [self OF_cryptoHashWithClass: [OFSHA224Hash class]];
}

- (OFString*)SHA256Hash
- (OFString *)SHA256Hash
{
	return [self OF_cryptoHashWithClass: [OFSHA256Hash class]];
}

- (OFString*)SHA384Hash
- (OFString *)SHA384Hash
{
	return [self OF_cryptoHashWithClass: [OFSHA384Hash class]];
}

- (OFString*)SHA512Hash
- (OFString *)SHA512Hash
{
	return [self OF_cryptoHashWithClass: [OFSHA512Hash class]];
}
@end

Modified src/OFString+JSONValue.m from [0b6aa35b67] to [44a7ffa4d7].

133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147







-
+








	if (ret == 0)
		return 0xFFFF;

	return ret;
}

static inline OFString*
static inline OFString *
parseString(const char **pointer, const char *stop, size_t *line)
{
	char *buffer;
	size_t i = 0;
	char delimiter = **pointer;

	if (++(*pointer) + 1 >= stop)
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298







-
+







		}
	}

	free(buffer);
	return nil;
}

static inline OFString*
static inline OFString *
parseIdentifier(const char **pointer, const char *stop)
{
	char *buffer;
	size_t i = 0;

	if ((buffer = malloc(stop - *pointer)) == NULL)
		return nil;
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398







-
+







	/*
	 * It is never possible to end with an identifier, thus we should never
	 * reach stop.
	 */
	return nil;
}

static inline OFMutableArray*
static inline OFMutableArray *
parseArray(const char **pointer, const char *stop, size_t *line,
    size_t depth, size_t depthLimit)
{
	OFMutableArray *array = [OFMutableArray array];

	if (++(*pointer) >= stop)
		return nil;
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
441
442
443
444
445
446
447

448
449
450
451
452
453
454
455







-
+







	}

	(*pointer)++;

	return array;
}

static inline OFMutableDictionary*
static inline OFMutableDictionary *
parseDictionary(const char **pointer, const char *stop, size_t *line,
    size_t depth, size_t depthLimit)
{
	OFMutableDictionary *dictionary = [OFMutableDictionary dictionary];

	if (++(*pointer) >= stop)
		return nil;
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534







-
+







	}

	(*pointer)++;

	return dictionary;
}

static inline OFNumber*
static inline OFNumber *
parseNumber(const char **pointer, const char *stop, size_t *line)
{
	bool isHex = (*pointer + 1 < stop && (*pointer)[1] == 'x');
	bool hasDecimal = false;
	size_t i;
	OFString *string;
	OFNumber *number;

Modified src/OFString+URLEncoding.h from [37eb93561c] to [f16f9f6de1].

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







-
+









-
+






-
+




@interface OFString (URLEncoding)
/*!
 * @brief Encodes a string for use in a URL.
 *
 * @return A new autoreleased string
 */
- (OFString*)stringByURLEncoding;
- (OFString *)stringByURLEncoding;

/*!
 * @brief Encodes a string for use in a URL, but does not escape the specified
 *	  ignored characters.
 *
 * @param allowed A C string of characters that should not be escaped
 *
 * @return A new autoreleased string
 */
- (OFString*)stringByURLEncodingWithAllowedCharacters: (const char*)allowed;
- (OFString *)stringByURLEncodingWithAllowedCharacters: (const char *)allowed;

/*!
 * @brief Decodes a string used in a URL.
 *
 * @return A new autoreleased string
 */
- (OFString*)stringByURLDecoding;
- (OFString *)stringByURLDecoding;
@end

OF_ASSUME_NONNULL_END

Modified src/OFString+URLEncoding.m from [cdac934c1e] to [9ad96294d0].

24
25
26
27
28
29
30
31

32
33
34
35
36

37
38
39
40
41
42
43
24
25
26
27
28
29
30

31
32
33
34
35

36
37
38
39
40
41
42
43







-
+




-
+







#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"

/* Reference for static linking */
int _OFString_URLEncoding_reference;

@implementation OFString (URLEncoding)
- (OFString*)stringByURLEncoding
- (OFString *)stringByURLEncoding
{
	return [self stringByURLEncodingWithAllowedCharacters: "$-_.!*()"];
}

- (OFString*)stringByURLEncodingWithAllowedCharacters: (const char*)allowed
- (OFString *)stringByURLEncodingWithAllowedCharacters: (const char *)allowed
{
	void *pool = objc_autoreleasePoolPush();
	const char *string = [self UTF8String];
	char *retCString;
	size_t i;
	OFString *ret;

82
83
84
85
86
87
88
89

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

89
90
91
92
93
94
95
96







-
+







	} @finally {
		free(retCString);
	}

	return ret;
}

- (OFString*)stringByURLDecoding
- (OFString *)stringByURLDecoding
{
	void *pool = objc_autoreleasePoolPush();
	OFString *ret;
	const char *string = [self UTF8String];
	char *retCString;
	char byte = 0;
	int state = 0;

Modified src/OFString+XMLEscaping.h from [9d40a596c2] to [54cf47bc37].

28
29
30
31
32
33
34
35

36
37
38
28
29
30
31
32
33
34

35
36
37
38







-
+




@interface OFString (XMLEscaping)
/*!
 * @brief Escapes a string for use in an XML document.
 *
 * @return A new autoreleased string
 */
- (OFString*)stringByXMLEscaping;
- (OFString *)stringByXMLEscaping;
@end

OF_ASSUME_NONNULL_END

Modified src/OFString+XMLEscaping.m from [a7d3ecc291] to [64cd2d1eac].

23
24
25
26
27
28
29
30

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

30
31
32
33
34
35
36
37







-
+







#import "OFString.h"

#import "OFOutOfMemoryException.h"

int _OFString_XMLEscaping_reference;

@implementation OFString (XMLEscaping)
- (OFString*)stringByXMLEscaping
- (OFString *)stringByXMLEscaping
{
	void *pool = objc_autoreleasePoolPush();
	char *retCString;
	const char *string, *append;
	size_t length, retLength, appendLen;
	size_t j;
	OFString *ret;

Modified src/OFString+XMLUnescaping.h from [80508f23b4] to [0f77351c40].

56
57
58
59
60
61
62
63
64


65
66
67
68
69
70
71

72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
56
57
58
59
60
61
62


63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94







-
-
+
+






-
+







-
+









-
+





 * it is unknown to the callback as well, in which case an exception will be
 * thrown.
 *
 * @param string The string which contains the unknown entity
 * @param entity The name of the entity that is unknown
 * @return A substitution for the entity or `nil`
 */
-	   (OFString*)string: (OFString*)string
  containsUnknownEntityNamed: (OFString*)entity;
-	  (OFString *)string: (OFString *)string
  containsUnknownEntityNamed: (OFString *)entity;
@end

@interface OFString (XMLUnescaping)
/*!
 * @brief Unescapes XML in the string.
 */
- (OFString*)stringByXMLUnescaping;
- (OFString *)stringByXMLUnescaping;

/*!
 * @brief Unescapes XML in the string and uses the specified delegate for
 *	  unknown entities.
 *
 * @param delegate An OFXMLUnescapingDelegate as a handler for unknown entities
 */
- (OFString*)stringByXMLUnescapingWithDelegate:
- (OFString *)stringByXMLUnescapingWithDelegate:
    (nullable id <OFStringXMLUnescapingDelegate>)delegate;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Unescapes XML in the string and uses the specified block for unknown
 *	  entities.
 *
 * @param block A block which handles unknown entities
 */
- (OFString*)stringByXMLUnescapingWithBlock:
- (OFString *)stringByXMLUnescapingWithBlock:
    (of_string_xml_unescaping_block_t)block;
#endif
@end

OF_ASSUME_NONNULL_END

Modified src/OFString+XMLUnescaping.m from [743856ba0d] to [d6e6b667b8].

21
22
23
24
25
26
27
28

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

28
29
30
31
32
33
34
35







-
+







#import "OFString.h"

#import "OFInvalidFormatException.h"
#import "OFUnknownXMLEntityException.h"

int _OFString_XMLUnescaping_reference;

static OF_INLINE OFString*
static OF_INLINE OFString *
parseNumericEntity(const char *entity, size_t length)
{
	of_unichar_t c;
	size_t i;
	char buffer[5];

	if (length == 1 || *entity != '#')
69
70
71
72
73
74
75
76
77


78
79
80
81
82
83
84
69
70
71
72
73
74
75


76
77
78
79
80
81
82
83
84







-
-
+
+







		return nil;
	buffer[i] = 0;

	return [OFString stringWithUTF8String: buffer
				       length: i];
}

static OFString*
parseEntities(OFString *self, id (*lookup)(void*, OFString*, OFString*),
static OFString *
parseEntities(OFString *self, id (*lookup)(void *, OFString *, OFString *),
    void *context)
{
	OFMutableString *ret;
	void *pool;
	const char *string;
	size_t i, last, length;
	bool inEntity;
201
202
203
204
205
206
207
208

209
210
211
212
213

214
215
216
217
218
219
220

221
222
223
224
225
226
201
202
203
204
205
206
207

208
209
210
211
212

213
214
215
216
217
218
219

220
221
222
223
224
225
226







-
+




-
+






-
+






		return nil;

	return block(self, entity);
}
#endif

@implementation OFString (XMLUnescaping)
- (OFString*)stringByXMLUnescaping
- (OFString *)stringByXMLUnescaping
{
	return [self stringByXMLUnescapingWithDelegate: nil];
}

- (OFString*)stringByXMLUnescapingWithDelegate:
- (OFString *)stringByXMLUnescapingWithDelegate:
    (id <OFStringXMLUnescapingDelegate>)delegate
{
	return parseEntities(self, lookupUsingDelegate, delegate);
}

#ifdef OF_HAVE_BLOCKS
- (OFString*)stringByXMLUnescapingWithBlock:
- (OFString *)stringByXMLUnescapingWithBlock:
    (of_string_xml_unescaping_block_t)block
{
	return parseEntities(self, lookupUsingBlock, block);
}
#endif
@end

Modified src/OFString.h from [df25fe3eba] to [1f9f9bd1d3].

119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136

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

149
150
151
152
153
154
155
156
157
158

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

171
172
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219
220

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

234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261
262
263
264

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

278
279
280
281
282
283
284
285



286
287
288
289
290

291
292
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308
309
310

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

328
329
330
331
332
333
334
335
336
337

338
339
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
474
475
476

477
478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
518



519
520
521
522
523

524
525
526
527
528
529



530
531
532
533
534
535

536
537
538
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553
554
555
556

557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
582
583
584

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

600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615

616
617
618
619
620
621
622
623
624
625
626
627
628
629

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646
647
648
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135

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

148
149
150
151
152
153
154
155
156
157

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

170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218
219

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

233
234
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263

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

277
278
279
280
281
282
283


284
285
286
287
288
289
290

291
292
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308
309
310

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

328
329
330
331
332
333
334
335
336
337

338
339
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
474
475
476

477
478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517


518
519
520
521
522
523
524

525
526
527
528
529


530
531
532
533
534
535
536
537

538
539
540
541
542
543
544
545
546
547
548

549
550
551
552
553
554
555
556
557
558

559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576

577
578
579
580
581
582
583
584
585
586

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

602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617

618
619
620
621
622
623
624
625
626
627
628
629
630
631

632
633
634
635
636
637
638
639
640
641
642
643
644
645
646

647
648
649
650
651
652
653
654
655
656
657
658

659
660
661
662
663
664
665
666







-
+









-
+











-
+









-
+











-
+









-
+









-
+








-
+









-
+










-
+












-
+









-
+









-
+










-
+












-
+






-
-
+
+
+




-
+









-
+









-
+
















-
+









-
+









-
+








-
+









-
+













-
+










-
+











-
+









-
+









-
+








-
+









-
+










-
+












-
+









-
+









-
+










-
+












-
+






-
-
+
+
+




-
+




-
-
+
+
+





-
+










-
+









-
+

















-
+









-
+














-
+















-
+













-
+














-
+











-
+








/*!
 * @brief Creates a new OFString from a UTF-8 encoded C string.
 *
 * @param UTF8String A UTF-8 encoded C string to initialize the OFString with
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF8String: (const char*)UTF8String;
+ (instancetype)stringWithUTF8String: (const char *)UTF8String;

/*!
 * @brief Creates a new OFString from a UTF-8 encoded C string with the
 *	  specified length.
 *
 * @param UTF8String A UTF-8 encoded C string to initialize the OFString with
 * @param UTF8StringLength The length of the UTF-8 encoded C string
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF8String: (const char*)UTF8String
+ (instancetype)stringWithUTF8String: (const char *)UTF8String
			      length: (size_t)UTF8StringLength;

/*!
 * @brief Creates a new OFString from a UTF-8 encoded C string without copying
 *	  the string.
 *
 * @param UTF8String A UTF-8 encoded C string to initialize the OFString with
 * @param freeWhenDone Whether to free the C string when the OFString gets
 *		       deallocated
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF8StringNoCopy: (char*)UTF8String
+ (instancetype)stringWithUTF8StringNoCopy: (char *)UTF8String
			      freeWhenDone: (bool)freeWhenDone;

/*!
 * @brief Creates a new OFString from a C string with the specified encoding.
 *
 * @param cString A C string to initialize the OFString with
 * @param encoding The encoding of the C string
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithCString: (const char*)cString
+ (instancetype)stringWithCString: (const char *)cString
			 encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Creates a new OFString from a C string with the specified encoding
 *	  and length.
 *
 * @param cString A C string to initialize the OFString with
 * @param encoding The encoding of the C string
 * @param cStringLength The length of the C string
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithCString: (const char*)cString
+ (instancetype)stringWithCString: (const char *)cString
			 encoding: (of_string_encoding_t)encoding
			   length: (size_t)cStringLength;

/*!
 * @brief Creates a new OFString from another string.
 *
 * @param string A string to initialize the OFString with
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithString: (OFString*)string;
+ (instancetype)stringWithString: (OFString *)string;

/*!
 * @brief Creates a new OFString from a Unicode string with the specified
 *	  length.
 *
 * @param characters An array of Unicode characters
 * @param length The length of the Unicode character array
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithCharacters: (const of_unichar_t*)characters
+ (instancetype)stringWithCharacters: (const of_unichar_t *)characters
			      length: (size_t)length;

/*!
 * @brief Creates a new OFString from a UTF-16 encoded string.
 *
 * @param string The UTF-16 string
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF16String: (const of_char16_t*)string;
+ (instancetype)stringWithUTF16String: (const of_char16_t *)string;

/*!
 * @brief Creates a new OFString from a UTF-16 encoded string with the
 *	  specified length.
 *
 * @param string The UTF-16 string
 * @param length The length of the UTF-16 string
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF16String: (const of_char16_t*)string
+ (instancetype)stringWithUTF16String: (const of_char16_t *)string
			       length: (size_t)length;

/*!
 * @brief Creates a new OFString from a UTF-16 encoded string, assuming the
 *	  specified byte order if no byte order mark is found.
 *
 * @param string The UTF-16 string
 * @param byteOrder The byte order to assume if there is no byte order mark
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF16String: (const of_char16_t*)string
+ (instancetype)stringWithUTF16String: (const of_char16_t *)string
			    byteOrder: (of_byte_order_t)byteOrder;

/*!
 * @brief Creates a new OFString from a UTF-16 encoded string with the
 *	  specified length, assuming the specified byte order if no byte order
 *	  mark is found.
 *
 * @param string The UTF-16 string
 * @param length The length of the UTF-16 string
 * @param byteOrder The byte order to assume if there is no byte order mark
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF16String: (const of_char16_t*)string
+ (instancetype)stringWithUTF16String: (const of_char16_t *)string
			       length: (size_t)length
			    byteOrder: (of_byte_order_t)byteOrder;

/*!
 * @brief Creates a new OFString from a UTF-32 encoded string.
 *
 * @param string The UTF-32 string
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF32String: (const of_char32_t*)string;
+ (instancetype)stringWithUTF32String: (const of_char32_t *)string;

/*!
 * @brief Creates a new OFString from a UTF-32 encoded string with the
 *	  specified length.
 *
 * @param string The UTF-32 string
 * @param length The length of the UTF-32 string
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF32String: (const of_char32_t*)string
+ (instancetype)stringWithUTF32String: (const of_char32_t *)string
			       length: (size_t)length;

/*!
 * @brief Creates a new OFString from a UTF-32 encoded string, assuming the
 *	  specified byte order if no byte order mark is found.
 *
 * @param string The UTF-32 string
 * @param byteOrder The byte order to assume if there is no byte order mark
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF32String: (const of_char32_t*)string
+ (instancetype)stringWithUTF32String: (const of_char32_t *)string
			    byteOrder: (of_byte_order_t)byteOrder;

/*!
 * @brief Creates a new OFString from a UTF-32 encoded string with the
 *	  specified length, assuming the specified byte order if no byte order
 *	  mark is found.
 *
 * @param string The UTF-32 string
 * @param length The length of the UTF-32 string
 * @param byteOrder The byte order to assume if there is no byte order mark
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithUTF32String: (const of_char32_t*)string
+ (instancetype)stringWithUTF32String: (const of_char32_t *)string
			       length: (size_t)length
			    byteOrder: (of_byte_order_t)byteOrder;

/*!
 * @brief Creates a new OFString from a format string.
 *
 * See printf for the format syntax. As an addition, %@ is available as format
 * specifier for objects, %C for of_unichar_t and %S for const of_unichar_t*.
 * See printf for the format syntax. As an addition, `%@` is available as
 * format specifier for objects, `%C` for `of_unichar_t` and `%S` for
 * `const of_unichar_t *`.
 *
 * @param format A string used as format to initialize the OFString
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithFormat: (OFConstantString*)format, ...;
+ (instancetype)stringWithFormat: (OFConstantString *)format, ...;

#ifdef OF_HAVE_FILES
/*!
 * @brief Creates a new OFString with the contents of the specified UTF-8
 *	  encoded file.
 *
 * @param path The path to the file
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithContentsOfFile: (OFString*)path;
+ (instancetype)stringWithContentsOfFile: (OFString *)path;

/*!
 * @brief Creates a new OFString with the contents of the specified file in the
 *	  specified encoding.
 *
 * @param path The path to the file
 * @param encoding The encoding of the file
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithContentsOfFile: (OFString*)path
+ (instancetype)stringWithContentsOfFile: (OFString *)path
				encoding: (of_string_encoding_t)encoding;
#endif

#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS)
/*!
 * @brief Creates a new OFString with the contents of the specified URL.
 *
 * If the URL's scheme is file, it tries UTF-8 encoding.
 *
 * If the URL's scheme is http(s), it tries to detect the encoding from the HTTP
 * headers. If it could not detect the encoding using the HTTP headers, it tries
 * UTF-8.
 *
 * @param URL The URL to the contents for the string
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithContentsOfURL: (OFURL*)URL;
+ (instancetype)stringWithContentsOfURL: (OFURL *)URL;

/*!
 * @brief Creates a new OFString with the contents of the specified URL in the
 *	  specified encoding.
 *
 * @param URL The URL to the contents for the string
 * @param encoding The encoding to assume
 * @return A new autoreleased OFString
 */
+ (instancetype)stringWithContentsOfURL: (OFURL*)URL
+ (instancetype)stringWithContentsOfURL: (OFURL *)URL
			       encoding: (of_string_encoding_t)encoding;
#endif

/*!
 * @brief Creates a path from the specified path components.
 *
 * @param components An array of components for the path
 * @return A new autoreleased OFString
 */
+ (OFString*)pathWithComponents: (OFArray OF_GENERIC(OFString*)*)components;
+ (OFString *)pathWithComponents: (OFArray OF_GENERIC(OFString *) *)components;

/*!
 * @brief Initializes an already allocated OFString from a UTF-8 encoded C
 *	  string.
 *
 * @param UTF8String A UTF-8 encoded C string to initialize the OFString with
 * @return An initialized OFString
 */
- initWithUTF8String: (const char*)UTF8String;
- initWithUTF8String: (const char *)UTF8String;

/*!
 * @brief Initializes an already allocated OFString from a UTF-8 encoded C
 *	  string with the specified length.
 *
 * @param UTF8String A UTF-8 encoded C string to initialize the OFString with
 * @param UTF8StringLength The length of the UTF-8 encoded C string
 * @return An initialized OFString
 */
- initWithUTF8String: (const char*)UTF8String
- initWithUTF8String: (const char *)UTF8String
	      length: (size_t)UTF8StringLength;

/*!
 * @brief Initializes an already allocated OFString from an UTF-8 encoded C
 *	  string without copying it, if possible.
 *
 * @note Mutable versions always create a copy!
 *
 * @param UTF8String A UTF-8 encoded C string to initialize the OFString with
 * @param freeWhenDone Whether to free the C string when it is not needed
 *		       anymore
 * @return An initialized OFString
 */
- initWithUTF8StringNoCopy: (char*)UTF8String
- initWithUTF8StringNoCopy: (char *)UTF8String
	      freeWhenDone: (bool)freeWhenDone;

/*!
 * @brief Initializes an already allocated OFString from a C string with the
 *	  specified encoding.
 *
 * @param cString A C string to initialize the OFString with
 * @param encoding The encoding of the C string
 * @return An initialized OFString
 */
- initWithCString: (const char*)cString
- initWithCString: (const char *)cString
	 encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Initializes an already allocated OFString from a C string with the
 *	  specified encoding and length.
 *
 * @param cString A C string to initialize the OFString with
 * @param encoding The encoding of the C string
 * @param cStringLength The length of the C string
 * @return An initialized OFString
 */
- initWithCString: (const char*)cString
- initWithCString: (const char *)cString
	 encoding: (of_string_encoding_t)encoding
	   length: (size_t)cStringLength;

/*!
 * @brief Initializes an already allocated OFString with another string.
 *
 * @param string A string to initialize the OFString with
 * @return An initialized OFString
 */
- initWithString: (OFString*)string;
- initWithString: (OFString *)string;

/*!
 * @brief Initializes an already allocated OFString with a Unicode string with
 *	  the specified length.
 *
 * @param characters An array of Unicode characters
 * @param length The length of the Unicode character array
 * @return An initialized OFString
 */
- initWithCharacters: (const of_unichar_t*)characters
- initWithCharacters: (const of_unichar_t *)characters
	      length: (size_t)length;

/*!
 * @brief Initializes an already allocated OFString with a UTF-16 string.
 *
 * @param string The UTF-16 string
 * @return An initialized OFString
 */
- initWithUTF16String: (const of_char16_t*)string;
- initWithUTF16String: (const of_char16_t *)string;

/*!
 * @brief Initializes an already allocated OFString with a UTF-16 string with
 *	  the specified length.
 *
 * @param string The UTF-16 string
 * @param length The length of the UTF-16 string
 * @return An initialized OFString
 */
- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	       length: (size_t)length;

/*!
 * @brief Initializes an already allocated OFString with a UTF-16 string,
 *	  assuming the specified byte order if no byte order mark is found.
 *
 * @param string The UTF-16 string
 * @param byteOrder The byte order to assume if there is no byte order mark
 * @return An initialized OFString
 */
- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	    byteOrder: (of_byte_order_t)byteOrder;

/*!
 * @brief Initializes an already allocated OFString with a UTF-16 string with
 *	  the specified length, assuming the specified byte order if no byte
 *	  order mark is found.
 *
 * @param string The UTF-16 string
 * @param length The length of the UTF-16 string
 * @param byteOrder The byte order to assume if there is no byte order mark
 * @return An initialized OFString
 */
- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder;

/*!
 * @brief Initializes an already allocated OFString with a UTF-32 string.
 *
 * @param string The UTF-32 string
 * @return An initialized OFString
 */
- initWithUTF32String: (const of_char32_t*)string;
- initWithUTF32String: (const of_char32_t *)string;

/*!
 * @brief Initializes an already allocated OFString with a UTF-32 string with
 *	  the specified length
 *
 * @param string The UTF-32 string
 * @param length The length of the UTF-32 string
 * @return An initialized OFString
 */
- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	       length: (size_t)length;

/*!
 * @brief Initializes an already allocated OFString with a UTF-32 string,
 *	  assuming the specified byte order if no byte order mark is found.
 *
 * @param string The UTF-32 string
 * @param byteOrder The byte order to assume if there is no byte order mark
 * @return An initialized OFString
 */
- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	    byteOrder: (of_byte_order_t)byteOrder;

/*!
 * @brief Initializes an already allocated OFString with a UTF-32 string with
 *	  the specified length, assuming the specified byte order if no byte
 *	  order mark is found.
 *
 * @param string The UTF-32 string
 * @param length The length of the UTF-32 string
 * @param byteOrder The byte order to assume if there is no byte order mark
 * @return An initialized OFString
 */
- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder;

/*!
 * @brief Initializes an already allocated OFString with a format string.
 *
 * See printf for the format syntax. As an addition, %@ is available as format
 * specifier for objects, %C for of_unichar_t and %S for const of_unichar_t*.
 * See printf for the format syntax. As an addition, `%@` is available as
 * format specifier for objects, `%C` for `of_unichar_t` and `%S` for
 * `const of_unichar_t *`.
 *
 * @param format A string used as format to initialize the OFString
 * @return An initialized OFString
 */
- initWithFormat: (OFConstantString*)format, ...;
- initWithFormat: (OFConstantString *)format, ...;

/*!
 * @brief Initializes an already allocated OFString with a format string.
 *
 * See printf for the format syntax. As an addition, %@ is available as format
 * specifier for objects, %C for of_unichar_t and %S for const of_unichar_t*.
 * See printf for the format syntax. As an addition, `%@` is available as
 * format specifier for objects, `%C` for `of_unichar_t` and `%S` for
 * `const of_unichar_t *`.
 *
 * @param format A string used as format to initialize the OFString
 * @param arguments The arguments used in the format string
 * @return An initialized OFString
 */
- initWithFormat: (OFConstantString*)format
- initWithFormat: (OFConstantString *)format
       arguments: (va_list)arguments;

#ifdef OF_HAVE_FILES
/*!
 * @brief Initializes an already allocated OFString with the contents of the
 *	  specified file in the specified encoding.
 *
 * @param path The path to the file
 * @return An initialized OFString
 */
- initWithContentsOfFile: (OFString*)path;
- initWithContentsOfFile: (OFString *)path;

/*!
 * @brief Initializes an already allocated OFString with the contents of the
 *	  specified file in the specified encoding.
 *
 * @param path The path to the file
 * @param encoding The encoding of the file
 * @return An initialized OFString
 */
- initWithContentsOfFile: (OFString*)path
- initWithContentsOfFile: (OFString *)path
		encoding: (of_string_encoding_t)encoding;
#endif

#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS)
/*!
 * @brief Initializes an already allocated OFString with the contents of the
 *	  specified URL.
 *
 * If the URL's scheme is file, it tries UTF-8 encoding.
 *
 * If the URL's scheme is http(s), it tries to detect the encoding from the HTTP
 * headers. If it could not detect the encoding using the HTTP headers, it tries
 * UTF-8.
 *
 * @param URL The URL to the contents for the string
 * @return An initialized OFString
 */
- initWithContentsOfURL: (OFURL*)URL;
- initWithContentsOfURL: (OFURL *)URL;

/*!
 * @brief Initializes an already allocated OFString with the contents of the
 *	  specified URL in the specified encoding.
 *
 * @param URL The URL to the contents for the string
 * @param encoding The encoding to assume
 * @return An initialized OFString
 */
- initWithContentsOfURL: (OFURL*)URL
- initWithContentsOfURL: (OFURL *)URL
	       encoding: (of_string_encoding_t)encoding;
#endif

/*!
 * @brief Writes the OFString into the specified C string with the specified
 *	  encoding.
 *
 * @param cString The C string to write into
 * @param maxLength The maximum number of bytes to write into the C string,
 *		    including the terminating zero
 * @param encoding The encoding to use for writing into the C string
 * @return The number of bytes written into the C string, without the
 *	   terminating zero
 */
- (size_t)getCString: (char*)cString
- (size_t)getCString: (char *)cString
	   maxLength: (size_t)maxLength
	    encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Writes the OFString into the specified C string with the specified
 *	  encoding, replacing characters that cannot be represented in the
 *	  specified encoding with a question mark.
 *
 * @param cString The C string to write into
 * @param maxLength The maximum number of bytes to write into the C string,
 *		    including the terminating zero
 * @param encoding The encoding to use for writing into the C string
 * @return The number of bytes written into the C string, without the
 *	   terminating zero
 */
- (size_t)getLossyCString: (char*)cString
- (size_t)getLossyCString: (char *)cString
		maxLength: (size_t)maxLength
		 encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Returns the OFString as a C string in the specified encoding.
 *
 * The result is valid until the autorelease pool is released. If you want to
 * use the result outside the scope of the current autorelease pool, you have to
 * copy it.
 *
 * @param encoding The encoding for the C string
 * @return The OFString as a C string in the specified encoding
 */
- (const char*)cStringWithEncoding: (of_string_encoding_t)encoding
- (const char *)cStringWithEncoding: (of_string_encoding_t)encoding
    OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns the OFString as a C string in the specified encoding,
 *	  replacing characters that cannot be represented in the specified
 *	  encoding with a question mark.
 *
 * The result is valid until the autorelease pool is released. If you want to
 * use the result outside the scope of the current autorelease pool, you have to
 * copy it.
 *
 * @param encoding The encoding for the C string
 * @return The OFString as a C string in the specified encoding
 */
- (const char*)lossyCStringWithEncoding: (of_string_encoding_t)encoding
- (const char *)lossyCStringWithEncoding: (of_string_encoding_t)encoding
    OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns the OFString as a UTF-8 encoded C string.
 *
 * The result is valid until the autorelease pool is released. If you want to
 * use the result outside the scope of the current autorelease pool, you have to
 * copy it.
 *
 * @return The OFString as a UTF-8 encoded C string
 */
- (const char*)UTF8String OF_RETURNS_INNER_POINTER;
- (const char *)UTF8String OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns the length of the string in Unicode characters.
 *
 * @return The length of the string in Unicode characters
 */
- (size_t)length;
681
682
683
684
685
686
687
688

689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705

706
707
708
709
710
711
712
713
714
715

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

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

746
747
748
749
750
751
752
753
754
755

756
757
758
759
760
761
762
763

764
765
766
767
768
769
770
771

772
773
774
775
776
777
778
779

780
781
782
783
784
785
786
787
788
789


790
791
792
793
794
795
796
797

798
799
800
801
802
803
804
805

806
807
808
809
810
811
812
813
814
815
816


817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833




834
835
836
837
838
839
840

841
842
843
844
845
846
847

848
849
850
851
852
853
854
855
856
857
858

859
860
861
862
863
864
865

866
867
868
869
870
871
872

873
874
875
876
877
878
879
880

881
882
883
884
885
886
887
888

889
890
891
892
893
894
895
896

897
898
899
900
901
902
903
904
905


906
907
908
909
910
911
912
913
914
915
916
917
918
919


920
921
922
923
924
925
926
927

928
929
930
931
932
933
934

935
936
937
938
939
940
941

942
943
944
945
946
947
948

949
950
951
952
953
954
955

956
957
958
959
960
961
962

963
964
965
966
967
968
969
970
971
972

973
974
975
976
977
978
979
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707

708
709
710
711
712
713
714
715
716
717

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

732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747

748
749
750
751
752
753
754
755
756
757

758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
773

774
775
776
777
778
779
780
781

782
783
784
785
786
787
788
789
790


791
792
793
794
795
796
797
798
799

800
801
802
803
804
805
806
807

808
809
810
811
812
813
814
815
816
817


818
819
820
821
822
823
824
825
826
827
828
829
830
831
832




833
834
835
836
837
838
839
840
841
842

843
844
845
846
847
848
849

850
851
852
853
854
855
856
857
858
859
860

861
862
863
864
865
866
867

868
869
870
871
872
873
874

875
876
877
878
879
880
881
882

883
884
885
886
887
888
889
890

891
892
893
894
895
896
897
898

899
900
901
902
903
904
905
906


907
908
909
910
911
912
913
914
915
916
917
918
919
920


921
922
923
924
925
926
927
928
929

930
931
932
933
934
935
936

937
938
939
940
941
942
943

944
945
946
947
948
949
950

951
952
953
954
955
956
957

958
959
960
961
962
963
964

965
966
967
968
969
970
971
972
973
974

975
976
977
978
979
980
981
982







-
+
















-
+









-
+













-
+















-
+









-
+







-
+







-
+







-
+








-
-
+
+







-
+







-
+









-
-
+
+













-
-
-
-
+
+
+
+






-
+






-
+










-
+






-
+






-
+







-
+







-
+







-
+







-
-
+
+












-
-
+
+







-
+






-
+






-
+






-
+






-
+






-
+









-
+







/*!
 * @brief Compares the OFString to another OFString without caring about the
 *	  case.
 *
 * @param otherString A string to compare with
 * @return An of_comparison_result_t
 */
- (of_comparison_result_t)caseInsensitiveCompare: (OFString*)otherString;
- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)otherString;

/*!
 * @brief Returns the Unicode character at the specified index.
 *
 * @param index The index of the Unicode character to return
 * @return The Unicode character at the specified index
 */
- (of_unichar_t)characterAtIndex: (size_t)index;

/*!
 * @brief Copies the Unicode characters in the specified range to the specified
 *	  buffer.
 *
 * @param buffer The buffer to store the Unicode characters
 * @param range The range of the Unicode characters to copy
 */
- (void)getCharacters: (of_unichar_t*)buffer
- (void)getCharacters: (of_unichar_t *)buffer
	      inRange: (of_range_t)range;

/*!
 * @brief Returns the range of the first occurrence of the string.
 *
 * @param string The string to search
 * @return The range of the first occurrence of the string or a range with
 *	   `OF_NOT_FOUND` as start position if it was not found
 */
- (of_range_t)rangeOfString: (OFString*)string;
- (of_range_t)rangeOfString: (OFString *)string;

/*!
 * @brief Returns the range of the string.
 *
 * @param string The string to search
 * @param options Options modifying search behaviour.@n
 *		  Possible values are:
 *		  Value                        | Description
 *		  -----------------------------|-------------------------------
 *		  `OF_STRING_SEARCH_BACKWARDS` | Search backwards in the string
 * @return The range of the first occurrence of the string or a range with
 *	   `OF_NOT_FOUND` as start position if it was not found
 */
- (of_range_t)rangeOfString: (OFString*)string
- (of_range_t)rangeOfString: (OFString *)string
		    options: (int)options;

/*!
 * @brief Returns the range of the string in the specified range.
 *
 * @param string The string to search
 * @param options Options modifying search behaviour.@n
 *		  Possible values are:
 *		  Value                        | Description
 *		  -----------------------------|-------------------------------
 *		  `OF_STRING_SEARCH_BACKWARDS` | Search backwards in the string
 * @param range The range in which to search
 * @return The range of the first occurrence of the string or a range with
 *	   `OF_NOT_FOUND` as start position if it was not found
 */
- (of_range_t)rangeOfString: (OFString*)string
- (of_range_t)rangeOfString: (OFString *)string
		    options: (int)options
		      range: (of_range_t)range;

/*!
 * @brief Returns whether the string contains the specified string.
 *
 * @param string The string to search
 * @return Whether the string contains the specified string
 */
- (bool)containsString: (OFString*)string;
- (bool)containsString: (OFString *)string;

/*!
 * @brief Creates a substring with the specified range.
 *
 * @param range The range of the substring
 * @return The substring as a new autoreleased OFString
 */
- (OFString*)substringWithRange: (of_range_t)range;
- (OFString *)substringWithRange: (of_range_t)range;

/*!
 * @brief Creates a new string by appending another string.
 *
 * @param string The string to append
 * @return A new, autoreleased OFString with the specified string appended
 */
- (OFString*)stringByAppendingString: (OFString*)string;
- (OFString *)stringByAppendingString: (OFString *)string;

/*!
 * @brief Creates a new string by appending the specified format.
 *
 * @param format A format string which generates the string to append
 * @return A new, autoreleased OFString with the specified format appended
 */
- (OFString*)stringByAppendingFormat: (OFConstantString*)format, ...;
- (OFString *)stringByAppendingFormat: (OFConstantString *)format, ...;

/*!
 * @brief Creates a new string by appending the specified format.
 *
 * @param format A format string which generates the string to append
 * @param arguments The arguments used in the format string
 * @return A new, autoreleased OFString with the specified format appended
 */
- (OFString*)stringByAppendingFormat: (OFConstantString*)format
			   arguments: (va_list)arguments;
- (OFString *)stringByAppendingFormat: (OFConstantString *)format
			    arguments: (va_list)arguments;

/*!
 * @brief Creates a new string by appending a path component.
 *
 * @param component The path component to append
 * @return A new, autoreleased OFString with the path component appended
 */
- (OFString*)stringByAppendingPathComponent: (OFString*)component;
- (OFString *)stringByAppendingPathComponent: (OFString *)component;

/*!
 * @brief Creates a new string by prepending another string.
 *
 * @param string The string to prepend
 * @return A new autoreleased OFString with the specified string prepended
 */
- (OFString*)stringByPrependingString: (OFString*)string;
- (OFString *)stringByPrependingString: (OFString *)string;

/*!
 * @brief Creates a new string by replacing the occurrences of the specified
 *	  string with the specified replacement.
 *
 * @param string The string to replace
 * @param replacement The string with which it should be replaced
 * @return A new string with the occurrences of the specified string replaced
 */
- (OFString*)stringByReplacingOccurrencesOfString: (OFString*)string
				       withString: (OFString*)replacement;
- (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string
					withString: (OFString *)replacement;

/*!
 * @brief Creates a new string by replacing the occurrences of the specified
 *	  string in the specified range with the specified replacement.
 *
 * @param string The string to replace
 * @param replacement The string with which it should be replaced
 * @param options Options modifying search behaviour.
 *		  Possible values are:
 *		    * None yet
 * @param range The range in which to replace the string
 * @return A new string with the occurrences of the specified string replaced
 */
- (OFString*)stringByReplacingOccurrencesOfString: (OFString*)string
				       withString: (OFString*)replacement
					  options: (int)options
					    range: (of_range_t)range;
- (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string
					withString: (OFString *)replacement
					   options: (int)options
					     range: (of_range_t)range;

/*!
 * @brief Returns the string in uppercase.
 *
 * @return The string in uppercase
 */
- (OFString*)uppercaseString;
- (OFString *)uppercaseString;

/*!
 * @brief Returns the string in lowercase.
 *
 * @return The string in lowercase
 */
- (OFString*)lowercaseString;
- (OFString *)lowercaseString;

/*!
 * @brief Returns the string capitalized.
 *
 * @note This only considers spaces, tabs and newlines to be word delimiters!
 *	 Also note that this might change in the future to all word delimiters
 *	 specified by Unicode!
 *
 * @return The capitalized string
 */
- (OFString*)capitalizedString;
- (OFString *)capitalizedString;

/*!
 * @brief Creates a new string by deleting leading whitespaces.
 *
 * @return A new autoreleased OFString with leading whitespaces deleted
 */
- (OFString*)stringByDeletingLeadingWhitespaces;
- (OFString *)stringByDeletingLeadingWhitespaces;

/*!
 * @brief Creates a new string by deleting trailing whitespaces.
 *
 * @return A new autoreleased OFString with trailing whitespaces deleted
 */
- (OFString*)stringByDeletingTrailingWhitespaces;
- (OFString *)stringByDeletingTrailingWhitespaces;

/*!
 * @brief Creates a new string by deleting leading and trailing whitespaces.
 *
 * @return A new autoreleased OFString with leading and trailing whitespaces
 *	   deleted
 */
- (OFString*)stringByDeletingEnclosingWhitespaces;
- (OFString *)stringByDeletingEnclosingWhitespaces;

/*!
 * @brief Checks whether the string has the specified prefix.
 *
 * @param prefix The prefix to check for
 * @return A boolean whether the string has the specified prefix
 */
- (bool)hasPrefix: (OFString*)prefix;
- (bool)hasPrefix: (OFString *)prefix;

/*!
 * @brief Checks whether the string has the specified suffix.
 *
 * @param suffix The suffix to check for
 * @return A boolean whether the string has the specified suffix
 */
- (bool)hasSuffix: (OFString*)suffix;
- (bool)hasSuffix: (OFString *)suffix;

/*!
 * @brief Separates an OFString into an OFArray of OFStrings.
 *
 * @param delimiter The delimiter for separating
 * @return An autoreleased OFArray with the separated string
 */
- (OFArray OF_GENERIC(OFString*)*)componentsSeparatedByString:
    (OFString*)delimiter;
- (OFArray OF_GENERIC(OFString *) *)componentsSeparatedByString:
    (OFString *)delimiter;

/*!
 * @brief Separates an OFString into an OFArray of OFStrings.
 *
 * @param delimiter The delimiter for separating
 * @param options Options according to which the string should be separated.@n
 *		  Possible values are:
 *		  Value                  | Description
 *		  -----------------------|----------------------
 * 		  `OF_STRING_SKIP_EMPTY` | Skip empty components
 * @return An autoreleased OFArray with the separated string
 */
- (OFArray OF_GENERIC(OFString*)*)
    componentsSeparatedByString: (OFString*)delimiter
- (OFArray OF_GENERIC(OFString *) *)
    componentsSeparatedByString: (OFString *)delimiter
			options: (int)options;

/*!
 * @brief Returns the components of the path.
 *
 * @return The components of the path
 */
- (OFArray OF_GENERIC(OFString*)*)pathComponents;
- (OFArray OF_GENERIC(OFString *) *)pathComponents;

/*!
 * @brief Returns the last component of the path.
 *
 * @return The last component of the path
 */
- (OFString*)lastPathComponent;
- (OFString *)lastPathComponent;

/*!
 * @brief Returns the file extension of the path.
 *
 * @return The file extension of the path
 */
- (OFString*)pathExtension;
- (OFString *)pathExtension;

/*!
 * @brief Returns the directory name of the path.
 *
 * @return The directory name of the path
 */
- (OFString*)stringByDeletingLastPathComponent;
- (OFString *)stringByDeletingLastPathComponent;

/*!
 * @brief Returns a new string with the file extension of the path removed.
 *
 * @return A new string with the file extension of the path removed
 */
- (OFString*)stringByDeletingPathExtension;
- (OFString *)stringByDeletingPathExtension;

/*!
 * @brief Returns the path with relative sub paths resolved.
 *
 * @return The path with relative sub paths resolved
 */
- (OFString*)stringByStandardizingPath;
- (OFString *)stringByStandardizingPath;

/*!
 * @brief Returns the URL path with relative sub paths resolved.
 *
 * This works similar to @ref stringByStandardizingPath, but is intended for
 * standardization of paths that are part of a URL.
 *
 * @return The URL path with relative sub paths resolved
 */
- (OFString*)stringByStandardizingURLPath;
- (OFString *)stringByStandardizingURLPath;

/*!
 * @brief Returns the decimal value of the string as an `intmax_t`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
1041
1042
1043
1044
1045
1046
1047
1048

1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059

1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102

1103
1104
1105
1106
1107
1108
1109
1110
1111

1112
1113
1114
1115
1116
1117
1118
1119
1120

1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141





1142
1143
1144
1145
1146
1147
1148
1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061

1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073

1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092

1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104

1105
1106
1107
1108
1109
1110
1111
1112
1113

1114
1115
1116
1117
1118
1119
1120
1121
1122

1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139





1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151







-
+










-
+











-
+


















-
+











-
+








-
+








-
+
















-
-
-
-
-
+
+
+
+
+







 *
 * The result is valid until the autorelease pool is released. If you want to
 * use the result outside the scope of the current autorelease pool, you have to
 * copy it.
 *
 * @return The string as an array of Unicode characters
 */
- (const of_unichar_t*)characters OF_RETURNS_INNER_POINTER;
- (const of_unichar_t *)characters OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns the string in UTF-16 encoding with native byte order.
 *
 * The result is valid until the autorelease pool is released. If you want to
 * use the result outside the scope of the current autorelease pool, you have to
 * copy it.
 *
 * @return The string in UTF-16 encoding with native byte order
 */
- (const of_char16_t*)UTF16String OF_RETURNS_INNER_POINTER;
- (const of_char16_t *)UTF16String OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns the string in UTF-16 encoding with the specified byte order.
 *
 * The result is valid until the autorelease pool is released. If you want to
 * use the result outside the scope of the current autorelease pool, you have to
 * copy it.
 *
 * @param byteOrder The byte order for the UTF-16 encoding
 * @return The string in UTF-16 encoding with the specified byte order
 */
- (const of_char16_t*)UTF16StringWithByteOrder: (of_byte_order_t)byteOrder
- (const of_char16_t *)UTF16StringWithByteOrder: (of_byte_order_t)byteOrder
    OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns the length of the string in UTF-16 characters.
 *
 * @return The length of string in UTF-16 characters
 */
- (size_t)UTF16StringLength;

/*!
 * @brief Returns the string in UTF-32 encoding with native byte order.
 *
 * The result is valid until the autorelease pool is released. If you want to
 * use the result outside the scope of the current autorelease pool, you have to
 * copy it.
 *
 * @return The string in UTF-32 encoding with native byte order
 */
- (const of_char32_t*)UTF32String OF_RETURNS_INNER_POINTER;
- (const of_char32_t *)UTF32String OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns the string in UTF-32 encoding with the specified byte order.
 *
 * The result is valid until the autorelease pool is released. If you want to
 * use the result outside the scope of the current autorelease pool, you have to
 * copy it.
 *
 * @param byteOrder The byte order for the UTF-32 encoding
 * @return The string in UTF-32 encoding with the specified byte order
 */
- (const of_char32_t*)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
- (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
    OF_RETURNS_INNER_POINTER;

#ifdef OF_HAVE_FILES
/*!
 * @brief Writes the string into the specified file using UTF-8 encoding.
 *
 * @param path The path of the file to write to
 */
- (void)writeToFile: (OFString*)path;
- (void)writeToFile: (OFString *)path;

/*!
 * @brief Writes the string into the specified file using the specified
 *	  encoding.
 *
 * @param path The path of the file to write to
 * @param encoding The encoding to use to write the string into the file
 */
- (void)writeToFile: (OFString*)path
- (void)writeToFile: (OFString *)path
	   encoding: (of_string_encoding_t)encoding;
#endif

#ifdef OF_HAVE_BLOCKS
/*!
 * Enumerates all lines in the receiver using the specified block.
 *
 * @brief block The block to call for each line
 */
- (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block;
#endif
@end

#ifdef __cplusplus
extern "C" {
#endif
extern of_string_encoding_t of_string_parse_encoding(OFString*);
extern size_t of_string_utf8_encode(of_unichar_t, char*);
extern ssize_t of_string_utf8_decode(const char*, size_t, of_unichar_t*);
extern size_t of_string_utf16_length(const of_char16_t*);
extern size_t of_string_utf32_length(const of_char32_t*);
extern of_string_encoding_t of_string_parse_encoding(OFString *);
extern size_t of_string_utf8_encode(of_unichar_t, char *);
extern ssize_t of_string_utf8_decode(const char *, size_t, of_unichar_t *);
extern size_t of_string_utf16_length(const of_char16_t *);
extern size_t of_string_utf32_length(const of_char32_t *);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

#import "OFConstantString.h"

Modified src/OFString.m from [bfc8b98fd1] to [e0471f5f58].

76
77
78
79
80
81
82
83

84
85
86
87
88
89
90




91
92
93

94
95

96
97

98
99

100
101

102
103

104
105

106
107

108
109

110
111

112
113

114
115
116
117
118
119
120
76
77
78
79
80
81
82

83
84
85
86




87
88
89
90
91
92

93
94

95
96

97
98

99
100

101
102

103
104

105
106

107
108

109
110

111
112

113
114
115
116
117
118
119
120







-
+



-
-
-
-
+
+
+
+


-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+







#endif

#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L)
static locale_t cLocale;
#endif

@interface OFString ()
- (size_t)OF_getCString: (char*)cString
- (size_t)OF_getCString: (char *)cString
	      maxLength: (size_t)maxLength
	       encoding: (of_string_encoding_t)encoding
		  lossy: (bool)lossy;
- (const char*)OF_cStringWithEncoding: (of_string_encoding_t)encoding
				lossy: (bool)lossy;
- (OFString*)OF_JSONRepresentationWithOptions: (int)options
					depth: (size_t)depth;
- (const char *)OF_cStringWithEncoding: (of_string_encoding_t)encoding
				 lossy: (bool)lossy;
- (OFString *)OF_JSONRepresentationWithOptions: (int)options
					 depth: (size_t)depth;
@end

extern bool of_unicode_to_iso_8859_2(const of_unichar_t*, unsigned char*,
extern bool of_unicode_to_iso_8859_2(const of_unichar_t *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_iso_8859_3(const of_unichar_t*, unsigned char*,
extern bool of_unicode_to_iso_8859_3(const of_unichar_t *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_iso_8859_15(const of_unichar_t*, unsigned char*,
extern bool of_unicode_to_iso_8859_15(const of_unichar_t *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_windows_1251(const of_unichar_t*, unsigned char*,
extern bool of_unicode_to_windows_1251(const of_unichar_t *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_windows_1252(const of_unichar_t*, unsigned char*,
extern bool of_unicode_to_windows_1252(const of_unichar_t *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_codepage_437(const of_unichar_t*, unsigned char*,
extern bool of_unicode_to_codepage_437(const of_unichar_t *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_codepage_850(const of_unichar_t*, unsigned char*,
extern bool of_unicode_to_codepage_850(const of_unichar_t *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_codepage_858(const of_unichar_t*, unsigned char*,
extern bool of_unicode_to_codepage_858(const of_unichar_t *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_mac_roman(const of_unichar_t*, unsigned char*,
extern bool of_unicode_to_mac_roman(const of_unichar_t *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_koi8_r(const of_unichar_t*, unsigned char*,
extern bool of_unicode_to_koi8_r(const of_unichar_t *, unsigned char *,
    size_t, bool);
extern bool of_unicode_to_koi8_u(const of_unichar_t*, unsigned char*,
extern bool of_unicode_to_koi8_u(const of_unichar_t *, unsigned char *,
    size_t, bool);

/* References for static linking */
void
_references_to_categories_of_OFString(void)
{
	_OFString_CryptoHashing_reference = 1;
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227







-
+








	return 0;
}

ssize_t
of_string_utf8_decode(const char *buffer_, size_t length, of_unichar_t *ret)
{
	const uint8_t *buffer = (const uint8_t*)buffer_;
	const uint8_t *buffer = (const uint8_t *)buffer_;

	if (!(*buffer & 0x80)) {
		*ret = buffer[0];
		return 1;
	}

	if ((*buffer & 0xE0) == 0xC0) {
282
283
284
285
286
287
288
289

290
291
292
293
294
295
296
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296







-
+








	while (*string++ != 0)
		length++;

	return length;
}

static OFString*
static OFString *
standardizePath(OFArray *components, OFString *currentDirectory,
    OFString *parentDirectory, OFString *joinString)
{
	void *pool = objc_autoreleasePoolPush();
	OFMutableArray *array;
	OFString *ret;
	bool done = false, startsWithEmpty, endsWithEmpty;
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387
388
389
390
391
392
393

394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446
447
448

449
450
451
452
453
454
455

456
457
458
459
460

461
462
463
464
465
466
467

468
469
470
471
472
473
474

475
476
477
478
479
480
481
482
483

484
485
486
487
488

489
490
491
492
493
494
495

496
497
498
499
500
501
502

503
504
505
506
507
508
509
510
511

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

525
526
527
528
529
530
531
532

533
534
535
536
537

538
539
540
541
542
543
544
545
546

547
548
549
550
551

552
553
554
555
556
557
558
559

560
561
562
563
564
565
566
357
358
359
360
361
362
363

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

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

393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421

422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442

443
444
445
446
447

448
449
450
451
452
453
454

455
456
457
458
459

460
461
462
463
464
465
466

467
468
469
470
471
472
473

474
475
476
477
478
479
480
481
482

483
484
485
486
487

488
489
490
491
492
493
494

495
496
497
498
499
500
501

502
503
504
505
506
507
508
509
510

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

524
525
526
527
528
529
530
531

532
533
534
535
536

537
538
539
540
541
542
543
544
545

546
547
548
549
550

551
552
553
554
555
556
557
558

559
560
561
562
563
564
565
566







-
+














-
+













-
+







-
+




















-
+




















-
+




-
+






-
+




-
+






-
+






-
+








-
+




-
+






-
+






-
+








-
+












-
+







-
+




-
+








-
+




-
+







-
+








@implementation OFString_placeholder
- init
{
	return (id)[[OFString_UTF8 alloc] init];
}

- initWithUTF8String: (const char*)UTF8String
- initWithUTF8String: (const char *)UTF8String
{
	id string;
	size_t length;
	void *storage;

	length = strlen(UTF8String);
	string = of_alloc_object([OFString_UTF8 class],
	    length + 1, 1, &storage);

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

- initWithUTF8String: (const char*)UTF8String
- initWithUTF8String: (const char *)UTF8String
	      length: (size_t)UTF8StringLength
{
	id string;
	void *storage;

	string = of_alloc_object([OFString_UTF8 class],
	    UTF8StringLength + 1, 1, &storage);

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

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

- initWithCString: (const char*)cString
- initWithCString: (const char *)cString
	 encoding: (of_string_encoding_t)encoding
{
	if (encoding == OF_STRING_ENCODING_UTF_8) {
		id string;
		size_t length;
		void *storage;

		length = strlen(cString);
		string = of_alloc_object([OFString_UTF8 class],
		    length + 1, 1, &storage);

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

	return (id)[[OFString_UTF8 alloc] initWithCString: cString
						 encoding: encoding];
}

- initWithCString: (const char*)cString
- initWithCString: (const char *)cString
	 encoding: (of_string_encoding_t)encoding
	   length: (size_t)cStringLength
{
	if (encoding == OF_STRING_ENCODING_UTF_8) {
		id string;
		void *storage;

		string = of_alloc_object([OFString_UTF8 class],
		    cStringLength + 1, 1, &storage);

		return (id)[string OF_initWithUTF8String: cString
						  length: cStringLength
						 storage: storage];
	}

	return (id)[[OFString_UTF8 alloc] initWithCString: cString
						 encoding: encoding
						   length: cStringLength];
}

- initWithString: (OFString*)string
- initWithString: (OFString *)string
{
	return (id)[[OFString_UTF8 alloc] initWithString: string];
}

- initWithCharacters: (const of_unichar_t*)string
- initWithCharacters: (const of_unichar_t *)string
	      length: (size_t)length
{
	return (id)[[OFString_UTF8 alloc] initWithCharacters: string
						      length: length];
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
{
	return (id)[[OFString_UTF8 alloc] initWithUTF16String: string];
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	       length: (size_t)length
{
	return (id)[[OFString_UTF8 alloc] initWithUTF16String: string
						       length: length];
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	    byteOrder: (of_byte_order_t)byteOrder
{
	return (id)[[OFString_UTF8 alloc] initWithUTF16String: string
						    byteOrder: byteOrder];
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	return (id)[[OFString_UTF8 alloc] initWithUTF16String: string
						       length: length
						    byteOrder: byteOrder];
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
{
	return (id)[[OFString_UTF8 alloc] initWithUTF32String: string];
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	       length: (size_t)length
{
	return (id)[[OFString_UTF8 alloc] initWithUTF32String: string
						       length: length];
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	    byteOrder: (of_byte_order_t)byteOrder
{
	return (id)[[OFString_UTF8 alloc] initWithUTF32String: string
						    byteOrder: byteOrder];
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	return (id)[[OFString_UTF8 alloc] initWithUTF32String: string
						       length: length
						    byteOrder: byteOrder];
}

- initWithFormat: (OFConstantString*)format, ...
- initWithFormat: (OFConstantString *)format, ...
{
	id ret;
	va_list arguments;

	va_start(arguments, format);
	ret = [[OFString_UTF8 alloc] initWithFormat: format
					  arguments: arguments];
	va_end(arguments);

	return ret;
}

- initWithFormat: (OFConstantString*)format
- initWithFormat: (OFConstantString *)format
       arguments: (va_list)arguments
{
	return (id)[[OFString_UTF8 alloc] initWithFormat: format
					       arguments: arguments];
}

#ifdef OF_HAVE_FILES
- initWithContentsOfFile: (OFString*)path
- initWithContentsOfFile: (OFString *)path
{
	return (id)[[OFString_UTF8 alloc] initWithContentsOfFile: path];
}

- initWithContentsOfFile: (OFString*)path
- initWithContentsOfFile: (OFString *)path
		encoding: (of_string_encoding_t)encoding
{
	return (id)[[OFString_UTF8 alloc] initWithContentsOfFile: path
							encoding: encoding];
}
#endif

#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS)
- initWithContentsOfURL: (OFURL*)URL
- initWithContentsOfURL: (OFURL *)URL
{
	return (id)[[OFString_UTF8 alloc] initWithContentsOfURL: URL];
}

- initWithContentsOfURL: (OFURL*)URL
- initWithContentsOfURL: (OFURL *)URL
	       encoding: (of_string_encoding_t)encoding
{
	return (id)[[OFString_UTF8 alloc] initWithContentsOfURL: URL
						       encoding: encoding];
}
#endif

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFString_UTF8 alloc] initWithSerialization: element];
}

- retain
{
	return self;
605
606
607
608
609
610
611
612

613
614
615
616
617

618
619
620
621
622
623
624
625

626
627
628
629
630
631
632
633

634
635
636
637
638
639
640

641
642
643
644
645
646
647
648
649

650
651
652
653
654

655
656
657
658
659
660
661

662
663
664
665
666

667
668
669
670
671
672
673

674
675
676
677
678
679
680

681
682
683
684
685
686
687
688
689

690
691
692
693
694

695
696
697
698
699
700
701

702
703
704
705
706
707
708

709
710
711
712
713
714
715
716
717

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

732
733
734
735
736

737
738
739
740
741
742
743
744
745

746
747
748
749
750

751
752
753
754
755
756
757
758

759
760
761
762
763
764
765
605
606
607
608
609
610
611

612
613
614
615
616

617
618
619
620
621
622
623
624

625
626
627
628
629
630
631
632

633
634
635
636
637
638
639

640
641
642
643
644
645
646
647
648

649
650
651
652
653

654
655
656
657
658
659
660

661
662
663
664
665

666
667
668
669
670
671
672

673
674
675
676
677
678
679

680
681
682
683
684
685
686
687
688

689
690
691
692
693

694
695
696
697
698
699
700

701
702
703
704
705
706
707

708
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
724
725
726
727
728
729
730

731
732
733
734
735

736
737
738
739
740
741
742
743
744

745
746
747
748
749

750
751
752
753
754
755
756
757

758
759
760
761
762
763
764
765







-
+




-
+







-
+







-
+






-
+








-
+




-
+






-
+




-
+






-
+






-
+








-
+




-
+






-
+






-
+








-
+













-
+




-
+








-
+




-
+







-
+







}

+ (instancetype)string
{
	return [[[self alloc] init] autorelease];
}

+ (instancetype)stringWithUTF8String: (const char*)UTF8String
+ (instancetype)stringWithUTF8String: (const char *)UTF8String
{
	return [[[self alloc] initWithUTF8String: UTF8String] autorelease];
}

+ (instancetype)stringWithUTF8String: (const char*)UTF8String
+ (instancetype)stringWithUTF8String: (const char *)UTF8String
			      length: (size_t)UTF8StringLength
{
	return [[[self alloc]
	    initWithUTF8String: UTF8String
			length: UTF8StringLength] autorelease];
}

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

+ (instancetype)stringWithCString: (const char*)cString
+ (instancetype)stringWithCString: (const char *)cString
			 encoding: (of_string_encoding_t)encoding
{
	return [[[self alloc] initWithCString: cString
				     encoding: encoding] autorelease];
}

+ (instancetype)stringWithCString: (const char*)cString
+ (instancetype)stringWithCString: (const char *)cString
			 encoding: (of_string_encoding_t)encoding
			   length: (size_t)cStringLength
{
	return [[[self alloc] initWithCString: cString
				     encoding: encoding
				       length: cStringLength] autorelease];
}

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

+ (instancetype)stringWithCharacters: (const of_unichar_t*)string
+ (instancetype)stringWithCharacters: (const of_unichar_t *)string
			      length: (size_t)length
{
	return [[[self alloc] initWithCharacters: string
					  length: length] autorelease];
}

+ (instancetype)stringWithUTF16String: (const of_char16_t*)string
+ (instancetype)stringWithUTF16String: (const of_char16_t *)string
{
	return [[[self alloc] initWithUTF16String: string] autorelease];
}

+ (instancetype)stringWithUTF16String: (const of_char16_t*)string
+ (instancetype)stringWithUTF16String: (const of_char16_t *)string
			       length: (size_t)length
{
	return [[[self alloc] initWithUTF16String: string
					   length: length] autorelease];
}

+ (instancetype)stringWithUTF16String: (const of_char16_t*)string
+ (instancetype)stringWithUTF16String: (const of_char16_t *)string
			    byteOrder: (of_byte_order_t)byteOrder
{
	return [[[self alloc] initWithUTF16String: string
					byteOrder: byteOrder] autorelease];
}

+ (instancetype)stringWithUTF16String: (const of_char16_t*)string
+ (instancetype)stringWithUTF16String: (const of_char16_t *)string
			       length: (size_t)length
			    byteOrder: (of_byte_order_t)byteOrder
{
	return [[[self alloc] initWithUTF16String: string
					   length: length
					byteOrder: byteOrder] autorelease];
}

+ (instancetype)stringWithUTF32String: (const of_char32_t*)string
+ (instancetype)stringWithUTF32String: (const of_char32_t *)string
{
	return [[[self alloc] initWithUTF32String: string] autorelease];
}

+ (instancetype)stringWithUTF32String: (const of_char32_t*)string
+ (instancetype)stringWithUTF32String: (const of_char32_t *)string
			       length: (size_t)length
{
	return [[[self alloc] initWithUTF32String: string
					   length: length] autorelease];
}

+ (instancetype)stringWithUTF32String: (const of_char32_t*)string
+ (instancetype)stringWithUTF32String: (const of_char32_t *)string
			    byteOrder: (of_byte_order_t)byteOrder
{
	return [[[self alloc] initWithUTF32String: string
					byteOrder: byteOrder] autorelease];
}

+ (instancetype)stringWithUTF32String: (const of_char32_t*)string
+ (instancetype)stringWithUTF32String: (const of_char32_t *)string
			       length: (size_t)length
			    byteOrder: (of_byte_order_t)byteOrder
{
	return [[[self alloc] initWithUTF32String: string
					   length: length
					byteOrder: byteOrder] autorelease];
}

+ (instancetype)stringWithFormat: (OFConstantString*)format, ...
+ (instancetype)stringWithFormat: (OFConstantString *)format, ...
{
	id ret;
	va_list arguments;

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

	return ret;
}

#ifdef OF_HAVE_FILES
+ (instancetype)stringWithContentsOfFile: (OFString*)path
+ (instancetype)stringWithContentsOfFile: (OFString *)path
{
	return [[[self alloc] initWithContentsOfFile: path] autorelease];
}

+ (instancetype)stringWithContentsOfFile: (OFString*)path
+ (instancetype)stringWithContentsOfFile: (OFString *)path
				encoding: (of_string_encoding_t)encoding
{
	return [[[self alloc] initWithContentsOfFile: path
					    encoding: encoding] autorelease];
}
#endif

#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS)
+ (instancetype)stringWithContentsOfURL: (OFURL*)URL
+ (instancetype)stringWithContentsOfURL: (OFURL *)URL
{
	return [[[self alloc] initWithContentsOfURL: URL] autorelease];
}

+ (instancetype)stringWithContentsOfURL: (OFURL*)URL
+ (instancetype)stringWithContentsOfURL: (OFURL *)URL
			       encoding: (of_string_encoding_t)encoding
{
	return [[[self alloc] initWithContentsOfURL: URL
					   encoding: encoding] autorelease];
}
#endif

+ (OFString*)pathWithComponents: (OFArray*)components
+ (OFString *)pathWithComponents: (OFArray *)components
{
	OFMutableString *ret = [OFMutableString string];
	bool first = true;

	for (OFString *component in components) {
		if (!first)
			[ret appendString: OF_PATH_DELIMITER_STRING];
784
785
786
787
788
789
790
791

792
793
794
795
796
797
798

799
800
801
802
803
804
805
806

807
808
809
810
811
812

813
814
815
816
817
818
819
820

821
822
823
824
825
826
827

828
829
830
831
832

833
834
835
836
837
838

839
840
841
842
843
844
845

846
847
848
849
850
851
852
853

854
855
856
857
858
859
860
861

862
863
864
865
866
867
868

869
870
871
872
873
874
875

876
877
878
879
880
881
882
883

884
885
886
887
888
889
890
891

892
893
894
895
896
897
898

899
900
901
902
903
904
905
906
907
908
909
910
911

912
913
914
915
916
917
918

919
920
921
922
923
924

925
926
927
928
929
930
931
784
785
786
787
788
789
790

791
792
793
794
795
796
797

798
799
800
801
802
803
804
805

806
807
808
809
810
811

812
813
814
815
816
817
818
819

820
821
822
823
824
825
826

827
828
829
830
831

832
833
834
835
836
837

838
839
840
841
842
843
844

845
846
847
848
849
850
851
852

853
854
855
856
857
858
859
860

861
862
863
864
865
866
867

868
869
870
871
872
873
874

875
876
877
878
879
880
881
882

883
884
885
886
887
888
889
890

891
892
893
894
895
896
897

898
899
900
901
902
903
904
905
906
907
908
909
910

911
912
913
914
915
916
917

918
919
920
921
922
923

924
925
926
927
928
929
930
931







-
+






-
+







-
+





-
+







-
+






-
+




-
+





-
+






-
+







-
+







-
+






-
+






-
+







-
+







-
+






-
+












-
+






-
+





-
+








		abort();
	}

	return [super init];
}

- initWithUTF8String: (const char*)UTF8String
- initWithUTF8String: (const char *)UTF8String
{
	return [self initWithCString: UTF8String
			    encoding: OF_STRING_ENCODING_UTF_8
			      length: strlen(UTF8String)];
}

- initWithUTF8String: (const char*)UTF8String
- initWithUTF8String: (const char *)UTF8String
	      length: (size_t)UTF8StringLength
{
	return [self initWithCString: UTF8String
			    encoding: OF_STRING_ENCODING_UTF_8
			      length: UTF8StringLength];
}

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

- initWithCString: (const char*)cString
- initWithCString: (const char *)cString
	 encoding: (of_string_encoding_t)encoding
{
	return [self initWithCString: cString
			    encoding: encoding
			      length: strlen(cString)];
}

- initWithCString: (const char*)cString
- initWithCString: (const char *)cString
	 encoding: (of_string_encoding_t)encoding
	   length: (size_t)cStringLength
{
	OF_INVALID_INIT_METHOD
}

- initWithString: (OFString*)string
- initWithString: (OFString *)string
{
	OF_INVALID_INIT_METHOD
}

- initWithCharacters: (const of_unichar_t*)string
- initWithCharacters: (const of_unichar_t *)string
	      length: (size_t)length
{
	OF_INVALID_INIT_METHOD
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
{
	return [self initWithUTF16String: string
				  length: of_string_utf16_length(string)
			       byteOrder: OF_BYTE_ORDER_NATIVE];
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	       length: (size_t)length
{
	return [self initWithUTF16String: string
				  length: length
			       byteOrder: OF_BYTE_ORDER_NATIVE];
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	    byteOrder: (of_byte_order_t)byteOrder
{
	return [self initWithUTF16String: string
				  length: of_string_utf16_length(string)
			       byteOrder: byteOrder];
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	OF_INVALID_INIT_METHOD
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
{
	return [self initWithUTF32String: string
				  length: of_string_utf32_length(string)
			       byteOrder: OF_BYTE_ORDER_NATIVE];
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	       length: (size_t)length
{
	return [self initWithUTF32String: string
				  length: length
			       byteOrder: OF_BYTE_ORDER_NATIVE];
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	    byteOrder: (of_byte_order_t)byteOrder
{
	return [self initWithUTF32String: string
				  length: of_string_utf32_length(string)
			       byteOrder: byteOrder];
}

- initWithUTF32String: (const of_char32_t*)string
- initWithUTF32String: (const of_char32_t *)string
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	OF_INVALID_INIT_METHOD
}

- initWithFormat: (OFConstantString*)format, ...
- initWithFormat: (OFConstantString *)format, ...
{
	id ret;
	va_list arguments;

	va_start(arguments, format);
	ret = [self initWithFormat: format
			 arguments: arguments];
	va_end(arguments);

	return ret;
}

- initWithFormat: (OFConstantString*)format
- initWithFormat: (OFConstantString *)format
       arguments: (va_list)arguments
{
	OF_INVALID_INIT_METHOD
}

#ifdef OF_HAVE_FILES
- initWithContentsOfFile: (OFString*)path
- initWithContentsOfFile: (OFString *)path
{
	return [self initWithContentsOfFile: path
				   encoding: OF_STRING_ENCODING_UTF_8];
}

- initWithContentsOfFile: (OFString*)path
- initWithContentsOfFile: (OFString *)path
		encoding: (of_string_encoding_t)encoding
{
	char *tmp;
	of_stat_t st;

	@try {
		OFFile *file;
965
966
967
968
969
970
971
972

973
974
975
976
977
978

979
980
981
982
983
984
985
965
966
967
968
969
970
971

972
973
974
975
976
977

978
979
980
981
982
983
984
985







-
+





-
+







	[self freeMemory: tmp];

	return self;
}
#endif

#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS)
- initWithContentsOfURL: (OFURL*)URL
- initWithContentsOfURL: (OFURL *)URL
{
	return [self initWithContentsOfURL: URL
				  encoding: OF_STRING_ENCODING_AUTODETECT];
}

- initWithContentsOfURL: (OFURL*)URL
- initWithContentsOfURL: (OFURL *)URL
	       encoding: (of_string_encoding_t)encoding
{
	void *pool;
	OFString *scheme;
# ifdef OF_HAVE_FILES
	Class c = [self class];
# endif
1017
1018
1019
1020
1021
1022
1023
1024

1025
1026
1027
1028
1029
1030
1031
1017
1018
1019
1020
1021
1022
1023

1024
1025
1026
1027
1028
1029
1030
1031







-
+








	objc_autoreleasePoolPop(pool);

	return self;
}
#endif

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	@try {
		void *pool = objc_autoreleasePoolPush();

		if (![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException exception];

1044
1045
1046
1047
1048
1049
1050
1051

1052
1053
1054
1055
1056
1057
1058
1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056
1057
1058







-
+







		[self release];
		@throw e;
	}

	return self;
}

- (size_t)OF_getCString: (char*)cString
- (size_t)OF_getCString: (char *)cString
	      maxLength: (size_t)maxLength
	       encoding: (of_string_encoding_t)encoding
		  lossy: (bool)lossy
{
	const of_unichar_t *characters = [self characters];
	size_t i, length = [self length];

1132
1133
1134
1135
1136
1137
1138
1139

1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152

1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204

1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217

1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230

1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243

1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256

1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282

1283
1284
1285
1286
1287
1288
1289
1290
1291
1292

1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303


1304
1305
1306
1307
1308
1309
1310
1132
1133
1134
1135
1136
1137
1138

1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151

1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164

1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177

1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190

1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203

1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216

1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229

1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242

1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255

1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268

1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281

1282
1283
1284
1285
1286
1287
1288
1289
1290
1291

1292
1293
1294
1295
1296
1297
1298
1299
1300
1301


1302
1303
1304
1305
1306
1307
1308
1309
1310







-
+












-
+












-
+












-
+












-
+












-
+












-
+












-
+












-
+












-
+












-
+












-
+









-
+









-
-
+
+







		return length;
#ifdef HAVE_ISO_8859_2
	case OF_STRING_ENCODING_ISO_8859_2:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_iso_8859_2(characters,
		    (unsigned char*)cString, length, lossy))
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_ISO_8859_3
	case OF_STRING_ENCODING_ISO_8859_3:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_iso_8859_3(characters,
		    (unsigned char*)cString, length, lossy))
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_ISO_8859_15
	case OF_STRING_ENCODING_ISO_8859_15:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_iso_8859_15(characters,
		    (unsigned char*)cString, length, lossy))
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_WINDOWS_1251
	case OF_STRING_ENCODING_WINDOWS_1251:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_windows_1251(characters,
		    (unsigned char*)cString, length, lossy))
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_WINDOWS_1252
	case OF_STRING_ENCODING_WINDOWS_1252:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_windows_1252(characters,
		    (unsigned char*)cString, length, lossy))
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_CODEPAGE_437
	case OF_STRING_ENCODING_CODEPAGE_437:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_codepage_437(characters,
		    (unsigned char*)cString, length, lossy))
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_CODEPAGE_850
	case OF_STRING_ENCODING_CODEPAGE_850:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_codepage_850(characters,
		    (unsigned char*)cString, length, lossy))
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_CODEPAGE_858
	case OF_STRING_ENCODING_CODEPAGE_858:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_codepage_858(characters,
		    (unsigned char*)cString, length, lossy))
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_MAC_ROMAN
	case OF_STRING_ENCODING_MAC_ROMAN:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_mac_roman(characters,
		    (unsigned char*)cString, length, lossy))
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_KOI8_R
	case OF_STRING_ENCODING_KOI8_R:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_koi8_r(characters,
		    (unsigned char*)cString, length, lossy))
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
#ifdef HAVE_KOI8_U
	case OF_STRING_ENCODING_KOI8_U:
		if (length + 1 > maxLength)
			@throw [OFOutOfRangeException exception];

		if (!of_unicode_to_koi8_u(characters,
		    (unsigned char*)cString, length, lossy))
		    (unsigned char *)cString, length, lossy))
			@throw [OFInvalidEncodingException exception];

		cString[length] = '\0';

		return length;
#endif
	default:
		@throw [OFNotImplementedException exceptionWithSelector: _cmd
								 object: self];
	}
}

- (size_t)getCString: (char*)cString
- (size_t)getCString: (char *)cString
	   maxLength: (size_t)maxLength
	    encoding: (of_string_encoding_t)encoding
{
	return [self OF_getCString: cString
			 maxLength: maxLength
			  encoding: encoding
			     lossy: false];
}

- (size_t)getLossyCString: (char*)cString
- (size_t)getLossyCString: (char *)cString
		maxLength: (size_t)maxLength
		 encoding: (of_string_encoding_t)encoding
{
	return [self OF_getCString: cString
			 maxLength: maxLength
			  encoding: encoding
			     lossy: true];
}

- (const char*)OF_cStringWithEncoding: (of_string_encoding_t)encoding
				lossy: (bool)lossy
- (const char *)OF_cStringWithEncoding: (of_string_encoding_t)encoding
				 lossy: (bool)lossy
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	size_t length = [self length];
	char *cString;

	switch (encoding) {
	case OF_STRING_ENCODING_UTF_8:;
1349
1350
1351
1352
1353
1354
1355
1356

1357
1358
1359
1360
1361
1362

1363
1364
1365
1366
1367
1368

1369
1370
1371
1372
1373
1374
1375
1349
1350
1351
1352
1353
1354
1355

1356
1357
1358
1359
1360
1361

1362
1363
1364
1365
1366
1367

1368
1369
1370
1371
1372
1373
1374
1375







-
+





-
+





-
+







	default:
		@throw [OFInvalidEncodingException exception];
	}

	return cString;
}

- (const char*)cStringWithEncoding: (of_string_encoding_t)encoding
- (const char *)cStringWithEncoding: (of_string_encoding_t)encoding
{
	return [self OF_cStringWithEncoding: encoding
				      lossy: false];
}

- (const char*)lossyCStringWithEncoding: (of_string_encoding_t)encoding
- (const char *)lossyCStringWithEncoding: (of_string_encoding_t)encoding
{
	return [self OF_cStringWithEncoding: encoding
				      lossy: true];
}

- (const char*)UTF8String
- (const char *)UTF8String
{
	return [self cStringWithEncoding: OF_STRING_ENCODING_UTF_8];
}

- (size_t)length
{
	OF_UNRECOGNIZED_SELECTOR
1422
1423
1424
1425
1426
1427
1428
1429

1430
1431
1432
1433
1434
1435
1436
1422
1423
1424
1425
1426
1427
1428

1429
1430
1431
1432
1433
1434
1435
1436







-
+







}

- (of_unichar_t)characterAtIndex: (size_t)index
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)getCharacters: (of_unichar_t*)buffer
- (void)getCharacters: (of_unichar_t *)buffer
	      inRange: (of_range_t)range
{
	for (size_t i = 0; i < range.length; i++)
		buffer[i] = [self characterAtIndex: range.location + i];
}

- (bool)isEqual: (id)object
1487
1488
1489
1490
1491
1492
1493
1494

1495
1496
1497
1498
1499
1500
1501
1487
1488
1489
1490
1491
1492
1493

1494
1495
1496
1497
1498
1499
1500
1501







-
+








	if (object == self)
		return OF_ORDERED_SAME;

	if (![object isKindOfClass: [OFString class]])
		@throw [OFInvalidArgumentException exception];

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

	pool = objc_autoreleasePoolPush();

	characters = [self characters];
	otherCharacters = [otherString characters];
1518
1519
1520
1521
1522
1523
1524
1525

1526
1527
1528
1529
1530
1531
1532
1518
1519
1520
1521
1522
1523
1524

1525
1526
1527
1528
1529
1530
1531
1532







-
+







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

	return OF_ORDERED_SAME;
}

- (of_comparison_result_t)caseInsensitiveCompare: (OFString*)otherString
- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)otherString
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters, *otherCharacters;
	size_t length, otherLength, minimumLength;

	if (otherString == self)
		return OF_ORDERED_SAME;
1599
1600
1601
1602
1603
1604
1605
1606

1607
1608
1609
1610
1611

1612
1613
1614
1615
1616
1617
1618
1599
1600
1601
1602
1603
1604
1605

1606
1607
1608
1609
1610

1611
1612
1613
1614
1615
1616
1617
1618







-
+




-
+







	}

	OF_HASH_FINALIZE(hash);

	return hash;
}

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

- (OFXMLElement*)XMLElementBySerializing
- (OFXMLElement *)XMLElementBySerializing
{
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;
	OFString *className;

	if ([self isKindOfClass: [OFMutableString class]])
		className = @"OFMutableString";
1626
1627
1628
1629
1630
1631
1632
1633

1634
1635
1636
1637
1638
1639

1640
1641
1642
1643
1644
1645
1646


1647
1648
1649
1650
1651
1652
1653
1626
1627
1628
1629
1630
1631
1632

1633
1634
1635
1636
1637
1638

1639
1640
1641
1642
1643
1644


1645
1646
1647
1648
1649
1650
1651
1652
1653







-
+





-
+





-
-
+
+







	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (OFString*)JSONRepresentation
- (OFString *)JSONRepresentation
{
	return [self OF_JSONRepresentationWithOptions: 0
						depth: 0];
}

- (OFString*)JSONRepresentationWithOptions: (int)options
- (OFString *)JSONRepresentationWithOptions: (int)options
{
	return [self OF_JSONRepresentationWithOptions: options
						depth: 0];
}

- (OFString*)OF_JSONRepresentationWithOptions: (int)options
					depth: (size_t)depth
- (OFString *)OF_JSONRepresentationWithOptions: (int)options
					 depth: (size_t)depth
{
	OFMutableString *JSON = [[self mutableCopy] autorelease];

	/* FIXME: This is slow! Write it in pure C! */
	[JSON replaceOccurrencesOfString: @"\\"
			      withString: @"\\\\"];
	[JSON replaceOccurrencesOfString: @"\""
1687
1688
1689
1690
1691
1692
1693
1694

1695
1696
1697
1698
1699
1700
1701
1687
1688
1689
1690
1691
1692
1693

1694
1695
1696
1697
1698
1699
1700
1701







-
+







	}

	[JSON makeImmutable];

	return JSON;
}

- (OFDataArray*)messagePackRepresentation
- (OFDataArray *)messagePackRepresentation
{
	OFDataArray *data;
	size_t length;

	length = [self UTF8StringLength];

	if (length <= 31) {
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
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







-
+






-
+







-
+








	[data addItems: [self UTF8String]
		 count: length];

	return data;
}

- (of_range_t)rangeOfString: (OFString*)string
- (of_range_t)rangeOfString: (OFString *)string
{
	return [self rangeOfString: string
			   options: 0
			     range: of_range(0, [self length])];
}

- (of_range_t)rangeOfString: (OFString*)string
- (of_range_t)rangeOfString: (OFString *)string
		    options: (int)options
{
	return [self rangeOfString: string
			   options: options
			     range: of_range(0, [self length])];
}

- (of_range_t)rangeOfString: (OFString*)string
- (of_range_t)rangeOfString: (OFString *)string
		    options: (int)options
		      range: (of_range_t)range
{
	void *pool;
	const of_unichar_t *searchCharacters;
	of_unichar_t *characters;
	size_t searchLength;
1818
1819
1820
1821
1822
1823
1824
1825

1826
1827
1828
1829
1830
1831
1832
1818
1819
1820
1821
1822
1823
1824

1825
1826
1827
1828
1829
1830
1831
1832







-
+







	}

	objc_autoreleasePoolPop(pool);

	return of_range(OF_NOT_FOUND, 0);
}

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

	if ((searchLength = [string length]) == 0)
		return true;
1848
1849
1850
1851
1852
1853
1854
1855

1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873

1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885

1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899


1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912

1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925

1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937


1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952




1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966

1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977

1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988

1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999

2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010

2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021

2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032

2033
2034
2035
2036
2037
2038
2039
1848
1849
1850
1851
1852
1853
1854

1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872

1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884

1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897


1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911

1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924

1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935


1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948




1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965

1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976

1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987

1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998

1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009

2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020

2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031

2032
2033
2034
2035
2036
2037
2038
2039







-
+

















-
+











-
+












-
-
+
+












-
+












-
+










-
-
+
+











-
-
-
-
+
+
+
+













-
+










-
+










-
+










-
+










-
+










-
+










-
+







	}

	objc_autoreleasePoolPop(pool);

	return false;
}

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

	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > [self length])
		@throw [OFOutOfRangeException exception];

	pool = objc_autoreleasePoolPush();
	ret = [[OFString alloc]
	    initWithCharacters: [self characters] + range.location
			length: range.length];
	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

- (OFString*)stringByAppendingString: (OFString*)string
- (OFString *)stringByAppendingString: (OFString *)string
{
	OFMutableString *new;

	new = [OFMutableString stringWithString: self];
	[new appendString: string];

	[new makeImmutable];

	return new;
}

- (OFString*)stringByAppendingFormat: (OFConstantString*)format, ...
- (OFString *)stringByAppendingFormat: (OFConstantString *)format, ...
{
	OFString *ret;
	va_list arguments;

	va_start(arguments, format);
	ret = [self stringByAppendingFormat: format
				  arguments: arguments];
	va_end(arguments);

	return ret;
}

- (OFString*)stringByAppendingFormat: (OFConstantString*)format
			   arguments: (va_list)arguments
- (OFString *)stringByAppendingFormat: (OFConstantString *)format
			    arguments: (va_list)arguments
{
	OFMutableString *new;

	new = [OFMutableString stringWithString: self];
	[new appendFormat: format
		arguments: arguments];

	[new makeImmutable];

	return new;
}

- (OFString*)stringByAppendingPathComponent: (OFString*)component
- (OFString *)stringByAppendingPathComponent: (OFString *)component
{
	void *pool = objc_autoreleasePoolPush();
	OFString *ret;

	ret = [OFString pathWithComponents:
	    [OFArray arrayWithObjects: self, component, nil]];

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

- (OFString*)stringByPrependingString: (OFString*)string
- (OFString *)stringByPrependingString: (OFString *)string
{
	OFMutableString *new = [[string mutableCopy] autorelease];

	[new appendString: self];

	[new makeImmutable];

	return new;
}

- (OFString*)stringByReplacingOccurrencesOfString: (OFString*)string
				       withString: (OFString*)replacement
- (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string
					withString: (OFString *)replacement
{
	OFMutableString *new = [[self mutableCopy] autorelease];

	[new replaceOccurrencesOfString: string
			     withString: replacement];

	[new makeImmutable];

	return new;
}

- (OFString*)stringByReplacingOccurrencesOfString: (OFString*)string
				       withString: (OFString*)replacement
					  options: (int)options
					    range: (of_range_t)range
- (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string
					withString: (OFString *)replacement
					   options: (int)options
					     range: (of_range_t)range
{
	OFMutableString *new = [[self mutableCopy] autorelease];

	[new replaceOccurrencesOfString: string
			     withString: replacement
				options: options
				  range: range];

	[new makeImmutable];

	return new;
}

- (OFString*)uppercaseString
- (OFString *)uppercaseString
{
	OFMutableString *new = [[self mutableCopy] autorelease];

	[new uppercase];

	[new makeImmutable];

	return new;
}

- (OFString*)lowercaseString
- (OFString *)lowercaseString
{
	OFMutableString *new = [[self mutableCopy] autorelease];

	[new lowercase];

	[new makeImmutable];

	return new;
}

- (OFString*)capitalizedString
- (OFString *)capitalizedString
{
	OFMutableString *new = [[self mutableCopy] autorelease];

	[new capitalize];

	[new makeImmutable];

	return new;
}

- (OFString*)stringByDeletingLeadingWhitespaces
- (OFString *)stringByDeletingLeadingWhitespaces
{
	OFMutableString *new = [[self mutableCopy] autorelease];

	[new deleteLeadingWhitespaces];

	[new makeImmutable];

	return new;
}

- (OFString*)stringByDeletingTrailingWhitespaces
- (OFString *)stringByDeletingTrailingWhitespaces
{
	OFMutableString *new = [[self mutableCopy] autorelease];

	[new deleteTrailingWhitespaces];

	[new makeImmutable];

	return new;
}

- (OFString*)stringByDeletingEnclosingWhitespaces
- (OFString *)stringByDeletingEnclosingWhitespaces
{
	OFMutableString *new = [[self mutableCopy] autorelease];

	[new deleteEnclosingWhitespaces];

	[new makeImmutable];

	return new;
}

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

	if ((prefixLength = [prefix length]) > [self length])
2055
2056
2057
2058
2059
2060
2061
2062

2063
2064
2065
2066
2067
2068
2069
2055
2056
2057
2058
2059
2060
2061

2062
2063
2064
2065
2066
2067
2068
2069







-
+







	} @finally {
		[self freeMemory: tmp];
	}

	return hasPrefix;
}

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

	if ((suffixLength = [suffix length]) > [self length])
2088
2089
2090
2091
2092
2093
2094
2095

2096
2097
2098
2099
2100
2101
2102


2103
2104
2105
2106
2107
2108
2109
2088
2089
2090
2091
2092
2093
2094

2095
2096
2097
2098
2099
2100


2101
2102
2103
2104
2105
2106
2107
2108
2109







-
+





-
-
+
+







	} @finally {
		[self freeMemory: tmp];
	}

	return hasSuffix;
}

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
- (OFArray *)componentsSeparatedByString: (OFString *)delimiter
{
	return [self componentsSeparatedByString: delimiter
					 options: 0];
}

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
				options: (int)options
- (OFArray *)componentsSeparatedByString: (OFString *)delimiter
				 options: (int)options
{
	void *pool;
	OFMutableArray *array = [OFMutableArray array];
	const of_unichar_t *characters, *delimiterCharacters;
	bool skipEmpty = (options & OF_STRING_SKIP_EMPTY);
	size_t length = [self length];
	size_t delimiterLength = [delimiter length];
2144
2145
2146
2147
2148
2149
2150
2151

2152
2153
2154
2155
2156
2157
2158
2144
2145
2146
2147
2148
2149
2150

2151
2152
2153
2154
2155
2156
2157
2158







-
+







	[array makeImmutable];

	objc_autoreleasePoolPop(pool);

	return array;
}

- (OFArray*)pathComponents
- (OFArray *)pathComponents
{
	OFMutableArray *ret;
	void *pool;
	const of_unichar_t *characters;
	size_t i, last = 0, length = [self length];

	ret = [OFMutableArray array];
2192
2193
2194
2195
2196
2197
2198
2199

2200
2201
2202
2203
2204
2205
2206
2192
2193
2194
2195
2196
2197
2198

2199
2200
2201
2202
2203
2204
2205
2206







-
+







	[ret makeImmutable];

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (OFString*)lastPathComponent
- (OFString *)lastPathComponent
{
	void *pool;
	const of_unichar_t *characters;
	size_t length = [self length];
	ssize_t i;

	if (length == 0)
2237
2238
2239
2240
2241
2242
2243
2244

2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264

2265
2266
2267
2268
2269
2270
2271
2237
2238
2239
2240
2241
2242
2243

2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263

2264
2265
2266
2267
2268
2269
2270
2271







-
+



















-
+







	 */
	if (i < 0)
		i = 0;

	return [self substringWithRange: of_range(i, length - i)];
}

- (OFString*)pathExtension
- (OFString *)pathExtension
{
	void *pool = objc_autoreleasePoolPush();
	OFString *ret, *fileName;
	size_t pos;

	fileName = [self lastPathComponent];
	pos = [fileName rangeOfString: @"."
			      options: OF_STRING_SEARCH_BACKWARDS].location;
	if (pos == OF_NOT_FOUND || pos == 0)
		return @"";

	ret = [fileName substringWithRange:
	    of_range(pos + 1, [fileName length] - pos - 1)];

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

- (OFString*)stringByDeletingLastPathComponent
- (OFString *)stringByDeletingLastPathComponent
{
	void *pool;
	const of_unichar_t *characters;
	size_t length = [self length];

	if (length == 0)
		return @"";
2295
2296
2297
2298
2299
2300
2301
2302

2303
2304
2305
2306
2307
2308
2309
2295
2296
2297
2298
2299
2300
2301

2302
2303
2304
2305
2306
2307
2308
2309







-
+







	}

	objc_autoreleasePoolPop(pool);

	return OF_PATH_CURRENT_DIRECTORY;
}

- (OFString*)stringByDeletingPathExtension
- (OFString *)stringByDeletingPathExtension
{
	void *pool;
	OFMutableArray *components;
	OFString *ret, *fileName;
	size_t pos;

	if ([self length] == 0)
2327
2328
2329
2330
2331
2332
2333
2334

2335
2336
2337
2338
2339
2340
2341

2342
2343
2344
2345
2346
2347
2348
2327
2328
2329
2330
2331
2332
2333

2334
2335
2336
2337
2338
2339
2340

2341
2342
2343
2344
2345
2346
2347
2348







-
+






-
+







	ret = [OFString pathWithComponents: components];

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

- (OFString*)stringByStandardizingPath
- (OFString *)stringByStandardizingPath
{
	return standardizePath([self pathComponents],
	    OF_PATH_CURRENT_DIRECTORY, OF_PATH_PARENT_DIRECTORY,
	    OF_PATH_DELIMITER_STRING);
}

- (OFString*)stringByStandardizingURLPath
- (OFString *)stringByStandardizingURLPath
{
	return standardizePath([self componentsSeparatedByString: @"/"],
	    @".", @"..", @"/");
}

- (intmax_t)decimalValue
{
2595
2596
2597
2598
2599
2600
2601
2602

2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616

2617
2618
2619
2620
2621

2622
2623
2624
2625
2626
2627
2628
2595
2596
2597
2598
2599
2600
2601

2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615

2616
2617
2618
2619
2620

2621
2622
2623
2624
2625
2626
2627
2628







-
+













-
+




-
+







				@throw [OFInvalidFormatException exception];

	objc_autoreleasePoolPop(pool);

	return value;
}

- (const of_unichar_t*)characters
- (const of_unichar_t *)characters
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	size_t length = [self length];
	of_unichar_t *ret;

	ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
				    count: length];
	[self getCharacters: ret
		    inRange: of_range(0, length)];

	return ret;
}

- (const of_char16_t*)UTF16String
- (const of_char16_t *)UTF16String
{
	return [self UTF16StringWithByteOrder: OF_BYTE_ORDER_NATIVE];
}

- (const of_char16_t*)UTF16StringWithByteOrder: (of_byte_order_t)byteOrder
- (const of_char16_t *)UTF16StringWithByteOrder: (of_byte_order_t)byteOrder
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];
	size_t length = [self length];
	of_char16_t *ret;
	size_t j;
2680
2681
2682
2683
2684
2685
2686
2687

2688
2689
2690
2691
2692

2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712

2713
2714
2715
2716
2717
2718

2719
2720
2721
2722
2723
2724
2725
2680
2681
2682
2683
2684
2685
2686

2687
2688
2689
2690
2691

2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711

2712
2713
2714
2715
2716
2717

2718
2719
2720
2721
2722
2723
2724
2725







-
+




-
+



















-
+





-
+







	for (size_t i = 0; i < length; i++)
		if (characters[i] > 0xFFFF)
			UTF16StringLength++;

	return UTF16StringLength;
}

- (const of_char32_t*)UTF32String
- (const of_char32_t *)UTF32String
{
	return [self UTF32StringWithByteOrder: OF_BYTE_ORDER_NATIVE];
}

- (const of_char32_t*)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
- (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	size_t length = [self length];
	of_char32_t *ret;

	ret = [object allocMemoryWithSize: sizeof(of_char32_t)
				    count: length + 1];
	[self getCharacters: ret
		    inRange: of_range(0, length)];
	ret[length] = 0;

	if (byteOrder != OF_BYTE_ORDER_NATIVE)
		for (size_t i = 0; i < length; i++)
			ret[i] = OF_BSWAP32(ret[i]);

	return ret;
}

#ifdef OF_HAVE_FILES
- (void)writeToFile: (OFString*)path
- (void)writeToFile: (OFString *)path
{
	[self writeToFile: path
		 encoding: OF_STRING_ENCODING_UTF_8];
}

- (void)writeToFile: (OFString*)path
- (void)writeToFile: (OFString *)path
	   encoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFFile *file;

	file = [OFFile fileWithPath: path
			       mode: @"wb"];

Modified src/OFString_UTF8+Private.h from [b08263a07b] to [94d042b3cd].

15
16
17
18
19
20
21
22

23
24

25
26
27
15
16
17
18
19
20
21

22
23

24
25
26
27







-
+

-
+



 */

#import "OFString_UTF8.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFString_UTF8 ()
- (instancetype)OF_initWithUTF8String: (const char*)UTF8String
- (instancetype)OF_initWithUTF8String: (const char *)UTF8String
			       length: (size_t)UTF8StringLength
			      storage: (char*)storage;
			      storage: (char *)storage;
@end

OF_ASSUME_NONNULL_END

Modified src/OFString_UTF8.h from [cbab9106f7] to [27665fb3c4].

40
41
42
43
44
45
46
47
48
49



50
51
52
53
54
40
41
42
43
44
45
46



47
48
49
50
51
52
53
54







-
-
-
+
+
+





	struct of_string_utf8_ivars _storage;
}
@end

#ifdef __cplusplus
extern "C" {
#endif
extern int of_string_utf8_check(const char*, size_t, size_t*);
extern size_t of_string_utf8_get_index(const char*, size_t);
extern size_t of_string_utf8_get_position(const char*, size_t, size_t);
extern int of_string_utf8_check(const char *, size_t, size_t *);
extern size_t of_string_utf8_get_index(const char *, size_t);
extern size_t of_string_utf8_get_position(const char *, size_t, size_t);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFString_UTF8.m from [961145e2e1] to [fc310b0712].

183
184
185
186
187
188
189
190

191
192

193
194
195
196
197
198
199
183
184
185
186
187
188
189

190
191

192
193
194
195
196
197
198
199







-
+

-
+







		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)OF_initWithUTF8String: (const char*)UTF8String
- (instancetype)OF_initWithUTF8String: (const char *)UTF8String
			       length: (size_t)UTF8StringLength
			      storage: (char*)storage
			      storage: (char *)storage
{
	self = [super init];

	@try {
		if (UTF8StringLength >= 3 &&
		    memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) {
			UTF8String += 3;
220
221
222
223
224
225
226
227

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

227
228
229
230
231
232
233
234







-
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		const of_char16_t *table;
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414







-
+















-
+







		[self release];
		@throw e;
	}

	return self;
}

- initWithUTF8StringNoCopy: (char*)UTF8String
- initWithUTF8StringNoCopy: (char *)UTF8String
	      freeWhenDone: (bool)freeWhenDone
{
	self = [super init];

	@try {
		size_t UTF8StringLength = strlen(UTF8String);

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

		_s = &_storage;

		_s->cString = (char*)UTF8String;
		_s->cString = (char *)UTF8String;
		_s->cStringLength = UTF8StringLength;

		if (freeWhenDone)
			_s->freeWhenDone = UTF8String;

		switch (of_string_utf8_check(UTF8String, UTF8StringLength,
		    &_s->length)) {
422
423
424
425
426
427
428
429

430
431
432
433
434
435
436
437
438
439
440

441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436
437
438
439

440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463







-
+










-
+















-
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		_s = &_storage;

		_s->cStringLength = [string UTF8StringLength];

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

		_s->length = [string length];

		_s->cString = [self allocMemoryWithSize: _s->cStringLength + 1];
		memcpy(_s->cString, [string UTF8String], _s->cStringLength + 1);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithCharacters: (const of_unichar_t*)characters
- initWithCharacters: (const of_unichar_t *)characters
	      length: (size_t)length
{
	self = [super init];

	@try {
		size_t j;

493
494
495
496
497
498
499
500

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

500
501
502
503
504
505
506
507







-
+







		[self release];
		@throw e;
	}

	return self;
}

- initWithUTF16String: (const of_char16_t*)string
- initWithUTF16String: (const of_char16_t *)string
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	self = [super init];

	@try {
		size_t j;
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592
578
579
580
581
582
583
584

585
586
587
588
589
590
591
592







-
+







		[self release];
		@throw e;
	}

	return self;
}

- initWithUTF32String: (const of_char32_t*)characters
- initWithUTF32String: (const of_char32_t *)characters
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	self = [super init];

	@try {
		size_t j;
645
646
647
648
649
650
651
652

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

652
653
654
655
656
657
658
659







-
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		char *tmp;
		int cStringLength;
697
698
699
700
701
702
703
704

705
706
707
708
709
710
711
697
698
699
700
701
702
703

704
705
706
707
708
709
710
711







-
+







{
	if (_s != NULL && _s->freeWhenDone != NULL)
		free(_s->freeWhenDone);

	[super dealloc];
}

- (size_t)getCString: (char*)cString
- (size_t)getCString: (char *)cString
	   maxLength: (size_t)maxLength
	    encoding: (of_string_encoding_t)encoding
{
	switch (encoding) {
	case OF_STRING_ENCODING_ASCII:
		if (_s->isUTF8)
			@throw [OFInvalidEncodingException exception];
720
721
722
723
724
725
726
727

728
729
730
731
732
733
734
735
736
737
738
739
740
741

742
743
744
745
746
747
748
720
721
722
723
724
725
726

727
728
729
730
731
732
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
748







-
+













-
+







	default:
		return [super getCString: cString
			       maxLength: maxLength
				encoding: encoding];
	}
}

- (const char*)cStringWithEncoding: (of_string_encoding_t)encoding
- (const char *)cStringWithEncoding: (of_string_encoding_t)encoding
{
	switch (encoding) {
	case OF_STRING_ENCODING_ASCII:
		if (_s->isUTF8)
			@throw [OFInvalidEncodingException exception];
		/* intentional fall-through */
	case OF_STRING_ENCODING_UTF_8:
		return _s->cString;
	default:
		return [super cStringWithEncoding: encoding];
	}
}

- (const char*)UTF8String
- (const char *)UTF8String
{
	return _s->cString;
}

- (size_t)length
{
	return _s->length;
800
801
802
803
804
805
806
807

808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827

828
829
830
831
832
833
834
800
801
802
803
804
805
806

807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826

827
828
829
830
831
832
833
834







-
+



















-
+








	if (object == self)
		return OF_ORDERED_SAME;

	if (![object isKindOfClass: [OFString class]])
		@throw [OFInvalidArgumentException exception];

	otherString = (OFString*)object;
	otherString = (OFString *)object;
	otherCStringLength = [otherString UTF8StringLength];
	minimumCStringLength = (_s->cStringLength > otherCStringLength
	    ? otherCStringLength : _s->cStringLength);

	if ((compare = memcmp(_s->cString, [otherString UTF8String],
	    minimumCStringLength)) == 0) {
		if (_s->cStringLength > otherCStringLength)
			return OF_ORDERED_DESCENDING;
		if (_s->cStringLength < otherCStringLength)
			return OF_ORDERED_ASCENDING;
		return OF_ORDERED_SAME;
	}

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

- (of_comparison_result_t)caseInsensitiveCompare: (OFString*)otherString
- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)otherString
{
	const char *otherCString;
	size_t otherCStringLength, minimumCStringLength;
#ifdef OF_HAVE_UNICODE_TABLES
	size_t i, j;
#endif
	int compare;
960
961
962
963
964
965
966
967

968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984

985
986
987
988
989
990
991
960
961
962
963
964
965
966

967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983

984
985
986
987
988
989
990
991







-
+
















-
+







	if (of_string_utf8_decode(_s->cString + index,
	    _s->cStringLength - index, &character) <= 0)
		@throw [OFInvalidEncodingException exception];

	return character;
}

- (void)getCharacters: (of_unichar_t*)buffer
- (void)getCharacters: (of_unichar_t *)buffer
	      inRange: (of_range_t)range
{
	/* TODO: Could be slightly optimized */
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = [self characters];

	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > _s->length)
		@throw [OFOutOfRangeException exception];

	memcpy(buffer, characters + range.location,
	    range.length * sizeof(of_unichar_t));

	objc_autoreleasePoolPop(pool);
}

- (of_range_t)rangeOfString: (OFString*)string
- (of_range_t)rangeOfString: (OFString *)string
		    options: (int)options
		      range: (of_range_t)range
{
	const char *cString = [string UTF8String];
	size_t cStringLength = [string UTF8StringLength];
	size_t rangeLocation, rangeLength;

1037
1038
1039
1040
1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062

1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081

1082
1083
1084
1085
1086
1087
1088
1089
1090
1091

1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103


1104
1105
1106
1107
1108
1109
1110
1037
1038
1039
1040
1041
1042
1043

1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061

1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080

1081
1082
1083
1084
1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101


1102
1103
1104
1105
1106
1107
1108
1109
1110







-
+

















-
+


















-
+









-
+










-
-
+
+







			}
		}
	}

	return of_range(OF_NOT_FOUND, 0);
}

- (bool)containsString: (OFString*)string
- (bool)containsString: (OFString *)string
{
	const char *cString = [string UTF8String];
	size_t cStringLength = [string UTF8StringLength];

	if (cStringLength == 0)
		return true;

	if (cStringLength > _s->cStringLength)
		return false;

	for (size_t i = 0; i <= _s->cStringLength - cStringLength; i++)
		if (memcmp(_s->cString + i, cString, cStringLength) == 0)
			return true;

	return false;
}

- (OFString*)substringWithRange: (of_range_t)range
- (OFString *)substringWithRange: (of_range_t)range
{
	size_t start = range.location;
	size_t end = range.location + range.length;

	if (range.length > SIZE_MAX - range.location || end > _s->length)
		@throw [OFOutOfRangeException exception];

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

	return [OFString stringWithUTF8String: _s->cString + start
				       length: end - start];
}

- (bool)hasPrefix: (OFString*)prefix
- (bool)hasPrefix: (OFString *)prefix
{
	size_t cStringLength = [prefix UTF8StringLength];

	if (cStringLength > _s->cStringLength)
		return false;

	return (memcmp(_s->cString, [prefix UTF8String], cStringLength) == 0);
}

- (bool)hasSuffix: (OFString*)suffix
- (bool)hasSuffix: (OFString *)suffix
{
	size_t cStringLength = [suffix UTF8StringLength];

	if (cStringLength > _s->cStringLength)
		return false;

	return (memcmp(_s->cString + (_s->cStringLength - cStringLength),
	    [suffix UTF8String], cStringLength) == 0);
}

- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
				options: (int)options
- (OFArray *)componentsSeparatedByString: (OFString *)delimiter
				 options: (int)options
{
	void *pool;
	OFMutableArray *array;
	const char *cString = [delimiter UTF8String];
	size_t cStringLength = [delimiter UTF8StringLength];
	bool skipEmpty = (options & OF_STRING_SKIP_EMPTY);
	size_t last;
1140
1141
1142
1143
1144
1145
1146
1147

1148
1149
1150
1151
1152
1153
1154
1140
1141
1142
1143
1144
1145
1146

1147
1148
1149
1150
1151
1152
1153
1154







-
+







	[array makeImmutable];

	objc_autoreleasePoolPop(pool);

	return array;
}

- (OFArray*)pathComponents
- (OFArray *)pathComponents
{
	OFMutableArray *ret;
	void *pool;
	size_t i, last = 0, pathCStringLength = _s->cStringLength;

	ret = [OFMutableArray array];

1186
1187
1188
1189
1190
1191
1192
1193

1194
1195
1196
1197
1198
1199
1200
1186
1187
1188
1189
1190
1191
1192

1193
1194
1195
1196
1197
1198
1199
1200







-
+







	[ret makeImmutable];

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (OFString*)lastPathComponent
- (OFString *)lastPathComponent
{
	size_t pathCStringLength = _s->cStringLength;
	ssize_t i;

	if (pathCStringLength == 0)
		return @"";

1221
1222
1223
1224
1225
1226
1227
1228

1229
1230
1231
1232
1233
1234
1235
1221
1222
1223
1224
1225
1226
1227

1228
1229
1230
1231
1232
1233
1234
1235







-
+







	if (i < 0)
		i = 0;

	return [OFString stringWithUTF8String: _s->cString + i
				       length: pathCStringLength - i];
}

- (OFString*)stringByDeletingLastPathComponent
- (OFString *)stringByDeletingLastPathComponent
{
	size_t pathCStringLength = _s->cStringLength;

	if (pathCStringLength == 0)
		return @"";

	if (OF_IS_PATH_DELIMITER(_s->cString[pathCStringLength - 1]))
1247
1248
1249
1250
1251
1252
1253
1254

1255
1256
1257
1258
1259
1260
1261
1247
1248
1249
1250
1251
1252
1253

1254
1255
1256
1257
1258
1259
1260
1261







-
+







	if (OF_IS_PATH_DELIMITER(_s->cString[0]))
		return [OFString stringWithUTF8String: _s->cString
					       length: 1];

	return OF_PATH_CURRENT_DIRECTORY;
}

- (const of_unichar_t*)characters
- (const of_unichar_t *)characters
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	of_unichar_t *ret;
	size_t i, j;

	ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
				    count: _s->length];
1275
1276
1277
1278
1279
1280
1281
1282

1283
1284
1285
1286
1287
1288
1289
1275
1276
1277
1278
1279
1280
1281

1282
1283
1284
1285
1286
1287
1288
1289







-
+







		ret[j++] = c;
		i += cLen;
	}

	return ret;
}

- (const of_char32_t*)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
- (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	of_char32_t *ret;
	size_t i, j;

	ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
				    count: _s->length + 1];

Modified src/OFSystemInfo.h from [318b983834] to [e8b6bc242b].

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







-
+













-
+








-
+







 * On Unix systems, this adheres to the XDG Base Directory specification.@n
 * On Mac OS X and iOS, it uses the `NSApplicationSupportDirectory` directory.@n
 * On Windows, it uses the `APPDATA` environment variable.@n
 * On Haiku, it uses the `B_USER_SETTINGS_DIRECTORY` directory.
 *
 * @return The path where user data for the application can be stored
 */
+ (OFString*)userDataPath;
+ (OFString *)userDataPath;

/*!
 * @brief Returns the path where user configuration for the application can be
 *	  stored.
 *
 * On Unix systems, this adheres to the XDG Base Directory specification.@n
 * On Mac OS X and iOS, it uses the `Preferences` directory inside of
 * `NSLibraryDirectory` directory.@n
 * On Windows, it uses the `APPDATA` environment variable.@n
 * On Haiku, it uses the `B_USER_SETTINGS_DIRECTORY` directory.
 *
 * @return The path where user configuration for the application can be stored
 */
+ (OFString*)userConfigPath;
+ (OFString *)userConfigPath;

/*!
 * @brief Returns the vendor of the CPU.
 *
 * If the vendor could not be determined, `nil` is returned instead.
 *
 * @return The vendor of the CPU
 */
+ (nullable OFString*)CPUVendor;
+ (nullable OFString *)CPUVendor;

#if defined(OF_X86_64) || defined(OF_X86) || defined(DOXYGEN)
/*!
 * @brief Returns whether the CPU supports MMX.
 *
 * @note This method is only available on x86 and x86_64.
 *

Modified src/OFSystemInfo.m from [3184c9a0c5] to [2dfc0a82b8].

139
140
141
142
143
144
145
146

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

146
147
148
149
150
151
152
153







-
+







}

+ (size_t)numberOfCPUs
{
	return numberOfCPUs;
}

+ (OFString*)userDataPath
+ (OFString *)userDataPath
{
#if defined(OF_MACOS) || defined(OF_IOS)
	void *pool = objc_autoreleasePoolPush();
	char pathC[PATH_MAX];
	OFMutableString *path;
	OFString *home;

229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243







-
+








	[var retain];
	objc_autoreleasePoolPop(pool);
	return [var autorelease];
#endif
}

+ (OFString*)userConfigPath
+ (OFString *)userConfigPath
{
#if defined(OF_MACOS) || defined(OF_IOS)
	void *pool = objc_autoreleasePoolPush();
	char pathC[PATH_MAX];
	OFMutableString *path;
	OFString *home;

320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334







-
+








	[var retain];
	objc_autoreleasePoolPop(pool);
	return [var autorelease];
#endif
}

+ (OFString*)CPUVendor
+ (OFString *)CPUVendor
{
#if defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
	struct x86_regs regs = x86_cpuid(0, 0);
	char buffer[12];

	if (regs.eax == 0)
		return nil;

Modified src/OFTCPSocket+SOCKS5.h from [a70c21b56b] to [615516372e].

23
24
25
26
27
28
29
30

31
32
33
34
23
24
25
26
27
28
29

30
31
32
33
34







-
+




#endif
extern int _OFTCPSocket_SOCKS5_reference;
#ifdef __cplusplus
}
#endif

@interface OFTCPSocket (SOCKS5)
- (void)OF_SOCKS5ConnectToHost: (OFString*)host
- (void)OF_SOCKS5ConnectToHost: (OFString *)host
			  port: (uint16_t)port;
@end

OF_ASSUME_NONNULL_END

Modified src/OFTCPSocket+SOCKS5.m from [8e795b494e] to [c2070c1b40].

54
55
56
57
58
59
60
61

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

61
62
63
64
65
66
67
68







-
+








		buffer += ret;
		length -= ret;
	}
}

@implementation OFTCPSocket (SOCKS5)
- (void)OF_SOCKS5ConnectToHost: (OFString*)host
- (void)OF_SOCKS5ConnectToHost: (OFString *)host
			  port: (uint16_t)port
{
	char request[] = { 5, 1, 0, 3 };
	char reply[256];
	void *pool;
	OFDataArray *connectRequest;

Modified src/OFTCPSocket.h from [7e829b3ab1] to [a9d0cd2fee].

82
83
84
85
86
87
88
89

90
91
92
93
94
95
96

97
98
99
100
101
102
103
82
83
84
85
86
87
88

89
90
91
92
93
94
95

96
97
98
99
100
101
102
103







-
+






-
+








/*!
 * @brief Sets the global SOCKS5 proxy host to use when creating a new socket
 *
 * @param SOCKS5Host The host to use as a SOCKS5 proxy when creating a new
 *		     socket
 */
+ (void)setSOCKS5Host: (nullable OFString*)SOCKS5Host;
+ (void)setSOCKS5Host: (nullable OFString *)SOCKS5Host;

/*!
 * @brief Returns the host to use as a SOCKS5 proxy when creating a new socket
 *
 * @return The host to use as a SOCKS5 proxy when creating a new socket
 */
+ (nullable OFString*)SOCKS5Host;
+ (nullable OFString *)SOCKS5Host;

/*!
 * @brief Sets the global SOCKS5 proxy port to use when creating a new socket
 *
 * @param SOCKS5Port The port to use as a SOCKS5 proxy when creating a new socket
 */
+ (void)setSOCKS5Port: (uint16_t)SOCKS5Port;
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
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







-
+













-
+












-
+














-
+








/*!
 * @brief Connect the OFTCPSocket to the specified destination.
 *
 * @param host The host to connect to
 * @param port The port on the host to connect to
 */
- (void)connectToHost: (OFString*)host
- (void)connectToHost: (OFString *)host
		 port: (uint16_t)port;

#ifdef OF_HAVE_THREADS
/*!
 * @brief Asynchronously connect the OFTCPSocket to the specified destination.
 *
 * @param host The host to connect to
 * @param port The port on the host to connect to
 * @param target The target on which to call the selector once the connection
 *		 has been established
 * @param selector The selector to call on the target. The signature must be
 *		   `void (OFTCPSocket *socket, OFException *exception)`.
 */
- (void)asyncConnectToHost: (OFString*)host
- (void)asyncConnectToHost: (OFString *)host
		      port: (uint16_t)port
		    target: (id)target
		  selector: (SEL)selector;

# ifdef OF_HAVE_BLOCKS
/*!
 * @brief Asynchronously connect the OFTCPSocket to the specified destination.
 *
 * @param host The host to connect to
 * @param port The port on the host to connect to
 * @param block The block to execute once the connection has been established
 */
- (void)asyncConnectToHost: (OFString*)host
- (void)asyncConnectToHost: (OFString *)host
		      port: (uint16_t)port
		     block: (of_tcp_socket_async_connect_block_t)block;
# endif
#endif

/*!
 * @brief Bind the socket to the specified host and port.
 *
 * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for
 *	       IPv6 to bind to all.
 * @param port The port to bind to. If the port is 0, an unused port will be
 *	       chosen, which can be obtained using the return value.
 * @return The port the socket was bound to
 */
- (uint16_t)bindToHost: (OFString*)host
- (uint16_t)bindToHost: (OFString *)host
		  port: (uint16_t)port;

/*!
 * @brief Listen on the socket.
 *
 * @param backLog Maximum length for the queue of pending connections.
 */
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221







-
+







/*!
 * @brief Returns the remote address of the socket.
 *
 * Only works with accepted sockets!
 *
 * @return The remote address as a string
 */
- (nullable OFString*)remoteAddress;
- (nullable OFString *)remoteAddress;

/*!
 * @brief Returns whether the socket is a listening socket.
 *
 * @return Whether the socket is a listening socket
 */
- (bool)isListening;

Modified src/OFTCPSocket.m from [f234be8d33] to [c7187f1cc0].

74
75
76
77
78
79
80
81
82
83



84
85
86
87
88
89
90



91
92
93
94
95
96
97
98
99



100
101
102
103
104
105
106
74
75
76
77
78
79
80



81
82
83
84
85
86
87



88
89
90
91
92
93
94
95
96



97
98
99
100
101
102
103
104
105
106







-
-
-
+
+
+




-
-
-
+
+
+






-
-
-
+
+
+







	SEL _selector;
# ifdef OF_HAVE_BLOCKS
	of_tcp_socket_async_connect_block_t _block;
# endif
	OFException *_exception;
}

- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
- initWithSourceThread: (OFThread *)sourceThread
		socket: (OFTCPSocket *)socket
		  host: (OFString *)host
		  port: (uint16_t)port
		target: (id)target
	      selector: (SEL)selector;
# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
- initWithSourceThread: (OFThread *)sourceThread
		socket: (OFTCPSocket *)socket
		  host: (OFString *)host
		  port: (uint16_t)port
		 block: (of_tcp_socket_async_connect_block_t)block;
# endif
@end

@implementation OFTCPSocket_ConnectThread
- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
- initWithSourceThread: (OFThread *)sourceThread
		socket: (OFTCPSocket *)socket
		  host: (OFString *)host
		  port: (uint16_t)port
		target: (id)target
	      selector: (SEL)selector
{
	self = [super init];

	@try {
115
116
117
118
119
120
121
122
123
124



125
126
127
128
129
130
131
115
116
117
118
119
120
121



122
123
124
125
126
127
128
129
130
131







-
-
-
+
+
+







		@throw e;
	}

	return self;
}

# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread
		socket: (OFTCPSocket*)socket
		  host: (OFString*)host
- initWithSourceThread: (OFThread *)sourceThread
		socket: (OFTCPSocket *)socket
		  host: (OFString *)host
		  port: (uint16_t)port
		 block: (of_tcp_socket_async_connect_block_t)block
{
	self = [super init];

	@try {
		_sourceThread = [sourceThread retain];
161
162
163
164
165
166
167
168
169


170
171
172
173
174
175
176
161
162
163
164
165
166
167


168
169
170
171
172
173
174
175
176







-
-
+
+







	[self join];

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(_socket, _exception);
	else {
# endif
		void (*func)(id, SEL, OFTCPSocket*, OFException*) =
		    (void(*)(id, SEL, OFTCPSocket*, OFException*))[_target
		void (*func)(id, SEL, OFTCPSocket *, OFException *) =
		    (void (*)(id, SEL, OFTCPSocket *, OFException *))[_target
		    methodForSelector: _selector];

		func(_target, _selector, _socket, _exception);
# ifdef OF_HAVE_BLOCKS
	}
# endif
}
196
197
198
199
200
201
202
203

204
205
206
207
208
209
210

211
212
213
214
215
216
217
196
197
198
199
200
201
202

203
204
205
206
207
208
209

210
211
212
213
214
215
216
217







-
+






-
+







}
@end
#endif

@implementation OFTCPSocket
@synthesize SOCKS5Host = _SOCKS5Host, SOCKS5Port = _SOCKS5Port;

+ (void)setSOCKS5Host: (OFString*)host
+ (void)setSOCKS5Host: (OFString *)host
{
	id old = defaultSOCKS5Host;
	defaultSOCKS5Host = [host copy];
	[old release];
}

+ (OFString*)SOCKS5Host
+ (OFString *)SOCKS5Host
{
	return [[defaultSOCKS5Host copy] autorelease];
}

+ (void)setSOCKS5Port: (uint16_t)port
{
	defaultSOCKS5Port = port;
241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
241
242
243
244
245
246
247

248
249
250
251
252
253
254
255







-
+







- (void)dealloc
{
	[_SOCKS5Host release];

	[super dealloc];
}

- (void)connectToHost: (OFString*)host
- (void)connectToHost: (OFString *)host
		 port: (uint16_t)port
{
	OFString *destinationHost = host;
	uint16_t destinationPort = port;
	of_resolver_result_t **results, **iter;
	int errNo = 0;

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







-
+


















-
+

















-
+








	if (_SOCKS5Host != nil)
		[self OF_SOCKS5ConnectToHost: destinationHost
					port: destinationPort];
}

#ifdef OF_HAVE_THREADS
- (void)asyncConnectToHost: (OFString*)host
- (void)asyncConnectToHost: (OFString *)host
		      port: (uint16_t)port
		    target: (id)target
		  selector: (SEL)selector
{
	void *pool = objc_autoreleasePoolPush();

	[[[[OFTCPSocket_ConnectThread alloc]
	    initWithSourceThread: [OFThread currentThread]
			  socket: self
			    host: host
			    port: port
			  target: target
			selector: selector] autorelease] start];

	objc_autoreleasePoolPop(pool);
}

# ifdef OF_HAVE_BLOCKS
- (void)asyncConnectToHost: (OFString*)host
- (void)asyncConnectToHost: (OFString *)host
		      port: (uint16_t)port
		     block: (of_tcp_socket_async_connect_block_t)block
{
	void *pool = objc_autoreleasePoolPush();

	[[[[OFTCPSocket_ConnectThread alloc]
	    initWithSourceThread: [OFThread currentThread]
			  socket: self
			    host: host
			    port: port
			   block: block] autorelease] start];

	objc_autoreleasePoolPop(pool);
}
# endif
#endif

- (uint16_t)bindToHost: (OFString*)host
- (uint16_t)bindToHost: (OFString *)host
		  port: (uint16_t)port
{
	of_resolver_result_t **results;
	const int one = 1;
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
	union {
		struct sockaddr_storage storage;
387
388
389
390
391
392
393
394

395
396
397
398
399
400
401
387
388
389
390
391
392
393

394
395
396
397
398
399
400
401







-
+








#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
		if ((flags = fcntl(_socket, F_GETFD, 0)) != -1)
			fcntl(_socket, F_SETFD, flags | FD_CLOEXEC);
#endif

		setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR,
		    (const char*)&one, (socklen_t)sizeof(one));
		    (const char *)&one, (socklen_t)sizeof(one));

#if defined(OF_WII) || defined(OF_NINTENDO_3DS)
		if (port != 0) {
#endif
			if (bind(_socket, results[0]->address,
			    results[0]->addressLength) != 0) {
				int errNo = of_socket_errno();
416
417
418
419
420
421
422
423

424
425
426
427
428
429

430
431
432
433
434
435
436
416
417
418
419
420
421
422

423
424
425
426
427
428

429
430
431
432
433
434
435
436







-
+





-
+







				int ret;

				while (rnd < 1024)
					rnd = (uint16_t)rand();

				switch (results[0]->family) {
				case AF_INET:
					((struct sockaddr_in*)
					((struct sockaddr_in *)
					    results[0]->address)->sin_port =
					    OF_BSWAP16_IF_LE(rnd);
					break;
# ifdef HAVE_IPV6
				case AF_INET6:
					((struct sockaddr_in6*)
					((struct sockaddr_in6 *)
					    results[0]->address)->sin6_port =
					    OF_BSWAP16_IF_LE(rnd);
					break;
# endif
				default:
					@throw [OFInvalidArgumentException
					    exception];
464
465
466
467
468
469
470
471

472
473
474
475
476
477
478
464
465
466
467
468
469
470

471
472
473
474
475
476
477
478







-
+







	}

	if (port > 0)
		return port;

#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
	addrLen = (socklen_t)sizeof(addr.storage);
	if (of_getsockname(_socket, (struct sockaddr*)&addr.storage,
	if (of_getsockname(_socket, (struct sockaddr *)&addr.storage,
	    &addrLen) != 0) {
		int errNo = of_socket_errno();

		close(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithHost: host
582
583
584
585
586
587
588
589

590
591
592
593
594
595
596
582
583
584
585
586
587
588

589
590
591
592
593
594
595
596







-
+







- (void)asyncAcceptWithBlock: (of_tcp_socket_async_accept_block_t)block
{
	[OFRunLoop OF_addAsyncAcceptForTCPSocket: self
					   block: block];
}
#endif

- (OFString*)remoteAddress
- (OFString *)remoteAddress
{
	OFString *ret;

	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_address == NULL)
608
609
610
611
612
613
614
615

616
617
618
619
620
621
622
623
624
625
626
627

628
629
630
631
632
633
634
635
636
637
638
639
640
641
642

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

655
656
657
658
659
660
661
608
609
610
611
612
613
614

615
616
617
618
619
620
621
622
623
624
625
626

627
628
629
630
631
632
633
634
635
636
637
638
639
640
641

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

654
655
656
657
658
659
660
661







-
+











-
+














-
+











-
+








#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
- (void)setKeepAliveEnabled: (bool)enabled
{
	int v = enabled;

	if (setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE,
	    (char*)&v, (socklen_t)sizeof(v)) != 0)
	    (char *)&v, (socklen_t)sizeof(v)) != 0)
		@throw [OFSetOptionFailedException
		    exceptionWithStream: self
				  errNo: of_socket_errno()];
}

- (bool)isKeepAliveEnabled
{
	int v;
	socklen_t len = sizeof(v);

	if (getsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE,
	    (char*)&v, &len) != 0 || len != sizeof(v))
	    (char *)&v, &len) != 0 || len != sizeof(v))
		@throw [OFGetOptionFailedException
		    exceptionWithStream: self
				  errNo: of_socket_errno()];

	return v;
}
#endif

#ifndef OF_WII
- (void)setTCPNoDelayEnabled: (bool)enabled
{
	int v = enabled;

	if (setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY,
	    (char*)&v, (socklen_t)sizeof(v)) != 0)
	    (char *)&v, (socklen_t)sizeof(v)) != 0)
		@throw [OFSetOptionFailedException
		    exceptionWithStream: self
				  errNo: of_socket_errno()];
}

- (bool)isTCPNoDelayEnabled
{
	int v;
	socklen_t len = sizeof(v);

	if (getsockopt(_socket, IPPROTO_TCP, TCP_NODELAY,
	    (char*)&v, &len) != 0 || len != sizeof(v))
	    (char *)&v, &len) != 0 || len != sizeof(v))
		@throw [OFGetOptionFailedException
		    exceptionWithStream: self
				  errNo: of_socket_errno()];

	return v;
}
#endif

Modified src/OFTLSSocket.h from [b87af1f574] to [27187de68b].

40
41
42
43
44
45
46
47

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

47
48
49
50
51
52
53
54







-
+







 *
 * @param socket The socket which wants to know if it should accept the received
 *		 certificate
 * @param certificate A dictionary with the fields of the received certificate
 * @return Whether the TLS socket should accept the received certificate chain
 */
-	     (bool)socket: (id <OFTLSSocket>)socket
  shouldAcceptCertificate: (OFDictionary*)certificate;
  shouldAcceptCertificate: (OFDictionary *)certificate;
@end

/*!
 * @protocol OFTLSSocket OFTLSSocket.h ObjFW/OFTLSSocket.h
 *
 * @brief A protocol that should be implemented by 3rd-party libraries
 *	  implementing TLS.
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
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







-
+










-
+










-
-
+
+











-
+









-
-
+
+











-
+













-
-
+
+













-
+




/*!
 * @brief Initializes the TLS socket with the specified TCP socket as its
 *	  underlying socket.
 *
 * @param socket The TCP socket to use as underlying socket
 */
- initWithSocket: (OFTCPSocket*)socket;
- initWithSocket: (OFTCPSocket *)socket;

/*!
 * @brief Initiates the TLS handshake.
 *
 * @note This is only useful if you used @ref initWithSocket: to start TLS on
 *	 a TCP socket which is already connected!
 *
 * @param host The host to expect for certificate verification.
 *	       May be `nil` if certificate verification is disabled.
 */
- (void)startTLSWithExpectedHost: (nullable OFString*)host;
- (void)startTLSWithExpectedHost: (nullable OFString *)host;

/*!
 * @brief Sets the path to the X.509 certificate file to use for the specified
 *	  SNI host.
 *
 * @param SNIHost The SNI host for which the path of the X.509 certificate file
 *		  should be set
 *
 * @param certificateFile The path to the X.509 certificate file
 */
- (void)setCertificateFile: (OFString*)certificateFile
		forSNIHost: (OFString*)SNIHost;
- (void)setCertificateFile: (OFString *)certificateFile
		forSNIHost: (OFString *)SNIHost;

/*!
 * @brief Returns the path of the X.509 certificate file used by the TLS socket
 *	  for the specified SNI host.
 *
 * @param SNIHost The SNI host for which the path of the X.509 certificate file
 *		  should be returned
 *
 * @return The path of the X.509 certificate file used by the TLS socket for
 *	   the specified SNI host
 */
- (nullable OFString*)certificateFileForSNIHost: (OFString*)SNIHost;
- (nullable OFString *)certificateFileForSNIHost: (OFString *)SNIHost;

/*!
 * @brief Sets the path to the PKCS#8 private key file to use for the specified
 *	  SNI host.
 *
 * @param privateKeyFile The path to the PKCS#8 private key file
 * @param SNIHost The SNI host for which the path to the PKCS#8 private key
 *		  file should be set
 */
- (void)setPrivateKeyFile: (OFString*)privateKeyFile
	       forSNIHost: (OFString*)SNIHost;
- (void)setPrivateKeyFile: (OFString *)privateKeyFile
	       forSNIHost: (OFString *)SNIHost;

/*!
 * @brief Returns the path of the PKCS#8 private key file used by the TLS
 *	  socket for the specified SNI host.
 *
 * @param SNIHost The SNI host for which the path of the PKCS#8 private key
 *		  file should be returned
 *
 * @return The path of the PKCS#8 private key file used by the TLS socket for
 *	   the specified SNI host
 */
- (nullable OFString*)privateKeyFileForSNIHost: (OFString*)SNIHost;
- (nullable OFString *)privateKeyFileForSNIHost: (OFString *)SNIHost;

/*!
 * @brief Sets the passphrase to decrypt the PKCS#8 private key file for the
 *	  specified SNI host.
 *
 * @warning You have to ensure that this is in secure memory protected from
 *	    swapping! This is also the reason why this is not an OFString.
 *
 * @param privateKeyPassphrase The passphrase to decrypt the PKCS#8 private
 *			       key file for the specified SNI host
 * @param SNIHost The SNI host for which the passphrase to decrypt the PKCS#8
 *		  private key file should be set
 */
- (void)setPrivateKeyPassphrase: (const char*)privateKeyPassphrase
		     forSNIHost: (OFString*)SNIHost;
- (void)setPrivateKeyPassphrase: (const char *)privateKeyPassphrase
		     forSNIHost: (OFString *)SNIHost;

/*!
 * @brief Returns the passphrase to decrypt the PKCS#8 private key file for the
 *	  specified SNI host.
 *
 * @warning You should not copy this to insecure memory which is swappable!
 *
 * @param SNIHost The SNI host for which the passphrase to decrypt the PKCS#8
 *		  private key file should be returned
 *
 * @return The passphrase to decrypt the PKCS#8 private key file for the
 *	   specified SNI host
 */
- (nullable const char*)privateKeyPassphraseForSNIHost: (OFString*)SNIHost;
- (nullable const char *)privateKeyPassphraseForSNIHost: (OFString *)SNIHost;
@end

OF_ASSUME_NONNULL_END

Modified src/OFTarArchive.h from [2ef22f87ee] to [f202a7f964].

39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92







-
+








-
+









-
+









-
+













-
+




/*!
 * @brief Creates a new OFTarArchive object with the specified stream.
 *
 * @param stream A stream from which the tar archive will be read
 * @return A new, autoreleased OFTarArchive
 */
+ (instancetype)archiveWithStream: (OFStream*)stream;
+ (instancetype)archiveWithStream: (OFStream *)stream;

#ifdef OF_HAVE_FILES
/*!
 * @brief Creates a new OFTarArchive object with the specified file.
 *
 * @param path The path to the tar archive
 * @return A new, autoreleased OFTarArchive
 */
+ (instancetype)archiveWithPath: (OFString*)path;
+ (instancetype)archiveWithPath: (OFString *)path;
#endif

/*!
 * @brief Initializes an already allocated OFTarArchive object with the
 *	  specified stream.
 *
 * @param stream A stream from which the tar archive will be read
 * @return An initialized OFTarArchive
 */
- initWithStream: (OFStream*)stream;
- initWithStream: (OFStream *)stream;

#ifdef OF_HAVE_FILES
/*!
 * @brief Initializes an already allocated OFTarArchive object with the
 *	  specified file.
 *
 * @param path The path to the tar archive
 * @return An initialized OFTarArchive
 */
- initWithPath: (OFString*)path;
- initWithPath: (OFString *)path;
#endif

/*!
 * @brief Returns the next entry from the tar archive or `nil` if all entries
 *	  have been read.
 *
 * @warning Calling @ref nextEntry will invalidate all streams returned by the
 *	    previous entry! Reading from an invalidated stream will throw an
 *	    @ref OFReadFailedException!
 *
 * @return The next entry from the tar archive or `nil` if all entries have
 *	   been read
 */
- (OFTarArchiveEntry*)nextEntry;
- (OFTarArchiveEntry *)nextEntry;
@end

OF_ASSUME_NONNULL_END

Modified src/OFTarArchive.m from [ffe423de16] to [ef68919153].

23
24
25
26
27
28
29
30

31
32
33
34
35
36

37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
23
24
25
26
27
28
29

30
31
32
33
34
35

36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59







-
+





-
+





-
+









-
+







#ifdef OF_HAVE_FILES
# import "OFFile.h"
#endif

#import "OFInvalidFormatException.h"

@implementation OFTarArchive: OFObject
+ (instancetype)archiveWithStream: (OFStream*)stream
+ (instancetype)archiveWithStream: (OFStream *)stream
{
	return [[[self alloc] initWithStream: stream] autorelease];
}

#ifdef OF_HAVE_FILES
+ (instancetype)archiveWithPath: (OFString*)path
+ (instancetype)archiveWithPath: (OFString *)path
{
	return [[[self alloc] initWithPath: path] autorelease];
}
#endif

- initWithStream: (OFStream*)stream
- initWithStream: (OFStream *)stream
{
	self = [super init];

	_stream = [stream retain];

	return self;
}

#ifdef OF_HAVE_FILES
- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
{
	self = [super init];

	@try {
		_stream = [[OFFile alloc] initWithPath: path
						  mode: @"rb"];
	} @catch (id e) {
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83







-
+







{
	[_stream release];
	[_lastReturnedEntry release];

	[super dealloc];
}

- (OFTarArchiveEntry*)nextEntry
- (OFTarArchiveEntry *)nextEntry
{
	union {
		char c[512];
		uint32_t u32[512 / sizeof(uint32_t)];
	} buffer;
	bool empty = true;

Modified src/OFTarArchiveEntry+Private.h from [5f38226781] to [6ecc8476c9].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#import "OFTarArchiveEntry.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFTarArchiveEntry ()
- (instancetype)OF_initWithHeader: (char[_Nonnull 512])header
			   stream: (OFStream*)stream;
			   stream: (OFStream *)stream;
- (void)OF_skip;
@end

OF_ASSUME_NONNULL_END

Modified src/OFTarArchiveEntry.m from [4e294b0368] to [c0d69369d6].

24
25
26
27
28
29
30
31

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

31
32
33
34
35
36
37
38







-
+







#import "OFTarArchiveEntry+Private.h"
#import "OFStream.h"
#import "OFDate.h"

#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"

static OFString*
static OFString *
stringFromBuffer(const char *buffer, size_t length)
{
	for (size_t i = 0; i < length; i++)
		if (buffer[i] == '\0')
			length = i;

	return [OFString stringWithUTF8String: buffer
54
55
56
57
58
59
60
61

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

61
62
63
64
65
66
67
68







-
+







@synthesize fileName = _fileName, mode = _mode, size = _size;
@synthesize modificationDate = _modificationDate, type = _type;
@synthesize targetFileName = _targetFileName;
@synthesize owner = _owner, group = _group;
@synthesize deviceMajor = _deviceMajor, deviceMinor = _deviceMinor;

- (instancetype)OF_initWithHeader: (char[512])header
			   stream: (OFStream*)stream
			   stream: (OFStream *)stream
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();

		_stream = [stream retain];
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130







-
+







	[_targetFileName release];
	[_owner release];
	[_group release];

	[super dealloc];
}

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

	if (_atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191







-
+







	}

	if (_size % 512 != 0)
		[_stream readIntoBuffer: buffer
			    exactLength: 512 - ((size_t)_size % 512)];
}

- (OFString*)description
- (OFString *)description
{
	void *pool = objc_autoreleasePoolPush();
	OFString *ret = [OFString stringWithFormat: @"<%@:\n"
	     @"\tFile name = %@\n"
	     @"\tMode = %06o\n"
	     @"\tSize = %" PRIu64 @"\n"
	     @"\tModification date = %@\n"

Modified src/OFThread.h from [5cd28cdb35] to [04bcc49824].

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







-
+






-
+







-
+















-
+







# endif

/*!
 * @brief Returns the current thread.
 *
 * @return The current thread
 */
+ (OFThread*)currentThread;
+ (OFThread *)currentThread;

/*!
 * @brief Returns the main thread.
 *
 * @return The main thread
 */
+ (OFThread*)mainThread;
+ (OFThread *)mainThread;

/*!
 * @brief Returns a dictionary to store thread-specific data, meaning it
 *	  returns a different dictionary for every thread.
 *
 * @return A dictionary to store thread-specific data.
 */
+ (OFMutableDictionary*)threadDictionary;
+ (OFMutableDictionary *)threadDictionary;
#endif

/*!
 * @brief Suspends execution of the current thread for the specified time
 *	  interval.
 *
 * @param timeInterval The number of seconds to sleep
 */
+ (void)sleepForTimeInterval: (of_time_interval_t)timeInterval;

/*!
 * @brief Suspends execution of the current thread until the specified date.
 *
 * @param date The date to wait for
 */
+ (void)sleepUntilDate: (OFDate*)date;
+ (void)sleepUntilDate: (OFDate *)date;

/*!
 * @brief Yields a processor voluntarily and moves the thread to the end of the
 *	  queue for its priority.
 */
+ (void)yield;

199
200
201
202
203
204
205
206

207
208
209
210
211
212
213

214
215
216
217
218
219
220

221
222
223
224
225
226
227
199
200
201
202
203
204
205

206
207
208
209
210
211
212

213
214
215
216
217
218
219

220
221
222
223
224
225
226
227







-
+






-
+






-
+







- (id)join;

/*!
 * @brief Returns the run loop for the thread.
 *
 * @return The run loop for the thread
 */
- (OFRunLoop*)runLoop;
- (OFRunLoop *)runLoop;

/*!
 * @brief Returns the name of the thread or `nil` if none has been set.
 *
 * @return The name of the thread or nil if none has been set
 */
- (nullable OFString*)name;
- (nullable OFString *)name;

/*!
 * @brief Sets the name for the thread.
 *
 * @param name The name for the thread
 */
- (void)setName: (nullable OFString*)name;
- (void)setName: (nullable OFString *)name;

/*!
 * @brief Returns the priority of the thread.
 *
 * This is a value between -1.0 (meaning lowest priority that still schedules)
 * and +1.0 (meaning highest priority that still allows getting preempted)
 * with normal priority being 0.0 (meaning being the same as the main thread).

Modified src/OFThread.m from [44538b1550] to [a839633991].

95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109







-
+








static of_tlskey_t threadSelfKey;
static OFThread *mainThread;

static void
callMain(id object)
{
	OFThread *thread = (OFThread*)object;
	OFThread *thread = (OFThread *)object;

	if (!of_tlskey_set(threadSelfKey, thread))
		@throw [OFInitializationFailedException
		    exceptionWithClass: [thread class]];

	thread->_pool = objc_autoreleasePoolPush();

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







-
+




-
+




-
+







# ifdef OF_HAVE_BLOCKS
+ (instancetype)threadWithThreadBlock: (of_thread_block_t)threadBlock
{
	return [[[self alloc] initWithThreadBlock: threadBlock] autorelease];
}
# endif

+ (OFThread*)currentThread
+ (OFThread *)currentThread
{
	return of_tlskey_get(threadSelfKey);
}

+ (OFThread*)mainThread
+ (OFThread *)mainThread
{
	return mainThread;
}

+ (OFMutableDictionary*)threadDictionary
+ (OFMutableDictionary *)threadDictionary
{
	OFThread *thread = of_tlskey_get(threadSelfKey);

	if (thread->_threadDictionary == nil)
		thread->_threadDictionary = [[OFMutableDictionary alloc] init];

	return thread->_threadDictionary;
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
218
219
220
221
222
223
224

225
226
227
228
229
230
231
232







-
+








	sleep((unsigned int)timeInterval);
	usleep((useconds_t)lrint(
	    (timeInterval - floor(timeInterval)) * 1000000));
#endif
}

+ (void)sleepUntilDate: (OFDate*)date
+ (void)sleepUntilDate: (OFDate *)date
{
	[self sleepForTimeInterval: [date timeIntervalSinceNow]];
}

+ (void)yield
{
#ifdef OF_HAVE_SCHED_YIELD
365
366
367
368
369
370
371
372

373
374
375
376
377
378

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

392
393
394
395
396

397
398
399
400
401
402
403
365
366
367
368
369
370
371

372
373
374
375
376
377

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

391
392
393
394
395

396
397
398
399
400
401
402
403







-
+





-
+












-
+




-
+







}

- copy
{
	return [self retain];
}

- (OFRunLoop*)runLoop
- (OFRunLoop *)runLoop
{
# ifdef OF_HAVE_ATOMIC_OPS
	if (_runLoop == nil) {
		OFRunLoop *tmp = [[OFRunLoop alloc] init];

		if (!of_atomic_ptr_cmpswap((void**)&_runLoop, nil, tmp))
		if (!of_atomic_ptr_cmpswap((void **)&_runLoop, nil, tmp))
			[tmp release];
	}
# else
	@synchronized (self) {
		if (_runLoop == nil)
			_runLoop = [[OFRunLoop alloc] init];
	}
# endif

	return [[_runLoop retain] autorelease];
}

- (OFString*)name
- (OFString *)name
{
	return [[_name copy] autorelease];
}

- (void)setName: (OFString*)name
- (void)setName: (OFString *)name
{
	OFString *old = name;
	_name = [name copy];
	[old release];

	if (_running == OF_THREAD_RUNNING)
		of_thread_set_name(_thread, (_name != nil

Modified src/OFThreadPool.m from [f68a86f2dd] to [04406d7334].

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







-
-
+
+



-
+




-
+







	OFList *_queue;
	OFCondition *_queueCondition, *_countCondition;
@public
	volatile bool _terminate;
	volatile int *_doneCount;
}

+ (instancetype)threadWithThreadPool: (OFThreadPool*)threadPool;
- initWithThreadPool: (OFThreadPool*)threadPool;
+ (instancetype)threadWithThreadPool: (OFThreadPool *)threadPool;
- initWithThreadPool: (OFThreadPool *)threadPool;
@end

@implementation OFThreadPoolThread
+ (instancetype)threadWithThreadPool: (OFThreadPool*)threadPool
+ (instancetype)threadWithThreadPool: (OFThreadPool *)threadPool
{
	return [[[self alloc] initWithThreadPool: threadPool] autorelease];
}

- initWithThreadPool: (OFThreadPool*)threadPool
- initWithThreadPool: (OFThreadPool *)threadPool
{
	self = [super init];

	@try {
		_queue = [threadPool->_queue retain];
		_queueCondition = [threadPool->_queueCondition retain];
		_countCondition = [threadPool->_countCondition retain];
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
312
313
314
315
316
317
318

319
320
321
322
323
324
325
326







-
+







	[_queue release];
	[_queueCondition release];
	[_countCondition release];

	[super dealloc];
}

- (void)OF_dispatchJob: (OFThreadPoolJob*)job
- (void)OF_dispatchJob: (OFThreadPoolJob *)job
{
	[_countCondition lock];
	_count++;
	[_countCondition unlock];

	[_queueCondition lock];
	@try {

Modified src/OFTimer.h from [6a8324c7be] to [8072cf7aa4].

212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245







-
+


















-
+







 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- initWithFireDate: (OFDate*)fireDate
- initWithFireDate: (OFDate *)fireDate
	  interval: (of_time_interval_t)interval
	    target: (id)target
	  selector: (SEL)selector
	   repeats: (bool)repeats;

/*!
 * @brief Initializes an already allocated timer with the specified time
 *	  interval.
 *
 * @param fireDate The date at which the timer should fire
 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param target The target on which to call the selector
 * @param selector The selector to call on the target
 * @param object An object to pass when calling the selector on the target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- initWithFireDate: (OFDate*)fireDate
- initWithFireDate: (OFDate *)fireDate
	  interval: (of_time_interval_t)interval
	    target: (id)target
	  selector: (SEL)selector
	    object: (nullable id)object
	   repeats: (bool)repeats;

/*!
254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

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

298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317







-
+



















-
+
















-
+











-
+







 * @param object1 The first object to pass when calling the selector on the
 *		  target
 * @param object2 The second object to pass when calling the selector on the
 *		  target
 * @param repeats Whether the timer repeats after it has been executed
 * @return An initialized timer
 */
- initWithFireDate: (OFDate*)fireDate
- initWithFireDate: (OFDate *)fireDate
	  interval: (of_time_interval_t)interval
	    target: (id)target
	  selector: (SEL)selector
	    object: (nullable id)object1
	    object: (nullable id)object2
	   repeats: (bool)repeats;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Initializes an already allocated timer with the specified time
 *	  interval.
 *
 * @param fireDate The date at which the timer should fire
 * @param interval The time interval after which to repeat the timer, if it is
 *		   a repeating timer
 * @param repeats Whether the timer repeats after it has been executed
 * @param block The block to invoke when the timer fires
 * @return An initialized timer
 */
- initWithFireDate: (OFDate*)fireDate
- initWithFireDate: (OFDate *)fireDate
	  interval: (of_time_interval_t)interval
	   repeats: (bool)repeats
	     block: (of_timer_block_t)block;
#endif

/*!
 * @brief Fires the timer, meaning it will execute the specified selector on the
 *	  target.
 */
- (void)fire;

/*!
 * @brief Returns the next date at which the timer will fire.
 *
 * @return The next date at which the timer will fire
 */
- (OFDate*)fireDate;
- (OFDate *)fireDate;

/*!
 * @brief Sets the next date at which the timer will fire.
 *
 * If the timer is already scheduled in a run loop, it will be rescheduled.
 * Note that rescheduling is an expensive operation, though it still might be
 * preferable to reschedule instead of invalidating the timer and creating a
 * new one.
 *
 * @param fireDate The next date at which the timer will fire
 */
- (void)setFireDate: (OFDate*)fireDate;
- (void)setFireDate: (OFDate *)fireDate;

/*!
 * @brief Invalidates the timer, preventing it from firing.
 */
- (void)invalidate;

#ifdef OF_HAVE_THREADS

Modified src/OFTimer.m from [14c8339812] to [abb68d10aa].

208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222







-
+







#endif

- init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)OF_initWithFireDate: (OFDate*)fireDate
- (instancetype)OF_initWithFireDate: (OFDate *)fireDate
			   interval: (of_time_interval_t)interval
			     target: (id)target
			   selector: (SEL)selector
			     object: (id)object1
			     object: (id)object2
			  arguments: (uint8_t)arguments
			    repeats: (bool)repeats
240
241
242
243
244
245
246
247

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

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

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

300
301
302
303
304
305
306
240
241
242
243
244
245
246

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

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

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306







-
+















-
+
















-
+


















-
+







		[self release];
		@throw e;
	}

	return self;
}

- initWithFireDate: (OFDate*)fireDate
- initWithFireDate: (OFDate *)fireDate
	  interval: (of_time_interval_t)interval
	    target: (id)target
	  selector: (SEL)selector
	   repeats: (bool)repeats
{
	return [self OF_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: nil
				  object: nil
			       arguments: 0
				 repeats: repeats];
}

- initWithFireDate: (OFDate*)fireDate
- initWithFireDate: (OFDate *)fireDate
	  interval: (of_time_interval_t)interval
	    target: (id)target
	  selector: (SEL)selector
	    object: (id)object
	   repeats: (bool)repeats
{
	return [self OF_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object
				  object: nil
			       arguments: 1
				 repeats: repeats];
}

- initWithFireDate: (OFDate*)fireDate
- initWithFireDate: (OFDate *)fireDate
	  interval: (of_time_interval_t)interval
	    target: (id)target
	  selector: (SEL)selector
	    object: (id)object1
	    object: (id)object2
	   repeats: (bool)repeats
{
	return [self OF_initWithFireDate: fireDate
				interval: interval
				  target: target
				selector: selector
				  object: object1
				  object: object2
			       arguments: 2
				 repeats: repeats];
}

#ifdef OF_HAVE_BLOCKS
- initWithFireDate: (OFDate*)fireDate
- initWithFireDate: (OFDate *)fireDate
	   interval: (of_time_interval_t)interval
	    repeats: (bool)repeats
	      block: (of_timer_block_t)block
{
	self = [super init];

	@try {
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360







-
+







- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	OFTimer *timer;

	if (![object isKindOfClass: [OFTimer class]])
		@throw [OFInvalidArgumentException exception];

	timer = (OFTimer*)object;
	timer = (OFTimer *)object;

	return [_fireDate compare: timer->_fireDate];
}

- (void)fire
{
	void *pool = objc_autoreleasePoolPush();
406
407
408
409
410
411
412
413

414
415
416
417
418

419
420
421
422
423
424
425
406
407
408
409
410
411
412

413
414
415
416
417

418
419
420
421
422
423
424
425







-
+




-
+







		[_condition unlock];
	}
#endif

	objc_autoreleasePoolPop(pool);
}

- (OFDate*)fireDate
- (OFDate *)fireDate
{
	return [[_fireDate copy] autorelease];
}

- (void)setFireDate: (OFDate*)fireDate
- (void)setFireDate: (OFDate *)fireDate
{
	[self retain];
	@try {
		@synchronized (self) {
			OFDate *old;

			[_inRunLoop OF_removeTimer: self];

Modified src/OFUDPSocket.h from [087ce7f471] to [05fb60ba2c].

108
109
110
111
112
113
114
115

116
117

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156


157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190

191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

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

245
246

247
248
249
250
251
252
253
108
109
110
111
112
113
114

115
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154


155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173

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

188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
238
239
240
241
242
243

244
245

246
247
248
249
250
251
252
253







-
+

-
+














-
+













-
+








-
-
+
+






-
+










-
+













-
+

-
+



















-
+




















-
+












-
+

-
+







 *	  port pair.
 *
 * @param host The host to resolve
 * @param port The port for the resulting address
 * @param address A pointer to the address that should be filled with the
 *		  host / port pair
 */
+ (void)resolveAddressForHost: (OFString*)host
+ (void)resolveAddressForHost: (OFString *)host
			 port: (uint16_t)port
		      address: (of_udp_socket_address_t*)address;
		      address: (of_udp_socket_address_t *)address;

#ifdef OF_HAVE_THREADS
/*!
 * @brief Asynchronously resolves the specified host and creates an address for
 *	  the host / port pair.
 *
 * @param host The host to resolve
 * @param port The port for the resulting address
 * @param target The target on which to call the selector once the host has been
 *		 resolved
 * @param selector The selector to call on the target. The signature must be
 *		   `void (OFString *host, uint16_t port,
 *		   of_udp_socket_address_t address, OFException *exception)`.
 */
+ (void)asyncResolveAddressForHost: (OFString*)host
+ (void)asyncResolveAddressForHost: (OFString *)host
			      port: (uint16_t)port
			    target: (id)target
			  selector: (SEL)selector;

# ifdef OF_HAVE_BLOCKS
/*!
 * @brief Asynchronously resolves the specified host and creates an address for
 *	  the host / port pair.
 *
 * @param host The host to resolve
 * @param port The port for the resulting address
 * @param block The block to execute once the host has been resolved
 */
+ (void)asyncResolveAddressForHost: (OFString*)host
+ (void)asyncResolveAddressForHost: (OFString *)host
			      port: (uint16_t)port
			     block: (of_udp_socket_async_resolve_block_t)block;
# endif
#endif

/*!
 * @brief Gets the host and port for the specified address.
 *
 * @param host A pointer to an OFString*. If it is not NULL, it will be set to
 *	       the host of the host / port pair.
 * @param host A pointer to an @ref OFString *. If it is not NULL, it will be
 *	       set to the host of the host / port pair.
 * @param port A pointer to an uint16_t. If it is not NULL, the port of the
 *	       host / port pair will be written to it.
 * @param address The address for which the host and port should be retrieved
 */
+ (void)getHost: (OFString *__autoreleasing _Nonnull *_Nullable)host
	andPort: (uint16_t *_Nullable)port
     forAddress: (of_udp_socket_address_t*)address;
     forAddress: (of_udp_socket_address_t *)address;

/*!
 * @brief Binds the socket to the specified host and port.
 *
 * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for
 *	       IPv6 to bind to all.
 * @param port The port to bind to. If the port is 0, an unused port will be
 *	       chosen, which can be obtained using the return value.
 * @return The port the socket was bound to
 */
- (uint16_t)bindToHost: (OFString*)host
- (uint16_t)bindToHost: (OFString *)host
		  port: (uint16_t)port;

/*!
 * @brief Receives a datagram and stores it into the specified buffer.
 *
 * If the buffer is too small, the datagram is truncated.
 *
 * @param buffer The buffer to write the datagram to
 * @param length The length of the buffer
 * @param sender A pointer to an @ref of_udp_socket_address_t, which will be
 *		 set to the address of the sender
 * @return The length of the received datagram
 */
- (size_t)receiveIntoBuffer: (void*)buffer
- (size_t)receiveIntoBuffer: (void *)buffer
		     length: (size_t)length
		     sender: (of_udp_socket_address_t*)sender;
		     sender: (of_udp_socket_address_t *)sender;

/*!
 * @brief Asynchronously receives a datagram and stores it into the specified
 *	  buffer.
 *
 * If the buffer is too small, the datagram is truncated.
 *
 * @param buffer The buffer to write the datagram to
 * @param length The length of the buffer
 * @param target The target on which the selector should be called when the
 *		 datagram has been received. If the method returns true, it
 *		 will be called again with the same buffer and maximum length
 *		 when more datagrams have been received. If you want the next
 *		 method in the queue to handle the datagram received next, you
 *		 need to return false from the method.
 * @param selector The selector to call on the target. The signature must be
 *		   `bool (OFUDPSocket *socket, void *buffer, size_t length,
 *		   of_udp_socket_address_t, OFException *exception)`.
 */
- (void)asyncReceiveIntoBuffer: (void*)buffer
- (void)asyncReceiveIntoBuffer: (void *)buffer
			length: (size_t)length
			target: (id)target
		      selector: (SEL)selector;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Asynchronously receives a datagram and stores it into the specified
 *	  buffer.
 *
 * If the buffer is too small, the datagram is truncated.
 *
 * @param buffer The buffer to write the datagram to
 * @param length The length of the buffer
 * @param block The block to call when the datagram has been received. If the
 *		block returns true, it will be called again with the same
 *		buffer and maximum length when more datagrams have been
 *		received. If you want the next method in the queue to handle
 *		the datagram received next, you need to return false from the
 *		method.
 */
- (void)asyncReceiveIntoBuffer: (void*)buffer
- (void)asyncReceiveIntoBuffer: (void *)buffer
			length: (size_t)length
			 block: (of_udp_socket_async_receive_block_t)block;
#endif

/*!
 * @brief Sends the specified datagram to the specified address.
 *
 * @param buffer The buffer to send as a datagram
 * @param length The length of the buffer
 * @param receiver A pointer to an @ref of_udp_socket_address_t to which the
 *		   datagram should be sent
 */
- (void)sendBuffer: (const void*)buffer
- (void)sendBuffer: (const void *)buffer
	    length: (size_t)length
	  receiver: (const of_udp_socket_address_t*)receiver;
	  receiver: (const of_udp_socket_address_t *)receiver;

/*!
 * @brief Cancels all pending asynchronous requests on the socket.
 */
- (void)cancelAsyncRequests;

/*!

Modified src/OFUDPSocket.m from [7e2210cd91] to [f67659d08d].

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







-
-
+
+




-
-
+
+






-
-
+
+







# ifdef OF_HAVE_BLOCKS
	of_udp_socket_async_resolve_block_t _block;
# endif
	of_udp_socket_address_t _address;
	OFException *_exception;
}

- initWithSourceThread: (OFThread*)sourceThread
		  host: (OFString*)host
- initWithSourceThread: (OFThread *)sourceThread
		  host: (OFString *)host
		  port: (uint16_t)port
		target: (id)target
	      selector: (SEL)selector;
# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread
		  host: (OFString*)host
- initWithSourceThread: (OFThread *)sourceThread
		  host: (OFString *)host
		  port: (uint16_t)port
		 block: (of_udp_socket_async_resolve_block_t)block;
# endif
@end

@implementation OFUDPSocket_ResolveThread
- initWithSourceThread: (OFThread*)sourceThread
		  host: (OFString*)host
- initWithSourceThread: (OFThread *)sourceThread
		  host: (OFString *)host
		  port: (uint16_t)port
		target: (id)target
	      selector: (SEL)selector
{
	self = [super init];

	@try {
89
90
91
92
93
94
95
96
97


98
99
100
101
102
103
104
89
90
91
92
93
94
95


96
97
98
99
100
101
102
103
104







-
-
+
+







		@throw e;
	}

	return self;
}

# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread
		  host: (OFString*)host
- initWithSourceThread: (OFThread *)sourceThread
		  host: (OFString *)host
		  port: (uint16_t)port
		 block: (of_udp_socket_async_resolve_block_t)block
{
	self = [super init];

	@try {
		_sourceThread = [sourceThread retain];
132
133
134
135
136
137
138
139
140
141
142




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




139
140
141
142
143
144
145
146
147
148
149







-
-
-
-
+
+
+
+







	[self join];

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(_host, _port, _address, _exception);
	else {
# endif
		void (*func)(id, SEL, OFString*, uint16_t,
		    of_udp_socket_address_t, OFException*) =
		    (void(*)(id, SEL, OFString*, uint16_t,
		    of_udp_socket_address_t, OFException*))[_target
		void (*func)(id, SEL, OFString *, uint16_t,
		    of_udp_socket_address_t, OFException *) =
		    (void (*)(id, SEL, OFString *, uint16_t,
		    of_udp_socket_address_t, OFException *))[_target
		    methodForSelector: _selector];

		func(_target, _selector, _host, _port, _address, _exception);
# ifdef OF_HAVE_BLOCKS
	}
# endif
}
190
191
192
193
194
195
196
197
198


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213


214
215
216
217
218
219
220
190
191
192
193
194
195
196


197
198
199
200
201
202
203
204
205
206
207
208
209
210
211


212
213
214
215
216
217
218
219
220







-
-
+
+













-
-
+
+







		    address2->length < (socklen_t)sizeof(struct sockaddr_in))
			@throw [OFInvalidArgumentException exception];
#else
		if (address1->length < 8 || address2->length < 8)
			@throw [OFInvalidArgumentException exception];
#endif

		sin_1 = (struct sockaddr_in*)&address1->address;
		sin_2 = (struct sockaddr_in*)&address2->address;
		sin_1 = (struct sockaddr_in *)&address1->address;
		sin_2 = (struct sockaddr_in *)&address2->address;

		if (sin_1->sin_port != sin_2->sin_port)
			return false;
		if (sin_1->sin_addr.s_addr != sin_2->sin_addr.s_addr)
			return false;

		break;
#ifdef HAVE_IPV6
	case AF_INET6:
		if (address1->length < sizeof(struct sockaddr_in6) ||
		    address2->length < sizeof(struct sockaddr_in6))
			@throw [OFInvalidArgumentException exception];

		sin6_1 = (struct sockaddr_in6*)&address1->address;
		sin6_2 = (struct sockaddr_in6*)&address2->address;
		sin6_1 = (struct sockaddr_in6 *)&address1->address;
		sin6_2 = (struct sockaddr_in6 *)&address2->address;

		if (sin6_1->sin6_port != sin6_2->sin6_port)
			return false;
		if (memcmp(sin6_1->sin6_addr.s6_addr,
		    sin6_2->sin6_addr.s6_addr,
		    sizeof(sin6_1->sin6_addr.s6_addr)) != 0)
			return false;
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271







-
+










-
+







		if (address->length < (socklen_t)sizeof(struct sockaddr_in))
			@throw [OFInvalidArgumentException exception];
#else
		if (address->length < 8)
			@throw [OFInvalidArgumentException exception];
#endif

		sin = (struct sockaddr_in*)&address->address;
		sin = (struct sockaddr_in *)&address->address;

		hash += (sin->sin_port << 1);
		hash ^= sin->sin_addr.s_addr;

		break;
#ifdef HAVE_IPV6
	case AF_INET6:
		if (address->length < sizeof(struct sockaddr_in6))
			@throw [OFInvalidArgumentException exception];

		sin6 = (struct sockaddr_in6*)&address->address;
		sin6 = (struct sockaddr_in6 *)&address->address;

		hash += (sin6->sin6_port << 1);

		OF_HASH_INIT(subhash);

		for (size_t i = 0; i < sizeof(sin6->sin6_addr.s6_addr); i++)
			OF_HASH_ADD(subhash, sin6->sin6_addr.s6_addr[i]);
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
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







-
+

-
+















-
+

















-
+
















-
-
-
+
+
+


-
+







}

+ (instancetype)socket
{
	return [[[self alloc] init] autorelease];
}

+ (void)resolveAddressForHost: (OFString*)host
+ (void)resolveAddressForHost: (OFString *)host
			 port: (uint16_t)port
		      address: (of_udp_socket_address_t*)address
		      address: (of_udp_socket_address_t *)address
{
	of_resolver_result_t **results =
	    of_resolve_host(host, port, SOCK_DGRAM);

	assert(results[0]->addressLength <=
	    (socklen_t)sizeof(address->address));

	memcpy(&address->address, results[0]->address,
	    results[0]->addressLength);
	address->length = results[0]->addressLength;

	of_resolver_free(results);
}

#ifdef OF_HAVE_THREADS
+ (void)asyncResolveAddressForHost: (OFString*)host
+ (void)asyncResolveAddressForHost: (OFString *)host
			      port: (uint16_t)port
			    target: (id)target
			  selector: (SEL)selector
{
	void *pool = objc_autoreleasePoolPush();

	[[[[OFUDPSocket_ResolveThread alloc]
	    initWithSourceThread: [OFThread currentThread]
			    host: host
			    port: port
			  target: target
			selector: selector] autorelease] start];

	objc_autoreleasePoolPop(pool);
}

# ifdef OF_HAVE_BLOCKS
+ (void)asyncResolveAddressForHost: (OFString*)host
+ (void)asyncResolveAddressForHost: (OFString *)host
			      port: (uint16_t)port
			     block: (of_udp_socket_async_resolve_block_t)block
{
	void *pool = objc_autoreleasePoolPush();

	[[[[OFUDPSocket_ResolveThread alloc]
	    initWithSourceThread: [OFThread currentThread]
			    host: host
			    port: port
			   block: block] autorelease] start];

	objc_autoreleasePoolPop(pool);
}
# endif
#endif

+ (void)getHost: (OFString *__autoreleasing*)host
	andPort: (uint16_t*)port
     forAddress: (of_udp_socket_address_t*)address
+ (void)getHost: (OFString *__autoreleasing *)host
	andPort: (uint16_t *)port
     forAddress: (of_udp_socket_address_t *)address
{
	of_address_to_string_and_port(
	    (struct sockaddr*)&address->address, address->length, host, port);
	    (struct sockaddr *)&address->address, address->length, host, port);
}

- init
{
	self = [super init];

	_socket = INVALID_SOCKET;
378
379
380
381
382
383
384
385

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

385
386
387
388
389
390
391
392







-
+







}

- copy
{
	return [self retain];
}

- (uint16_t)bindToHost: (OFString*)host
- (uint16_t)bindToHost: (OFString *)host
		  port: (uint16_t)port
{
	of_resolver_result_t **results;
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
	union {
		struct sockaddr_storage storage;
		struct sockaddr_in in;
440
441
442
443
444
445
446
447

448
449
450
451
452
453

454
455
456
457
458
459
460
440
441
442
443
444
445
446

447
448
449
450
451
452

453
454
455
456
457
458
459
460







-
+





-
+







				int ret;

				while (rnd < 1024)
					rnd = (uint16_t)rand();

				switch (results[0]->family) {
				case AF_INET:
					((struct sockaddr_in*)
					((struct sockaddr_in *)
					    results[0]->address)->sin_port =
					    OF_BSWAP16_IF_LE(rnd);
					break;
# ifdef HAVE_IPV6
				case AF_INET6:
					((struct sockaddr_in6*)
					((struct sockaddr_in6 *)
					    results[0]->address)->sin6_port =
					    OF_BSWAP16_IF_LE(rnd);
					break;
# endif
				default:
					@throw [OFInvalidArgumentException
					    exception];
488
489
490
491
492
493
494
495

496
497
498
499
500
501
502
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502







-
+







	}

	if (port > 0)
		return port;

#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
	addrLen = (socklen_t)sizeof(addr.storage);
	if (of_getsockname(_socket, (struct sockaddr*)&addr.storage,
	if (of_getsockname(_socket, (struct sockaddr *)&addr.storage,
	    &addrLen) != 0) {
		int errNo = of_socket_errno();

		close(_socket);
		_socket = INVALID_SOCKET;

		@throw [OFBindFailedException exceptionWithHost: host
517
518
519
520
521
522
523
524

525
526

527
528
529
530
531
532
533
534
535
536
537

538
539
540
541
542
543
544
545
546
547

548
549
550
551
552
553
554
555
556
557

558
559
560
561
562
563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
578
579
580
581

582
583

584
585
586
587
588
589
590
591
592
593

594
595
596
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611
517
518
519
520
521
522
523

524
525

526
527
528
529
530
531
532
533
534
535
536

537
538
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553
554
555
556

557
558
559
560
561
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
577
578
579
580

581
582

583
584
585
586
587
588
589
590
591
592

593
594
595
596
597
598
599
600
601
602
603

604
605
606
607
608
609
610
611







-
+

-
+










-
+









-
+









-
+












-
+










-
+

-
+









-
+










-
+







	_socket = INVALID_SOCKET;
	@throw [OFBindFailedException exceptionWithHost: host
						   port: port
						 socket: self
						  errNo: EAFNOSUPPORT];
}

- (size_t)receiveIntoBuffer: (void*)buffer
- (size_t)receiveIntoBuffer: (void *)buffer
		     length: (size_t)length
		     sender: (of_udp_socket_address_t*)sender
		     sender: (of_udp_socket_address_t *)sender
{
	ssize_t ret;

	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

	sender->length = (socklen_t)sizeof(sender->address);

#ifndef OF_WINDOWS
	if ((ret = recvfrom(_socket, buffer, length, 0,
	    (struct sockaddr*)&sender->address, &sender->length)) < 0)
	    (struct sockaddr *)&sender->address, &sender->length)) < 0)
		@throw [OFReadFailedException
		    exceptionWithObject: self
			requestedLength: length
				  errNo: of_socket_errno()];
#else
	if (length > INT_MAX)
		@throw [OFOutOfRangeException exception];

	if ((ret = recvfrom(_socket, buffer, (int)length, 0,
	    (struct sockaddr*)&sender->address, &sender->length)) < 0)
	    (struct sockaddr *)&sender->address, &sender->length)) < 0)
		@throw [OFReadFailedException
		    exceptionWithObject: self
			requestedLength: length
				  errNo: of_socket_errno()];
#endif

	return ret;
}

- (void)asyncReceiveIntoBuffer: (void*)buffer
- (void)asyncReceiveIntoBuffer: (void *)buffer
			length: (size_t)length
			target: (id)target
		      selector: (SEL)selector
{
	[OFRunLoop OF_addAsyncReceiveForUDPSocket: self
					   buffer: buffer
					   length: length
					   target: target
					 selector: selector];
}

#ifdef OF_HAVE_BLOCKS
- (void)asyncReceiveIntoBuffer: (void*)buffer
- (void)asyncReceiveIntoBuffer: (void *)buffer
			length: (size_t)length
			 block: (of_udp_socket_async_receive_block_t)block
{
	[OFRunLoop OF_addAsyncReceiveForUDPSocket: self
					   buffer: buffer
					   length: length
					    block: block];
}
#endif

- (void)sendBuffer: (const void*)buffer
- (void)sendBuffer: (const void *)buffer
	    length: (size_t)length
	  receiver: (const of_udp_socket_address_t*)receiver
	  receiver: (const of_udp_socket_address_t *)receiver
{
	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

#ifndef OF_WINDOWS
	if (length > SSIZE_MAX)
		@throw [OFOutOfRangeException exception];

	if (sendto(_socket, buffer, length, 0,
	    (struct sockaddr*)&receiver->address,
	    (struct sockaddr *)&receiver->address,
	    receiver->length) != (ssize_t)length)
		@throw [OFWriteFailedException
		    exceptionWithObject: self
			requestedLength: length
				  errNo: of_socket_errno()];
#else
	if (length > INT_MAX)
		@throw [OFOutOfRangeException exception];

	if (sendto(_socket, buffer, (int)length, 0,
	    (struct sockaddr*)&receiver->address,
	    (struct sockaddr *)&receiver->address,
	    receiver->length) != (int)length)
		@throw [OFWriteFailedException
		    exceptionWithObject: self
			requestedLength: length
				  errNo: of_socket_errno()];
#endif
}

Modified src/OFURL.h from [336f088c44] to [de5ad4004e].

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







-
+









-
-
+
+







-
+







-
+









-
-
+
+






-
+




/*!
 * @brief Creates a new URL with the specified string.
 *
 * @param string A string describing a URL
 * @return A new, autoreleased OFURL
 */
+ (instancetype)URLWithString: (OFString*)string;
+ (instancetype)URLWithString: (OFString *)string;

/*!
 * @brief Creates a new URL with the specified string relative to the
 *	  specified URL.
 *
 * @param string A string describing a URL
 * @param URL An URL to which the string is relative
 * @return A new, autoreleased OFURL
 */
+ (instancetype)URLWithString: (OFString*)string
		relativeToURL: (OFURL*)URL;
+ (instancetype)URLWithString: (OFString *)string
		relativeToURL: (OFURL *)URL;

/*!
 * @brief Creates a new URL with the specified local file path.
 *
 * @param path The local file path
 * @return A new, autoreleased OFURL
 */
+ (instancetype)fileURLWithPath: (OFString*)path;
+ (instancetype)fileURLWithPath: (OFString *)path;

/*!
 * @brief Initializes an already allocated OFURL with the specified string.
 *
 * @param string A string describing a URL
 * @return An initialized OFURL
 */
- initWithString: (OFString*)string;
- initWithString: (OFString *)string;

/*!
 * @brief Initializes an already allocated OFURL with the specified string and
 *	  relative URL.
 *
 * @param string A string describing a URL
 * @param URL A URL to which the string is relative
 * @return An initialized OFURL
 */
- initWithString: (OFString*)string
   relativeToURL: (OFURL*)URL;
- initWithString: (OFString *)string
   relativeToURL: (OFURL *)URL;

/*!
 * @brief Returns the URL as a string.
 *
 * @return The URL as a string
 */
- (OFString*)string;
- (OFString *)string;
@end

OF_ASSUME_NONNULL_END

Modified src/OFURL.m from [9669ae9920] to [b76d8bb1be].

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







-
+




-
-
+
+





-
+












-
+







@synthesize query = _query, fragment = _fragment;

+ (instancetype)URL
{
	return [[[self alloc] init] autorelease];
}

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

+ (instancetype)URLWithString: (OFString*)string
		relativeToURL: (OFURL*)URL
+ (instancetype)URLWithString: (OFString *)string
		relativeToURL: (OFURL *)URL
{
	return [[[self alloc] initWithString: string
			       relativeToURL: URL] autorelease];
}

+ (instancetype)fileURLWithPath: (OFString*)path
+ (instancetype)fileURLWithPath: (OFString *)path
{
	OFURL *URL = [OFURL URL];
	void *pool = objc_autoreleasePoolPush();

	[URL setScheme: @"file"];
	[URL setPath: [[path pathComponents] componentsJoinedByString: @"/"]];

	objc_autoreleasePoolPop(pool);

	return URL;
}

- initWithString: (OFString*)string
- initWithString: (OFString *)string
{
	char *UTF8String, *UTF8String2 = NULL;

	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
193
194
195
196
197
198
199
200
201


202
203
204
205
206
207
208
193
194
195
196
197
198
199


200
201
202
203
204
205
206
207
208







-
-
+
+







	} @finally {
		free(UTF8String2);
	}

	return self;
}

- initWithString: (OFString*)string
   relativeToURL: (OFURL*)URL
- initWithString: (OFString *)string
   relativeToURL: (OFURL *)URL
{
	char *UTF8String, *UTF8String2 = NULL;

	if ([string containsString: @"://"])
		return [self initWithString: string];

	self = [super init];
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281







-
+







	} @finally {
		free(UTF8String2);
	}

	return self;
}

- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	@try {
		void *pool = objc_autoreleasePoolPush();

		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException exception];
380
381
382
383
384
385
386
387

388
389
390
391
392
393
394
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394







-
+







		[copy release];
		@throw e;
	}

	return copy;
}

- (OFString*)string
- (OFString *)string
{
	OFMutableString *ret = [OFMutableString string];
	void *pool = objc_autoreleasePoolPush();

	[ret appendFormat: @"%@://", _scheme];

	if ([_scheme isEqual: @"file"]) {
431
432
433
434
435
436
437
438

439
440
441
442
443
444

445
446
447
448
449
450
451
431
432
433
434
435
436
437

438
439
440
441
442
443

444
445
446
447
448
449
450
451







-
+





-
+







	objc_autoreleasePoolPop(pool);

	[ret makeImmutable];

	return ret;
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat: @"<%@: %@>",
					   [self class], [self string]];
}

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

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

Modified src/OFXMLAttribute.h from [3c807a0561] to [2122e7a8be].

49
50
51
52
53
54
55
56
57


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



70
71
72
73
74
75
76
77
78
79


80
81
82
83
84
85
86
87
88
89
90
91



92
93
94
49
50
51
52
53
54
55


56
57
58
59
60
61
62
63
64
65
66



67
68
69
70
71
72
73
74
75
76
77


78
79
80
81
82
83
84
85
86
87
88



89
90
91
92
93
94







-
-
+
+









-
-
-
+
+
+








-
-
+
+









-
-
-
+
+
+



/*!
 * @brief Creates a new XML attribute.
 *
 * @param name The name of the attribute
 * @param stringValue The string value of the attribute
 * @return A new autoreleased OFXMLAttribute with the specified parameters
 */
+ (instancetype)attributeWithName: (OFString*)name
		      stringValue: (OFString*)stringValue;
+ (instancetype)attributeWithName: (OFString *)name
		      stringValue: (OFString *)stringValue;

/*!
 * @brief Creates a new XML attribute.
 *
 * @param name The name of the attribute
 * @param namespace_ The namespace of the attribute
 * @param stringValue The string value of the attribute
 * @return A new autoreleased OFXMLAttribute with the specified parameters
 */
+ (instancetype)attributeWithName: (OFString*)name
			namespace: (nullable OFString*)namespace_
		      stringValue: (OFString*)stringValue;
+ (instancetype)attributeWithName: (OFString *)name
			namespace: (nullable OFString *)namespace_
		      stringValue: (OFString *)stringValue;

/*!
 * @brief Initializes an already allocated OFXMLAttribute.
 *
 * @param name The name of the attribute
 * @param stringValue The string value of the attribute
 * @return An initialized OFXMLAttribute with the specified parameters
 */
- initWithName: (OFString*)name
   stringValue: (OFString*)stringValue;
- initWithName: (OFString *)name
   stringValue: (OFString *)stringValue;

/*!
 * @brief Initializes an already allocated OFXMLAttribute.
 *
 * @param name The name of the attribute
 * @param namespace_ The namespace of the attribute
 * @param stringValue The string value of the attribute
 * @return An initialized OFXMLAttribute with the specified parameters
 */
- initWithName: (OFString*)name
     namespace: (nullable OFString*)namespace_
   stringValue: (OFString*)stringValue;
- initWithName: (OFString *)name
     namespace: (nullable OFString *)namespace_
   stringValue: (OFString *)stringValue;
@end

OF_ASSUME_NONNULL_END

Modified src/OFXMLAttribute.m from [c87ea13e1e] to [08b89a1a1d].

22
23
24
25
26
27
28
29
30
31



32
33
34
35
36
37
38
39


40
41
42
43
44
45
46


47
48
49
50
51
52
53
54
55



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

72
73
74
75
76
77
78
22
23
24
25
26
27
28



29
30
31
32
33
34
35
36
37


38
39
40
41
42
43
44


45
46
47
48
49
50
51
52



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

71
72
73
74
75
76
77
78







-
-
-
+
+
+






-
-
+
+





-
-
+
+






-
-
-
+
+
+















-
+







#import "OFXMLElement.h"

#import "OFInvalidArgumentException.h"

@implementation OFXMLAttribute
@synthesize name = _name, namespace = _namespace;

+ (instancetype)attributeWithName: (OFString*)name
			namespace: (OFString*)namespace
		      stringValue: (OFString*)stringValue
+ (instancetype)attributeWithName: (OFString *)name
			namespace: (OFString *)namespace
		      stringValue: (OFString *)stringValue
{
	return [[[self alloc] initWithName: name
				 namespace: namespace
			       stringValue: stringValue] autorelease];
}

+ (instancetype)attributeWithName: (OFString*)name
		      stringValue: (OFString*)stringValue
+ (instancetype)attributeWithName: (OFString *)name
		      stringValue: (OFString *)stringValue
{
	return [[[self alloc] initWithName: name
			       stringValue: stringValue] autorelease];
}

- initWithName: (OFString*)name
   stringValue: (OFString*)stringValue
- initWithName: (OFString *)name
   stringValue: (OFString *)stringValue
{
	return [self initWithName: name
			namespace: nil
		      stringValue: stringValue];
}

- initWithName: (OFString*)name
     namespace: (OFString*)namespace
   stringValue: (OFString*)stringValue
- initWithName: (OFString *)name
     namespace: (OFString *)namespace
   stringValue: (OFString *)stringValue
{
	self = [super init];

	@try {
		_name = [name copy];
		_namespace = [namespace copy];
		_stringValue = [stringValue copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		void *pool = objc_autoreleasePoolPush();

		if (![[element name] isEqual: [self className]] ||
100
101
102
103
104
105
106
107

108
109
110
111
112

113
114
115
116
117
118
119
100
101
102
103
104
105
106

107
108
109
110
111

112
113
114
115
116
117
118
119







-
+




-
+







	[_name release];
	[_namespace release];
	[_stringValue release];

	[super dealloc];
}

- (OFString*)stringValue
- (OFString *)stringValue
{
	return [[_stringValue copy] autorelease];
}

- (void)setStringValue: (OFString*)stringValue
- (void)setStringValue: (OFString *)stringValue
{
	OFString *old = _stringValue;
	_stringValue = [stringValue copy];
	[old release];
}

- (bool)isEqual: (id)object
147
148
149
150
151
152
153
154

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

154
155
156
157
158
159
160
161







-
+







	OF_HASH_ADD_HASH(hash, [_stringValue hash]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

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

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

172
173
174
175
176
177
178
179

180
181
182
183
184
185
172
173
174
175
176
177
178

179
180
181
182
183
184
185







-
+






	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFXMLAttribute: name=%@, "
					   @"namespace=%@, stringValue=%@>",
					   _name, _namespace, _stringValue];
}
@end

Modified src/OFXMLCDATA.h from [304bae9f03] to [db549733cc].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45

46
47
48
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44

45
46
47
48







-
+







-
+




/*!
 * @brief Creates a new OFXMLCDATA with the specified string.
 *
 * @param string The string value for the CDATA
 * @return A new OFXMLCDATA
 */
+ (instancetype)CDATAWithString: (OFString*)string;
+ (instancetype)CDATAWithString: (OFString *)string;

/*!
 * @brief Initializes an already allocated OFXMLCDATA with the specified string.
 *
 * @param string The string value for the CDATA
 * @return An initialized OFXMLCDATA
 */
- initWithString: (OFString*)string;
- initWithString: (OFString *)string;
@end

OF_ASSUME_NONNULL_END

Modified src/OFXMLCDATA.m from [4599ccf7bf] to [710869577e].

19
20
21
22
23
24
25
26

27
28
29
30
31

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

46
47
48
49
50
51
52
19
20
21
22
23
24
25

26
27
28
29
30

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

45
46
47
48
49
50
51
52







-
+




-
+













-
+







#import "OFXMLCDATA.h"
#import "OFString.h"
#import "OFXMLElement.h"

#import "OFInvalidArgumentException.h"

@implementation OFXMLCDATA
+ (instancetype)CDATAWithString: (OFString*)string
+ (instancetype)CDATAWithString: (OFString *)string
{
	return [[[self alloc] initWithString: string] autorelease];
}

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

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

	return self;
}

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

	@try {
		void *pool = objc_autoreleasePoolPush();

		if (![[element name] isEqual: [self className]] ||
84
85
86
87
88
89
90
91

92
93
94
95
96

97
98
99
100
101
102
103

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

117
118
119
120
121

122
123
124
125
126
127

128
129
130
131
132

133
134
135
136
137
138
139
140
141
84
85
86
87
88
89
90

91
92
93
94
95

96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120

121
122
123
124
125
126

127
128
129
130
131

132
133
134
135
136
137
138
139
140
141







-
+




-
+






-
+












-
+




-
+





-
+




-
+









}

- (uint32_t)hash
{
	return [_CDATA hash];
}

- (OFString*)stringValue
- (OFString *)stringValue
{
	return [[_CDATA copy] autorelease];
}

- (void)setStringValue: (OFString*)stringValue
- (void)setStringValue: (OFString *)stringValue
{
	OFString *old = _CDATA;
	_CDATA = [stringValue copy];
	[old release];
}

- (OFString*)XMLString
- (OFString *)XMLString
{
	void *pool = objc_autoreleasePoolPush();
	OFString *tmp = [_CDATA
	    stringByReplacingOccurrencesOfString: @"]]>"
				      withString: @"]]>]]&gt;<![CDATA["];
	OFString *ret = [OFString stringWithFormat: @"<![CDATA[%@]]>", tmp];

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

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
{
	return [self XMLString];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				level: (unsigned int)level
{
	return [self XMLString];
}

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

- (OFXMLElement*)XMLElementBySerializing
- (OFXMLElement *)XMLElementBySerializing
{
	OFXMLElement *element =
	    [OFXMLElement elementWithName: [self className]
				namespace: OF_SERIALIZATION_NS];
	[element addChild: self];

	return element;
}
@end

Modified src/OFXMLCharacters.h from [e8d5ddfaa4] to [c3eee8f6e8].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46

47
48
49
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45

46
47
48
49







-
+








-
+




/*!
 * @brief Creates a new OFXMLCharacters with the specified string.
 *
 * @param string The string value for the characters
 * @return A new OFXMLCharacters
 */
+ (instancetype)charactersWithString: (OFString*)string;
+ (instancetype)charactersWithString: (OFString *)string;

/*!
 * @brief Initializes an already allocated OFXMLCharacters with the specified
 *	  string.
 *
 * @param string The string value for the characters
 * @return An initialized OFXMLCharacters
 */
- initWithString: (OFString*)string;
- initWithString: (OFString *)string;
@end

OF_ASSUME_NONNULL_END

Modified src/OFXMLCharacters.m from [28531794c6] to [6b9ad84ac8].

19
20
21
22
23
24
25
26

27
28
29
30
31

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

46
47
48
49
50
51
52
19
20
21
22
23
24
25

26
27
28
29
30

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

45
46
47
48
49
50
51
52







-
+




-
+













-
+







#import "OFXMLCharacters.h"
#import "OFString.h"
#import "OFXMLElement.h"

#import "OFInvalidArgumentException.h"

@implementation OFXMLCharacters
+ (instancetype)charactersWithString: (OFString*)string
+ (instancetype)charactersWithString: (OFString *)string
{
	return [[[self alloc] initWithString: string] autorelease];
}

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

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

	return self;
}

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

	@try {
		void *pool = objc_autoreleasePoolPush();

		if (![[element name] isEqual: [self className]] ||
84
85
86
87
88
89
90
91

92
93
94
95
96

97
98
99
100
101
102
103






104
105
106
107
108


109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130
84
85
86
87
88
89
90

91
92
93
94
95

96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118

119

120
121
122
123






124
125
126
127
128
129
130







-
+




-
+






-
+
+
+
+
+
+




-
+
+




-
+
-




-
-
-
-
-
-
+






}

- (uint32_t)hash
{
	return [_characters hash];
}

- (OFString*)stringValue
- (OFString *)stringValue
{
	return [[_characters copy] autorelease];
}

- (void)setStringValue: (OFString*)stringValue
- (void)setStringValue: (OFString *)stringValue
{
	OFString *old = _characters;
	_characters = [stringValue copy];
	[old release];
}

- (OFString*)XMLString
- (OFString *)XMLString
{
	return [_characters stringByXMLEscaping];
}

- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
{
	return [_characters stringByXMLEscaping];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				 level: (unsigned int)level
{
	return [_characters stringByXMLEscaping];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
- (OFString *)description
				level: (unsigned int)level
{
	return [_characters stringByXMLEscaping];
}

- (OFString*)description
{
	return [_characters stringByXMLEscaping];
}

- (OFXMLElement*)XMLElementBySerializing
- (OFXMLElement *)XMLElementBySerializing
{
	return [OFXMLElement elementWithName: [self className]
				   namespace: OF_SERIALIZATION_NS
				 stringValue: _characters];
}
@end

Modified src/OFXMLComment.h from [2461477eef] to [bbf17f1ff7].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46

47
48
49
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45

46
47
48
49







-
+








-
+




/*!
 * @brief Creates a new OFXMLComment with the specified string.
 *
 * @param string The string for the comment
 * @return A new OFXMLComment
 */
+ (instancetype)commentWithString: (OFString*)string;
+ (instancetype)commentWithString: (OFString *)string;

/*!
 * @brief Initializes an already allocated OFXMLComment with the specified
 *	  string.
 *
 * @param string The string for the comment
 * @return An initialized OFXMLComment
 */
- initWithString: (OFString*)string;
- initWithString: (OFString *)string;
@end

OF_ASSUME_NONNULL_END

Modified src/OFXMLComment.m from [abbf99f0c2] to [3ef625ba5d].

21
22
23
24
25
26
27
28

29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
21
22
23
24
25
26
27

28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54







-
+




-
+













-
+







#import "OFXMLComment.h"
#import "OFString.h"
#import "OFXMLElement.h"

#import "OFInvalidArgumentException.h"

@implementation OFXMLComment
+ (instancetype)commentWithString: (OFString*)string
+ (instancetype)commentWithString: (OFString *)string
{
	return [[[self alloc] initWithString: string] autorelease];
}

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

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

	return self;
}

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

	@try {
		void *pool = objc_autoreleasePoolPush();

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







-
+




-
+




-
+




-
-
+
+







}

- (uint32_t)hash
{
	return [_comment hash];
}

- (OFString*)stringValue
- (OFString *)stringValue
{
	return @"";
}

- (OFString*)XMLString
- (OFString *)XMLString
{
	return [OFString stringWithFormat: @"<!--%@-->", _comment];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
{
	return [OFString stringWithFormat: @"<!--%@-->", _comment];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
				level: (unsigned int)level
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				 level: (unsigned int)level
{
	OFString *ret;

	if (indentation > 0 && level > 0) {
		char *whitespaces = [self allocMemoryWithSize:
		    (level * indentation) + 1];
		memset(whitespaces, ' ', level * indentation);
125
126
127
128
129
130
131
132

133
134
135
136
137

138
139
140
141
142
143
125
126
127
128
129
130
131

132
133
134
135
136

137
138
139
140
141
142
143







-
+




-
+






		}
	} else
		ret = [OFString stringWithFormat: @"<!--%@-->", _comment];

	return ret;
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat: @"<!--%@-->", _comment];
}

- (OFXMLElement*)XMLElementBySerializing
- (OFXMLElement *)XMLElementBySerializing
{
	return [OFXMLElement elementWithName: [self className]
				   namespace: OF_SERIALIZATION_NS
				 stringValue: _comment];
}
@end

Modified src/OFXMLElement.h from [1f4a21c910] to [246cb3356f].

31
32
33
34
35
36
37
38
39
40



41
42
43
44
45
46
47
31
32
33
34
35
36
37



38
39
40
41
42
43
44
45
46
47







-
-
-
+
+
+







 * @class OFXMLElement OFXMLElement.h ObjFW/OFXMLElement.h
 *
 * @brief A class which stores an XML element.
 */
@interface OFXMLElement: OFXMLNode
{
	OFString *_name, *_namespace, *_defaultNamespace;
	OFMutableArray OF_GENERIC(OFXMLAttribute*) *_attributes;
	OFMutableDictionary OF_GENERIC(OFString*, OFString*) *_namespaces;
	OFMutableArray OF_GENERIC(OFXMLNode*) *_children;
	OFMutableArray OF_GENERIC(OFXMLAttribute *) *_attributes;
	OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_namespaces;
	OFMutableArray OF_GENERIC(OFXMLNode *) *_children;
}

/*!
 * The name of the element.
 */
@property (nonatomic, copy) OFString *name;

62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80


81
82
83
84
85
86
87
88
89
90
91


92
93
94
95
96
97
98
99
100
101
102
103
104
105



106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141

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


154
155
156
157
158
159
160
161
162
163
164
165


166
167
168
169
170
171
172
173
174
175
176
177
178
179



180
181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218


219
220
221
222
223
224
225
226
227


228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252
253
254
255
256


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



272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289


290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
305


306
307
308
309
310
311
312

313
314
315
316
317
318
319

320
321
322
323
324
325
326

327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368


369
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384

385
386
387
388
389
390
391
392


393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408


409
410
411
412
413
414
415
416
417
418


419
420
421
422
423
424
425
426
427
428
429



430
431
432
433
434
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78


79
80
81
82
83
84
85
86
87
88
89


90
91
92
93
94
95
96
97
98
99
100
101
102



103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151


152
153
154
155
156
157
158
159
160
161
162
163


164
165
166
167
168
169
170
171
172
173
174
175
176



177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216


217
218
219
220
221
222
223
224
225


226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
252
253
254


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



269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287


288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
303


304
305
306
307
308
309
310
311

312
313
314
315
316
317
318

319
320
321
322
323
324
325

326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366


367
368
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383

384
385
386
387
388
389
390


391
392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
415
416
417


418
419
420
421
422
423
424
425
426
427



428
429
430
431
432
433
434
435







-
+









-
-
+
+









-
-
+
+











-
-
-
+
+
+








-
+







-
+









-
+








-
+










-
-
+
+










-
-
+
+











-
-
-
+
+
+









-
+








-
+









-
+








-
-
+
+







-
-
+
+






-
+









-
+










-
-
+
+












-
-
-
+
+
+







-
+








-
-
+
+






-
+







-
-
+
+






-
+






-
+






-
+







-
+








-
+







-
+















-
-
+
+








-
+






-
+






-
-
+
+







-
+







-
+
+








-
-
+
+








-
-
-
+
+
+






/*!
 * @brief Creates a new XML element with the specified name.
 *
 * @param name The name for the element
 * @return A new autoreleased OFXMLElement with the specified element name
 */
+ (instancetype)elementWithName: (OFString*)name;
+ (instancetype)elementWithName: (OFString *)name;

/*!
 * @brief Creates a new XML element with the specified name and string value.
 *
 * @param name The name for the element
 * @param stringValue The value for the element
 * @return A new autoreleased OFXMLElement with the specified element name and
 *	   value
 */
+ (instancetype)elementWithName: (OFString*)name
		    stringValue: (nullable OFString*)stringValue;
+ (instancetype)elementWithName: (OFString *)name
		    stringValue: (nullable OFString *)stringValue;

/*!
 * @brief Creates a new XML element with the specified name and namespace.
 *
 * @param name The name for the element
 * @param namespace_ The namespace for the element
 * @return A new autoreleased OFXMLElement with the specified element name and
 *	   namespace
 */
+ (instancetype)elementWithName: (OFString*)name
		      namespace: (nullable OFString*)namespace_;
+ (instancetype)elementWithName: (OFString *)name
		      namespace: (nullable OFString *)namespace_;

/*!
 * @brief Creates a new XML element with the specified name, namespace and
 * 	  string value.
 *
 * @param name The name for the element
 * @param namespace_ The namespace for the element
 * @param stringValue The value for the element
 * @return A new autoreleased OFXMLElement with the specified element name,
 *	   namespace and value
 */
+ (instancetype)elementWithName: (OFString*)name
		      namespace: (nullable OFString*)namespace_
		    stringValue: (nullable OFString*)stringValue;
+ (instancetype)elementWithName: (OFString *)name
		      namespace: (nullable OFString *)namespace_
		    stringValue: (nullable OFString *)stringValue;

/*!
 * @brief Creates a new element with the specified element.
 *
 * @param element An OFXMLElement to initialize the OFXMLElement with
 * @return A new autoreleased OFXMLElement with the contents of the specified
 *	   element
 */
+ (instancetype)elementWithElement: (OFXMLElement*)element;
+ (instancetype)elementWithElement: (OFXMLElement *)element;

/*!
 * @brief Parses the string and returns an OFXMLElement for it.
 *
 * @param string The string to parse
 * @return A new autoreleased OFXMLElement with the contents of the string
 */
+ (instancetype)elementWithXMLString: (OFString*)string;
+ (instancetype)elementWithXMLString: (OFString *)string;

#ifdef OF_HAVE_FILES
/*!
 * @brief Parses the specified file and returns an OFXMLElement for it.
 *
 * @param path The path to the file
 * @return A new autoreleased OFXMLElement with the contents of the specified
 *	   file
 */
+ (instancetype)elementWithFile: (OFString*)path;
+ (instancetype)elementWithFile: (OFString *)path;
#endif

/*!
 * @brief Initializes an already allocated OFXMLElement with the specified name.
 *
 * @param name The name for the element
 * @return An initialized OFXMLElement with the specified element name
 */
- initWithName: (OFString*)name;
- initWithName: (OFString *)name;

/*!
 * @brief Initializes an already allocated OFXMLElement with the specified name
 *	  and string value.
 *
 * @param name The name for the element
 * @param stringValue The value for the element
 * @return An initialized OFXMLElement with the specified element name and
 *	   value
 */
- initWithName: (OFString*)name
   stringValue: (nullable OFString*)stringValue;
- initWithName: (OFString *)name
   stringValue: (nullable OFString *)stringValue;

/*!
 * @brief Initializes an already allocated OFXMLElement with the specified name
 *	  and namespace.
 *
 * @param name The name for the element
 * @param namespace_ The namespace for the element
 * @return An initialized OFXMLElement with the specified element name and
 *	   namespace
 */
- initWithName: (OFString*)name
     namespace: (nullable OFString*)namespace_;
- initWithName: (OFString *)name
     namespace: (nullable OFString *)namespace_;

/*!
 * @brief Initializes an already allocated OFXMLElement with the specified name,
 *	  namespace and value.
 *
 * @param name The name for the element
 * @param namespace_ The namespace for the element
 * @param stringValue The value for the element
 * @return An initialized OFXMLElement with the specified element name,
 *	   namespace and value
 */
- initWithName: (OFString*)name
     namespace: (nullable OFString*)namespace_
   stringValue: (nullable OFString*)stringValue;
- initWithName: (OFString *)name
     namespace: (nullable OFString *)namespace_
   stringValue: (nullable OFString *)stringValue;

/*!
 * @brief Initializes an already allocated OFXMLElement with the specified
 *	  element.
 *
 * @param element An OFXMLElement to initialize the OFXMLElement with
 * @return A new autoreleased OFXMLElement with the contents of the specified
 *	   element
 */
- initWithElement: (OFXMLElement*)element;
- initWithElement: (OFXMLElement *)element;

/*!
 * @brief Parses the string and initializes an already allocated OFXMLElement
 *	  with it.
 *
 * @param string The string to parse
 * @return An initialized OFXMLElement with the contents of the string
 */
- initWithXMLString: (OFString*)string;
- initWithXMLString: (OFString *)string;

#ifdef OF_HAVE_FILES
/*!
 * @brief Parses the specified file and initializes an already allocated
 *	  OFXMLElement with it.
 *
 * @param path The path to the file
 * @return An initialized OFXMLElement with the contents of the specified file
 */
- initWithFile: (OFString*)path;
- initWithFile: (OFString *)path;
#endif

/*!
 * @brief Sets a prefix for a namespace.
 *
 * @param prefix The prefix for the namespace
 * @param namespace_ The namespace for which the prefix is set
 */
- (void)setPrefix: (OFString*)prefix
     forNamespace: (OFString*)namespace_;
- (void)setPrefix: (OFString *)prefix
     forNamespace: (OFString *)namespace_;

/*!
 * @brief Binds a prefix for a namespace.
 *
 * @param prefix The prefix for the namespace
 * @param namespace_ The namespace for which the prefix is bound
 */
- (void)bindPrefix: (OFString*)prefix
      forNamespace: (OFString*)namespace_;
- (void)bindPrefix: (OFString *)prefix
      forNamespace: (OFString *)namespace_;

/*!
 * @brief Returns an OFArray with the attributes of the element.
 *
 * @return An OFArray with the attributes of the element
 */
- (nullable OFArray OF_GENERIC(OFXMLAttribute*)*)attributes;
- (nullable OFArray OF_GENERIC(OFXMLAttribute *) *)attributes;

/*!
 * @brief Adds the specified attribute.
 *
 * If an attribute with the same name and namespace already exists, it is not
 * added.
 *
 * @param attribute The attribute to add
 */
- (void)addAttribute: (OFXMLAttribute*)attribute;
- (void)addAttribute: (OFXMLAttribute *)attribute;

/*!
 * @brief Adds the specified attribute with the specified string value.
 *
 * If an attribute with the same name and namespace already exists, it is not
 * added.
 *
 * @param name The name of the attribute
 * @param stringValue The value of the attribute
 */
- (void)addAttributeWithName: (OFString*)name
		 stringValue: (OFString*)stringValue;
- (void)addAttributeWithName: (OFString *)name
		 stringValue: (OFString *)stringValue;

/*!
 * @brief Adds the specified attribute with the specified namespace and string
 *	  value.
 *
 * If an attribute with the same name and namespace already exists, it is not
 * added.
 *
 * @param name The name of the attribute
 * @param namespace_ The namespace of the attribute
 * @param stringValue The value of the attribute
 */
- (void)addAttributeWithName: (OFString*)name
		   namespace: (nullable OFString*)namespace_
		 stringValue: (OFString*)stringValue;
- (void)addAttributeWithName: (OFString *)name
		   namespace: (nullable OFString *)namespace_
		 stringValue: (OFString *)stringValue;

/*!
 * @brief Returns the attribute with the specified name.
 *
 * @param attributeName The name of the attribute
 * @return The attribute with the specified name
 */
- (OFXMLAttribute*)attributeForName: (OFString*)attributeName;
- (OFXMLAttribute *)attributeForName: (OFString *)attributeName;

/*!
 * @brief Returns the attribute with the specified name and namespace.
 *
 * @param attributeName The name of the attribute
 * @param attributeNS The namespace of the attribute
 * @return The attribute with the specified name and namespace
 */
- (OFXMLAttribute*)attributeForName: (OFString*)attributeName
			  namespace: (nullable OFString*)attributeNS;
- (OFXMLAttribute *)attributeForName: (OFString *)attributeName
			   namespace: (nullable OFString *)attributeNS;

/*!
 * @brief Removes the attribute with the specified name.
 *
 * @param attributeName The name of the attribute
 */
- (void)removeAttributeForName: (OFString*)attributeName;
- (void)removeAttributeForName: (OFString *)attributeName;

/*!
 * @brief Removes the attribute with the specified name and namespace.
 *
 * @param attributeName The name of the attribute
 * @param attributeNS The namespace of the attribute
 */
- (void)removeAttributeForName: (OFString*)attributeName
		     namespace: (nullable OFString*)attributeNS;
- (void)removeAttributeForName: (OFString *)attributeName
		     namespace: (nullable OFString *)attributeNS;

/*!
 * @brief Removes all children and adds the children from the specified array.
 *
 * @param children The new children to add
 */
- (void)setChildren: (nullable OFArray OF_GENERIC(OFXMLNode*)*)children;
- (void)setChildren: (nullable OFArray OF_GENERIC(OFXMLNode *) *)children;

/*!
 * @brief Returns an array of OFXMLNodes with all children of the element.
 *
 * @return An array of OFXMLNodes with all children of the element
 */
- (nullable OFArray OF_GENERIC(OFXMLNode*)*)children;
- (nullable OFArray OF_GENERIC(OFXMLNode *) *)children;

/*!
 * @brief Adds a child to the OFXMLElement.
 *
 * @param child An OFXMLNode which is added as a child
 */
- (void)addChild: (OFXMLNode*)child;
- (void)addChild: (OFXMLNode *)child;

/*!
 * @brief Inserts a child at the specified index.
 *
 * @param child An OFXMLNode which is added as a child
 * @param index The index where the child is added
 */
- (void)insertChild: (OFXMLNode*)child
- (void)insertChild: (OFXMLNode *)child
	    atIndex: (size_t)index;

/*!
 * @brief Inserts the specified children at the specified index.
 *
 * @param children An array of OFXMLNodes which are added as children
 * @param index The index where the child is added
 */
- (void)insertChildren: (OFArray OF_GENERIC(OFXMLNode*)*)children
- (void)insertChildren: (OFArray OF_GENERIC(OFXMLNode *) *)children
	       atIndex: (size_t)index;

/*!
 * @brief Removes the first child that is equal to the specified OFXMLNode.
 *
 * @param child The child to remove from the OFXMLElement
 */
- (void)removeChild: (OFXMLNode*)child;
- (void)removeChild: (OFXMLNode *)child;

/*!
 * @brief Removes the child at the specified index.
 *
 * @param index The index of the child to remove
 */

- (void)removeChildAtIndex: (size_t)index;
/*!
 * @brief Replaces the first child that is equal to the specified OFXMLNode
 *	  with the specified node.
 *
 * @param child The child to replace
 * @param node The node to replace the child with
 */
- (void)replaceChild: (OFXMLNode*)child
	    withNode: (OFXMLNode*)node;
- (void)replaceChild: (OFXMLNode *)child
	    withNode: (OFXMLNode *)node;

/*!
 * @brief Replaces the child at the specified index with the specified node.
 *
 * @param index The index of the child to replace
 * @param node The node to replace the child with
 */
- (void)replaceChildAtIndex: (size_t)index
		   withNode: (OFXMLNode*)node;
		   withNode: (OFXMLNode *)node;

/*!
 * @brief Returns all children that are elements.
 *
 * @return All children that are elements
 */
- (OFArray OF_GENERIC(OFXMLElement*)*)elements;
- (OFArray OF_GENERIC(OFXMLElement *) *)elements;

/*!
 * @brief Returns all children that have the specified namespace.
 *
 * @return All children that have the specified namespace
 */
- (OFArray OF_GENERIC(OFXMLElement*)*)elementsForNamespace:
    (nullable OFString*)elementNS;
- (OFArray OF_GENERIC(OFXMLElement *) *)elementsForNamespace:
    (nullable OFString *)elementNS;

/*!
 * @brief Returns the first child element with the specified name.
 *
 * @param elementName The name of the element
 * @return The first child element with the specified name
 */
- (OFXMLElement*)elementForName: (OFString*)elementName;
- (OFXMLElement *)elementForName: (OFString *)elementName;

/*!
 * @brief Returns the child elements with the specified name.
 *
 * @param elementName The name of the elements
 * @return The child elements with the specified name
 */
- (OFArray OF_GENERIC(OFXMLElement*)*)elementsForName: (OFString*)elementName;
- (OFArray OF_GENERIC(OFXMLElement *) *)elementsForName:
    (OFString *)elementName;

/*!
 * @brief Returns the first child element with the specified name and namespace.
 *
 * @param elementName The name of the element
 * @param elementNS The namespace of the element
 * @return The first child element with the specified name and namespace
 */
- (OFXMLElement*)elementForName: (OFString*)elementName
		      namespace: (nullable OFString*)elementNS;
- (OFXMLElement *)elementForName: (OFString *)elementName
		       namespace: (nullable OFString *)elementNS;

/*!
 * @brief Returns the child elements with the specified name and namespace.
 *
 * @param elementName The name of the elements
 * @param elementNS The namespace of the elements
 * @return The child elements with the specified name and namespace
 */
- (OFArray OF_GENERIC(OFXMLElement*)*)
    elementsForName: (OFString*)elementName
	  namespace: (nullable OFString*)elementNS;
- (OFArray OF_GENERIC(OFXMLElement *) *)
    elementsForName: (OFString *)elementName
	  namespace: (nullable OFString *)elementNS;
@end

OF_ASSUME_NONNULL_END

#import "OFXMLElement+Serialization.h"

Modified src/OFXMLElement.m from [1e9e755319] to [919c1667cd].

52
53
54
55
56
57
58
59
60


61
62
63
64
65
66
67
52
53
54
55
56
57
58


59
60
61
62
63
64
65
66
67







-
-
+
+







{
@public
	OFXMLElement *_element;
}
@end

@implementation OFXMLElement_OFXMLElementBuilderDelegate
- (void)elementBuilder: (OFXMLElementBuilder*)builder
       didBuildElement: (OFXMLElement*)element
- (void)elementBuilder: (OFXMLElementBuilder *)builder
       didBuildElement: (OFXMLElement *)element
{
	if (_element == nil)
		_element = [element retain];
}

- (void)dealloc
{
79
80
81
82
83
84
85
86

87
88
89
90
91
92


93
94
95
96
97
98
99


100
101
102
103
104
105
106
107



108
109
110
111
112
113
114

115
116
117
118
119

120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144


145
146
147
148
149
150
151
152


153
154
155
156
157
158
159
160
161



162
163
164
165
166
167
168
79
80
81
82
83
84
85

86
87
88
89
90


91
92
93
94
95
96
97


98
99
100
101
102
103
104



105
106
107
108
109
110
111
112
113

114
115
116
117
118

119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142


143
144
145
146
147
148
149
150


151
152
153
154
155
156
157
158



159
160
161
162
163
164
165
166
167
168







-
+




-
-
+
+





-
-
+
+





-
-
-
+
+
+






-
+




-
+





-
+










-
+






-
-
+
+






-
-
+
+






-
-
-
+
+
+







{
	if (self == [OFXMLElement class]) {
		charactersClass = [OFXMLCharacters class];
		CDATAClass = [OFXMLCDATA class];
	}
}

+ (instancetype)elementWithName: (OFString*)name
+ (instancetype)elementWithName: (OFString *)name
{
	return [[[self alloc] initWithName: name] autorelease];
}

+ (instancetype)elementWithName: (OFString*)name
		    stringValue: (OFString*)stringValue
+ (instancetype)elementWithName: (OFString *)name
		    stringValue: (OFString *)stringValue
{
	return [[[self alloc] initWithName: name
			       stringValue: stringValue] autorelease];
}

+ (instancetype)elementWithName: (OFString*)name
		      namespace: (OFString*)ns
+ (instancetype)elementWithName: (OFString *)name
		      namespace: (OFString *)ns
{
	return [[[self alloc] initWithName: name
				 namespace: ns] autorelease];
}

+ (instancetype)elementWithName: (OFString*)name
		      namespace: (OFString*)ns
		    stringValue: (OFString*)stringValue
+ (instancetype)elementWithName: (OFString *)name
		      namespace: (OFString *)ns
		    stringValue: (OFString *)stringValue
{
	return [[[self alloc] initWithName: name
				 namespace: ns
			       stringValue: stringValue] autorelease];
}

+ (instancetype)elementWithElement: (OFXMLElement*)element
+ (instancetype)elementWithElement: (OFXMLElement *)element
{
	return [[[self alloc] initWithElement: element] autorelease];
}

+ (instancetype)elementWithXMLString: (OFString*)string
+ (instancetype)elementWithXMLString: (OFString *)string
{
	return [[[self alloc] initWithXMLString: string] autorelease];
}

#ifdef OF_HAVE_FILES
+ (instancetype)elementWithFile: (OFString*)path
+ (instancetype)elementWithFile: (OFString *)path
{
	return [[[self alloc] initWithFile: path] autorelease];
}
#endif

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithName: (OFString*)name
- initWithName: (OFString *)name
{
	return [self initWithName: name
			namespace: nil
		      stringValue: nil];
}

- initWithName: (OFString*)name
   stringValue: (OFString*)stringValue
- initWithName: (OFString *)name
   stringValue: (OFString *)stringValue
{
	return [self initWithName: name
			namespace: nil
		      stringValue: stringValue];
}

- initWithName: (OFString*)name
     namespace: (OFString*)namespace
- initWithName: (OFString *)name
     namespace: (OFString *)namespace
{
	return [self initWithName: name
			namespace: namespace
		      stringValue: nil];
}

- initWithName: (OFString*)name
     namespace: (OFString*)namespace
   stringValue: (OFString*)stringValue
- initWithName: (OFString *)name
     namespace: (OFString *)namespace
   stringValue: (OFString *)stringValue
{
	self = [super init];

	@try {
		if (name == nil)
			@throw [OFInvalidArgumentException exception];

180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194







-
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		if (element == nil)
			@throw [OFInvalidArgumentException exception];

202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216







-
+







		[self release];
		@throw e;
	}

	return self;
}

- initWithXMLString: (OFString*)string
- initWithXMLString: (OFString *)string
{
	void *pool;
	OFXMLParser *parser;
	OFXMLElementBuilder *builder;
	OFXMLElement_OFXMLElementBuilderDelegate *delegate;

	[self release];
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251







-
+








	objc_autoreleasePoolPop(pool);

	return self;
}

#ifdef OF_HAVE_FILES
- initWithFile: (OFString*)path
- initWithFile: (OFString *)path
{
	void *pool;
	OFXMLParser *parser;
	OFXMLElementBuilder *builder;
	OFXMLElement_OFXMLElementBuilderDelegate *delegate;

	[self release];
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283







-
+








	objc_autoreleasePoolPop(pool);

	return self;
}
#endif

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

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFXMLElement *attributesElement, *namespacesElement;
		OFXMLElement *childrenElement;
368
369
370
371
372
373
374
375

376
377
378
379
380

381
382
383
384
385
386
387

388
389
390
391
392

393
394
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
368
369
370
371
372
373
374

375
376
377
378
379

380
381
382
383
384
385
386

387
388
389
390
391

392
393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409







-
+




-
+






-
+




-
+









-
+







	[_attributes release];
	[_namespaces release];
	[_children release];

	[super dealloc];
}

- (OFArray*)attributes
- (OFArray *)attributes
{
	return [[_attributes copy] autorelease];
}

- (void)setChildren: (OFArray*)children
- (void)setChildren: (OFArray *)children
{
	OFArray *old = _children;
	_children = [children copy];
	[old release];
}

- (OFArray*)children
- (OFArray *)children
{
	return [[_children copy] autorelease];
}

- (void)setStringValue: (OFString*)stringValue
- (void)setStringValue: (OFString *)stringValue
{
	void *pool = objc_autoreleasePoolPush();

	[self setChildren: [OFArray arrayWithObject:
	    [OFXMLCharacters charactersWithString: stringValue]]];

	objc_autoreleasePoolPop(pool);
}

- (OFString*)stringValue
- (OFString *)stringValue
{
	OFMutableString *ret;

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

	ret = [OFMutableString string];
417
418
419
420
421
422
423
424
425
426
427




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

441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
417
418
419
420
421
422
423




424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439

440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468







-
-
-
-
+
+
+
+












-
+




















-
+







	}

	[ret makeImmutable];

	return ret;
}

- (OFString*)OF_XMLStringWithParent: (OFXMLElement*)parent
			 namespaces: (OFDictionary*)allNamespaces
			indentation: (unsigned int)indentation
			      level: (unsigned int)level
- (OFString *)OF_XMLStringWithParent: (OFXMLElement *)parent
			  namespaces: (OFDictionary *)allNamespaces
			 indentation: (unsigned int)indentation
			       level: (unsigned int)level
{
	void *pool;
	char *cString;
	size_t length, i;
	OFString *prefix, *parentPrefix;
	OFString *ret;
	OFString *defaultNS;

	pool = objc_autoreleasePoolPush();

	parentPrefix = [allNamespaces objectForKey:
	    (parent != nil && parent->_namespace != nil
	    ? parent->_namespace : (OFString*)@"")];
	    ? parent->_namespace : (OFString *)@"")];

	/* Add the namespaces of the current element */
	if (allNamespaces != nil) {
		OFEnumerator *keyEnumerator = [_namespaces keyEnumerator];
		OFEnumerator *objectEnumerator = [_namespaces objectEnumerator];
		OFMutableDictionary *tmp;
		id key, object;

		tmp = [[allNamespaces mutableCopy] autorelease];

		while ((key = [keyEnumerator nextObject]) != nil &&
		    (object = [objectEnumerator nextObject]) != nil)
			[tmp setObject: object
				forKey: key];

		allNamespaces = tmp;
	} else
		allNamespaces = _namespaces;

	prefix = [allNamespaces objectForKey:
	    (_namespace != nil ? _namespace : (OFString*)@"")];
	    (_namespace != nil ? _namespace : (OFString *)@"")];

	if (parent != nil && parent->_namespace != nil && parentPrefix == nil)
		defaultNS = parent->_namespace;
	else if (parent != nil && parent->_defaultNamespace != nil)
		defaultNS = parent->_defaultNamespace;
	else
		defaultNS = _defaultNamespace;
585
586
587
588
589
590
591
592

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

592
593
594
595
596
597
598
599







-
+







			OFString *childString;
			unsigned int ind = (indent ? indentation : 0);

			if (ind)
				[tmp addItem: "\n"];

			if ([child isKindOfClass: [OFXMLElement class]])
				childString = [(OFXMLElement*)child
				childString = [(OFXMLElement *)child
				    OF_XMLStringWithParent: self
						namespaces: allNamespaces
					       indentation: ind
						     level: level + 1];
			else
				childString = [child
				    XMLStringWithIndentation: ind
659
660
661
662
663
664
665
666

667
668
669
670
671
672
673
674

675
676
677
678
679
680
681
682
683


684
685
686
687
688
689
690
691

692
693
694
695
696
697
698
659
660
661
662
663
664
665

666
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681


682
683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698







-
+







-
+







-
-
+
+







-
+







					      length: length];
	} @finally {
		[self freeMemory: cString];
	}
	return ret;
}

- (OFString*)XMLString
- (OFString *)XMLString
{
	return [self OF_XMLStringWithParent: nil
				 namespaces: nil
				indentation: 0
				      level: 0];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
{
	return [self OF_XMLStringWithParent: nil
				 namespaces: nil
				indentation: indentation
				      level: 0];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
				level: (unsigned int)level
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				 level: (unsigned int)level
{
	return [self OF_XMLStringWithParent: nil
				 namespaces: nil
				indentation: indentation
				      level: level];
}

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

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

752
753
754
755
756
757
758
759

760
761
762
763
764
765
766
767
768
769
770


771
772
773
774
775
776
777
778
779



780
781
782
783
784
785
786
787
788
789
790

791
792
793
794
795
796
797
798
799
800
801


802
803
804
805
806
807
808
809
810
811
812
813
814

815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830


831
832
833
834
835
836
837
752
753
754
755
756
757
758

759
760
761
762
763
764
765
766
767
768


769
770
771
772
773
774
775
776



777
778
779
780
781
782
783
784
785
786
787
788
789

790
791
792
793
794
795
796
797
798
799


800
801
802
803
804
805
806
807
808
809
810
811
812
813

814
815
816
817
818
819
820
821
822
823
824
825
826
827
828


829
830
831
832
833
834
835
836
837







-
+









-
-
+
+






-
-
-
+
+
+










-
+









-
-
+
+












-
+














-
-
+
+







	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (void)addAttribute: (OFXMLAttribute*)attribute
- (void)addAttribute: (OFXMLAttribute *)attribute
{
	if (_attributes == nil)
		_attributes = [[OFMutableArray alloc] init];

	if ([self attributeForName: attribute->_name
			 namespace: attribute->_namespace] == nil)
		[_attributes addObject: attribute];
}

- (void)addAttributeWithName: (OFString*)name
		 stringValue: (OFString*)stringValue
- (void)addAttributeWithName: (OFString *)name
		 stringValue: (OFString *)stringValue
{
	[self addAttributeWithName: name
			 namespace: nil
		       stringValue: stringValue];
}

- (void)addAttributeWithName: (OFString*)name
		   namespace: (OFString*)namespace
		 stringValue: (OFString*)stringValue
- (void)addAttributeWithName: (OFString *)name
		   namespace: (OFString *)namespace
		 stringValue: (OFString *)stringValue
{
	void *pool = objc_autoreleasePoolPush();

	[self addAttribute: [OFXMLAttribute attributeWithName: name
						    namespace: namespace
						  stringValue: stringValue]];

	objc_autoreleasePoolPop(pool);
}

- (OFXMLAttribute*)attributeForName: (OFString*)attributeName
- (OFXMLAttribute *)attributeForName: (OFString *)attributeName
{
	for (OFXMLAttribute *attribute in _attributes)
		if (attribute->_namespace == nil &&
		    [attribute->_name isEqual: attributeName])
			return [[attribute retain] autorelease];

	return nil;
}

- (OFXMLAttribute*)attributeForName: (OFString*)attributeName
			  namespace: (OFString*)attributeNS
- (OFXMLAttribute *)attributeForName: (OFString *)attributeName
			   namespace: (OFString *)attributeNS
{
	if (attributeNS == nil)
		return [self attributeForName: attributeName];

	for (OFXMLAttribute *attribute in _attributes)
		if ([attribute->_namespace isEqual: attributeNS] &&
		    [attribute->_name isEqual: attributeName])
			return [[attribute retain] autorelease];

	return nil;
}

- (void)removeAttributeForName: (OFString*)attributeName
- (void)removeAttributeForName: (OFString *)attributeName
{
	OFXMLAttribute *const *objects = [_attributes objects];
	size_t count = [_attributes count];

	for (size_t i = 0; i < count; i++) {
		if (objects[i]->_namespace == nil &&
		    [objects[i]->_name isEqual: attributeName]) {
			[_attributes removeObjectAtIndex: i];

			return;
		}
	}
}

- (void)removeAttributeForName: (OFString*)attributeName
		     namespace: (OFString*)attributeNS
- (void)removeAttributeForName: (OFString *)attributeName
		     namespace: (OFString *)attributeNS
{
	OFXMLAttribute *const *objects;
	size_t count;

	if (attributeNS == nil) {
		[self removeAttributeForName: attributeName];
		return;
845
846
847
848
849
850
851
852
853


854
855
856
857
858
859
860
861
862
863
864
865


866
867
868
869
870
871
872
873
874

875
876
877
878
879
880
881
882
883
884
885

886
887
888
889
890
891
892
893
894
895
896
897
898

899
900
901
902
903
904
905
906
907
908
909

910
911
912
913
914
915
916
917
918
919
920
921
922
923


924
925
926
927
928
929
930
931
932
933
934

935
936
937
938
939
940
941
942
943

944
945
946
947
948
949


950
951
952
953
954
955

956
957

958
959
960
961

962
963
964
965
966
967
968

969
970

971
972
973
974

975
976
977
978
979
980
981
982
983
984
985
986
987

988
989

990
991
992
993

994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007


1008
1009

1010
1011
1012
1013
1014
1015
1016
1017
1018

1019
1020
1021
1022
1023
1024
1025
845
846
847
848
849
850
851


852
853
854
855
856
857
858
859
860
861
862
863


864
865
866
867
868
869
870
871
872
873

874
875
876
877
878
879
880
881
882
883
884

885
886
887
888
889
890
891
892
893
894
895
896
897

898
899
900
901
902
903
904
905
906
907
908

909
910
911
912
913
914
915
916
917
918
919
920
921


922
923
924
925
926
927
928
929
930
931
932
933

934
935
936
937
938
939
940
941
942

943
944
945
946
947


948
949
950
951
952
953
954

955
956

957
958
959
960

961
962
963
964
965
966
967

968
969

970
971
972
973

974
975
976
977
978
979
980
981
982
983
984
985
986

987
988

989
990
991
992

993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005


1006
1007
1008

1009
1010
1011
1012
1013
1014
1015
1016
1017

1018
1019
1020
1021
1022
1023
1024
1025







-
-
+
+










-
-
+
+








-
+










-
+












-
+










-
+












-
-
+
+










-
+








-
+




-
-
+
+





-
+

-
+



-
+






-
+

-
+



-
+












-
+

-
+



-
+












-
-
+
+

-
+








-
+







		    [objects[i]->_name isEqual: attributeName]) {
			[_attributes removeObjectAtIndex: i];
				return;
		}
	}
}

- (void)setPrefix: (OFString*)prefix
     forNamespace: (OFString*)namespace
- (void)setPrefix: (OFString *)prefix
     forNamespace: (OFString *)namespace
{
	if ([prefix length] == 0)
		@throw [OFInvalidArgumentException exception];
	if (namespace == nil)
		namespace = @"";

	[_namespaces setObject: prefix
			forKey: namespace];
}

- (void)bindPrefix: (OFString*)prefix
      forNamespace: (OFString*)namespace
- (void)bindPrefix: (OFString *)prefix
      forNamespace: (OFString *)namespace
{
	[self setPrefix: prefix
	   forNamespace: namespace];
	[self addAttributeWithName: prefix
			 namespace: @"http://www.w3.org/2000/xmlns/"
		       stringValue: namespace];
}

- (void)addChild: (OFXMLNode*)child
- (void)addChild: (OFXMLNode *)child
{
	if ([child isKindOfClass: [OFXMLAttribute class]])
		@throw [OFInvalidArgumentException exception];

	if (_children == nil)
		_children = [[OFMutableArray alloc] init];

	[_children addObject: child];
}

- (void)insertChild: (OFXMLNode*)child
- (void)insertChild: (OFXMLNode *)child
	    atIndex: (size_t)index
{
	if ([child isKindOfClass: [OFXMLAttribute class]])
		@throw [OFInvalidArgumentException exception];

	if (_children == nil)
		_children = [[OFMutableArray alloc] init];

	[_children insertObject: child
			atIndex: index];
}

- (void)insertChildren: (OFArray*)children
- (void)insertChildren: (OFArray *)children
	       atIndex: (size_t)index
{
	for (OFXMLNode *node in children)
		if ([node isKindOfClass: [OFXMLAttribute class]])
			@throw [OFInvalidArgumentException exception];

	[_children insertObjectsFromArray: children
				  atIndex: index];
}

- (void)removeChild: (OFXMLNode*)child
- (void)removeChild: (OFXMLNode *)child
{
	if ([child isKindOfClass: [OFXMLAttribute class]])
		@throw [OFInvalidArgumentException exception];

	[_children removeObject: child];
}

- (void)removeChildAtIndex: (size_t)index
{
	[_children removeObjectAtIndex: index];
}

- (void)replaceChild: (OFXMLNode*)child
	    withNode: (OFXMLNode*)node
- (void)replaceChild: (OFXMLNode *)child
	    withNode: (OFXMLNode *)node
{
	if ([node isKindOfClass: [OFXMLAttribute class]] ||
	    [child isKindOfClass: [OFXMLAttribute class]])
		@throw [OFInvalidArgumentException exception];

	[_children replaceObject: child
		      withObject: node];
}

- (void)replaceChildAtIndex: (size_t)index
		   withNode: (OFXMLNode*)node
		   withNode: (OFXMLNode *)node
{
	if ([node isKindOfClass: [OFXMLAttribute class]])
		@throw [OFInvalidArgumentException exception];

	[_children replaceObjectAtIndex: index
			     withObject: node];
}

- (OFXMLElement*)elementForName: (OFString*)elementName
- (OFXMLElement *)elementForName: (OFString *)elementName
{
	return [[self elementsForName: elementName] firstObject];
}

- (OFXMLElement*)elementForName: (OFString*)elementName
		      namespace: (OFString*)elementNS
- (OFXMLElement *)elementForName: (OFString *)elementName
		       namespace: (OFString *)elementNS
{
	return [[self elementsForName: elementName
			    namespace: elementNS] firstObject];
}

- (OFArray*)elements
- (OFArray *)elements
{
	OFMutableArray OF_GENERIC(OFXMLElement*) *ret = [OFMutableArray array];
	OFMutableArray OF_GENERIC(OFXMLElement *) *ret = [OFMutableArray array];

	for (OFXMLNode *child in _children)
		if ([child isKindOfClass: [OFXMLElement class]])
			[ret addObject: (OFXMLElement*)child];
			[ret addObject: (OFXMLElement *)child];

	[ret makeImmutable];

	return ret;
}

- (OFArray*)elementsForName: (OFString*)elementName
- (OFArray *)elementsForName: (OFString *)elementName
{
	OFMutableArray OF_GENERIC(OFXMLElement*) *ret = [OFMutableArray array];
	OFMutableArray OF_GENERIC(OFXMLElement *) *ret = [OFMutableArray array];

	for (OFXMLNode *child in _children) {
		if ([child isKindOfClass: [OFXMLElement class]]) {
			OFXMLElement *element = (OFXMLElement*)child;
			OFXMLElement *element = (OFXMLElement *)child;

			if (element->_namespace == nil &&
			    [element->_name isEqual: elementName])
				[ret addObject: element];
		}
	}

	[ret makeImmutable];

	return ret;
}

- (OFArray*)elementsForNamespace: (OFString*)elementNS
- (OFArray *)elementsForNamespace: (OFString *)elementNS
{
	OFMutableArray OF_GENERIC(OFXMLElement*) *ret = [OFMutableArray array];
	OFMutableArray OF_GENERIC(OFXMLElement *) *ret = [OFMutableArray array];

	for (OFXMLNode *child in _children) {
		if ([child isKindOfClass: [OFXMLElement class]]) {
			OFXMLElement *element = (OFXMLElement*)child;
			OFXMLElement *element = (OFXMLElement *)child;

			if (element->_name != nil &&
			    [element->_namespace isEqual: elementNS])
				[ret addObject: element];
		}
	}

	[ret makeImmutable];

	return ret;
}

- (OFArray*)elementsForName: (OFString*)elementName
		  namespace: (OFString*)elementNS
- (OFArray *)elementsForName: (OFString *)elementName
		   namespace: (OFString *)elementNS
{
	OFMutableArray OF_GENERIC(OFXMLElement*) *ret;
	OFMutableArray OF_GENERIC(OFXMLElement *) *ret;

	if (elementNS == nil)
		return [self elementsForName: elementName];

	ret = [OFMutableArray array];

	for (OFXMLNode *child in _children) {
		if ([child isKindOfClass: [OFXMLElement class]]) {
			OFXMLElement *element = (OFXMLElement*)child;
			OFXMLElement *element = (OFXMLElement *)child;

			if ([element->_namespace isEqual: elementNS] &&
			    [element->_name isEqual: elementName])
				[ret addObject: element];
		}
	}

Modified src/OFXMLElementBuilder.h from [ae237ad96d] to [123ad23954].

37
38
39
40
41
42
43
44
45


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


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82




83
84
85
86
87
88
89
90
91
92
93


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
37
38
39
40
41
42
43


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


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




79
80
81
82
83
84
85
86
87
88
89
90
91


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115







-
-
+
+












-
-
+
+



















-
-
-
-
+
+
+
+









-
-
+
+














-
+







 * If the OFXMLElementBuilder was used as a delegate for the OFXMLParser since
 * parsing started, this will return the complete document as an OFXMLElement
 * with all children.
 *
 * @param builder The builder which built an OFXMLElement
 * @param element The OFXMLElement the OFXMLElementBuilder built
 */
- (void)elementBuilder: (OFXMLElementBuilder*)builder
       didBuildElement: (OFXMLElement*)element;
- (void)elementBuilder: (OFXMLElementBuilder *)builder
       didBuildElement: (OFXMLElement *)element;

@optional
/*!
 * @brief This callback is called when the OFXMLElementBuilder built an
 *	  OFXMLNode which is not inside an element.
 *
 * This is usually called for comments or whitespace character data before the
 * root element.
 *
 * @param builder The builder which built the OFXMLNode without parent
 * @param node The OFXMLNode the OFXMLElementBuilder built
 */
-   (void)elementBuilder: (OFXMLElementBuilder*)builder
  didBuildParentlessNode: (OFXMLNode*)node;
-   (void)elementBuilder: (OFXMLElementBuilder *)builder
  didBuildParentlessNode: (OFXMLNode *)node;

/*!
 * @brief This callback is called when the OFXMLElementBuilder gets a close tag
 *	  which does not belong there.
 *
 * Most likely, the OFXMLElementBuilder was used to build XML only of a child
 * of the root element and the root element was closed. Often the delegate is
 * set to the OFXMLElementBuilder when a certain element is found, this can be
 * used then to set the delegate back after that certain element has been
 * closed.
 *
 * If this method is not implemented in the delegate, the default is to throw
 * an OFMalformedXMLException.
 *
 * @param builder The builder which did not expect the close tag
 * @param name The name of the close tag
 * @param prefix The prefix of the close tag
 * @param namespace_ The namespace of the close tag
 */
- (void)elementBuilder: (OFXMLElementBuilder*)builder
  didNotExpectCloseTag: (OFString*)name
		prefix: (nullable OFString*)prefix
	     namespace: (nullable OFString*)namespace_;
- (void)elementBuilder: (OFXMLElementBuilder *)builder
  didNotExpectCloseTag: (OFString *)name
		prefix: (nullable OFString *)prefix
	     namespace: (nullable OFString *)namespace_;

/*!
 * @brief This callback is called when the XML parser for the element builder
 *	  found an unknown entity.
 *
 * @param builder The element builder which found an unknown entity
 * @param entity The name of the entity
 * @return The substitution for the entity
 */
- (OFString*)elementBuilder: (OFXMLElementBuilder*)builder
    foundUnknownEntityNamed: (OFString*)entity;
- (OFString *)elementBuilder: (OFXMLElementBuilder *)builder
     foundUnknownEntityNamed: (OFString *)entity;
@end

/*!
 * @class OFXMLElementBuilder OFXMLElementBuilder.h ObjFW/OFXMLElementBuilder.h
 *
 * @brief A class implementing the OFXMLParserDelegate protocol that can build
 * OFXMLElements from the document parsed by the OFXMLParser.
 *
 * It can also be used to build OFXMLElements from parts of the document by
 * first parsing stuff using the OFXMLParser with another delegate and then
 * setting the OFXMLElementBuilder as delegate for the parser.
 */
@interface OFXMLElementBuilder: OFObject <OFXMLParserDelegate>
{
	OFMutableArray OF_GENERIC(OFXMLElement*) *_stack;
	OFMutableArray OF_GENERIC(OFXMLElement *) *_stack;
	id <OFXMLElementBuilderDelegate> _delegate;
}

/*!
 * The delegate for the OFXMLElementBuilder.
 */
@property OF_NULLABLE_PROPERTY (assign)

Modified src/OFXMLElementBuilder.m from [7a305bddbd] to [8f1f7d2342].

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







-
-
+
+













-
-
-
-
-
+
+
+
+
+







- (void)dealloc
{
	[_stack release];

	[super dealloc];
}

-		 (void)parser: (OFXMLParser*)parser
  foundProcessingInstructions: (OFString*)pi
-		 (void)parser: (OFXMLParser *)parser
  foundProcessingInstructions: (OFString *)pi
{
	OFXMLProcessingInstructions *node = [OFXMLProcessingInstructions
	    processingInstructionsWithString: pi];
	OFXMLElement *parent = [_stack lastObject];

	if (parent != nil)
		[parent addChild: node];
	else if ([_delegate respondsToSelector:
	    @selector(elementBuilder:didBuildParentlessNode:)])
		[_delegate elementBuilder: self
		   didBuildParentlessNode: node];
}

-    (void)parser: (OFXMLParser*)parser
  didStartElement: (OFString*)name
	   prefix: (OFString*)prefix
	namespace: (OFString*)namespace
       attributes: (OFArray*)attributes
-    (void)parser: (OFXMLParser *)parser
  didStartElement: (OFString *)name
	   prefix: (OFString *)prefix
	namespace: (OFString *)namespace
       attributes: (OFArray *)attributes
{
	OFXMLElement *element = [OFXMLElement elementWithName: name
						    namespace: namespace];

	for (OFXMLAttribute *attribute in attributes) {
		if ([attribute namespace] == nil &&
		    [[attribute name] isEqual: @"xmlns"])
94
95
96
97
98
99
100
101
102
103
104




105
106
107
108
109
110
111
94
95
96
97
98
99
100




101
102
103
104
105
106
107
108
109
110
111







-
-
-
-
+
+
+
+







		[element addAttribute: attribute];
	}

	[[_stack lastObject] addChild: element];
	[_stack addObject: element];
}

-  (void)parser: (OFXMLParser*)parser
  didEndElement: (OFString*)name
	 prefix: (OFString*)prefix
      namespace: (OFString*)namespace
-  (void)parser: (OFXMLParser *)parser
  didEndElement: (OFString *)name
	 prefix: (OFString *)prefix
      namespace: (OFString *)namespace
{
	switch ([_stack count]) {
	case 0:
		if ([_delegate respondsToSelector: @selector(elementBuilder:
		    didNotExpectCloseTag:prefix:namespace:)])
			[_delegate elementBuilder: self
			     didNotExpectCloseTag: name
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
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







-
-
+
+















-
-
+
+












-
-
+
+












-
-
+
+









			  didBuildElement: [_stack firstObject]];
		break;
	}

	[_stack removeLastObject];
}

-    (void)parser: (OFXMLParser*)parser
  foundCharacters: (OFString*)characters
-    (void)parser: (OFXMLParser *)parser
  foundCharacters: (OFString *)characters
{
	OFXMLCharacters *node;
	OFXMLElement *parent;

	node = [OFXMLCharacters charactersWithString: characters];
	parent = [_stack lastObject];

	if (parent != nil)
		[parent addChild: node];
	else if ([_delegate respondsToSelector:
	    @selector(elementBuilder:didBuildParentlessNode:)])
		[_delegate  elementBuilder: self
		    didBuildParentlessNode: node];
}

- (void)parser: (OFXMLParser*)parser
    foundCDATA: (OFString*)CDATA
- (void)parser: (OFXMLParser *)parser
    foundCDATA: (OFString *)CDATA
{
	OFXMLCDATA *node = [OFXMLCDATA CDATAWithString: CDATA];
	OFXMLElement *parent = [_stack lastObject];

	if (parent != nil)
		[parent addChild: node];
	else if ([_delegate respondsToSelector:
	    @selector(elementBuilder:didBuildParentlessNode:)])
		[_delegate elementBuilder: self
		   didBuildParentlessNode: node];
}

- (void)parser: (OFXMLParser*)parser
  foundComment: (OFString*)comment
- (void)parser: (OFXMLParser *)parser
  foundComment: (OFString *)comment
{
	OFXMLComment *node = [OFXMLComment commentWithString: comment];
	OFXMLElement *parent = [_stack lastObject];

	if (parent != nil)
		[parent addChild: node];
	else if ([_delegate respondsToSelector:
	    @selector(elementBuilder:didBuildParentlessNode:)])
		[_delegate elementBuilder: self
		   didBuildParentlessNode: node];
}

-	(OFString*)parser: (OFXMLParser*)parser
  foundUnknownEntityNamed: (OFString*)entity
-      (OFString *)parser: (OFXMLParser *)parser
  foundUnknownEntityNamed: (OFString *)entity
{
	if ([_delegate respondsToSelector:
	    @selector(elementBuilder:foundUnknownEntityNamed:)])
		return [_delegate elementBuilder: self
			 foundUnknownEntityNamed: entity];

	return nil;
}
@end

Modified src/OFXMLNode.h from [ffe6f2a2b2] to [a5851a48bd].

26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50







-
+









-
+







 */
@interface OFXMLNode: OFObject <OFCopying, OFSerialization>
/*!
 * @brief Returns the contents of the receiver as a string value.
 *
 * @return A string with the string value
 */
- (OFString*)stringValue;
- (OFString *)stringValue;

/*!
 * @brief Sets the string value of the receiver to the specified string.
 *
 * For an @ref OFXMLElement, it removes all children and creates a single child
 * with the specified string value.
 *
 * @param stringValue The new string value for the node
 */
- (void)setStringValue: (OFString*)stringValue;
- (void)setStringValue: (OFString *)stringValue;

/*!
 * @brief Returns the contents of the receiver as a decimal value.
 *
 * @return An integer with the decimal value
 */
- (intmax_t)decimalValue;
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
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







-
+









-
+










-
-
+
+



- (double)doubleValue;

/*!
 * @brief Returns an OFString representing the OFXMLNode as an XML string.
 *
 * @return An OFString representing the OFXMLNode as an XML string
 */
- (OFString*)XMLString;
- (OFString *)XMLString;

/*!
 * @brief Returns an OFString representing the OFXMLNode as an XML string with
 *	  indentation.
 *
 * @param indentation The indentation for the XML string
 * @return An OFString representing the OFXMLNode as an XML string with
 *	   indentation
 */
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation;
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation;

/*!
 * @brief Returns an OFString representing the OFXMLNode as an XML string with
 *	  indentation for the specified level.
 *
 * @param indentation The indentation for the XML string
 * @param level The level of indentation
 * @return An OFString representing the OFXMLNode as an XML string with
 *	   indentation
 */
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
				level: (unsigned int)level;
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				 level: (unsigned int)level;
@end

OF_ASSUME_NONNULL_END

Modified src/OFXMLNode.m from [4a9dbfcb4a] to [d0fa412fe1].

16
17
18
19
20
21
22
23

24
25
26
27
28

29
30
31
32
33

34
35
36
37
38
39
40
16
17
18
19
20
21
22

23
24
25
26
27

28
29
30
31
32

33
34
35
36
37
38
39
40







-
+




-
+




-
+








#include "config.h"

#import "OFXMLNode.h"
#import "OFString.h"

@implementation OFXMLNode
- initWithSerialization: (OFXMLElement*)element
- initWithSerialization: (OFXMLElement *)element
{
	OF_INVALID_INIT_METHOD
}

- (OFString*)stringValue
- (OFString *)stringValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setStringValue: (OFString*)stringValue
- (void)setStringValue: (OFString *)stringValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (intmax_t)decimalValue
{
	return [[self stringValue] decimalValue];
51
52
53
54
55
56
57
58

59
60
61
62
63
64

65
66
67
68
69
70
71


72
73
74
75
76

77
78
79
80
81

82
83
84
85
86
87
88
89
90
51
52
53
54
55
56
57

58
59
60
61
62
63

64
65
66
67
68
69


70
71
72
73
74
75

76
77
78
79
80

81
82
83
84
85
86
87
88
89
90







-
+





-
+





-
-
+
+




-
+




-
+









}

- (double)doubleValue
{
	return [[self stringValue] doubleValue];
}

- (OFString*)XMLString
- (OFString *)XMLString
{
	return [self XMLStringWithIndentation: 0
					level: 0];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
{
	return [self XMLStringWithIndentation: 0
					level: 0];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
				level: (unsigned int)level
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				 level: (unsigned int)level
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFString*)description
- (OFString *)description
{
	return [self XMLStringWithIndentation: 2];
}

- (OFXMLElement*)XMLElementBySerializing
- (OFXMLElement *)XMLElementBySerializing
{
	OF_UNRECOGNIZED_SELECTOR
}

- copy
{
	return [self retain];
}
@end

Modified src/OFXMLParser.h from [c42e8d4f95] to [cd9a216dbc].

39
40
41
42
43
44
45
46
47


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64





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




78
79
80
81
82
83
84
85
86
87
88
89


90
91
92
93
94
95
96
97
98


99
100
101
102
103
104
105
106
107


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


123
124
125
126
127
128
129
39
40
41
42
43
44
45


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





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




74
75
76
77
78
79
80
81
82
83
84
85
86
87


88
89
90
91
92
93
94
95
96


97
98
99
100
101
102
103
104
105


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


121
122
123
124
125
126
127
128
129







-
-
+
+












-
-
-
-
-
+
+
+
+
+









-
-
-
-
+
+
+
+










-
-
+
+







-
-
+
+







-
-
+
+













-
-
+
+







/*!
 * @brief This callback is called when the XML parser found processing
 *	  instructions.
 *
 * @param parser The parser which found processing instructions
 * @param pi The processing instructions
 */
-		 (void)parser: (OFXMLParser*)parser
  foundProcessingInstructions: (OFString*)pi;
-		 (void)parser: (OFXMLParser *)parser
  foundProcessingInstructions: (OFString *)pi;

/*!
 * @brief This callback is called when the XML parser found the start of a new
 *	  tag.
 *
 * @param parser The parser which found a new tag
 * @param name The name of the tag which just started
 * @param prefix The prefix of the tag which just started or `nil`
 * @param ns The namespace of the tag which just started or `nil`
 * @param attributes The attributes included in the tag which just started or
 *		     `nil`
 */
-    (void)parser: (OFXMLParser*)parser
  didStartElement: (OFString*)name
	   prefix: (nullable OFString*)prefix
	namespace: (nullable OFString*)ns
       attributes: (nullable OFArray OF_GENERIC(OFXMLAttribute*)*)attributes;
-    (void)parser: (OFXMLParser *)parser
  didStartElement: (OFString *)name
	   prefix: (nullable OFString *)prefix
	namespace: (nullable OFString *)ns
       attributes: (nullable OFArray OF_GENERIC(OFXMLAttribute *) *)attributes;

/*!
 * @brief This callback is called when the XML parser found the end of a tag.
 *
 * @param parser The parser which found the end of a tag
 * @param name The name of the tag which just ended
 * @param prefix The prefix of the tag which just ended or `nil`
 * @param ns The namespace of the tag which just ended or `nil`
 */
-  (void)parser: (OFXMLParser*)parser
  didEndElement: (OFString*)name
	 prefix: (nullable OFString*)prefix
      namespace: (nullable OFString*)ns;
-  (void)parser: (OFXMLParser *)parser
  didEndElement: (OFString *)name
	 prefix: (nullable OFString *)prefix
      namespace: (nullable OFString *)ns;

/*!
 * @brief This callback is called when the XML parser found characters.
 *
 * In case there are comments or CDATA, it is possible that this callback is
 * called multiple times in a row.
 *
 * @param parser The parser which found a string
 * @param characters The characters the XML parser found
 */
-    (void)parser: (OFXMLParser*)parser
  foundCharacters: (OFString*)characters;
-    (void)parser: (OFXMLParser *)parser
  foundCharacters: (OFString *)characters;

/*!
 * @brief This callback is called when the XML parser found CDATA.
 *
 * @param parser The parser which found a string
 * @param CDATA The CDATA the XML parser found
 */
- (void)parser: (OFXMLParser*)parser
    foundCDATA: (OFString*)CDATA;
- (void)parser: (OFXMLParser *)parser
    foundCDATA: (OFString *)CDATA;

/*!
 * @brief This callback is called when the XML parser found a comment.
 *
 * @param parser The parser which found a comment
 * @param comment The comment the XML parser found
 */
- (void)parser: (OFXMLParser*)parser
  foundComment: (OFString*)comment;
- (void)parser: (OFXMLParser *)parser
  foundComment: (OFString *)comment;

/*!
 * @brief This callback is called when the XML parser found an entity it
 *	  doesn't know.
 *
 * The callback is supposed to return a substitution for the entity or `nil` if
 * it is not known to the callback as well, in which case an exception will be
 * risen.
 *
 * @param parser The parser which found an unknown entity
 * @param entity The name of the entity the XML parser didn't know
 * @return A substitution for the entity or `nil`
 */
-	(OFString*)parser: (OFXMLParser*)parser
  foundUnknownEntityNamed: (OFString*)entity;
-      (OFString *)parser: (OFXMLParser *)parser
  foundUnknownEntityNamed: (OFString *)entity;
@end

/*!
 * @class OFXMLParser OFXMLParser.h ObjFW/OFXMLParser.h
 *
 * @brief An event-based XML parser.
 *
157
158
159
160
161
162
163
164

165
166

167
168
169

170
171
172
173
174
175
176
157
158
159
160
161
162
163

164
165

166
167
168

169
170
171
172
173
174
175
176







-
+

-
+


-
+







		OF_XMLPARSER_NUM_STATES
	} _state;
	size_t _i, _last;
	const char *_data;
	OFDataArray *_buffer;
	OFString *_name, *_prefix;
	OFMutableArray
	    OF_GENERIC(OFMutableDictionary OF_GENERIC(OFString*, OFString*)*)
	    OF_GENERIC(OFMutableDictionary OF_GENERIC(OFString *, OFString *) *)
	    *_namespaces;
	OFMutableArray OF_GENERIC(OFXMLAttribute*) *_attributes;
	OFMutableArray OF_GENERIC(OFXMLAttribute *) *_attributes;
	OFString *_attributeName, *_attributePrefix;
	char _delimiter;
	OFMutableArray OF_GENERIC(OFString*) *_previous;
	OFMutableArray OF_GENERIC(OFString *) *_previous;
	size_t _level;
	bool _acceptProlog;
	size_t _lineNumber;
	bool _lastCarriageReturn, _finishedParsing;
	of_string_encoding_t _encoding;
	size_t _depthLimit;
}
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213

214
215
216
217
218
219
220

221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212

213
214
215
216
217
218
219

220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235







-
+







-
+






-
+







-
+








/*!
 * @brief Parses the specified buffer with the specified size.
 *
 * @param buffer The buffer to parse
 * @param length The length of the buffer
 */
- (void)parseBuffer: (const char*)buffer
- (void)parseBuffer: (const char *)buffer
	     length: (size_t)length;

/*!
 * @brief Parses the specified string.
 *
 * @param string The string to parse
 */
- (void)parseString: (OFString*)string;
- (void)parseString: (OFString *)string;

/*!
 * @brief Parses the specified stream.
 *
 * @param stream The stream to parse
 */
- (void)parseStream: (OFStream*)stream;
- (void)parseStream: (OFStream *)stream;

#ifdef OF_HAVE_FILES
/*!
 * @brief Parses the specified file.
 *
 * @param path The path to the file to parse
*/
- (void)parseFile: (OFString*)path;
- (void)parseFile: (OFString *)path;
#endif

/*!
 * @brief Returns the current line number.
 *
 * @return The current line number
 */

Modified src/OFXMLParser.m from [3771da0801] to [829d513f17].

56
57
58
59
60
61
62
63

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

63
64
65
66
67
68
69
70







-
+







						     length: length];
		[buffer addItems: [tmp UTF8String]
			   count: [tmp UTF8StringLength]];
		objc_autoreleasePoolPop(pool);
	}
}

static OFString*
static OFString *
transformString(OFXMLParser *parser, OFDataArray *buffer, size_t cut,
    bool unescape)
{
	char *items = [buffer items];
	size_t length = [buffer count] - cut;
	bool hasEntities = false;
	OFString *ret;
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108







-
+







			    exceptionWithParser: parser];
		}
	}

	return ret;
}

static OFString*
static OFString *
namespaceForPrefix(OFString *prefix, OFArray *namespaces)
{
	OFDictionary *const *objects = [namespaces objects];
	size_t count = [namespaces count];

	if (prefix == nil)
		prefix = @"";
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242







-
+







	[_attributeName release];
	[_attributePrefix release];
	[_previous release];

	[super dealloc];
}

- (void)parseBuffer: (const char*)buffer
- (void)parseBuffer: (const char *)buffer
	     length: (size_t)length
{
	_data = buffer;

	for (_i = _last = 0; _i < length; _i++) {
		size_t j = _i;

255
256
257
258
259
260
261
262

263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
255
256
257
258
259
260
261

262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294







-
+





-
+


















-
+








	/* In OF_XMLPARSER_IN_TAG, there can be only spaces */
	if (length - _last > 0 && _state != OF_XMLPARSER_IN_TAG)
		appendToBuffer(_buffer, _data + _last, _encoding,
		    length - _last);
}

- (void)parseString: (OFString*)string
- (void)parseString: (OFString *)string
{
	[self parseBuffer: [string UTF8String]
		   length: [string UTF8StringLength]];
}

- (void)parseStream: (OFStream*)stream
- (void)parseStream: (OFStream *)stream
{
	size_t pageSize = [OFSystemInfo pageSize];
	char *buffer = [self allocMemoryWithSize: pageSize];

	@try {
		while (![stream isAtEndOfStream]) {
			size_t length = [stream readIntoBuffer: buffer
							length: pageSize];

			[self parseBuffer: buffer
				   length: length];
		}
	} @finally {
		[self freeMemory: buffer];
	}
}

#ifdef OF_HAVE_FILES
- (void)parseFile: (OFString*)path
- (void)parseFile: (OFString *)path
{
	OFFile *file = [[OFFile alloc] initWithPath: path
					       mode: @"rb"];

	@try {
		[self parseStream: file];
	} @finally {
386
387
388
389
390
391
392
393

394
395
396
397
398
399
400
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400







-
+







		_acceptProlog = false;
		_i--;
		break;
	}
}

/* <?xml […]?> */
- (bool)OF_parseXMLProcessingInstructions: (OFString*)pi
- (bool)OF_parseXMLProcessingInstructions: (OFString *)pi
{
	const char *cString;
	size_t length, last;
	int PIState = 0;
	OFString *attribute = nil;
	OFMutableString *value = nil;
	char piDelimiter = 0;
1006
1007
1008
1009
1010
1011
1012
1013
1014


1015
1016
1017
1018
1019
1020
1021
1022
1023
1006
1007
1008
1009
1010
1011
1012


1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023







-
-
+
+









}

- (bool)hasFinishedParsing
{
	return _finishedParsing;
}

-	   (OFString*)string: (OFString*)string
  containsUnknownEntityNamed: (OFString*)entity
-	  (OFString *)string: (OFString *)string
  containsUnknownEntityNamed: (OFString *)entity
{
	if ([_delegate respondsToSelector:
	    @selector(parser:foundUnknownEntityNamed:)])
		return [_delegate parser: self
		 foundUnknownEntityNamed: entity];

	return nil;
}
@end

Modified src/OFXMLProcessingInstructions.h from [9c168a002a] to [5d805de72a].

31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47

48
49
50
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46

47
48
49
50







-
+








-
+




/*!
 * @brief Creates a new OFXMLProcessingInstructions with the specified string.
 *
 * @param string The string for the processing instructions
 * @return A new OFXMLProcessingInstructions
 */
+ (instancetype)processingInstructionsWithString: (OFString*)string;
+ (instancetype)processingInstructionsWithString: (OFString *)string;

/*!
 * @brief Initializes an already allocated OFXMLProcessingInstructions with the
 *	  specified string.
 *
 * @param string The string for the processing instructions
 * @return An initialized OFXMLProcessingInstructions
 */
- initWithString: (OFString*)string;
- initWithString: (OFString *)string;
@end

OF_ASSUME_NONNULL_END

Modified src/OFXMLProcessingInstructions.m from [65c42678b7] to [dd195c67f8].

21
22
23
24
25
26
27
28

29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
21
22
23
24
25
26
27

28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54







-
+




-
+













-
+







#import "OFXMLProcessingInstructions.h"
#import "OFString.h"
#import "OFXMLElement.h"

#import "OFInvalidArgumentException.h"

@implementation OFXMLProcessingInstructions
+ (instancetype)processingInstructionsWithString: (OFString*)string
+ (instancetype)processingInstructionsWithString: (OFString *)string
{
	return [[[self alloc] initWithString: string] autorelease];
}

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

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

	return self;
}

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

	@try {
		void *pool = objc_autoreleasePoolPush();

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







-
+




-
+




-
+




-
-
+
+







}

- (uint32_t)hash
{
	return [_processingInstructions hash];
}

- (OFString*)stringValue
- (OFString *)stringValue
{
	return @"";
}

- (OFString*)XMLString
- (OFString *)XMLString
{
	return [OFString stringWithFormat: @"<?%@?>", _processingInstructions];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
{
	return [OFString stringWithFormat: @"<?%@?>", _processingInstructions];
}

- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
				level: (unsigned int)level
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				 level: (unsigned int)level
{
	OFString *ret;

	if (indentation > 0 && level > 0) {
		char *whitespaces = [self allocMemoryWithSize:
		    (level * indentation) + 1];
		memset(whitespaces, ' ', level * indentation);
126
127
128
129
130
131
132
133

134
135
136
137
138

139
140
141
142
143
144
126
127
128
129
130
131
132

133
134
135
136
137

138
139
140
141
142
143
144







-
+




-
+






	} else
		ret = [OFString stringWithFormat: @"<?%@?>",
						  _processingInstructions];

	return ret;
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat: @"<?%@?>", _processingInstructions];
}

- (OFXMLElement*)XMLElementBySerializing
- (OFXMLElement *)XMLElementBySerializing
{
	return [OFXMLElement elementWithName: [self className]
				   namespace: OF_SERIALIZATION_NS
				 stringValue: _processingInstructions];
}
@end

Modified src/OFZIPArchive.h from [f0d277203d] to [490d5f93ce].

37
38
39
40
41
42
43
44
45


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

62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
37
38
39
40
41
42
43


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

61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118







-
-
+
+















-
+








-
+









-
+









-
+












-
+











-
+



{
	OFSeekableStream *_stream;
	uint32_t _diskNumber, _centralDirectoryDisk;
	uint64_t _centralDirectoryEntriesInDisk, _centralDirectoryEntries;
	uint64_t _centralDirectorySize;
	int64_t _centralDirectoryOffset;
	OFString *_archiveComment;
	OFMutableArray OF_GENERIC(OFZIPArchiveEntry*) *_entries;
	OFMutableDictionary OF_GENERIC(OFString*, OFZIPArchiveEntry*)
	OFMutableArray OF_GENERIC(OFZIPArchiveEntry *) *_entries;
	OFMutableDictionary OF_GENERIC(OFString *, OFZIPArchiveEntry *)
	    *_pathToEntryMap;
	OFStream *_lastReturnedStream;
}

/*!
 * The archive comment.
 */
@property (readonly, nonatomic) OFString *archiveComment;

/*!
 * @brief Creates a new OFZIPArchive object with the specified seekable stream.
 *
 * @param stream A seekable stream from which the ZIP archive will be read
 * @return A new, autoreleased OFZIPArchive
 */
+ (instancetype)archiveWithSeekableStream: (OFSeekableStream*)stream;
+ (instancetype)archiveWithSeekableStream: (OFSeekableStream *)stream;

#ifdef OF_HAVE_FILES
/*!
 * @brief Creates a new OFZIPArchive object with the specified file.
 *
 * @param path The path to the ZIP file
 * @return A new, autoreleased OFZIPArchive
 */
+ (instancetype)archiveWithPath: (OFString*)path;
+ (instancetype)archiveWithPath: (OFString *)path;
#endif

/*!
 * @brief Initializes an already allocated OFZIPArchive object with the
 *	  specified seekable stream.
 *
 * @param stream A seekable stream from which the ZIP archive will be read
 * @return An initialized OFZIPArchive
 */
- initWithSeekableStream: (OFSeekableStream*)stream;
- initWithSeekableStream: (OFSeekableStream *)stream;

#ifdef OF_HAVE_FILES
/*!
 * @brief Initializes an already allocated OFZIPArchive object with the
 *	  specified file.
 *
 * @param path The path to the ZIP file
 * @return An initialized OFZIPArchive
 */
- initWithPath: (OFString*)path;
- initWithPath: (OFString *)path;
#endif

/*!
 * @brief Returns the entries of the central directory of the archive as an
 * 	  array of objects of class @ref OFZIPArchiveEntry.
 *
 * The objects of the array have the same order as the entries in the central
 * directory, which does not need to be the order in which the actual files are
 * stored.
 *
 * @return The entries of the central directory of the archive as an array
 */
- (OFArray OF_GENERIC(OFZIPArchiveEntry*)*)entries;
- (OFArray OF_GENERIC(OFZIPArchiveEntry *) *)entries;

/*!
 * @brief Returns a stream for reading the specified file from the archive.
 *
 * @warning Calling @ref streamForReadingFile: will invalidate all streams
 *	    previously returned by @ref streamForReadingFile:! Reading from an
 *	    invalidated stream will throw an @ref OFReadFailedException!
 *
 * @param path The path to the file inside the archive
 * @return A stream for reading the specified file form the archive
 */
- (OFStream*)streamForReadingFile: (OFString*)path;
- (OFStream *)streamForReadingFile: (OFString *)path;
@end

OF_ASSUME_NONNULL_END

Modified src/OFZIPArchive.m from [16b7ebc50b] to [df3e45938b].

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







-
-
+
+












-
-
+
+







	uint16_t _lastModifiedFileTime, _lastModifiedFileDate;
	uint32_t _CRC32;
	uint64_t _compressedSize, _uncompressedSize;
	OFString *_fileName;
	OFDataArray *_extraField;
}

- initWithStream: (OFStream*)stream;
- (bool)matchesEntry: (OFZIPArchiveEntry*)entry;
- initWithStream: (OFStream *)stream;
- (bool)matchesEntry: (OFZIPArchiveEntry *)entry;
@end

@interface OFZIPArchive_FileStream: OFStream
{
	OFStream *_stream, *_decompressedStream;
	OFZIPArchive_LocalFileHeader *_localFileHeader;
	bool _hasDataDescriptor;
	uint64_t _size;
	uint32_t _CRC32;
	bool _atEndOfStream, _closed;
}

-  initWithStream: (OFStream*)path
  localFileHeader: (OFZIPArchive_LocalFileHeader*)localFileHeader;
-  initWithStream: (OFStream *)path
  localFileHeader: (OFZIPArchive_LocalFileHeader *)localFileHeader;
@end

uint32_t
of_zip_archive_read_field32(uint8_t **data, uint16_t *size)
{
	uint32_t field = 0;

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







-
+





-
+










-
+

















-
+







		@throw e;
	}
}

@implementation OFZIPArchive
@synthesize archiveComment = _archiveComment;

+ (instancetype)archiveWithSeekableStream: (OFSeekableStream*)stream
+ (instancetype)archiveWithSeekableStream: (OFSeekableStream *)stream
{
	return [[[self alloc] initWithSeekableStream: stream] autorelease];
}

#ifdef OF_HAVE_FILES
+ (instancetype)archiveWithPath: (OFString*)path
+ (instancetype)archiveWithPath: (OFString *)path
{
	return [[[self alloc] initWithPath: path] autorelease];
}
#endif

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithSeekableStream: (OFSeekableStream*)stream
- initWithSeekableStream: (OFSeekableStream *)stream
{
	self = [super init];

	@try {
		_stream = [stream retain];

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

	return self;
}

#ifdef OF_HAVE_FILES
- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
{
	self = [super init];

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

318
319
320
321
322
323
324
325

326
327
328
329
330

331
332
333
334
335
336
337
318
319
320
321
322
323
324

325
326
327
328
329

330
331
332
333
334
335
336
337







-
+




-
+








	[_entries makeImmutable];
	[_pathToEntryMap makeImmutable];

	objc_autoreleasePoolPop(pool);
}

- (OFArray*)entries
- (OFArray *)entries
{
	return [[_entries copy] autorelease];
}

- (OFStream*)streamForReadingFile: (OFString*)path
- (OFStream *)streamForReadingFile: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFZIPArchiveEntry *entry = [_pathToEntryMap objectForKey: path];
	OFZIPArchive_LocalFileHeader *localFileHeader;
	int64_t offset64;

	if (entry == nil)
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384







-
+







	objc_autoreleasePoolPop(pool);

	return [[_lastReturnedStream retain] autorelease];
}
@end

@implementation OFZIPArchive_LocalFileHeader
- initWithStream: (OFStream*)stream
- initWithStream: (OFStream *)stream
{
	self = [super init];

	@try {
		uint16_t fileNameLength, extraFieldLength;
		of_string_encoding_t encoding;
		uint8_t *ZIP64;
432
433
434
435
436
437
438
439

440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461


462
463
464
465
466
467
468
432
433
434
435
436
437
438

439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459


460
461
462
463
464
465
466
467
468







-
+




















-
-
+
+







{
	[_fileName release];
	[_extraField release];

	[super dealloc];
}

- (bool)matchesEntry: (OFZIPArchiveEntry*)entry
- (bool)matchesEntry: (OFZIPArchiveEntry *)entry
{
	if (_compressionMethod != [entry compressionMethod] ||
	    _lastModifiedFileTime != [entry OF_lastModifiedFileTime] ||
	    _lastModifiedFileDate != [entry OF_lastModifiedFileDate])
		return false;

	if (!(_generalPurposeBitFlag & (1 << 3)))
		if (_CRC32 != [entry CRC32] ||
		    _compressedSize != [entry compressedSize] ||
		    _uncompressedSize != [entry uncompressedSize])
			return false;

	if (![_fileName isEqual: [entry fileName]])
		return false;

	return true;
}
@end

@implementation OFZIPArchive_FileStream
-  initWithStream: (OFStream*)stream
  localFileHeader: (OFZIPArchive_LocalFileHeader*)localFileHeader
-  initWithStream: (OFStream *)stream
  localFileHeader: (OFZIPArchive_LocalFileHeader *)localFileHeader
{
	self = [super init];

	@try {
		_stream = [stream retain];

		switch (localFileHeader->_compressionMethod) {
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
506
507
508
509
510
511
512

513
514
515
516
517
518
519
520







-
+







}

- (bool)lowlevelIsAtEndOfStream
{
	return _atEndOfStream;
}

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

	if (_atEndOfStream || _closed)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];

Modified src/OFZIPArchiveEntry+Private.h from [94e173a584] to [aa6cbb3cc6].

18
19
20
21
22
23
24
25

26
27
28
18
19
20
21
22
23
24

25
26
27
28







-
+




OF_ASSUME_NONNULL_BEGIN

@interface OFZIPArchiveEntry ()
@property (readonly) uint16_t OF_lastModifiedFileTime, OF_lastModifiedFileDate;
@property (readonly) int64_t OF_localFileHeaderOffset;

- (instancetype)OF_initWithStream: (OFStream*)stream;
- (instancetype)OF_initWithStream: (OFStream *)stream;
@end

OF_ASSUME_NONNULL_END

Modified src/OFZIPArchiveEntry.h from [51727c4cd0] to [860be1e03d].

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







-
+






-
+











-
+







@property (readonly) uint16_t generalPurposeBitFlag;

/*!
 * @brief Returns the last modification date of the entry's file.
 *
 * @return The last modification date of the entry's file
 */
- (OFDate*)modificationDate;
- (OFDate *)modificationDate;

/*!
 * @brief Returns the extra field of the entry.
 *
 * @return The extra field of the entry
 */
- (OFDataArray*)extraField;
- (OFDataArray *)extraField;
@end

#ifdef __cplusplus
extern "C" {
#endif
/*!
 * @brief Converts the ZIP entry version to a string
 *
 * @param version The ZIP entry version to convert to a string
 * @return The ZIP entry version as a string
 */
extern OFString* of_zip_archive_entry_version_to_string(uint16_t version);
extern OFString *of_zip_archive_entry_version_to_string(uint16_t version);

/*!
 * @brief Gets a pointer to and the size of the extensible data field with the
 *	  specified tag.
 *
 * @param extraField The extra field to search for an extensible data field with
 *		     the specified tag

Modified src/OFZIPArchiveEntry.m from [75090f7155] to [7d2a571c32].

24
25
26
27
28
29
30
31
32


33
34

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


31
32
33

34
35
36
37
38
39
40
41







-
-
+
+

-
+







#import "OFDataArray.h"
#import "OFDate.h"
#import "OFStream.h"

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

extern uint32_t of_zip_archive_read_field32(uint8_t**, uint16_t*);
extern uint64_t of_zip_archive_read_field64(uint8_t**, uint16_t*);
extern uint32_t of_zip_archive_read_field32(uint8_t **, uint16_t *);
extern uint64_t of_zip_archive_read_field64(uint8_t **, uint16_t *);

OFString*
OFString *
of_zip_archive_entry_version_to_string(uint16_t version)
{
	const char *attrCompat = NULL;

	switch (version >> 8) {
	case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_MSDOS:
		attrCompat = "MS-DOS or OS/2";
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165







-
+







@synthesize CRC32 = _CRC32;
@synthesize versionSpecificAttributes = _versionSpecificAttributes;
@synthesize generalPurposeBitFlag = _generalPurposeBitFlag;
@synthesize OF_lastModifiedFileTime = _lastModifiedFileTime;
@synthesize OF_lastModifiedFileDate = _lastModifiedFileDate;
@synthesize OF_localFileHeaderOffset = _localFileHeaderOffset;

- (instancetype)OF_initWithStream: (OFStream*)stream
- (instancetype)OF_initWithStream: (OFStream *)stream
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		uint16_t fileNameLength, extraFieldLength, fileCommentLength;
		of_string_encoding_t encoding;
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
233
234
235
236
237
238
239

240
241
242
243
244
245
246
247







-
+







	[_fileName release];
	[_extraField release];
	[_fileComment release];

	[super dealloc];
}

- (OFDate*)modificationDate
- (OFDate *)modificationDate
{
	void *pool = objc_autoreleasePoolPush();
	uint16_t year = ((_lastModifiedFileDate & 0xFE00) >> 9) + 1980;
	uint8_t month = (_lastModifiedFileDate & 0x1E0) >> 5;
	uint8_t day = (_lastModifiedFileDate & 0x1F);
	uint8_t hour = (_lastModifiedFileTime & 0xF800) >> 11;
	uint8_t minute = (_lastModifiedFileTime & 0x7E0) >> 5;
257
258
259
260
261
262
263
264

265
266
267
268
269

270
271
272
273
274
275
276
257
258
259
260
261
262
263

264
265
266
267
268

269
270
271
272
273
274
275
276







-
+




-
+







						format: @"%Y-%m-%d %H:%M:%S"];

	objc_autoreleasePoolPop(pool);

	return [date autorelease];
}

- (OFDataArray*)extraField
- (OFDataArray *)extraField
{
	return [[_extraField copy] autorelease];
}

- (OFString*)description
- (OFString *)description
{
	void *pool = objc_autoreleasePoolPush();
	OFString *ret = [OFString stringWithFormat: @"<%@:\n"
	    @"\tFile name = %@\n"
	    @"\tFile comment = %@\n"
	    @"\tGeneral purpose bit flag = %u\n"
	    @"\tCompression method = %u\n"

Modified src/atomic_no_threads.h from [3924fe3a37] to [152148fa91].

25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57







-
+

















-
+







{
	return (*p += i);
}

static OF_INLINE void *_Nullable
of_atomic_ptr_add(void *volatile _Nullable *_Nonnull p, intptr_t i)
{
	return (*(char* volatile*)p += i);
	return (*(char *volatile *)p += i);
}

static OF_INLINE int
of_atomic_int_sub(volatile int *_Nonnull p, int i)
{
	return (*p -= i);
}

static OF_INLINE int32_t
of_atomic_int32_sub(volatile int32_t *_Nonnull p, int32_t i)
{
	return (*p -= i);
}

static OF_INLINE void *_Nullable
of_atomic_ptr_sub(void *volatile _Nullable *_Nonnull p, intptr_t i)
{
	return (*(char* volatile*)p -= i);
	return (*(char *volatile *)p -= i);
}

static OF_INLINE int
of_atomic_int_inc(volatile int *_Nonnull p)
{
	return ++*p;
}

Modified src/atomic_osatomic.h from [7e5dffc102] to [4f277f9764].

28
29
30
31
32
33
34
35

36
37

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

58
59

60
61
62
63
64
65
66
28
29
30
31
32
33
34

35
36

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

57
58

59
60
61
62
63
64
65
66







-
+

-
+



















-
+

-
+







	return OSAtomicAdd32(i, p);
}

static OF_INLINE void *_Nullable
of_atomic_ptr_add(void *volatile _Nullable *_Nonnull p, intptr_t i)
{
#ifdef __LP64__
	return (void*)OSAtomicAdd64(i, (int64_t*)p);
	return (void *)OSAtomicAdd64(i, (int64_t *)p);
#else
	return (void*)OSAtomicAdd32(i, (int32_t*)p);
	return (void *)OSAtomicAdd32(i, (int32_t *)p);
#endif
}

static OF_INLINE int
of_atomic_int_sub(volatile int *_Nonnull p, int i)
{
	return OSAtomicAdd32(-i, p);
}

static OF_INLINE int32_t
of_atomic_int32_sub(volatile int32_t *_Nonnull p, int32_t i)
{
	return OSAtomicAdd32(-i, p);
}

static OF_INLINE void *_Nullable
of_atomic_ptr_sub(void *volatile _Nullable *_Nonnull p, intptr_t i)
{
#ifdef __LP64__
	return (void*)OSAtomicAdd64(-i, (int64_t*)p);
	return (void *)OSAtomicAdd64(-i, (int64_t *)p);
#else
	return (void*)OSAtomicAdd32(-i, (int32_t*)p);
	return (void *)OSAtomicAdd32(-i, (int32_t *)p);
#endif
}

static OF_INLINE int
of_atomic_int_inc(volatile int *_Nonnull p)
{
	return OSAtomicIncrement32(p);

Modified src/atomic_powerpc.h from [56d99bc409] to [1547de0695].

55
56
57
58
59
60
61
62

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

62
63
64
65
66
67
68
69







-
+







	    "add	%0, %0, %1\n\t"
	    "stwcx.	%0, 0, %2\n\t"
	    "bne-	0b"
	    : "=&r"(i)
	    : "r"(i), "r"(p)
	);

	return (void*)i;
	return (void *)i;
}

static OF_INLINE int
of_atomic_int_sub(volatile int *_Nonnull p, int i)
{
	__asm__ __volatile__ (
	    "0:\n\t"
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117







-
+







	    "sub	%0, %0, %1\n\t"
	    "stwcx.	%0, 0, %2\n\t"
	    "bne-	0b"
	    : "=&r"(i)
	    : "r"(i), "r"(p)
	);

	return (void*)i;
	return (void *)i;
}

static OF_INLINE int
of_atomic_int_inc(volatile int *_Nonnull p)
{
	int i;

Modified src/atomic_sync_builtins.h from [b3ae278d63] to [228897fe83].

25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57







-
+

















-
+







{
	return __sync_add_and_fetch(p, i);
}

static OF_INLINE void *_Nullable
of_atomic_ptr_add(void *volatile _Nullable *_Nonnull p, intptr_t i)
{
	return __sync_add_and_fetch(p, (void*)i);
	return __sync_add_and_fetch(p, (void *)i);
}

static OF_INLINE int
of_atomic_int_sub(volatile int *_Nonnull p, int i)
{
	return __sync_sub_and_fetch(p, i);
}

static OF_INLINE int32_t
of_atomic_int32_sub(volatile int32_t *_Nonnull p, int32_t i)
{
	return __sync_sub_and_fetch(p, i);
}

static OF_INLINE void *_Nullable
of_atomic_ptr_sub(void *volatile _Nullable *_Nonnull p, intptr_t i)
{
	return __sync_sub_and_fetch(p, (void*)i);
	return __sync_sub_and_fetch(p, (void *)i);
}

static OF_INLINE int
of_atomic_int_inc(volatile int *_Nonnull p)
{
	return __sync_add_and_fetch(p, 1);
}

Modified src/atomic_x86.h from [7c455e67f3] to [1b998b9efc].

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







-
+









-
+







	    "lock\n\t"
	    "xaddq	%0, %2\n\t"
	    "addq	%1, %0"
	    : "+&r"(i)
	    : "r"(i), "m"(*p)
	);

	return (void*)i;
	return (void *)i;
#elif defined(OF_X86_ASM)
	__asm__ __volatile__ (
	    "lock\n\t"
	    "xaddl	%0, %2\n\t"
	    "addl	%1, %0"
	    : "+&r"(i)
	    : "r"(i), "m"(*p)
	);

	return (void*)i;
	return (void *)i;
#endif
}

static OF_INLINE int
of_atomic_int_sub(volatile int *_Nonnull p, int i)
{
	if (sizeof(int) == 4)
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
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







-
+










-
+







	    "lock\n\t"
	    "xaddq	%0, %2\n\t"
	    "subq	%1, %0"
	    : "+&r"(i)
	    : "r"(i), "m"(*p)
	);

	return (void*)i;
	return (void *)i;
#elif defined(OF_X86_ASM)
	__asm__ __volatile__ (
	    "negl	%0\n\t"
	    "lock\n\t"
	    "xaddl	%0, %2\n\t"
	    "subl	%1, %0"
	    : "+&r"(i)
	    : "r"(i), "m"(*p)
	);

	return (void*)i;
	return (void *)i;
#endif
}

static OF_INLINE int
of_atomic_int_inc(volatile int *_Nonnull p)
{
	int i;

Modified src/autorelease.h from [d57fd73d90] to [208b8e102b].

24
25
26
27
28
29
30
31

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

31
32
33
34
35
36
37
38







-
+







extern "C" {
#endif
/*!
 * @brief Creates a new autorelease pool.
 *
 * @return An identifier for the created autorelease pool
 */
extern void* objc_autoreleasePoolPush();
extern void *objc_autoreleasePoolPush();

/*!
 * @brief Drains an autorelease pool.
 *
 * @param pool An identifier for the pool to drain
 */
extern void objc_autoreleasePoolPop(void *pool);

Modified src/autorelease.m from [1e49675760] to [bf8548a62d].

43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66







-
+








-
+







{
	OF_ENSURE(of_tlskey_new(&objectsKey));
	OF_ENSURE(of_tlskey_new(&topKey));
	OF_ENSURE(of_tlskey_new(&sizeKey));
}
#endif

void*
void *
objc_autoreleasePoolPush()
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	id *top = of_tlskey_get(topKey);
	id *objects = of_tlskey_get(objectsKey);
#endif
	ptrdiff_t offset = top - objects;

	return (void*)offset;
	return (void *)offset;
}

void
objc_autoreleasePoolPop(void *offset)
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	id *top = of_tlskey_get(topKey);
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
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







-
+











-
+








		OF_ENSURE((objects = malloc(size)) != NULL);

		top = objects;

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
		OF_ENSURE(of_tlskey_set(objectsKey, objects));
		OF_ENSURE(of_tlskey_set(sizeKey, (void*)(uintptr_t)size));
		OF_ENSURE(of_tlskey_set(sizeKey, (void *)(uintptr_t)size));
#endif
	}

	if ((uintptr_t)top >= (uintptr_t)objects + size) {
		ptrdiff_t diff = top - objects;

		size += [OFSystemInfo pageSize];
		OF_ENSURE((objects = realloc(objects, size)) != NULL);

#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
		OF_ENSURE(of_tlskey_set(objectsKey, objects));
		OF_ENSURE(of_tlskey_set(sizeKey, (void*)(uintptr_t)size));
		OF_ENSURE(of_tlskey_set(sizeKey, (void *)(uintptr_t)size));
#endif

		top = objects + diff;
	}

	*top = object;
	top++;

Modified src/base64.h from [1b98b68ead] to [187615e668].

27
28
29
30
31
32
33
34
35


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


34
35
36
37
38
39
40







-
-
+
+






@class OFString;
@class OFDataArray;

#ifdef __cplusplus
extern "C" {
#endif
extern OFString* of_base64_encode(const void*, size_t);
extern bool of_base64_decode(OFDataArray*, const char*, size_t);
extern OFString *of_base64_encode(const void *, size_t);
extern bool of_base64_decode(OFDataArray *, const char *, size_t);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/base64.m from [214663ac89] to [1b4e200414].

35
36
37
38
39
40
41
42

43
44
45
46

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

42
43
44
45

46
47
48
49
50
51
52
53







-
+



-
+







	55, 56, 57, 58, 59, 60, 61, -1, -1, -1,  0, -1, -1, -1,  0,  1,  2,
	 3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
	20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30,
	31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
	48, 49, 50, 51, -1, -1, -1, -1, -1
};

OFString*
OFString *
of_base64_encode(const void *data, size_t length)
{
	OFMutableString *ret = [OFMutableString string];
	uint8_t *buffer = (uint8_t*)data;
	uint8_t *buffer = (uint8_t *)data;
	size_t i;
	uint8_t rest;
	char tb[4];
	uint32_t sb;

	rest = length % 3;

94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108







-
+








	return ret;
}

bool
of_base64_decode(OFDataArray *data, const char *string, size_t length)
{
	const uint8_t *buffer = (const uint8_t*)string;
	const uint8_t *buffer = (const uint8_t *)string;
	size_t i;

	if ((length & 3) != 0)
		return false;

	if ([data itemSize] != 1)
		return false;

Modified src/block.h from [735c685469] to [9d0c7b51a6].

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







-
-
+
+








-
+

-
+
+







-
+


-
+



		const char *signature;
	} *descriptor;
} of_block_literal_t;

#ifdef __cplusplus
extern "C" {
#endif
extern void* _Block_copy(const void*);
extern void _Block_release(const void*);
extern void *_Block_copy(const void *);
extern void _Block_release(const void *);

# if defined(OF_WINDOWS) && defined(OF_COMPILING_OBJFW)
/*
 * Clang has implicit declarations for these, but they are dllimport. When
 * compiling ObjFW itself, these need to be dllexport.
 */
extern __declspec(dllexport) struct objc_abi_class _NSConcreteStackBlock;
extern __declspec(dllexport) struct objc_abi_class _NSConcreteGlobalBlock;
extern __declspec(dllexport) void _Block_object_assign(void*, const void*,
extern __declspec(dllexport) void _Block_object_assign(void *, const void *,
    const int);
extern __declspec(dllexport) void _Block_object_dispose(const void*, const int);
extern __declspec(dllexport) void _Block_object_dispose(const void *,
    const int);
# endif
#ifdef __cplusplus
}
#endif

#ifndef Block_copy
# define Block_copy(...) \
    ((__typeof__(__VA_ARGS__))_Block_copy((const void*)(__VA_ARGS__)))
    ((__typeof__(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
#endif
#ifndef Block_release
# define Block_release(...) _Block_release((const void*)(__VA_ARGS__))
# define Block_release(...) _Block_release((const void *)(__VA_ARGS__))
#endif

OF_ASSUME_NONNULL_END

Modified src/bridge/NSArray_OFArray.h from [58defe4ba5] to [8bde2d37be].

19
20
21
22
23
24
25
26

27
19
20
21
22
23
24
25

26
27







-
+

@class OFArray;

@interface NSArray_OFArray: NSArray
{
	OFArray *_array;
}

- initWithOFArray: (OFArray*)array;
- initWithOFArray: (OFArray *)array;
@end

Modified src/bridge/NSArray_OFArray.m from [cba0f47bb2] to [ab0fe4a97d].

17
18
19
20
21
22
23
24

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

42
43
44
45
46
47
48
17
18
19
20
21
22
23

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

41
42
43
44
45
46
47
48







-
+
















-
+







#import "NSArray_OFArray.h"
#import "OFArray.h"
#import "OFBridging.h"

#import "OFOutOfRangeException.h"

@implementation NSArray_OFArray
- initWithOFArray: (OFArray*)array
- initWithOFArray: (OFArray *)array
{
	if ((self = [super init]) != nil) {
		@try {
			_array = [array retain];
		} @catch (id e) {
			return nil;
		}
	}

	return self;
}

- (id)objectAtIndex: (NSUInteger)index
{
	id object = [_array objectAtIndex: index];

	if ([(OFObject*)object conformsToProtocol: @protocol(OFBridging)])
	if ([(OFObject *)object conformsToProtocol: @protocol(OFBridging)])
		return [object NSObject];

	return object;
}

- (NSUInteger)count
{

Modified src/bridge/NSDictionary_OFDictionary.h from [c7b6c32d51] to [57ff64c5b6].

19
20
21
22
23
24
25
26

27
19
20
21
22
23
24
25

26
27







-
+

@class OFDictionary;

@interface NSDictionary_OFDictionary: NSDictionary
{
	OFDictionary *_dictionary;
}

- initWithOFDictionary: (OFDictionary*)dictionary;
- initWithOFDictionary: (OFDictionary *)dictionary;
@end

Modified src/bridge/NSDictionary_OFDictionary.m from [7efb530341] to [8917cda49a].

19
20
21
22
23
24
25
26

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

44
45
46
47
48

49
50
51
52
53
54
55
19
20
21
22
23
24
25

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

43
44
45
46
47

48
49
50
51
52
53
54
55







-
+
















-
+




-
+








#import "NSBridging.h"
#import "OFBridging.h"

#import "OFOutOfRangeException.h"

@implementation NSDictionary_OFDictionary
- initWithOFDictionary: (OFDictionary*)dictionary
- initWithOFDictionary: (OFDictionary *)dictionary
{
	if ((self = [super init]) != nil) {
		@try {
			_dictionary = [dictionary retain];
		} @catch (id e) {
			return nil;
		}
	}

	return self;
}

- (id)objectForKey: (id)key
{
	id object;

	if ([(NSObject*)key conformsToProtocol: @protocol(NSBridging)])
	if ([(NSObject *)key conformsToProtocol: @protocol(NSBridging)])
		key = [key OFObject];

	object = [_dictionary objectForKey: key];

	if ([(OFObject*)object conformsToProtocol: @protocol(OFBridging)])
	if ([(OFObject *)object conformsToProtocol: @protocol(OFBridging)])
		return [object NSObject];

	return object;
}

- (NSUInteger)count
{

Modified src/bridge/OFArray_NSArray.h from [44f8cea25c] to [ff8b9d8260].

23
24
25
26
27
28
29
30

31
23
24
25
26
27
28
29

30
31







-
+

@class NSArray;

@interface OFArray_NSArray: OFArray
{
	NSArray *_array;
}

- initWithNSArray: (NSArray*)array;
- initWithNSArray: (NSArray *)array;
@end

Modified src/bridge/OFArray_NSArray.m from [b5d4fd1d10] to [94ceef5c3f].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







#import "OFArray_NSArray.h"
#import "NSBridging.h"

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

@implementation OFArray_NSArray
- initWithNSArray: (NSArray*)array
- initWithNSArray: (NSArray *)array
{
	self = [super init];

	@try {
		if (array == nil)
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62
63







-
+










	id object;

	if (index > NSUIntegerMax)
		@throw [OFOutOfRangeException exception];

	object = [_array objectAtIndex: index];

	if ([(NSObject*)object conformsToProtocol: @protocol(NSBridging)])
	if ([(NSObject *)object conformsToProtocol: @protocol(NSBridging)])
		return [object OFObject];

	return object;
}

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

Modified src/bridge/OFDictionary_NSDictionary.h from [4f087176a3] to [bc29657cbb].

23
24
25
26
27
28
29
30

31
23
24
25
26
27
28
29

30
31







-
+

@class NSDictionary;

@interface OFDictionary_NSDictionary: OFDictionary
{
	NSDictionary *_dictionary;
}

- initWithNSDictionary: (NSDictionary*)dictionary;
- initWithNSDictionary: (NSDictionary *)dictionary;
@end

Modified src/bridge/OFDictionary_NSDictionary.m from [38c430eb6b] to [8b7a3db643].

20
21
22
23
24
25
26
27

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

27
28
29
30
31
32
33
34







-
+








#import "NSBridging.h"
#import "OFBridging.h"

#import "OFInitializationFailedException.h"

@implementation OFDictionary_NSDictionary
- initWithNSDictionary: (NSDictionary*)dictionary
- initWithNSDictionary: (NSDictionary *)dictionary
{
	self = [super init];

	@try {
		if (dictionary == nil)
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];
42
43
44
45
46
47
48
49

50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
42
43
44
45
46
47
48

49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64







-
+




-
+










	return self;
}

- (id)objectForKey: (id)key
{
	id object;

	if ([(OFObject*)key conformsToProtocol: @protocol(OFBridging)])
	if ([(OFObject *)key conformsToProtocol: @protocol(OFBridging)])
		key = [key NSObject];

	object = [_dictionary objectForKey: key];

	if ([(NSObject*)object conformsToProtocol: @protocol(NSBridging)])
	if ([(NSObject *)object conformsToProtocol: @protocol(NSBridging)])
		return [object OFObject];

	return object;
}

- (size_t)count
{
	return [_dictionary count];
}
@end

Modified src/exceptions/OFAcceptFailedException.m from [11a91dcb56] to [3dce4b47ac].

48
49
50
51
52
53
54
55

56
57
58
59
60
61
48
49
50
51
52
53
54

55
56
57
58
59
60
61







-
+






- (void)dealloc
{
	[_socket release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to accept connection in socket of class %@: %@",
	    [_socket class], of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFAddressTranslationFailedException.h from [2e4d1739ad] to [254e69058d].

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







-
+

-
+









-
+

-
+






/*!
 * @brief Creates a new, autoreleased address translation failed exception.
 *
 * @param host The host for which translation was requested
 * @return A new, autoreleased address translation failed exception
 */
+ (instancetype)exceptionWithHost: (nullable OFString*)host;
+ (instancetype)exceptionWithHost: (nullable OFString *)host;

+ (instancetype)exceptionWithHost: (nullable OFString*)host
+ (instancetype)exceptionWithHost: (nullable OFString *)host
			    error: (int)error;
+ (instancetype)exceptionWithError: (int)error;

/*!
 * @brief Initializes an already allocated address translation failed exception.
 *
 * @param host The host for which translation was requested
 * @return An initialized address translation failed exception
 */
- initWithHost: (nullable OFString*)host;
- initWithHost: (nullable OFString *)host;

- (instancetype)initWithHost: (nullable OFString*)host
- (instancetype)initWithHost: (nullable OFString *)host
		       error: (int)error;
- (instancetype)initWithError: (int)error;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFAddressTranslationFailedException.m from [eb706ff06f] to [b3820ad5f4].

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







-
+




-
+











-
+













-
+








	if (!of_mutex_new(&mutex))
		@throw [OFInitializationFailedException
		    exceptionWithClass: class];
}
#endif

+ (instancetype)exceptionWithHost: (OFString*)host
+ (instancetype)exceptionWithHost: (OFString *)host
{
	return [[[self alloc] initWithHost: host] autorelease];
}

+ (instancetype)exceptionWithHost: (OFString*)host
+ (instancetype)exceptionWithHost: (OFString *)host
			    error: (int)error
{
	return [[[self alloc] initWithHost: host
				     error: error] autorelease];
}

+ (instancetype)exceptionWithError: (int)error
{
	return [[[self alloc] initWithError: error] autorelease];
}

- initWithHost: (OFString*)host
- initWithHost: (OFString *)host
{
	self = [super init];

	@try {
		_host = [host copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithHost: (OFString*)host
- (instancetype)initWithHost: (OFString *)host
		       error: (int)error
{
	self = [super init];

	@try {
		_host = [host copy];
		_error = error;
105
106
107
108
109
110
111
112

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

112
113
114
115
116
117
118
119







-
+







- (void)dealloc
{
	[_host release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	/* FIXME: Add proper description for Win32 */
#ifndef OF_WINDOWS
	if (_error == 0) {
#endif
		if (_host != nil)
			return [OFString stringWithFormat:

Modified src/exceptions/OFAllocFailedException.h from [4100b2fe9e] to [adf82e28da].

37
38
39
40
41
42
43
44

45
46
47
37
38
39
40
41
42
43

44
45
46
47







-
+



 */
@interface OFAllocFailedException: OFObject
/*!
 * @brief Returns a description of the exception.
 *
 * @return A description of the exception
 */
- (OFString*)description;
- (OFString *)description;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFAllocFailedException.m from [6b2c31fa22] to [3f54c3ecda].

26
27
28
29
30
31
32
33







34
35
36
37
38
39


40
41
42
43
44
45



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

58
59
60
61
62
63
64
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43


44
45
46
47
48
49


50
51
52
53
54
55
56








57
58
59
60
61
62
63
64







-
+
+
+
+
+
+
+




-
-
+
+




-
-
+
+
+




-
-
-
-
-
-
-
-
+







}

- init
{
	OF_INVALID_INIT_METHOD
}

- (void*)allocMemoryWithSize: (size_t)size
- (void *)allocMemoryWithSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)allocMemoryForNItems: (size_t)nitems
		      withSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)allocMemoryForNItems: (size_t)nitems
                     withSize: (size_t)size
- (void *)resizeMemory: (void *)ptr
		toSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)resizeMemory: (void*)ptr
	       toSize: (size_t)size
- (void *)resizeMemory: (void *)ptr
	      toNItems: (size_t)nitems
	      withSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void*)resizeMemory: (void*)ptr
	     toNItems: (size_t)nitems
	     withSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)freeMemory: (void*)ptr
- (void)freeMemory: (void *)ptr
{
	OF_UNRECOGNIZED_SELECTOR
}

- retain
{
	return self;
79
80
81
82
83
84
85
86

87
88
89
90
79
80
81
82
83
84
85

86
87
88
89
90







-
+




}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}

- (OFString*)description
- (OFString *)description
{
	return @"Allocating an object failed!";
}
@end

Modified src/exceptions/OFAlreadyConnectedException.m from [975e60fb76] to [e64bcd1baf].

39
40
41
42
43
44
45
46

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

46
47
48
49
50
51
52
53
54
55
56







-
+










- (void)dealloc
{
	[_socket release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_socket)
		return [OFString stringWithFormat:
		    @"The socket of type %@ is already connected or bound and "
		    @"thus can't be connected or bound again!",
		    [_socket class]];
	else
		return @"A connection has already been established!";
}
@end

Modified src/exceptions/OFBindFailedException.h from [c2c0f94e68] to [533b445442].

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







-
+













-
+






 *
 * @param host The host on which binding failed
 * @param port The port on which binding failed
 * @param socket The socket which could not be bound
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased bind failed exception
 */
+ (instancetype)exceptionWithHost: (OFString*)host
+ (instancetype)exceptionWithHost: (OFString *)host
			     port: (uint16_t)port
			   socket: (id)socket
			    errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated bind failed exception.
 *
 * @param host The host on which binding failed
 * @param port The port on which binding failed
 * @param socket The socket which could not be bound
 * @param errNo The errno of the error that occurred
 * @return An initialized bind failed exception
 */
- initWithHost: (OFString*)host
- initWithHost: (OFString *)host
	  port: (uint16_t)port
	socket: (id)socket
	 errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFBindFailedException.m from [54991134ed] to [e0e0543c8b].

20
21
22
23
24
25
26
27

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

44
45
46
47
48
49
50
20
21
22
23
24
25
26

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

43
44
45
46
47
48
49
50







-
+















-
+








#import "OFBindFailedException.h"
#import "OFString.h"

@implementation OFBindFailedException
@synthesize host = _host, port = _port, socket = _socket, errNo = _errNo;

+ (instancetype)exceptionWithHost: (OFString*)host
+ (instancetype)exceptionWithHost: (OFString *)host
			     port: (uint16_t)port
			   socket: (id)socket
			    errNo: (int)errNo
{
	return [[[self alloc] initWithHost: host
				      port: port
				    socket: socket
				     errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithHost: (OFString*)host
- initWithHost: (OFString *)host
	  port: (uint16_t)port
	socket: (id)socket
	 errNo: (int)errNo
{
	self = [super init];

	@try {
64
65
66
67
68
69
70
71

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

71
72
73
74
75
76
77
78







-
+







{
	[_host release];
	[_socket release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Binding to port %" @PRIu16 @" on host %@ failed in socket of "
	    @"type %@: %@",
	    _port, _host, [_socket class], of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFChangeCurrentDirectoryPathFailedException.h from [93572132e5] to [9414640136].

47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65

66
67
68
69
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64

65
66
67
68
69







-
+










-
+




 *	  exception.
 *
 * @param path The path of the directory to which the current path could not be
 *	       changed
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased change current directory path failed exception
 */
+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
			    errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated change directory failed exception.
 *
 * @param path The path of the directory to which the current path could not be
 *	       changed
 * @param errNo The errno of the error that occurred
 * @return An initialized change current directory path failed exception
 */
- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
	 errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFChangeCurrentDirectoryPathFailedException.m from [6a0c2056fa] to [2d31d2e850].

18
19
20
21
22
23
24
25

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

38
39
40
41
42
43
44
18
19
20
21
22
23
24

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

37
38
39
40
41
42
43
44







-
+











-
+








#import "OFChangeCurrentDirectoryPathFailedException.h"
#import "OFString.h"

@implementation OFChangeCurrentDirectoryPathFailedException
@synthesize path = _path, errNo = _errNo;

+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
			    errNo: (int)errNo
{
	return [[[self alloc] initWithPath: path
				     errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
	 errNo: (int)errNo
{
	self = [super init];

	@try {
		_path = [path copy];
		_errNo = errNo;
53
54
55
56
57
58
59
60

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

60
61
62
63
64
65
66







-
+






- (void)dealloc
{
	[_path release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to change the current directory path to %@: %@",
	    _path, of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFChangeOwnerFailedException.h from [b287da5fe9] to [4b057b44b4].

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







-
-
-
+
+
+











-
-
-
+
+
+




 *
 * @param path The path of the item
 * @param owner The new owner for the item
 * @param group The new group for the item
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased change owner failed exception
 */
+ (instancetype)exceptionWithPath: (OFString*)path
			    owner: (nullable OFString*)owner
			    group: (nullable OFString*)group
+ (instancetype)exceptionWithPath: (OFString *)path
			    owner: (nullable OFString *)owner
			    group: (nullable OFString *)group
			    errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated change owner failed exception.
 *
 * @param path The path of the item
 * @param owner The new owner for the item
 * @param group The new group for the item
 * @param errNo The errno of the error that occurred
 * @return An initialized change owner failed exception
 */
- initWithPath: (OFString*)path
	 owner: (nullable OFString*)owner
	 group: (nullable OFString*)group
- initWithPath: (OFString *)path
	 owner: (nullable OFString *)owner
	 group: (nullable OFString *)group
	 errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFChangeOwnerFailedException.m from [c1acdcd0f7] to [a981279a06].

18
19
20
21
22
23
24
25
26
27



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



44
45
46
47
48
49
50
18
19
20
21
22
23
24



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



41
42
43
44
45
46
47
48
49
50







-
-
-
+
+
+













-
-
-
+
+
+








#import "OFChangeOwnerFailedException.h"
#import "OFString.h"

@implementation OFChangeOwnerFailedException
@synthesize path = _path, owner = _owner, group = _group, errNo = _errNo;

+ (instancetype)exceptionWithPath: (OFString*)path
			    owner: (OFString*)owner
			    group: (OFString*)group
+ (instancetype)exceptionWithPath: (OFString *)path
			    owner: (OFString *)owner
			    group: (OFString *)group
			    errNo: (int)errNo
{
	return [[[self alloc] initWithPath: path
				     owner: owner
				     group: group
				     errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithPath: (OFString*)path
	 owner: (OFString*)owner
	 group: (OFString*)group
- initWithPath: (OFString *)path
	 owner: (OFString *)owner
	 group: (OFString *)group
	 errNo: (int)errNo
{
	self = [super init];

	@try {
		_path  = [path copy];
		_owner = [owner copy];
63
64
65
66
67
68
69
70

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

70
71
72
73
74
75
76
77







-
+







	[_path release];
	[_owner release];
	[_group release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_group == nil)
		return [OFString stringWithFormat:
		    @"Failed to change owner of item at path %@ to %@: %@",
		    _path, _owner, of_strerror(_errNo)];
	else if (_owner == nil)
		return [OFString stringWithFormat:

Modified src/exceptions/OFChangePermissionsFailedException.h from [0f5d5d06cd] to [4969272a62].

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







-
+











-
+





 * @brief Creates a new, autoreleased change permissions failed exception.
 *
 * @param path The path of the item
 * @param permissions The new permissions for the item
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased change permissions failed exception
 */
+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
		      permissions: (mode_t)permissions
			    errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated change permissions failed exception.
 *
 * @param path The path of the item
 * @param permissions The new permissions for the item
 * @param errNo The errno of the error that occurred
 * @return An initialized change permissions failed exception
 */
- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
   permissions: (mode_t)permissions
	 errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFChangePermissionsFailedException.m from [f51299aa20] to [b3ab971426].

18
19
20
21
22
23
24
25

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

40
41
42
43
44
45
46
18
19
20
21
22
23
24

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

39
40
41
42
43
44
45
46







-
+













-
+








#import "OFChangePermissionsFailedException.h"
#import "OFString.h"

@implementation OFChangePermissionsFailedException
@synthesize path = _path, permissions = _permissions, errNo = _errNo;

+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
		      permissions: (mode_t)permissions
			    errNo: (int)errNo
{
	return [[[self alloc] initWithPath: path
			       permissions: permissions
				     errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
   permissions: (mode_t)permissions
	 errNo: (int)errNo
{
	self = [super init];

	@try {
		_path = [path copy];
57
58
59
60
61
62
63
64

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

64
65
66
67
68
69
70







-
+






- (void)dealloc
{
	[_path release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to change permissions of item at path %@ to %d: %@",
	    _path, _permissions, of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFChecksumFailedException.m from [195b33d7d2] to [9e360e89d7].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#include "config.h"

#import "OFChecksumFailedException.h"
#import "OFString.h"

@implementation OFChecksumFailedException
- (OFString*)description
- (OFString *)description
{
	return @"Checksum mismatch!";
}
@end

Modified src/exceptions/OFConditionBroadcastFailedException.h from [437194a4ea] to [bec42f7089].

43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58

59
60
61
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57

58
59
60
61







-
+







-
+




/*!
 * @brief Returns a new, autoreleased condition broadcast failed exception.
 *
 * @param condition The condition which could not be broadcasted
 * @return A new, autoreleased condition broadcast failed exception
 */
+ (instancetype)exceptionWithCondition: (nullable OFCondition*)condition;
+ (instancetype)exceptionWithCondition: (nullable OFCondition *)condition;

/*!
 * @brief Initializes an already allocated condition broadcast failed exception.
 *
 * @param condition The condition which could not be broadcasted
 * @return An initialized condition broadcast failed exception
 */
- initWithCondition: (nullable OFCondition*)condition;
- initWithCondition: (nullable OFCondition *)condition;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFConditionBroadcastFailedException.m from [025e3341b0] to [b1afbaa1c2].

19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
19
20
21
22
23
24
25

26
27
28
29
30

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

47
48
49
50
51
52
53
54
55
56







-
+




-
+















-
+









#import "OFConditionBroadcastFailedException.h"
#import "OFString.h"
#import "OFCondition.h"

@implementation OFConditionBroadcastFailedException
@synthesize condition = _condition;

+ (instancetype)exceptionWithCondition: (OFCondition*)condition
+ (instancetype)exceptionWithCondition: (OFCondition *)condition
{
	return [[[self alloc] initWithCondition: condition] autorelease];
}

- initWithCondition: (OFCondition*)condition
- initWithCondition: (OFCondition *)condition
{
	self = [super init];

	_condition = [condition retain];

	return self;
}

- (void)dealloc
{
	[_condition release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_condition != nil)
		return [OFString stringWithFormat:
		    @"Broadcasting a condition of type %@ failed!",
		    [_condition class]];
	else
		return @"Broadcasting a condition failed!";
}
@end

Modified src/exceptions/OFConditionSignalFailedException.h from [39b1e11cca] to [98ff55faa5].

43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58

59
60
61
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57

58
59
60
61







-
+







-
+




/*!
 * @brief Creates a new, autoreleased condition signal failed exception.
 *
 * @param condition The condition which could not be signaled
 * @return A new, autoreleased condition signal failed exception
 */
+ (instancetype)exceptionWithCondition: (nullable OFCondition*)condition;
+ (instancetype)exceptionWithCondition: (nullable OFCondition *)condition;

/*!
 * @brief Initializes an already allocated condition signal failed exception.
 *
 * @param condition The condition which could not be signaled
 * @return An initialized condition signal failed exception
 */
- initWithCondition: (nullable OFCondition*)condition;
- initWithCondition: (nullable OFCondition *)condition;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFConditionSignalFailedException.m from [ed61ab5b51] to [f8777a8229].

19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
19
20
21
22
23
24
25

26
27
28
29
30

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

47
48
49
50
51
52
53
54
55
56







-
+




-
+















-
+









#import "OFConditionSignalFailedException.h"
#import "OFString.h"
#import "OFCondition.h"

@implementation OFConditionSignalFailedException
@synthesize condition = _condition;

+ (instancetype)exceptionWithCondition: (OFCondition*)condition
+ (instancetype)exceptionWithCondition: (OFCondition *)condition
{
	return [[[self alloc] initWithCondition: condition] autorelease];
}

- initWithCondition: (OFCondition*)condition
- initWithCondition: (OFCondition *)condition
{
	self = [super init];

	_condition = [condition retain];

	return self;
}

- (void)dealloc
{
	[_condition release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_condition != nil)
		return [OFString stringWithFormat:
		    @"Signaling a condition of type %@ failed!",
		    [_condition class]];
	else
		return @"Signaling a condition failed!";
}
@end

Modified src/exceptions/OFConditionStillWaitingException.h from [3b236e57e8] to [8ebf47ac72].

44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59

60
61
62
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58

59
60
61
62







-
+







-
+




/*!
 * @brief Creates a new, autoreleased condition still waiting exception.
 *
 * @param condition The condition for which is still being waited
 * @return A new, autoreleased condition still waiting exception
 */
+ (instancetype)exceptionWithCondition: (nullable OFCondition*)condition;
+ (instancetype)exceptionWithCondition: (nullable OFCondition *)condition;

/*!
 * @brief Initializes an already allocated condition still waiting exception.
 *
 * @param condition The condition for which is still being waited
 * @return An initialized condition still waiting exception
 */
- initWithCondition: (nullable OFCondition*)condition;
- initWithCondition: (nullable OFCondition *)condition;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFConditionStillWaitingException.m from [6747f3c524] to [ec957ebffb].

19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
19
20
21
22
23
24
25

26
27
28
29
30

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

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







-
+




-
+















-
+











#import "OFConditionStillWaitingException.h"
#import "OFString.h"
#import "OFCondition.h"

@implementation OFConditionStillWaitingException
@synthesize condition = _condition;

+ (instancetype)exceptionWithCondition: (OFCondition*)condition
+ (instancetype)exceptionWithCondition: (OFCondition *)condition
{
	return [[[self alloc] initWithCondition: condition] autorelease];
}

- initWithCondition: (OFCondition*)condition
- initWithCondition: (OFCondition *)condition
{
	self = [super init];

	_condition = [condition retain];

	return self;
}

- (void)dealloc
{
	[_condition release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_condition != nil)
		return [OFString stringWithFormat:
		    @"Deallocation of a condition of type %@ was tried, even "
		    "though a thread was still waiting for it!",
		    [_condition class]];
	else
		return @"Deallocation of a condition was tried, even though a "
		    "thread was still waiting for it!";
}
@end

Modified src/exceptions/OFConditionWaitFailedException.h from [509f0c4160] to [09e764d0e9].

43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58

59
60
61
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57

58
59
60
61







-
+







-
+




/*!
 * @brief Creates a new, autoreleased condition wait failed exception.
 *
 * @param condition The condition for which could not be waited
 * @return A new, autoreleased condition wait failed exception
 */
+ (instancetype)exceptionWithCondition: (nullable OFCondition*)condition;
+ (instancetype)exceptionWithCondition: (nullable OFCondition *)condition;

/*!
 * @brief Initializes an already allocated condition wait failed exception.
 *
 * @param condition The condition for which could not be waited
 * @return An initialized condition wait failed exception
 */
- initWithCondition: (nullable OFCondition*)condition;
- initWithCondition: (nullable OFCondition *)condition;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFConditionWaitFailedException.m from [71f9cc7f2e] to [d191ac48bf].

19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
19
20
21
22
23
24
25

26
27
28
29
30

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

47
48
49
50
51
52
53
54
55
56







-
+




-
+















-
+









#import "OFConditionWaitFailedException.h"
#import "OFString.h"
#import "OFCondition.h"

@implementation OFConditionWaitFailedException
@synthesize condition = _condition;

+ (instancetype)exceptionWithCondition: (OFCondition*)condition
+ (instancetype)exceptionWithCondition: (OFCondition *)condition
{
	return [[[self alloc] initWithCondition: condition] autorelease];
}

- initWithCondition: (OFCondition*)condition
- initWithCondition: (OFCondition *)condition
{
	self = [super init];

	_condition = [condition retain];

	return self;
}

- (void)dealloc
{
	[_condition release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_condition != nil)
		return [OFString stringWithFormat:
		    @"Waiting for a condition of type %@ failed!",
		    [_condition class]];
	else
		return @"Waiting for a condition failed!";
}
@end

Modified src/exceptions/OFConnectionFailedException.h from [1c78b42463] to [da0c71c6e8].

60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
60
61
62
63
64
65
66

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

80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112







-
+












-
+












-
+












-
+






 * @brief Creates a new, autoreleased connection failed exception.
 *
 * @param host The host to which the connection failed
 * @param port The port on the host to which the connection failed
 * @param socket The socket which could not connect
 * @return A new, autoreleased connection failed exception
 */
+ (instancetype)exceptionWithHost: (OFString*)host
+ (instancetype)exceptionWithHost: (OFString *)host
			     port: (uint16_t)port
			   socket: (id)socket;

/*!
 * @brief Creates a new, autoreleased connection failed exception.
 *
 * @param host The host to which the connection failed
 * @param port The port on the host to which the connection failed
 * @param socket The socket which could not connect
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased connection failed exception
 */
+ (instancetype)exceptionWithHost: (OFString*)host
+ (instancetype)exceptionWithHost: (OFString *)host
			     port: (uint16_t)port
			   socket: (id)socket
			    errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated connection failed exception.
 *
 * @param host The host to which the connection failed
 * @param port The port on the host to which the connection failed
 * @param socket The socket which could not connect
 * @return An initialized connection failed exception
 */
- initWithHost: (OFString*)host
- initWithHost: (OFString *)host
	  port: (uint16_t)port
	socket: (id)socket;

/*!
 * @brief Initializes an already allocated connection failed exception.
 *
 * @param host The host to which the connection failed
 * @param port The port on the host to which the connection failed
 * @param socket The socket which could not connect
 * @param errNo The errno of the error that occurred
 * @return An initialized connection failed exception
 */
- initWithHost: (OFString*)host
- initWithHost: (OFString *)host
	  port: (uint16_t)port
	socket: (id)socket
	 errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFConnectionFailedException.m from [8b464d6b37] to [6e3b6ce290].

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36

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

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

71
72
73
74
75
76
77
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35

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

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

70
71
72
73
74
75
76
77







-
+








-
+















-
+

















-
+








#import "OFConnectionFailedException.h"
#import "OFString.h"

@implementation OFConnectionFailedException
@synthesize host = _host, port = _port, socket = _socket, errNo = _errNo;

+ (instancetype)exceptionWithHost: (OFString*)host
+ (instancetype)exceptionWithHost: (OFString *)host
			     port: (uint16_t)port
			   socket: (id)socket
{
	return [[[self alloc] initWithHost: host
				      port: port
				    socket: socket] autorelease];
}

+ (instancetype)exceptionWithHost: (OFString*)host
+ (instancetype)exceptionWithHost: (OFString *)host
			     port: (uint16_t)port
			   socket: (id)socket
			    errNo: (int)errNo
{
	return [[[self alloc] initWithHost: host
				      port: port
				    socket: socket
				     errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithHost: (OFString*)host
- initWithHost: (OFString *)host
	  port: (uint16_t)port
	socket: (id)socket
{
	self = [super init];

	@try {
		_host = [host copy];
		_socket = [socket retain];
		_port = port;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithHost: (OFString*)host
- initWithHost: (OFString *)host
	  port: (uint16_t)port
	socket: (id)socket
	 errNo: (int)errNo
{
	self = [super init];

	@try {
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111







-
+













{
	[_host release];
	[_socket release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_errNo != 0)
		return [OFString stringWithFormat:
		    @"A connection to %@ on port %" @PRIu16 @" could not be "
		    @"established in socket of type %@: %@",
		    _host, _port, [_socket class], of_strerror(_errNo)];
	else
		return [OFString stringWithFormat:
		    @"A connection to %@ on port %" @PRIu16 @" could not be "
		    @"established in socket of type %@!",
		    _host, _port, [_socket class]];
}
@end

Modified src/exceptions/OFCopyItemFailedException.h from [3689d773a6] to [46a6589334].

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







-
-
+
+










-
-
+
+




 * @brief Creates a new, autoreleased copy item failed exception.
 *
 * @param sourcePath The original path
 * @param destinationPath The new path
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased copy item failed exception
 */
+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath
				  errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated copy item failed exception.
 *
 * @param sourcePath The original path
 * @param destinationPath The new path
 * @param errNo The errno of the error that occurred
 * @return An initialized copy item failed exception
 */
- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath
	       errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFCopyItemFailedException.m from [69d065156f] to [4db34f034e].

19
20
21
22
23
24
25
26
27


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


42
43
44
45
46
47
48
19
20
21
22
23
24
25


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


40
41
42
43
44
45
46
47
48







-
-
+
+












-
-
+
+







#import "OFCopyItemFailedException.h"
#import "OFString.h"

@implementation OFCopyItemFailedException
@synthesize sourcePath = _sourcePath, destinationPath = _destinationPath;
@synthesize errNo = _errNo;

+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath
				  errNo: (int)errNo
{
	return [[[self alloc] initWithSourcePath: sourcePath
				 destinationPath: destinationPath
					   errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath
	       errNo: (int)errNo
{
	self = [super init];

	@try {
		_sourcePath = [sourcePath copy];
		_destinationPath = [destinationPath copy];
59
60
61
62
63
64
65
66

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

66
67
68
69
70
71







-
+





{
	[_sourcePath release];
	[_destinationPath release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat: @"Failed to copy item %@ to %@: %@",
	    _sourcePath, _destinationPath, of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFCreateDirectoryFailedException.h from [ceed172fa5] to [0aeac91f5f].

45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62

63
64
65
66
67







-
+










-
+




 * @brief Creates a new, autoreleased create directory failed exception.
 *
 * @param path A string with the path of the directory which could not be
 *	       created
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased create directory failed exception
 */
+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
			    errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated create directory failed exception.
 *
 * @param path A string with the path of the directory which could not be
 *	       created
 * @param errNo The errno of the error that occurred
 * @return An initialized create directory failed exception
 */
- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
	 errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFCreateDirectoryFailedException.m from [8f9bca9236] to [ac18aba803].

18
19
20
21
22
23
24
25

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

38
39
40
41
42
43
44
18
19
20
21
22
23
24

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

37
38
39
40
41
42
43
44







-
+











-
+








#import "OFCreateDirectoryFailedException.h"
#import "OFString.h"

@implementation OFCreateDirectoryFailedException
@synthesize path = _path, errNo = _errNo;

+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
			    errNo: (int)errNo
{
	return [[[self alloc] initWithPath: path
				     errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
	 errNo: (int)errNo
{
	self = [super init];

	@try {
		_path = [path copy];
		_errNo = errNo;
53
54
55
56
57
58
59
60

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

60
61
62
63
64
65
66







-
+






- (void)dealloc
{
	[_path release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to create directory %@: %@",
	    _path, of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFCreateSymbolicLinkFailedException.h from [0d686e2861] to [57208c7e32].

49
50
51
52
53
54
55
56
57


58
59
60
61
62
63
64
65
66
67
68


69
70
71
72
73
74
75
76
77
78
79
80


81
82
83
84
85
86
87
88
89
90
91
92


93
94
95
96
49
50
51
52
53
54
55


56
57
58
59
60
61
62
63
64
65
66


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


79
80
81
82
83
84
85
86
87
88
89
90


91
92
93
94
95
96







-
-
+
+









-
-
+
+










-
-
+
+










-
-
+
+




/*!
 * @brief Creates a new, autoreleased create symbolic link failed exception.
 *
 * @param sourcePath The source for the symbolic link
 * @param destinationPath The destination for the symbolic link
 * @return A new, autoreleased create symbolic link failed exception
 */
+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath;
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath;

/*!
 * @brief Creates a new, autoreleased create symbolic link failed exception.
 *
 * @param sourcePath The source for the symbolic link
 * @param destinationPath The destination for the symbolic link
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased create symbolic link failed exception
 */
+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath
				  errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated create symbolic link failed
 *	  exception.
 *
 * @param sourcePath The source for the symbolic link
 * @param destinationPath The destination for the symbolic link
 * @return An initialized create symbolic link failed exception
 */
- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath;
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath;

/*!
 * @brief Initializes an already allocated create symbolic link failed
 *	  exception.
 *
 * @param sourcePath The source for the symbolic link
 * @param destinationPath The destination for the symbolic link
 * @param errNo The errno of the error that occurred
 * @return An initialized create symbolic link failed exception
 */
- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath
	       errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFCreateSymbolicLinkFailedException.m from [3c148de5f6] to [2ef5f721b8].

19
20
21
22
23
24
25
26
27


28
29
30
31
32
33
34


35
36
37
38
39
40
41
42
43
44
45
46
47
48


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64


65
66
67
68
69
70
71
19
20
21
22
23
24
25


26
27
28
29
30
31
32


33
34
35
36
37
38
39
40
41
42
43
44
45
46


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62


63
64
65
66
67
68
69
70
71







-
-
+
+





-
-
+
+












-
-
+
+














-
-
+
+







#import "OFCreateSymbolicLinkFailedException.h"
#import "OFString.h"

@implementation OFCreateSymbolicLinkFailedException
@synthesize sourcePath = _sourcePath, destinationPath = _destinationPath;
@synthesize errNo = _errNo;

+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath
{
	return [[[self alloc] initWithSourcePath: sourcePath
				 destinationPath: destinationPath] autorelease];
}

+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath
				  errNo: (int)errNo
{
	return [[[self alloc] initWithSourcePath: sourcePath
				 destinationPath: destinationPath
					   errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath
{
	self = [super init];

	@try {
		_sourcePath = [sourcePath copy];
		_destinationPath = [destinationPath copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath
	       errNo: (int)errNo
{
	self = [super init];

	@try {
		_sourcePath = [sourcePath copy];
		_destinationPath = [destinationPath copy];
82
83
84
85
86
87
88
89

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

89
90
91
92
93
94
95
96
97
98
99
100
101







-
+












{
	[_sourcePath release];
	[_destinationPath release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_errNo != 0)
		return [OFString stringWithFormat:
		    @"Failed to create symbolic link %@ with destination "
		    @"%@: %@", _destinationPath, _sourcePath,
		    of_strerror(_errNo)];
	else
		return [OFString stringWithFormat:
		    @"Failed to create symbolic link %@ with destination %@!",
		    _destinationPath, _sourcePath];
}
@end

Modified src/exceptions/OFEnumerationMutationException.m from [b84dce21cd] to [8fcf852c28].

44
45
46
47
48
49
50
51

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

51
52
53
54
55
56
57







-
+






- (void)dealloc
{
	[_object release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Object of class %@ was mutated during enumeration!",
	    [_object class]];
}
@end

Modified src/exceptions/OFException.h from [c5510791b2] to [4f8a3eb7a0].

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







-
+







-
+





-
+





+ (instancetype)exception;

/*!
 * @brief Returns a description of the exception.
 *
 * @return A description of the exception
 */
- (OFString*)description;
- (OFString *)description;

/*!
 * @brief Returns a backtrace of when the exception was created or nil if no
 *	  backtrace is available.
 *
 * @return A backtrace of when the exception was created
 */
- (nullable OFArray*)backtrace;
- (nullable OFArray *)backtrace;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern OFString* of_strerror(int errNo);
extern OFString *of_strerror(int errNo);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFException.m from [8fabc728f2] to [0b126c90fd].

73
74
75
76
77
78
79
80

81
82

83
84


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

99
100
101
102
103
104
105
73
74
75
76
77
78
79

80
81

82
83

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

99
100
101
102
103
104
105
106







-
+

-
+

-
+
+













-
+








struct backtrace_ctx {
	void **backtrace;
	uint8_t i;
};

extern _Unwind_Reason_Code _Unwind_Backtrace(
    _Unwind_Reason_Code(*)(struct _Unwind_Context*, void*), void*);
    _Unwind_Reason_Code (*)(struct _Unwind_Context *, void *), void *);
# ifndef HAVE_ARM_EHABI_EXCEPTIONS
extern uintptr_t _Unwind_GetIP(struct _Unwind_Context*);
extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *);
# else
extern int _Unwind_VRS_Get(struct _Unwind_Context*, int, uint32_t, int, void*);
extern int _Unwind_VRS_Get(struct _Unwind_Context *, int, uint32_t, int,
    void *);
# endif
#endif

#if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS)
static of_mutex_t mutex;

OF_CONSTRUCTOR()
{
	if (!of_mutex_new(&mutex))
		@throw [OFInitializationFailedException exception];
}
#endif

OFString*
OFString *
of_strerror(int errNo)
{
	OFString *ret;
#ifdef HAVE_STRERROR_R
	char buffer[256];
#endif

224
225
226
227
228
229
230
231

232
233
234
235
236

237
238
239
240
241
242
243
225
226
227
228
229
230
231

232
233
234
235
236

237
238
239
240
241
242
243
244







-
+




-
+







static _Unwind_Reason_Code
backtrace_callback(struct _Unwind_Context *ctx, void *data)
{
	struct backtrace_ctx *bt = data;

	if (bt->i < OF_BACKTRACE_SIZE) {
# ifndef HAVE_ARM_EHABI_EXCEPTIONS
		bt->backtrace[bt->i++] = (void*)_Unwind_GetIP(ctx);
		bt->backtrace[bt->i++] = (void *)_Unwind_GetIP(ctx);
# else
		uintptr_t ip;

		_Unwind_VRS_Get(ctx, 0, 15, 0, &ip);
		bt->backtrace[bt->i++] = (void*)(ip & ~1);
		bt->backtrace[bt->i++] = (void *)(ip & ~1);
# endif
		return _URC_OK;
	}

	return _URC_END_OF_STACK;
}
#endif
259
260
261
262
263
264
265
266

267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288


289
290
291
292
293
294
295
260
261
262
263
264
265
266

267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287


288
289
290
291
292
293
294
295
296







-
+





-
+














-
-
+
+







	ctx.i = 0;
	_Unwind_Backtrace(backtrace_callback, &ctx);

	return self;
}
#endif

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"An exception of type %@ occurred!", [self class]];
}

- (OFArray*)backtrace
- (OFArray *)backtrace
{
#ifdef HAVE_DWARF_EXCEPTIONS
	OFMutableArray *backtrace = [OFMutableArray array];
	void *pool = objc_autoreleasePoolPush();

	for (uint8_t i = 0;
	    i < OF_BACKTRACE_SIZE && _backtrace[i] != NULL; i++) {
# ifdef HAVE_DLADDR
		Dl_info info;

		if (dladdr(_backtrace[i], &info)) {
			OFString *frame;

			if (info.dli_sname != NULL) {
				ptrdiff_t offset = (char*)_backtrace[i] -
				    (char*)info.dli_saddr;
				ptrdiff_t offset = (char *)_backtrace[i] -
				    (char *)info.dli_saddr;

				frame = [OFString stringWithFormat:
				    @"%p <%s+%td> at %s",
				    _backtrace[i], info.dli_sname, offset,
				    info.dli_fname];
			} else
				frame = [OFString stringWithFormat:

Modified src/exceptions/OFGetOptionFailedException.h from [be9a0844ee] to [fa09b15fcb].

45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62

63
64
65
66
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61

62
63
64
65
66







-
+









-
+




/*!
 * @brief Creates a new, autoreleased get option failed exception.
 *
 * @param stream The stream for which the option could not be gotten
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased get option failed exception
 */
+ (instancetype)exceptionWithStream: (OFStream*)stream
+ (instancetype)exceptionWithStream: (OFStream *)stream
			      errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated get option failed exception.
 *
 * @param stream The stream for which the option could not be gotten
 * @param errNo The errno of the error that occurred
 * @return An initialized get option failed exception
 */
- initWithStream: (OFStream*)stream
- initWithStream: (OFStream *)stream
	   errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFGetOptionFailedException.m from [345844c106] to [e981c51f46].

19
20
21
22
23
24
25
26

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

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

57
58
59
60
61
62
19
20
21
22
23
24
25

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

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

56
57
58
59
60
61
62







-
+











-
+

















-
+






#import "OFGetOptionFailedException.h"
#import "OFString.h"
#import "OFStream.h"

@implementation OFGetOptionFailedException
@synthesize stream = _stream, errNo = _errNo;

+ (instancetype)exceptionWithStream: (OFStream*)stream
+ (instancetype)exceptionWithStream: (OFStream *)stream
			      errNo: (int)errNo
{
	return [[[self alloc] initWithStream: stream
				       errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithStream: (OFStream*)stream
- initWithStream: (OFStream *)stream
	   errNo: (int)errNo
{
	self = [super init];

	_stream = [stream retain];
	_errNo = errNo;

	return self;
}

- (void)dealloc
{
	[_stream release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Getting an option in a stream of type %@ failed: %@",
	    [_stream class], of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFHTTPRequestFailedException.h from [40f50e7dcf] to [1c80228554].

51
52
53
54
55
56
57
58
59


60
61
62
63
64
65
66
67
68
69


70
71
72
51
52
53
54
55
56
57


58
59
60
61
62
63
64
65
66
67


68
69
70
71
72







-
-
+
+








-
-
+
+



/*!
 * @brief Creates a new, autoreleased HTTP request failed exception.
 *
 * @param request The HTTP request which failed
 * @param response The response for the failed HTTP request
 * @return A new, autoreleased HTTP request failed exception
 */
+ (instancetype)exceptionWithRequest: (OFHTTPRequest*)request
			    response: (OFHTTPResponse*)response;
+ (instancetype)exceptionWithRequest: (OFHTTPRequest *)request
			    response: (OFHTTPResponse *)response;

/*!
 * @brief Initializes an already allocated HTTP request failed exception.
 *
 * @param request The HTTP request which failed
 * @param response The response for the failed HTTP request
 * @return A new HTTP request failed exception
 */
- initWithRequest: (OFHTTPRequest*)request
	 response: (OFHTTPResponse*)response;
- initWithRequest: (OFHTTPRequest *)request
	 response: (OFHTTPResponse *)response;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFHTTPRequestFailedException.m from [64833ce62b] to [057b189e49].

20
21
22
23
24
25
26
27
28


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


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

59
60
61
62
63
64
65
66
67
20
21
22
23
24
25
26


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


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

58
59
60
61
62
63
64
65
66
67







-
-
+
+










-
-
+
+

















-
+









#import "OFString.h"
#import "OFHTTPRequest.h"
#import "OFHTTPResponse.h"

@implementation OFHTTPRequestFailedException
@synthesize request = _request, response = _response;

+ (instancetype)exceptionWithRequest: (OFHTTPRequest*)request
			    response: (OFHTTPResponse*)response
+ (instancetype)exceptionWithRequest: (OFHTTPRequest *)request
			    response: (OFHTTPResponse *)response
{
	return [[[self alloc] initWithRequest: request
				     response: response] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithRequest: (OFHTTPRequest*)request
	 response: (OFHTTPResponse*)response
- initWithRequest: (OFHTTPRequest *)request
	 response: (OFHTTPResponse *)response
{
	self = [super init];

	_request = [request retain];
	_response = [response retain];

	return self;
}

- (void)dealloc
{
	[_request release];
	[_response release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	const char *method =
	    of_http_request_method_to_string([_request method]);

	return [OFString stringWithFormat:
	    @"An HTTP %s request with URL %@ failed with code %d!", method,
	    [_request URL], [_response statusCode]];
}
@end

Modified src/exceptions/OFHashAlreadyCalculatedException.m from [eb2edfffd8] to [8cb0db74ba].

44
45
46
47
48
49
50
51

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

51
52
53
54
55
56
57







-
+






- (void)dealloc
{
	[_object release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"The hash of type %@ has already been calculated and thus no new "
	    @"data can be added!", [_object class]];
}
@end

Modified src/exceptions/OFInitializationFailedException.m from [43347ab5a7] to [ba889780e2].

32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47







-
+








	self = [super init];

	_inClass = class;

	return self;
}

- (OFString*)description
- (OFString *)description
{
	if (_inClass != Nil)
		return [OFString stringWithFormat:
		    @"Initialization failed for or in class %@!", _inClass];
	else
		return @"Initialization failed!";
}
@end

Modified src/exceptions/OFInvalidArgumentException.m from [39fc972cd6] to [1f482687a4].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#include "config.h"

#import "OFInvalidArgumentException.h"
#import "OFString.h"

@implementation OFInvalidArgumentException
- (OFString*)description
- (OFString *)description
{
	return @"An invalid argument or receiver has been specified!";
}
@end

Modified src/exceptions/OFInvalidEncodingException.m from [ee5034e1e3] to [f8e0dbcc4e].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#include "config.h"

#import "OFInvalidEncodingException.h"
#import "OFString.h"

@implementation OFInvalidEncodingException
- (OFString*)description
- (OFString *)description
{
	return @"An encoding is invalid!";
}
@end

Modified src/exceptions/OFInvalidFormatException.m from [ca5337e1a5] to [0f9113584d].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#include "config.h"

#import "OFInvalidFormatException.h"
#import "OFString.h"

@implementation OFInvalidFormatException
- (OFString*)description
- (OFString *)description
{
	return @"A format is invalid!";
}
@end

Modified src/exceptions/OFInvalidJSONException.h from [3515e6b03e] to [7f5296b3be].

43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60

61
62
63
64
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59

60
61
62
63
64







-
+









-
+




/*!
 * @brief Creates a new, autoreleased invalid JSON exception.
 *
 * @param string The string containing the invalid JSON representation
 * @param line The line in which the parsing error was encountered
 * @return A new, autoreleased invalid JSON exception
 */
+ (instancetype)exceptionWithString: (OFString*)string
+ (instancetype)exceptionWithString: (OFString *)string
			       line: (size_t)line;

/*!
 * @brief Initializes an already allocated invalid JSON exception.
 *
 * @param string The string containing the invalid JSON representation
 * @param line The line in which the parsing error was encountered
 * @return An initialized invalid JSON exception
 */
- initWithString: (OFString*)string
- initWithString: (OFString *)string
	    line: (size_t)line;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFInvalidJSONException.m from [07d0c99f72] to [fff3723ab2].

18
19
20
21
22
23
24
25

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

38
39
40
41
42
43
44
18
19
20
21
22
23
24

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

37
38
39
40
41
42
43
44







-
+











-
+








#import "OFInvalidJSONException.h"
#import "OFString.h"

@implementation OFInvalidJSONException
@synthesize string = _string, line = _line;

+ (instancetype)exceptionWithString: (OFString*)string
+ (instancetype)exceptionWithString: (OFString *)string
			       line: (size_t)line
{
	return [[[self alloc] initWithString: string
					line: line] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

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

	@try {
		_string = [string copy];
		_line = line;
53
54
55
56
57
58
59
60

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

60
61
62
63
64
65







-
+





- (void)dealloc
{
	[_string release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"The JSON representation is invalid in line %zu!", _line];
}
@end

Modified src/exceptions/OFInvalidServerReplyException.m from [9775fd5471] to [3aa3e7a152].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#include "config.h"

#import "OFInvalidServerReplyException.h"
#import "OFString.h"

@implementation OFInvalidServerReplyException
- (OFString*)description
- (OFString *)description
{
	return @"Got an invalid reply from the server!";
}
@end

Modified src/exceptions/OFLinkFailedException.h from [330c1ca862] to [447f9c2dc0].

48
49
50
51
52
53
54
55
56


57
58
59
60
61
62
63
64
65
66
67


68
69
70
71
72
73
74
75
76
77
78


79
80
81
82
83
84
85
86
87
88
89


90
91
92
93
48
49
50
51
52
53
54


55
56
57
58
59
60
61
62
63
64
65


66
67
68
69
70
71
72
73
74
75
76


77
78
79
80
81
82
83
84
85
86
87


88
89
90
91
92
93







-
-
+
+









-
-
+
+









-
-
+
+









-
-
+
+




/*!
 * @brief Creates a new, autoreleased link failed exception.
 *
 * @param sourcePath The source for the link
 * @param destinationPath The destination for the link
 * @return A new, autoreleased link failed exception
 */
+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath;
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath;

/*!
 * @brief Creates a new, autoreleased link failed exception.
 *
 * @param sourcePath The source for the link
 * @param destinationPath The destination for the link
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased link failed exception
 */
+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath
				  errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated link failed exception.
 *
 * @param sourcePath The source for the link
 * @param destinationPath The destination for the link
 * @return An initialized link failed exception
 */
- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath;
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath;

/*!
 * @brief Initializes an already allocated link failed exception.
 *
 * @param sourcePath The source for the link
 * @param destinationPath The destination for the link
 * @param errNo The errno of the error that occurred
 * @return An initialized link failed exception
 */
- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath
	       errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFLinkFailedException.m from [22b0d59c65] to [ec984119f3].

19
20
21
22
23
24
25
26
27


28
29
30
31
32
33
34


35
36
37
38
39
40
41
42
43
44
45
46
47
48


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64


65
66
67
68
69
70
71
19
20
21
22
23
24
25


26
27
28
29
30
31
32


33
34
35
36
37
38
39
40
41
42
43
44
45
46


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62


63
64
65
66
67
68
69
70
71







-
-
+
+





-
-
+
+












-
-
+
+














-
-
+
+







#import "OFLinkFailedException.h"
#import "OFString.h"

@implementation OFLinkFailedException
@synthesize sourcePath = _sourcePath, destinationPath = _destinationPath;
@synthesize errNo = _errNo;

+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath
{
	return [[[self alloc] initWithSourcePath: sourcePath
				 destinationPath: destinationPath] autorelease];
}

+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath
				  errNo: (int)errNo
{
	return [[[self alloc] initWithSourcePath: sourcePath
				 destinationPath: destinationPath
					   errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath
{
	self = [super init];

	@try {
		_sourcePath = [sourcePath copy];
		_destinationPath = [destinationPath copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath
	       errNo: (int)errNo
{
	self = [super init];

	@try {
		_sourcePath = [sourcePath copy];
		_destinationPath = [destinationPath copy];
82
83
84
85
86
87
88
89

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

89
90
91
92
93
94
95
96
97
98
99
100







-
+











{
	[_sourcePath release];
	[_destinationPath release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_errNo != 0)
		return [OFString stringWithFormat:
		    @"Failed to link file %@ to %@: %@",
		    _sourcePath, _destinationPath, of_strerror(_errNo)];
	else
		return [OFString stringWithFormat:
		    @"Failed to link file %@ to %@!",
		    _sourcePath, _destinationPath];
}
@end

Modified src/exceptions/OFListenFailedException.m from [50635a2fc6] to [68088da6a3].

52
53
54
55
56
57
58
59

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

59
60
61
62
63
64
65







-
+






- (void)dealloc
{
	[_socket release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to listen in socket of type %@ with a back log of %d: %@",
	    [_socket class], _backLog, of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFLockFailedException.m from [c4b871bd29] to [cdfa88a638].

39
40
41
42
43
44
45
46

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

46
47
48
49
50
51
52
53
54







-
+








- (void)dealloc
{
	[_lock release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_lock != nil)
		return [OFString stringWithFormat:
		    @"A lock of type %@ could not be locked!", [_lock class]];
	else
		return @"A lock could not be locked!";
}
@end

Modified src/exceptions/OFMalformedXMLException.h from [969464470b] to [63ec37adb1].

38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53

54
55
56
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52

53
54
55
56







-
+







-
+




/*!
 * @brief Creates a new, autoreleased malformed XML exception.
 *
 * @param parser The parser which encountered malformed XML
 * @return A new, autoreleased malformed XML exception
 */
+ (instancetype)exceptionWithParser: (nullable OFXMLParser*)parser;
+ (instancetype)exceptionWithParser: (nullable OFXMLParser *)parser;

/*!
 * @brief Initializes an already allocated malformed XML exception.
 *
 * @param parser The parser which encountered malformed XML
 * @return An initialized malformed XML exception
 */
- initWithParser: (nullable OFXMLParser*)parser;
- initWithParser: (nullable OFXMLParser *)parser;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFMalformedXMLException.m from [d00b6e0bb4] to [d7fbc3fc45].

19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
19
20
21
22
23
24
25

26
27
28
29
30

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

47
48
49
50
51
52
53
54
55
56







-
+




-
+















-
+









#import "OFMalformedXMLException.h"
#import "OFString.h"
#import "OFXMLParser.h"

@implementation OFMalformedXMLException
@synthesize parser = _parser;

+ (instancetype)exceptionWithParser: (OFXMLParser*)parser
+ (instancetype)exceptionWithParser: (OFXMLParser *)parser
{
	return [[[self alloc] initWithParser: parser] autorelease];
}

- initWithParser: (OFXMLParser*)parser
- initWithParser: (OFXMLParser *)parser
{
	self = [super init];

	_parser = [parser retain];

	return self;
}

- (void)dealloc
{
	[_parser release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_parser != nil)
		return [OFString stringWithFormat:
		    @"An XML parser of type %@ encountered malformed XML in "
		    @"line %zu!", [_parser class], [_parser lineNumber]];
	else
		return @"An XML parser encountered malformed XML!";
}
@end

Modified src/exceptions/OFMemoryNotPartOfObjectException.h from [e71e1b14f0] to [63c9dc8e41].

44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61

62
63
64
65
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60

61
62
63
64
65







-
+









-
+




/*!
 * @brief Creates a new, autoreleased memory not part of object exception.
 *
 * @param pointer A pointer to the memory that is not part of the object
 * @param object The object which the memory is not part of
 * @return A new, autoreleased memory not part of object exception
 */
+ (instancetype)exceptionWithPointer: (void*)pointer
+ (instancetype)exceptionWithPointer: (void *)pointer
			      object: (id)object;

/*!
 * @brief Initializes an already allocated memory not part of object exception.
 *
 * @param pointer A pointer to the memory that is not part of the object
 * @param object The object which the memory is not part of
 * @return An initialized memory not part of object exception
 */
- initWithPointer: (void*)pointer
- initWithPointer: (void *)pointer
	   object: (id)object;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFMemoryNotPartOfObjectException.m from [0b7ef4c480] to [b8b6e69018].

18
19
20
21
22
23
24
25

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

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

56
57
58
59
60
61
62
63
18
19
20
21
22
23
24

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

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

55
56
57
58
59
60
61
62
63







-
+











-
+

















-
+









#import "OFMemoryNotPartOfObjectException.h"
#import "OFString.h"

@implementation OFMemoryNotPartOfObjectException
@synthesize pointer = _pointer, object = _object;

+ (instancetype)exceptionWithPointer: (void*)pointer
+ (instancetype)exceptionWithPointer: (void *)pointer
			      object: (id)object
{
	return [[[self alloc] initWithPointer: pointer
				       object: object] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithPointer: (void*)pointer
- initWithPointer: (void *)pointer
	   object: (id)object
{
	self = [super init];

	_pointer = pointer;
	_object = [object retain];

	return self;
}

- (void)dealloc
{
	[_object release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Deallocation or reallocation of memory not allocated as part of "
	    @"object of type %@ was attempted! It is also possible that there "
	    @"was an attempt to free the same memory twice.",
	    [_object class]];
}
@end

Modified src/exceptions/OFMoveItemFailedException.h from [220654d393] to [02563e9d4c].

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







-
-
+
+










-
-
+
+




 * @brief Creates a new, autoreleased move item failed exception.
 *
 * @param sourcePath The original path
 * @param destinationPath The new path
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased move item failed exception
 */
+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath
				  errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated move item failed exception.
 *
 * @param sourcePath The original path
 * @param destinationPath The new path
 * @param errNo The errno of the error that occurred
 * @return An initialized move item failed exception
 */
- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath
	       errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFMoveItemFailedException.m from [aaaad6a4f1] to [fa7b0f3804].

19
20
21
22
23
24
25
26
27


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


42
43
44
45
46
47
48
19
20
21
22
23
24
25


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


40
41
42
43
44
45
46
47
48







-
-
+
+












-
-
+
+







#import "OFMoveItemFailedException.h"
#import "OFString.h"

@implementation OFMoveItemFailedException
@synthesize sourcePath = _sourcePath, destinationPath = _destinationPath;
@synthesize errNo = _errNo;

+ (instancetype)exceptionWithSourcePath: (OFString*)sourcePath
			destinationPath: (OFString*)destinationPath
+ (instancetype)exceptionWithSourcePath: (OFString *)sourcePath
			destinationPath: (OFString *)destinationPath
				  errNo: (int)errNo
{
	return [[[self alloc] initWithSourcePath: sourcePath
				 destinationPath: destinationPath
					   errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithSourcePath: (OFString*)sourcePath
     destinationPath: (OFString*)destinationPath
- initWithSourcePath: (OFString *)sourcePath
     destinationPath: (OFString *)destinationPath
	       errNo: (int)errNo
{
	self = [super init];

	@try {
		_sourcePath = [sourcePath copy];
		_destinationPath = [destinationPath copy];
59
60
61
62
63
64
65
66

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

66
67
68
69
70
71
72







-
+






{
	[_sourcePath release];
	[_destinationPath release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to move item at path %@ to %@: %@",
	    _sourcePath, _destinationPath, of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFNotImplementedException.m from [ed856a0deb] to [37412f6538].

48
49
50
51
52
53
54
55

56
57
58
59
60
61
48
49
50
51
52
53
54

55
56
57
58
59
60
61







-
+






- (void)dealloc
{
	[_object release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"The selector %s is not understood by an object of type %@ or not "
	    @"(fully) implemented!", sel_getName(_selector), [_object class]];
}
@end

Modified src/exceptions/OFNotOpenException.m from [b3c92769c2] to [80096a1857].

44
45
46
47
48
49
50
51

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

51
52
53
54
55
56
57







-
+






- (void)dealloc
{
	[_object release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"The object of type %@ is not open, connected or bound!",
	    [_object class]];
}
@end

Modified src/exceptions/OFObserveFailedException.h from [032d2564af] to [1a6c8ec6c9].

45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62

63
64
65
66
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61

62
63
64
65
66







-
+









-
+




/*!
 * @brief Creates a new, autoreleased observe failed exception.
 *
 * @param observer The observer which failed to observe
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased observe failed exception
 */
+ (instancetype)exceptionWithObserver: (OFKernelEventObserver*)observer
+ (instancetype)exceptionWithObserver: (OFKernelEventObserver *)observer
				errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated observe failed exception.
 *
 * @param observer The observer which failed to observe
 * @param errNo The errno of the error that occurred
 * @return An initialized observe failed exception
 */
- initWithObserver: (OFKernelEventObserver*)observer
- initWithObserver: (OFKernelEventObserver *)observer
	     errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFObserveFailedException.m from [47e61e26c4] to [23af32b8f2].

19
20
21
22
23
24
25
26

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

39
40
41
42
43
44
45
19
20
21
22
23
24
25

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

38
39
40
41
42
43
44
45







-
+











-
+







#import "OFObserveFailedException.h"
#import "OFString.h"
#import "OFKernelEventObserver.h"

@implementation OFObserveFailedException
@synthesize observer = _observer, errNo = _errNo;

+ (instancetype)exceptionWithObserver: (OFKernelEventObserver*)observer
+ (instancetype)exceptionWithObserver: (OFKernelEventObserver *)observer
				errNo: (int)errNo
{
	return [[[self alloc] initWithObserver: observer
					 errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithObserver: (OFKernelEventObserver*)observer
- initWithObserver: (OFKernelEventObserver *)observer
	     errNo: (int)errNo
{
	self = [super init];

	@try {
		_observer = [observer retain];
		_errNo = errNo;
54
55
56
57
58
59
60
61

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

61
62
63
64
65
66
67







-
+






- (void)dealloc
{
	[_observer release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"An observer of class %@ failed to observe: %@",
	    [_observer className], of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFOpenItemFailedException.h from [7e4d67733e] to [b39007397c].

47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64


65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85


86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
103
104


105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125


126
127
128
129
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62


63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83


84
85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102


103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
123


124
125
126
127
128
129







-
+








-
-
+
+








-
+










-
-
+
+








-
+








-
-
+
+








-
+










-
-
+
+





/*!
 * @brief Creates a new, autoreleased open item failed exception.
 *
 * @param path A string with the path of the item tried to open
 * @return A new, autoreleased open item failed exception
 */
+ (instancetype)exceptionWithPath: (OFString*)path;
+ (instancetype)exceptionWithPath: (OFString *)path;

/*!
 * @brief Creates a new, autoreleased open item failed exception.
 *
 * @param path A string with the path of the item tried to open
 * @param mode A string with the mode in which the item should have been opened
 * @return A new, autoreleased open item failed exception
 */
+ (instancetype)exceptionWithPath: (OFString*)path
			     mode: (nullable OFString*)mode;
+ (instancetype)exceptionWithPath: (OFString *)path
			     mode: (nullable OFString *)mode;

/*!
 * @brief Creates a new, autoreleased open item failed exception.
 *
 * @param path A string with the path of the item tried to open
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased open item failed exception
 */
+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
			    errNo: (int)errNo;

/*!
 * @brief Creates a new, autoreleased open item failed exception.
 *
 * @param path A string with the path of the item tried to open
 * @param mode A string with the mode in which the item should have been opened
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased open item failed exception
 */
+ (instancetype)exceptionWithPath: (OFString*)path
			     mode: (nullable OFString*)mode
+ (instancetype)exceptionWithPath: (OFString *)path
			     mode: (nullable OFString *)mode
			    errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated open item failed exception.
 *
 * @param path A string with the path of the item which could not be opened
 * @return An initialized open item failed exception
 */
- initWithPath: (OFString*)path;
- initWithPath: (OFString *)path;

/*!
 * @brief Initializes an already allocated open item failed exception.
 *
 * @param path A string with the path of the item which could not be opened
 * @param mode A string with the mode in which the item should have been opened
 * @return An initialized open item failed exception
 */
- initWithPath: (OFString*)path
	  mode: (nullable OFString*)mode;
- initWithPath: (OFString *)path
	  mode: (nullable OFString *)mode;

/*!
 * @brief Initializes an already allocated open item failed exception.
 *
 * @param path A string with the path of the item which could not be opened
 * @param errNo The errno of the error that occurred
 * @return An initialized open item failed exception
 */
- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
	 errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated open item failed exception.
 *
 * @param path A string with the path of the item which could not be opened
 * @param mode A string with the mode in which the item should have been opened
 * @param errNo The errno of the error that occurred
 * @return An initialized open item failed exception
 */
- initWithPath: (OFString*)path
	  mode: (nullable OFString*)mode
- initWithPath: (OFString *)path
	  mode: (nullable OFString *)mode
	 errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFOpenItemFailedException.m from [4c0e145a1c] to [7244bfb39e].

18
19
20
21
22
23
24
25

26
27
28
29
30
31


32
33
34
35
36
37

38
39
40
41
42
43
44
45


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

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


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105


106
107
108
109
110
111
112
18
19
20
21
22
23
24

25
26
27
28
29


30
31
32
33
34
35
36

37
38
39
40
41
42
43


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

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


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

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103


104
105
106
107
108
109
110
111
112







-
+




-
-
+
+





-
+






-
-
+
+












-
+













-
-
+
+














-
+















-
-
+
+








#import "OFOpenItemFailedException.h"
#import "OFString.h"

@implementation OFOpenItemFailedException
@synthesize path = _path, mode = _mode, errNo = _errNo;

+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
{
	return [[[self alloc] initWithPath: path] autorelease];
}

+ (instancetype)exceptionWithPath: (OFString*)path
			     mode: (OFString*)mode
+ (instancetype)exceptionWithPath: (OFString *)path
			     mode: (OFString *)mode
{
	return [[[self alloc] initWithPath: path
				      mode: mode] autorelease];
}

+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
			    errNo: (int)errNo
{
	return [[[self alloc] initWithPath: path
				     errNo: errNo] autorelease];
}

+ (instancetype)exceptionWithPath: (OFString*)path
			     mode: (OFString*)mode
+ (instancetype)exceptionWithPath: (OFString *)path
			     mode: (OFString *)mode
			    errNo: (int)errNo
{
	return [[[self alloc] initWithPath: path
				      mode: mode
				     errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

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

	@try {
		_path = [path copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		_path  = [path copy];
		_mode  = [mode copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
	 errNo: (int)errNo
{
	self = [super init];

	@try {
		_path  = [path copy];
		_errNo = errNo;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithPath: (OFString*)path
	  mode: (OFString*)mode
- initWithPath: (OFString *)path
	  mode: (OFString *)mode
	 errNo: (int)errNo
{
	self = [super init];

	@try {
		_path  = [path copy];
		_mode  = [mode copy];
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137







-
+







{
	[_path release];
	[_mode release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_mode != nil) {
		if (_errNo != 0)
			return [OFString stringWithFormat:
			    @"Failed to open item %@ with mode %@: %@",
			    _path, _mode, of_strerror(_errNo)];
		else

Modified src/exceptions/OFOutOfMemoryException.m from [6bb162b64c] to [7cb2b989ab].

33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48







-
+








	self = [super init];

	_requestedSize = requestedSize;

	return self;
}

- (OFString*)description
- (OFString *)description
{
	if (_requestedSize != 0)
		return [OFString stringWithFormat:
		    @"Could not allocate %zu bytes!", _requestedSize];
	else
		return @"Could not allocate enough memory!";
}
@end

Modified src/exceptions/OFOutOfRangeException.m from [9f20a6032d] to [fe616e607b].

16
17
18
19
20
21
22
23

24
25
26
27
16
17
18
19
20
21
22

23
24
25
26
27







-
+





#include "config.h"

#import "OFOutOfRangeException.h"
#import "OFString.h"

@implementation OFOutOfRangeException
- (OFString*)description
- (OFString *)description
{
	return @"Value out of range!";
}
@end

Modified src/exceptions/OFReadFailedException.m from [b465546e7d] to [afe0beee73].

16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
16
17
18
19
20
21
22

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







-
+












#include "config.h"

#import "OFReadFailedException.h"
#import "OFString.h"

@implementation OFReadFailedException
- (OFString*)description
- (OFString *)description
{
	if (_errNo != 0)
		return [OFString stringWithFormat:
		    @"Failed to read %zu bytes from an object of type %@: %@",
		    _requestedLength, [_object class], of_strerror(_errNo)];
	else
		return [OFString stringWithFormat:
		    @"Failed to read %zu bytes from an object of type %@!",
		    _requestedLength, [_object class]];
}
@end

Modified src/exceptions/OFReadOrWriteFailedException.m from [a4c5d2c02e] to [cf55ce6afb].

71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91







-
+













- (void)dealloc
{
	[_object release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_errNo != 0)
		return [OFString stringWithFormat:
		    @"Failed to read or write %zu bytes from / to an object of "
		    @"type %@: %@",
		    _requestedLength, [_object class], of_strerror(_errNo)];
	else
		return [OFString stringWithFormat:
		    @"Failed to read or write %zu bytes from / to an object of "
		    @"type %@!",
		    _requestedLength, [_object class]];
}
@end

Modified src/exceptions/OFRemoveItemFailedException.h from [69fce99bc1] to [4041699ca7].

43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60

61
62
63
64
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59

60
61
62
63
64







-
+









-
+




/*!
 * @brief Creates a new, autoreleased remove failed exception.
 *
 * @param path The path of the item which could not be removed
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased remove item failed exception
 */
+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
			    errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated remove failed exception.
 *
 * @param path The path of the item which could not be removed
 * @param errNo The errno of the error that occurred
 * @return An initialized remove item failed exception
 */
- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
	 errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFRemoveItemFailedException.m from [1914700cdc] to [a7ff1e04ee].

18
19
20
21
22
23
24
25

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

38
39
40
41
42
43
44
18
19
20
21
22
23
24

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

37
38
39
40
41
42
43
44







-
+











-
+








#import "OFRemoveItemFailedException.h"
#import "OFString.h"

@implementation OFRemoveItemFailedException
@synthesize path = _path, errNo = _errNo;

+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
			    errNo: (int)errNo
{
	return [[[self alloc] initWithPath: path
				     errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
	 errNo: (int)errNo
{
	self = [super init];

	@try {
		_path = [path copy];
		_errNo = errNo;
53
54
55
56
57
58
59
60

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

60
61
62
63
64
65
66







-
+






- (void)dealloc
{
	[_path release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to remove item at path %@: %@",
	    _path, of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFSandboxActivationFailedException.h from [b24879b2d6] to [a9acd16049].

46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63

64
65
66
67
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62

63
64
65
66
67







-
+









-
+




/*!
 * @brief Creates a new, autoreleased sandboxing failed exception.
 *
 * @param sandbox The sandbox which could not be activated
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased sandboxing failed exception
 */
+ (instancetype)exceptionWithSandbox: (OFSandbox*)sandbox
+ (instancetype)exceptionWithSandbox: (OFSandbox *)sandbox
			       errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated sandboxing failed exception.
 *
 * @param sandbox The sandbox which could not be activated
 * @param errNo The errno of the error that occurred
 * @return An initialized sandboxing failed exception
 */
- initWithSandbox: (OFSandbox*)sandbox
- initWithSandbox: (OFSandbox *)sandbox
	    errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFSandboxActivationFailedException.m from [1e4f886387] to [a66044aa59].

19
20
21
22
23
24
25
26

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

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

57
58
59
60
61
19
20
21
22
23
24
25

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

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

56
57
58
59
60
61







-
+











-
+

















-
+





#import "OFSandboxActivationFailedException.h"
#import "OFString.h"
#import "OFSandbox.h"

@implementation OFSandboxActivationFailedException
@synthesize sandbox = _sandbox, errNo = _errNo;

+ (instancetype)exceptionWithSandbox: (OFSandbox*)sandbox
+ (instancetype)exceptionWithSandbox: (OFSandbox *)sandbox
			       errNo: (int)errNo
{
	return [[[self alloc] initWithSandbox: sandbox
					errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithSandbox: (OFSandbox*)sandbox
- initWithSandbox: (OFSandbox *)sandbox
	    errNo: (int)errNo
{
	self = [super init];

	_sandbox = [sandbox retain];
	_errNo = errNo;

	return self;
}

- (void)dealloc
{
	[_sandbox release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"The sandbox could not be applied: %@", of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFSeekFailedException.h from [1e5a86504e] to [b3ad469847].

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







-
+













-
+






 *
 * @param stream The stream for which seeking failed
 * @param offset The offset to which seeking failed
 * @param whence To what the offset is relative
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased seek failed exception
 */
+ (instancetype)exceptionWithStream: (OFSeekableStream*)stream
+ (instancetype)exceptionWithStream: (OFSeekableStream *)stream
			     offset: (of_offset_t)offset
			     whence: (int)whence
			      errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated seek failed exception.
 *
 * @param stream The stream for which seeking failed
 * @param offset The offset to which seeking failed
 * @param whence To what the offset is relative
 * @param errNo The errno of the error that occurred
 * @return An initialized seek failed exception
 */
- initWithStream: (OFSeekableStream*)stream
- initWithStream: (OFSeekableStream *)stream
	  offset: (of_offset_t)offset
	  whence: (int)whence
	   errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFSeekFailedException.m from [1eb0d20455] to [00e16809f3].

20
21
22
23
24
25
26
27

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

44
45
46
47
48
49
50
20
21
22
23
24
25
26

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

43
44
45
46
47
48
49
50







-
+















-
+







#import "OFString.h"
#import "OFSeekableStream.h"

@implementation OFSeekFailedException
@synthesize stream = _stream, offset = _offset, whence = _whence;
@synthesize errNo = _errNo;

+ (instancetype)exceptionWithStream: (OFSeekableStream*)stream
+ (instancetype)exceptionWithStream: (OFSeekableStream *)stream
			     offset: (of_offset_t)offset
			     whence: (int)whence
			      errNo: (int)errNo
{
	return [[[self alloc] initWithStream: stream
				      offset: offset
				      whence: whence
				       errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithStream: (OFSeekableStream*)stream
- initWithStream: (OFSeekableStream *)stream
	  offset: (of_offset_t)offset
	  whence: (int)whence
	   errNo: (int)errNo
{
	self = [super init];

	_stream = [stream retain];
58
59
60
61
62
63
64
65

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

65
66
67
68
69
70
71







-
+






- (void)dealloc
{
	[_stream release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Seeking failed in stream of type %@: %@",
	    [_stream class], of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFSetOptionFailedException.h from [7844ba8833] to [4fba02e1a0].

45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62

63
64
65
66
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61

62
63
64
65
66







-
+









-
+




/*!
 * @brief Creates a new, autoreleased set option failed exception.
 *
 * @param stream The stream for which the option could not be set
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased set option failed exception
 */
+ (instancetype)exceptionWithStream: (OFStream*)stream
+ (instancetype)exceptionWithStream: (OFStream *)stream
			      errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated set option failed exception.
 *
 * @param stream The stream for which the option could not be set
 * @param errNo The errno of the error that occurred
 * @return An initialized set option failed exception
 */
- initWithStream: (OFStream*)stream
- initWithStream: (OFStream *)stream
	   errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFSetOptionFailedException.m from [454f1fd9ab] to [50bd99831b].

19
20
21
22
23
24
25
26

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

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

57
58
59
60
61
62
19
20
21
22
23
24
25

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

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

56
57
58
59
60
61
62







-
+











-
+

















-
+






#import "OFSetOptionFailedException.h"
#import "OFString.h"
#import "OFStream.h"

@implementation OFSetOptionFailedException
@synthesize stream = _stream, errNo = _errNo;

+ (instancetype)exceptionWithStream: (OFStream*)stream
+ (instancetype)exceptionWithStream: (OFStream *)stream
			      errNo: (int)errNo
{
	return [[[self alloc] initWithStream: stream
				       errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithStream: (OFStream*)stream
- initWithStream: (OFStream *)stream
	   errNo: (int)errNo
{
	self = [super init];

	_stream = [stream retain];
	_errNo = errNo;

	return self;
}

- (void)dealloc
{
	[_stream release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Setting an option in a stream of type %@ failed: %@",
	    [_stream class], of_strerror(_errNo)];
}
@end

Modified src/exceptions/OFStatItemFailedException.h from [34fa416e50] to [c430472e6c].

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







-
+









-
+









-
+









-
+




/*!
 * @brief Creates a new, autoreleased stat item failed exception.
 *
 * @param path A string with the path of the item whose status could not be
 *	       retrieved
 * @return A new, autoreleased stat item failed exception
 */
+ (instancetype)exceptionWithPath: (OFString*)path;
+ (instancetype)exceptionWithPath: (OFString *)path;

/*!
 * @brief Creates a new, autoreleased stat item failed exception.
 *
 * @param path A string with the path of the item whose status could not be
 *	       retrieved
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased stat item failed exception
 */
+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
			    errNo: (int)errNo;

/*!
 * @brief Initializes an already allocated stat item failed exception.
 *
 * @param path A string with the path of the item whose status could not be
 *	       retrieved
 * @return An initialized stat item failed exception
 */
- initWithPath: (OFString*)path;
- initWithPath: (OFString *)path;

/*!
 * @brief Initializes an already allocated stat item failed exception.
 *
 * @param path A string with the path of the item whose status could not be
 *	       retrieved
 * @param errNo The errno of the error that occurred
 * @return An initialized stat item failed exception
 */
- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
	 errNo: (int)errNo;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFStatItemFailedException.m from [19703146d5] to [ffd210e74b].

18
19
20
21
22
23
24
25

26
27
28
29
30

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

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

57
58
59
60
61
62
63
18
19
20
21
22
23
24

25
26
27
28
29

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

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

56
57
58
59
60
61
62
63







-
+




-
+











-
+













-
+








#import "OFStatItemFailedException.h"
#import "OFString.h"

@implementation OFStatItemFailedException
@synthesize path = _path, errNo = _errNo;

+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
{
	return [[[self alloc] initWithPath: path] autorelease];
}

+ (instancetype)exceptionWithPath: (OFString*)path
+ (instancetype)exceptionWithPath: (OFString *)path
			    errNo: (int)errNo
{
	return [[[self alloc] initWithPath: path
				     errNo: errNo] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

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

	@try {
		_path = [path copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithPath: (OFString*)path
- initWithPath: (OFString *)path
	 errNo: (int)errNo
{
	self = [super init];

	@try {
		_path  = [path copy];
		_errNo = errNo;
72
73
74
75
76
77
78
79

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

79
80
81
82
83
84
85
86
87
88







-
+









- (void)dealloc
{
	[_path release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_errNo != 0)
		return [OFString stringWithFormat:
		    @"Failed to stat item %@: %@", _path, of_strerror(_errNo)];
	else
		return [OFString stringWithFormat:
		    @"Failed to stat item %@!", _path];
}
@end

Modified src/exceptions/OFStillLockedException.m from [91b0b01b3c] to [af438cc6c1].

39
40
41
42
43
44
45
46

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

46
47
48
49
50
51
52
53
54
55
56







-
+










- (void)dealloc
{
	[_lock release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_lock != nil)
		return [OFString stringWithFormat:
		    @"Deallocation of a lock of type %@ even though it was "
		    @"still locked!", [_lock class]];
	else
		return @"Deallocation of a lock even though it was still "
		    @"locked!";
}
@end

Modified src/exceptions/OFThreadJoinFailedException.h from [45c508a2e4] to [2bb131ccb4].

42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57

58
59
60
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56

57
58
59
60







-
+







-
+




/*!
 * @brief Creates a new, autoreleased thread join failed exception.
 *
 * @param thread The thread which could not be joined
 * @return A new, autoreleased thread join failed exception
 */
+ (instancetype)exceptionWithThread: (nullable OFThread*)thread;
+ (instancetype)exceptionWithThread: (nullable OFThread *)thread;

/*!
 * @brief Initializes an already allocated thread join failed exception.
 *
 * @param thread The thread which could not be joined
 * @return An initialized thread join failed exception
 */
- initWithThread: (nullable OFThread*)thread;
- initWithThread: (nullable OFThread *)thread;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFThreadJoinFailedException.m from [c4c229f651] to [f8db38d484].

19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
19
20
21
22
23
24
25

26
27
28
29
30

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

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







-
+




-
+















-
+











#import "OFThreadJoinFailedException.h"
#import "OFString.h"
#import "OFThread.h"

@implementation OFThreadJoinFailedException
@synthesize thread = _thread;

+ (instancetype)exceptionWithThread: (OFThread*)thread
+ (instancetype)exceptionWithThread: (OFThread *)thread
{
	return [[[self alloc] initWithThread: thread] autorelease];
}

- initWithThread: (OFThread*)thread
- initWithThread: (OFThread *)thread
{
	self = [super init];

	_thread = [thread retain];

	return self;
}

- (void)dealloc
{
	[_thread release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_thread != nil)
		return [OFString stringWithFormat:
		    @"Joining a thread of type %@ failed! Most likely, another "
		    @"thread already waits for the thread to join.",
		    [_thread class]];
	else
		return @"Joining a thread failed! Most likely, another thread "
		    @"already waits for the thread to join.";
}
@end

Modified src/exceptions/OFThreadStartFailedException.h from [1927c7649a] to [df2070febe].

42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57

58
59
60
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56

57
58
59
60







-
+







-
+




/*!
 * @brief Creates a new, autoreleased thread start failed exception.
 *
 * @param thread The thread which could not be started
 * @return A new, autoreleased thread start failed exception
 */
+ (instancetype)exceptionWithThread: (nullable OFThread*)thread;
+ (instancetype)exceptionWithThread: (nullable OFThread *)thread;

/*!
 * @brief Initializes an already allocated thread start failed exception.
 *
 * @param thread The thread which could not be started
 * @return An initialized thread start failed exception
 */
- initWithThread: (nullable OFThread*)thread;
- initWithThread: (nullable OFThread *)thread;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFThreadStartFailedException.m from [ab02e3a892] to [a98d20539d].

19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
19
20
21
22
23
24
25

26
27
28
29
30

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

47
48
49
50
51
52
53
54
55







-
+




-
+















-
+








#import "OFThreadStartFailedException.h"
#import "OFString.h"
#import "OFThread.h"

@implementation OFThreadStartFailedException
@synthesize thread = _thread;

+ (instancetype)exceptionWithThread: (OFThread*)thread
+ (instancetype)exceptionWithThread: (OFThread *)thread
{
	return [[[self alloc] initWithThread: thread] autorelease];
}

- initWithThread: (OFThread*)thread
- initWithThread: (OFThread *)thread
{
	self = [super init];

	_thread = [thread retain];

	return self;
}

- (void)dealloc
{
	[_thread release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_thread != nil)
		return [OFString stringWithFormat:
		    @"Starting a thread of type %@ failed!", [_thread class]];
	else
		return @"Starting a thread failed!";
}
@end

Modified src/exceptions/OFThreadStillRunningException.h from [d5d503dfe2] to [6ad8b75800].

42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57

58
59
60
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56

57
58
59
60







-
+







-
+




/*!
 * @brief Creates a new, autoreleased thread still running exception.
 *
 * @param thread The thread which is still running
 * @return A new, autoreleased thread still running exception
 */
+ (instancetype)exceptionWithThread: (nullable OFThread*)thread;
+ (instancetype)exceptionWithThread: (nullable OFThread *)thread;

/*!
 * @brief Initializes an already allocated thread still running exception.
 *
 * @param thread The thread which is still running
 * @return An initialized thread still running exception
 */
- initWithThread: (nullable OFThread*)thread;
- initWithThread: (nullable OFThread *)thread;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFThreadStillRunningException.m from [7f6b444bcd] to [c688f113b8].

19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
19
20
21
22
23
24
25

26
27
28
29
30

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

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







-
+




-
+















-
+











#import "OFThreadStillRunningException.h"
#import "OFString.h"
#import "OFThread.h"

@implementation OFThreadStillRunningException
@synthesize thread = _thread;

+ (instancetype)exceptionWithThread: (OFThread*)thread
+ (instancetype)exceptionWithThread: (OFThread *)thread
{
	return [[[self alloc] initWithThread: thread] autorelease];
}

- initWithThread: (OFThread*)thread
- initWithThread: (OFThread *)thread
{
	self = [super init];

	_thread = [thread retain];

	return self;
}

- (void)dealloc
{
	[_thread release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_thread)
		return [OFString stringWithFormat:
		    @"Deallocation of a thread of type %@ was tried, even "
		    @"though it was still running!",
		    [_thread class]];
	else
		return @"Deallocation of a thread was tried, even though it "
		    @"was still running!";
}
@end

Modified src/exceptions/OFTruncatedDataException.m from [9a0b5ba873] to [b0b9afa776].

16
17
18
19
20
21
22
23

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

23
24
25
26
27
28







-
+






#include "config.h"

#import "OFTruncatedDataException.h"
#import "OFString.h"

@implementation OFTruncatedDataException
- (OFString*)description
- (OFString *)description
{
	return @"Truncated data was received or produced when it should not "
	    @"have been truncated!";
}
@end

Modified src/exceptions/OFUnboundNamespaceException.h from [b5af7ca552] to [fce75de0fe].

49
50
51
52
53
54
55
56
57


58
59
60
61
62
63
64
65
66
67


68
69
70
49
50
51
52
53
54
55


56
57
58
59
60
61
62
63
64
65


66
67
68
69
70







-
-
+
+








-
-
+
+



/*!
 * @brief Creates a new, autoreleased unbound namespace exception.
 *
 * @param namespace_ The namespace which is unbound
 * @param element The element in which the namespace was not bound
 * @return A new, autoreleased unbound namespace exception
 */
+ (instancetype)exceptionWithNamespace: (OFString*)namespace_
			       element: (OFXMLElement*)element;
+ (instancetype)exceptionWithNamespace: (OFString *)namespace_
			       element: (OFXMLElement *)element;

/*!
 * @brief Initializes an already allocated unbound namespace exception.
 *
 * @param namespace_ The namespace which is unbound
 * @param element The element in which the namespace was not bound
 * @return An initialized unbound namespace exception
 */
- initWithNamespace: (OFString*)namespace_
	    element: (OFXMLElement*)element;
- initWithNamespace: (OFString *)namespace_
	    element: (OFXMLElement *)element;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFUnboundNamespaceException.m from [67dd861578] to [62bea9dc90].

19
20
21
22
23
24
25
26
27


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


40
41
42
43
44
45
46
19
20
21
22
23
24
25


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


38
39
40
41
42
43
44
45
46







-
-
+
+










-
-
+
+







#import "OFUnboundNamespaceException.h"
#import "OFString.h"
#import "OFXMLElement.h"

@implementation OFUnboundNamespaceException
@synthesize namespace = _namespace, element = _element;

+ (instancetype)exceptionWithNamespace: (OFString*)namespace
			       element: (OFXMLElement*)element
+ (instancetype)exceptionWithNamespace: (OFString *)namespace
			       element: (OFXMLElement *)element
{
	return [[[self alloc] initWithNamespace: namespace
					element: element] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithNamespace: (OFString*)namespace
	    element: (OFXMLElement*)element
- initWithNamespace: (OFString *)namespace
	    element: (OFXMLElement *)element
{
	self = [super init];

	@try {
		_namespace = [namespace copy];
		_element = [element retain];
	} @catch (id e) {
55
56
57
58
59
60
61
62

63
64
65
66
67
68
55
56
57
58
59
60
61

62
63
64
65
66
67
68







-
+






{
	[_namespace release];
	[_element release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"The namespace %@ is not bound in an element of type %@!",
	    _namespace, [_element class]];
}
@end

Modified src/exceptions/OFUnboundPrefixException.h from [85076c578b] to [8b87f7d166].

45
46
47
48
49
50
51
52
53


54
55
56
57
58
59
60
61
62
63


64
65
66
45
46
47
48
49
50
51


52
53
54
55
56
57
58
59
60
61


62
63
64
65
66







-
-
+
+








-
-
+
+



/*!
 * @brief Creates a new, autoreleased unbound prefix exception.
 *
 * @param prefix The prefix which is unbound
 * @param parser The parser which encountered the unbound prefix
 * @return A new, autoreleased unbound prefix exception
 */
+ (instancetype)exceptionWithPrefix: (OFString*)prefix
			     parser: (OFXMLParser*)parser;
+ (instancetype)exceptionWithPrefix: (OFString *)prefix
			     parser: (OFXMLParser *)parser;

/*!
 * @brief Initializes an already allocated unbound prefix exception.
 *
 * @param prefix The prefix which is unbound
 * @param parser The parser which encountered the unbound prefix
 * @return An initialized unbound prefix exception
 */
- initWithPrefix: (OFString*)prefix
	  parser: (OFXMLParser*)parser;
- initWithPrefix: (OFString *)prefix
	  parser: (OFXMLParser *)parser;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFUnboundPrefixException.m from [e44ccf7144] to [eea8d45e3d].

19
20
21
22
23
24
25
26
27


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


40
41
42
43
44
45
46
19
20
21
22
23
24
25


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


38
39
40
41
42
43
44
45
46







-
-
+
+










-
-
+
+







#import "OFUnboundPrefixException.h"
#import "OFString.h"
#import "OFXMLParser.h"

@implementation OFUnboundPrefixException
@synthesize prefix = _prefix, parser = _parser;

+ (instancetype)exceptionWithPrefix: (OFString*)prefix
			     parser: (OFXMLParser*)parser
+ (instancetype)exceptionWithPrefix: (OFString *)prefix
			     parser: (OFXMLParser *)parser
{
	return [[[self alloc] initWithPrefix: prefix
				      parser: parser] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithPrefix: (OFString*)prefix
	  parser: (OFXMLParser*)parser
- initWithPrefix: (OFString *)prefix
	  parser: (OFXMLParser *)parser
{
	self = [super init];

	@try {
		_prefix = [prefix copy];
		_parser = [parser retain];
	} @catch (id e) {
55
56
57
58
59
60
61
62

63
64
65
66
67
68
55
56
57
58
59
60
61

62
63
64
65
66
67
68







-
+






{
	[_prefix release];
	[_parser release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"An XML parser of type %@ encountered the unbound prefix %@ in "
	    @"line %zu!", [_parser class], _prefix, [_parser lineNumber]];
}
@end

Modified src/exceptions/OFUndefinedKeyException.h from [a2963e0e91] to [f6db7d17ce].

51
52
53
54
55
56
57
58

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

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

83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
51
52
53
54
55
56
57

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

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

82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98







-
+











-
+











-
+











-
+




 *
 * @param object The object on which the key is undefined
 * @param key The key which is undefined
 *
 * @return A new, autoreleased undefined key exception
 */
+ (instancetype)exceptionWithObject: (id)object
				key: (OFString*)key;
				key: (OFString *)key;

/*!
 * @brief Creates a new, autoreleased undefined key exception.
 *
 * @param object The object on which the key is undefined
 * @param key The key which is undefined
 * @param value The value for the undefined key
 *
 * @return A new, autoreleased undefined key exception
 */
+ (instancetype)exceptionWithObject: (id)object
				key: (OFString*)key
				key: (OFString *)key
			      value: (id)value;

/*!
 * @brief Initializes an already allocated undefined key exception.
 *
 * @param object The object on which the key is undefined
 * @param key The key which is undefined
 *
 * @return An initialized undefined key exception
 */
- initWithObject: (id)object
	     key: (OFString*)key;
	     key: (OFString *)key;

/*!
 * @brief Initializes an already allocated undefined key exception.
 *
 * @param object The object on which the key is undefined
 * @param key The key which is undefined
 * @param value The value for the undefined key
 *
 * @return An initialized undefined key exception
 */
- initWithObject: (id)object
	     key: (OFString*)key
	     key: (OFString *)key
	   value: (id)value;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFUndefinedKeyException.m from [3df049e465] to [d7d9dee998].

19
20
21
22
23
24
25
26

27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
19
20
21
22
23
24
25

26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70







-
+






-
+













-
+















-
+







#import "OFUndefinedKeyException.h"
#import "OFString.h"

@implementation OFUndefinedKeyException
@synthesize object = _object, key = _key, value = _value;

+ (instancetype)exceptionWithObject: (id)object
				key: (OFString*)key
				key: (OFString *)key
{
	return [[[self alloc] initWithObject: object
					 key: key] autorelease];
}

+ (instancetype)exceptionWithObject: (id)object
				key: (OFString*)key
				key: (OFString *)key
			      value: (id)value
{
	return [[[self alloc] initWithObject: object
					 key: key
				       value: value] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithObject: (id)object
	     key: (OFString*)key
	     key: (OFString *)key
{
	self = [super init];

	@try {
		_object = [object retain];
		_key = [key copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithObject: (id)object
	     key: (OFString*)key
	     key: (OFString *)key
	   value: (id)value
{
	self = [super init];

	@try {
		_object = [object retain];
		_key = [key copy];
82
83
84
85
86
87
88
89

90
91
92
93
94
95
82
83
84
85
86
87
88

89
90
91
92
93
94
95







-
+






	[_object release];
	[_key release];
	[_value release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"The key \"%@\" is undefined for an object of type %@!",
	    _key, [_object className]];
}
@end

Modified src/exceptions/OFUnknownXMLEntityException.h from [5738d0e30e] to [f1e9896ef6].

37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52

53
54
55
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51

52
53
54
55







-
+







-
+




/*!
 * @brief Creates a new, autoreleased unknown XML entity exception.
 *
 * @param entityName The name of the unknown XML entity
 * @return A new, autoreleased unknown XML entity exception
 */
+ (instancetype)exceptionWithEntityName: (OFString*)entityName;
+ (instancetype)exceptionWithEntityName: (OFString *)entityName;

/*!
 * @brief Initializes an already allocated unknown XML entity exception.
 *
 * @param entityName The name of the unknown XML entity
 * @return An initialized unknown XML entity exception
 */
- initWithEntityName: (OFString*)entityName;
- initWithEntityName: (OFString *)entityName;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFUnknownXMLEntityException.m from [806dd9465e] to [0c33db3e95].

18
19
20
21
22
23
24
25

26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
18
19
20
21
22
23
24

25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57







-
+




-
+




















-
+







#import "OFUnknownXMLEntityException.h"
#import "OFString.h"

@implementation OFUnknownXMLEntityException
@synthesize entityName = _entityName;

+ (instancetype)exceptionWithEntityName: (OFString*)entityName
+ (instancetype)exceptionWithEntityName: (OFString *)entityName
{
	return [[[self alloc] initWithEntityName: entityName] autorelease];
}

- initWithEntityName: (OFString*)entityName
- initWithEntityName: (OFString *)entityName
{
	self = [super init];

	@try {
		_entityName = [entityName copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_entityName release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"A parser encountered an unknown XML entity named %@!",
	    _entityName];
}
@end

Modified src/exceptions/OFUnlockFailedException.m from [eaf81e8b6a] to [ebd625dff3].

39
40
41
42
43
44
45
46

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

46
47
48
49
50
51
52
53
54







-
+








- (void)dealloc
{
	[_lock release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	if (_lock != nil)
		return [OFString stringWithFormat:
		    @"A lock of type %@ could not be unlocked!", [_lock class]];
	else
		return @"A lock could not be unlocked!";
}
@end

Modified src/exceptions/OFUnsupportedProtocolException.m from [e8d73cf6b5] to [c9e247cc3c].

19
20
21
22
23
24
25
26

27
28

29
30
31
32
33
34
35
36

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

53
54
55
56
57
19
20
21
22
23
24
25

26
27

28
29
30
31
32
33
34
35

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

52
53
54
55
56
57







-
+

-
+







-
+















-
+





#import "OFUnsupportedProtocolException.h"
#import "OFString.h"
#import "OFURL.h"

@implementation OFUnsupportedProtocolException
@synthesize URL = _URL;

+ (instancetype)exceptionWithURL: (OFURL*)url
+ (instancetype)exceptionWithURL: (OFURL *)URL
{
	return [[[self alloc] initWithURL: url] autorelease];
	return [[[self alloc] initWithURL: URL] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

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

	_URL = [URL retain];

	return self;
}

- (void)dealloc
{
	[_URL release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"The protocol of URL %@ is not supported!", _URL];
}
@end

Modified src/exceptions/OFUnsupportedVersionException.h from [b5d4712496] to [bc3b738b3c].

37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52

53
54
55
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51

52
53
54
55







-
+







-
+




/*!
 * @brief Creates a new, autoreleased unsupported version exception.
 *
 * @param version The version which is unsupported
 * @return A new, autoreleased unsupported version exception
 */
+ (instancetype)exceptionWithVersion: (OFString*)version;
+ (instancetype)exceptionWithVersion: (OFString *)version;

/*!
 * @brief Initializes an already allocated unsupported protocol exception.
 *
 * @param version The version which is unsupported
 * @return An initialized unsupported version exception
 */
- initWithVersion: (OFString*)version;
- initWithVersion: (OFString *)version;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFUnsupportedVersionException.m from [3cc78a8ad0] to [ec312f72f0].

18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35

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

57
58
59
60
61
62
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62







-
+









-
+




















-
+







#import "OFUnsupportedVersionException.h"
#import "OFString.h"

@implementation OFUnsupportedVersionException
@synthesize version = _version;

+ (instancetype)exceptionWithVersion: (OFString*)version
+ (instancetype)exceptionWithVersion: (OFString *)version
{
	return [[[self alloc] initWithVersion: version] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithVersion: (OFString*)version
- initWithVersion: (OFString *)version
{
	self = [super init];

	@try {
		_version = [version copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_version release];

	[super dealloc];
}

- (OFString*)description
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Version %@ of the format or protocol is not supported!",
	    _version];
}
@end

Modified src/exceptions/OFWriteFailedException.m from [0575bc984b] to [c720bc4acd].

16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
16
17
18
19
20
21
22

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







-
+












#include "config.h"

#import "OFWriteFailedException.h"
#import "OFString.h"

@implementation OFWriteFailedException
- (OFString*)description
- (OFString *)description
{
	if (_errNo != 0)
		return [OFString stringWithFormat:
		    @"Failed to write %zu bytes to an object of type %@: %@",
		    _requestedLength, [_object class], of_strerror(_errNo)];
	else
		return [OFString stringWithFormat:
		    @"Failed to write %zu bytes to an object of type %@!",
		    _requestedLength, [_object class]];
}
@end

Modified src/instance.h from [69b1191150] to [0671acd0b4].

18
19
20
21
22
23
24
25

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

25
26
27
28
29
30







-
+






OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern id objc_constructInstance(Class _Nullable, void *_Nullable);
extern void* objc_destructInstance(id);
extern void *objc_destructInstance(id);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/instance.m from [995026f596] to [dcb3da3872].

34
35
36
37
38
39
40
41

42
43

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

41
42

43
44
45
46
47
48
49
50







-
+

-
+








	if (constructSel == NULL)
		constructSel = sel_registerName(".cxx_construct");

	if (!class_respondsToSelector(cls, constructSel))
		return true;

	construct = (id(*)(id, SEL))
	construct = (id (*)(id, SEL))
	    class_getMethodImplementation(cls, constructSel);
	last = (id(*)(id, SEL))
	last = (id (*)(id, SEL))
	    class_getMethodImplementation(super, constructSel);

	if (construct == last)
		return true;

	return (construct(obj, constructSel) != nil);
}
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
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







-
+

















-
+












	if (!callConstructors(cls, obj))
		return nil;

	return obj;
}

void*
void *
objc_destructInstance(id obj)
{
	Class cls;
	void (*last)(id, SEL) = NULL;

#ifdef OF_OBJFW_RUNTIME
	objc_zero_weak_references(obj);
#endif

	if (destructSel == NULL)
		destructSel = sel_registerName(".cxx_destruct");

	for (cls = object_getClass(obj); cls != Nil;
	    cls = class_getSuperclass(cls)) {
		void (*destruct)(id, SEL);

		if (class_respondsToSelector(cls, destructSel)) {
			if ((destruct = (void(*)(id, SEL))
			if ((destruct = (void (*)(id, SEL))
			    class_getMethodImplementation(cls,
			    destructSel)) != last)
				destruct(obj, destructSel);

			last = destruct;
		} else
			break;
	}

	return obj;
}

Modified src/macros.h from [acbe9b9b4a] to [4c5e15ca2a].

587
588
589
590
591
592
593
594

595
596
597
598
599
600

601
602
603
604
605
606
607
608
609
610
611

612
613

614
615
616
617
618
619
620
587
588
589
590
591
592
593

594
595
596
597
598
599

600
601
602
603
604
605
606
607
608
609
610

611
612

613
614
615
616
617
618
619
620







-
+





-
+










-
+

-
+








static OF_INLINE void
of_bitset_clear(uint8_t *storage, size_t index)
{
	storage[index / 8] &= ~(1 << (index % 8));
}

static OF_INLINE char*
static OF_INLINE char *
of_strdup(const char *string)
{
	char *copy;
	size_t length = strlen(string);

	if ((copy = (char*)malloc(length + 1)) == NULL)
	if ((copy = (char *)malloc(length + 1)) == NULL)
		return NULL;

	memcpy(copy, string, length + 1);

	return copy;
}

static OF_INLINE void
of_explicit_memset(void *buffer_, int character, size_t length)
{
	volatile unsigned char *buffer = (volatile unsigned char*)buffer_;
	volatile unsigned char *buffer = (volatile unsigned char *)buffer_;

	while (buffer < (unsigned char*)buffer_ + length)
	while (buffer < (unsigned char *)buffer_ + length)
		*buffer++ = character;
}

static OF_INLINE bool
of_ascii_isalpha(char c)
{
	return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));

Modified src/of_asprintf.m from [eefc8c03cc] to [dfdbe062d8].

404
405
406
407
408
409
410
411

412
413
414
415
416
417
418
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418







-
+







		if (ctx->lengthModifier != LENGTH_MODIFIER_NONE)
			return false;

		ctx->subformat[ctx->subformatLen - 1] = 's';

		{
			const of_unichar_t *arg =
			    va_arg(ctx->arguments, const of_unichar_t*);
			    va_arg(ctx->arguments, const of_unichar_t *);
			size_t j, len = of_string_utf32_length(arg);
			char *buffer;

			if (SIZE_MAX / 4 < len || (SIZE_MAX / 4) - len < 1)
				return false;

			if ((buffer = malloc((len * 4) + 1)) == NULL)
599
600
601
602
603
604
605
606

607
608
609
610
611

612
613
614
615
616
617
618
619
620
621
622
623
624

625
626
627
628
629
630

631
632
633
634

635
636
637
638

639
640
641
642

643
644
645
646

647
648
649
650

651
652
653
654

655
656
657
658

659
660
661
662
663
664
665
599
600
601
602
603
604
605

606
607
608
609
610

611
612
613
614
615
616
617
618
619
620
621
622
623

624
625
626
627
628
629

630

631
632

633
634
635
636

637
638
639
640

641
642
643
644

645
646
647
648

649
650
651
652

653
654
655
656

657
658
659
660
661
662
663
664







-
+




-
+












-
+





-
+
-


-
+



-
+



-
+



-
+



-
+



-
+



-
+







		}

		break;
	case 's':
		switch (ctx->lengthModifier) {
		case LENGTH_MODIFIER_NONE:
			tmpLen = asprintf(&tmp, ctx->subformat,
			    va_arg(ctx->arguments, const char*));
			    va_arg(ctx->arguments, const char *));
			break;
#ifdef HAVE_WCHAR_T
		case LENGTH_MODIFIER_L:
			tmpLen = asprintf(&tmp, ctx->subformat,
			    va_arg(ctx->arguments, const wchar_t*));
			    va_arg(ctx->arguments, const wchar_t *));
			break;
#endif
		default:
			return false;
		}

		break;
	case 'p':
		if (ctx->lengthModifier != LENGTH_MODIFIER_NONE)
			return false;

		tmpLen = asprintf(&tmp, ctx->subformat,
		    va_arg(ctx->arguments, void*));
		    va_arg(ctx->arguments, void *));

		break;
	case 'n':
		switch (ctx->lengthModifier) {
		case LENGTH_MODIFIER_NONE:
			*va_arg(ctx->arguments, int*) =
			*va_arg(ctx->arguments, int *) = (int)ctx->bufferLen;
			    (int)ctx->bufferLen;
			break;
		case LENGTH_MODIFIER_HH:
			*va_arg(ctx->arguments, signed char*) =
			*va_arg(ctx->arguments, signed char *) =
			    (signed char)ctx->bufferLen;
			break;
		case LENGTH_MODIFIER_H:
			*va_arg(ctx->arguments, short*) =
			*va_arg(ctx->arguments, short *) =
			    (short)ctx->bufferLen;
			break;
		case LENGTH_MODIFIER_L:
			*va_arg(ctx->arguments, long*) =
			*va_arg(ctx->arguments, long *) =
			    (long)ctx->bufferLen;
			break;
		case LENGTH_MODIFIER_LL:
			*va_arg(ctx->arguments, long long*) =
			*va_arg(ctx->arguments, long long *) =
			    (long long)ctx->bufferLen;
			break;
		case LENGTH_MODIFIER_J:
			*va_arg(ctx->arguments, intmax_t*) =
			*va_arg(ctx->arguments, intmax_t *) =
			    (intmax_t)ctx->bufferLen;
			break;
		case LENGTH_MODIFIER_Z:
			*va_arg(ctx->arguments, size_t*) =
			*va_arg(ctx->arguments, size_t *) =
			    (size_t)ctx->bufferLen;
			break;
		case LENGTH_MODIFIER_T:
			*va_arg(ctx->arguments, ptrdiff_t*) =
			*va_arg(ctx->arguments, ptrdiff_t *) =
			    (ptrdiff_t)ctx->bufferLen;
			break;
		default:
			return false;
		}

		break;
694
695
696
697
698
699
700
701

702
703
704
705
706
707
708
693
694
695
696
697
698
699

700
701
702
703
704
705
706
707







-
+








	ctx->last = ctx->i + 1;
	ctx->state = STATE_STRING;

	return true;
}

static bool (*states[])(struct context*) = {
static bool (*states[])(struct context *) = {
	stringState,
	formatFlagsState,
	formatFieldWidthState,
	formatLengthModifierState,
	formatConversionSpecifierState
};

Modified src/of_strptime.h from [564125a9eb] to [6dafa57dc4].

26
27
28
29
30
31
32
33

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

33
34
35
36
37
38
39







-
+






#import "macros.h"

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern const char* of_strptime(const char*, const char*,
extern const char *of_strptime(const char *buf, const char *fmt,
    struct tm *tm, int16_t *tz);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/of_strptime.m from [9c609e758d] to [0c80605e9d].

18
19
20
21
22
23
24
25

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

25
26
27
28
29
30
31
32







-
+








#include <string.h>

#include <time.h>

#import "macros.h"

const char*
const char *
of_strptime(const char *buffer, const char *format, struct tm *tm, int16_t *tz)
{
	enum {
		SEARCH_CONVERSION_SPECIFIER,
		IN_CONVERSION_SPECIFIER
	} state = SEARCH_CONVERSION_SPECIFIER;
	size_t j, bufferLen, formatLen;

Modified src/resolver.h from [27e1b81eb2] to [d006d1407a].

53
54
55
56
57
58
59
60
61


62
63
64
65
66
67
68
53
54
55
56
57
58
59


60
61
62
63
64
65
66
67
68







-
-
+
+







    uint16_t port, int protocol);

/*!
 * @brief Converts the specified address to a string and port pair.
 *
 * @param address The address to convert to a string
 * @param addressLength The length of the address to convert to a string
 * @param host A pointer to an OFString* which should be set to the host of the
 *	       address or NULL if the host is not needed
 * @param host A pointer to an @ref OFString * which should be set to the host
 *	       of the address or NULL if the host is not needed
 * @param port A pointer to an uint16_t which should be set to the port of the
 *	       address or NULL if the port is not needed
 */
extern void of_address_to_string_and_port(struct sockaddr *address,
    socklen_t addressLength,
    OFString *__autoreleasing _Nonnull *_Nullable host,
    uint16_t *_Nullable port);

Modified src/resolver.m from [e5254d8f80] to [1e35fdb00e].

49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63







-
+







OF_CONSTRUCTOR()
{
	if (!of_mutex_new(&mutex))
		@throw [OFInitializationFailedException exception];
}
#endif

of_resolver_result_t**
of_resolver_result_t **
of_resolve_host(OFString *host, uint16_t port, int type)
{
	of_resolver_result_t **ret, **retIter;
	of_resolver_result_t *results, *resultsIter;
	size_t count;
#ifdef HAVE_GETADDRINFO
	struct addrinfo hints = { 0 }, *res, *res0;
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185







-
+







			addr->sin_family = AF_INET;
			addr->sin_port = OF_BSWAP16_IF_LE(port);
			addr->sin_addr.s_addr = s_addr;

			tmp->family = AF_INET;
			tmp->type = type;
			tmp->protocol = 0;
			tmp->address = (struct sockaddr*)addr;
			tmp->address = (struct sockaddr *)addr;
#ifndef OF_WII
			tmp->addressLength = sizeof(*addr);
#else
			tmp->addressLength = 8;
#endif

			ret[0] = tmp;
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245







-
+







				@throw [OFOutOfRangeException exception];

			memcpy(&addrsIter->sin_addr.s_addr, *ip, he->h_length);

			resultsIter->family = he->h_addrtype;
			resultsIter->type = type;
			resultsIter->protocol = 0;
			resultsIter->address = (struct sockaddr*)addrsIter;
			resultsIter->address = (struct sockaddr *)addrsIter;
			resultsIter->addressLength = sizeof(*addrsIter);

			*retIter = resultsIter;
		}
# ifdef OF_HAVE_THREADS
	} @finally {
		if (!of_mutex_unlock(&mutex))
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
329







-
+








-
+







# if OF_HAVE_THREADS
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

	@try {
# endif
		if ((hostCString = inet_ntoa(
		    ((struct sockaddr_in*)(void*)address)->sin_addr)) == NULL)
		    ((struct sockaddr_in *)(void *)address)->sin_addr)) == NULL)
			@throw [OFAddressTranslationFailedException
			    exceptionWithError: h_errno];

		if (host != NULL)
			*host = [OFString stringWithUTF8String: hostCString];

		if (port != NULL)
			*port = OF_BSWAP16_IF_LE(
			    ((struct sockaddr_in*)(void*)address)->sin_port);
			    ((struct sockaddr_in *)(void *)address)->sin_port);
# if OF_HAVE_THREADS
	} @finally {
		if (!of_mutex_unlock(&mutex))
			@throw [OFUnlockFailedException exception];
	}
# endif
#endif

Modified src/runtime/arc.m from [120ac4ff9d] to [ae0f383c89].

142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156







-
+







					    old->locations[old->count];

					/*
					 * We don't care if making it smaller
					 * fails.
					 */
					if ((locations = realloc(old->locations,
					    old->count * sizeof(id*))) != NULL)
					    old->count * sizeof(id *))) != NULL)
						old->locations = locations;
				}

				break;
			}
		}
	}
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178







-
+







				OBJC_ERROR("Not enough memory to allocate weak "
				    "reference!");

			objc_hashtable_set(hashtable, value, ref);
		}

		if ((ref->locations = realloc(ref->locations,
		    (ref->count + 1) * sizeof(id*))) == NULL)
		    (ref->count + 1) * sizeof(id *))) == NULL)
			OBJC_ERROR("Not enough memory to allocate weak "
			    "reference!")

		ref->locations[ref->count++] = object;
	} else
		value = nil;

Modified src/runtime/category.m from [4388419943] to [768ffeb962].

28
29
30
31
32
33
34
35

36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64

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

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

99
100
101
102
103
104
105
106

107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
28
29
30
31
32
33
34

35
36
37
38
39
40

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

54
55
56
57
58
59
60
61
62
63

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

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

98
99
100
101
102
103
104
105

106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128







-
+





-
+












-
+









-
+















-
+

















-
+







-
+





-
+











-
+




static void
register_selectors(struct objc_abi_category *cat)
{
	for (struct objc_abi_method_list *ml = cat->instance_methods;
	    ml != NULL; ml = ml->next)
		for (unsigned int i = 0; i < ml->count; i++)
			objc_register_selector(
			    (struct objc_abi_selector*)&ml->methods[i]);
			    (struct objc_abi_selector *)&ml->methods[i]);

	for (struct objc_abi_method_list *ml = cat->class_methods;
	    ml != NULL; ml = ml->next)
		for (unsigned int i = 0; i < ml->count; i++)
			objc_register_selector(
			    (struct objc_abi_selector*)&ml->methods[i]);
			    (struct objc_abi_selector *)&ml->methods[i]);
}

static void
register_category(struct objc_abi_category *cat)
{
	struct objc_abi_category **cats;
	Class cls = objc_classname_to_class(cat->class_name, false);

	if (categories == NULL)
		categories = objc_hashtable_new(
		    objc_hash_string, objc_equal_string, 2);

	cats = (struct objc_abi_category**)objc_hashtable_get(categories,
	cats = (struct objc_abi_category **)objc_hashtable_get(categories,
	    cat->class_name);

	if (cats != NULL) {
		struct objc_abi_category **ncats;
		size_t i;

		for (i = 0; cats[i] != NULL; i++);

		if ((ncats = realloc(cats,
		    (i + 2) * sizeof(struct objc_abi_category*))) == NULL)
		    (i + 2) * sizeof(struct objc_abi_category *))) == NULL)
			OBJC_ERROR("Not enough memory for category %s of "
			    "class %s!", cat->category_name, cat->class_name);

		ncats[i] = cat;
		ncats[i + 1] = NULL;
		objc_hashtable_set(categories, cat->class_name, ncats);

		if (cls != Nil && cls->info & OBJC_CLASS_INFO_SETUP) {
			objc_update_dtable(cls);
			objc_update_dtable(cls->isa);
		}

		return;
	}

	if ((cats = malloc(2 * sizeof(struct objc_abi_category*))) == NULL)
	if ((cats = malloc(2 * sizeof(struct objc_abi_category *))) == NULL)
		OBJC_ERROR("Not enough memory for category %s of class %s!\n",
		    cat->category_name, cat->class_name);

	cats[0] = cat;
	cats[1] = NULL;
	objc_hashtable_set(categories, cat->class_name, cats);

	if (cls != Nil && cls->info & OBJC_CLASS_INFO_SETUP) {
		objc_update_dtable(cls);
		objc_update_dtable(cls->isa);
	}
}

void
objc_register_all_categories(struct objc_abi_symtab *symtab)
{
	struct objc_abi_category **cats =
	    (struct objc_abi_category**)symtab->defs + symtab->cls_def_cnt;
	    (struct objc_abi_category **)symtab->defs + symtab->cls_def_cnt;

	for (size_t i = 0; i < symtab->cat_def_cnt; i++) {
		register_selectors(cats[i]);
		register_category(cats[i]);
	}
}

struct objc_category**
struct objc_category **
objc_categories_for_class(Class cls)
{
	if (categories == NULL)
		return NULL;

	return (struct objc_category**)objc_hashtable_get(categories,
	return (struct objc_category **)objc_hashtable_get(categories,
	    cls->name);
}

void
objc_unregister_all_categories(void)
{
	if (categories == NULL)
		return;

	for (uint32_t i = 0; i < categories->size; i++)
		if (categories->data[i] != NULL)
			free((void*)categories->data[i]->obj);
			free((void *)categories->data[i]->obj);

	objc_hashtable_free(categories);
	categories = NULL;
}

Modified src/runtime/class.m from [a5e62b6d57] to [bb8140f5e4].

68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82







-
+







register_selectors(struct objc_abi_class *cls)
{
	struct objc_abi_method_list *ml;

	for (ml = cls->methodlist; ml != NULL; ml = ml->next)
		for (unsigned int i = 0; i < ml->count; i++)
			objc_register_selector(
			    (struct objc_abi_selector*)&ml->methods[i]);
			    (struct objc_abi_selector *)&ml->methods[i]);
}

Class
objc_classname_to_class(const char *name, bool cache)
{
	Class cls;

131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145







-
+







{
	SEL selector = sel_registerName(method);

	for (struct objc_method_list *ml = cls->isa->methodlist;
	    ml != NULL; ml = ml->next)
		for (unsigned int i = 0; i < ml->count; i++)
			if (sel_isEqual((SEL)&ml->methods[i].sel, selector))
				((void(*)(id, SEL))ml->methods[i].imp)(cls,
				((void (*)(id, SEL))ml->methods[i].imp)(cls,
				    selector);
}

static bool
has_load(Class cls)
{
	SEL selector = sel_registerName("load");
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282







-
+







setup_class(Class cls)
{
	const char *superclass;

	if (cls->info & OBJC_CLASS_INFO_SETUP)
		return;

	if ((superclass = ((struct objc_abi_class*)cls)->superclass) != NULL) {
	if ((superclass = ((struct objc_abi_class *)cls)->superclass) != NULL) {
		Class super = objc_classname_to_class(superclass, false);

		if (super == Nil)
			return;

		setup_class(super);

381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395







-
+







}

void
objc_register_all_classes(struct objc_abi_symtab *symtab)
{
	for (uint16_t i = 0; i < symtab->cls_def_cnt; i++) {
		struct objc_abi_class *cls =
		    (struct objc_abi_class*)symtab->defs[i];
		    (struct objc_abi_class *)symtab->defs[i];

		register_class(cls);
		register_selectors(cls);
		register_selectors(cls->metaclass);
	}

	for (uint16_t i = 0; i < symtab->cls_def_cnt; i++) {
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466







-
+







}

void
objc_registerClassPair(Class cls)
{
	objc_global_mutex_lock();

	register_class((struct objc_abi_class*)cls);
	register_class((struct objc_abi_class *)cls);

	if (cls->superclass != Nil) {
		add_subclass(cls);
		add_subclass(cls->isa);
	}

	cls->info |= OBJC_CLASS_INFO_SETUP;
564
565
566
567
568
569
570
571

572
573
574
575
576
577
578
564
565
566
567
568
569
570

571
572
573
574
575
576
577
578







-
+







	}

	objc_global_mutex_unlock();

	return j;
}

Class*
Class *
objc_copyClassList(unsigned int *len)
{
	Class *ret;
	unsigned int count;

	objc_global_mutex_lock();

597
598
599
600
601
602
603
604

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

604
605
606
607
608
609
610
611







-
+







{
	if (cls == Nil)
		return false;

	return (cls->info & OBJC_CLASS_INFO_METACLASS);
}

const char*
const char *
class_getName(Class cls)
{
	if (cls == Nil)
		return "";

	return cls->name;
}
666
667
668
669
670
671
672
673

674
675
676
677
678
679
680
666
667
668
669
670
671
672

673
674
675
676
677
678
679
680







-
+







	if (cls == Nil)
		return NULL;

	dummy.isa = cls;
	return objc_msg_lookup_stret((id)&dummy, sel);
}

static struct objc_method*
static struct objc_method *
get_method(Class cls, SEL sel)
{
	struct objc_method_list *ml;
	struct objc_category **cats;

	for (ml = cls->methodlist; ml != NULL; ml = ml->next)
		for (unsigned int i = 0; i < ml->count; i++)
715
716
717
718
719
720
721
722

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

722
723
724
725
726
727
728
729







-
+







	ml->methods[0].imp = imp;

	cls->methodlist = ml;

	objc_update_dtable(cls);
}

const char*
const char *
class_getMethodTypeEncoding(Class cls, SEL sel)
{
	struct objc_method *method;

	if (cls == Nil)
		return NULL;

787
788
789
790
791
792
793
794

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

809
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824
825

826
827
828
829
830
831
832
787
788
789
790
791
792
793

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

808
809
810
811
812
813
814
815

816
817
818
819
820
821
822
823
824

825
826
827
828
829
830
831
832







-
+













-
+







-
+








-
+







object_getClass(id obj_)
{
	struct objc_object *obj;

	if (obj_ == nil)
		return Nil;

	obj = (struct objc_object*)obj_;
	obj = (struct objc_object *)obj_;

	return obj->isa;
}

Class
object_setClass(id obj_, Class cls)
{
	struct objc_object *obj;
	Class old;

	if (obj_ == nil)
		return Nil;

	obj = (struct objc_object*)obj_;
	obj = (struct objc_object *)obj_;

	old = obj->isa;
	obj->isa = cls;

	return old;
}

const char*
const char *
object_getClassName(id obj)
{
	return class_getName(object_getClass(obj));
}

static void
unregister_class(Class rcls)
{
	struct objc_abi_class *cls = (struct objc_abi_class*)rcls;
	struct objc_abi_class *cls = (struct objc_abi_class *)rcls;

	if ((rcls->info & OBJC_CLASS_INFO_SETUP) &&
	    rcls->superclass != Nil &&
	    rcls->superclass->subclass_list != NULL) {
		size_t i = SIZE_MAX, count = 0;
		Class *tmp;

Modified src/runtime/dtable.m from [4412ed5617] to [6f5c36ea25].

47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61







-
+







	}
#else
	for (uint_fast16_t i = 0; i < 256; i++)
		empty_level2->buckets[i] = (IMP)0;
#endif
}

struct objc_dtable*
struct objc_dtable *
objc_dtable_new(void)
{
	struct objc_dtable *dtable;

#ifdef OF_SELUID24
	if (empty_level2 == NULL || empty_level3 == NULL)
		init();

Modified src/runtime/exception.m from [bff9221b2d] to [9516bed461].

112
113
114
115
116
117
118

119

120
121
122
123
124
125
126
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127







+
-
+







	_URC_CONTINUE_UNWIND	= 8,
	_URC_FAILURE		= 9
} _Unwind_Reason_Code;

struct objc_exception {
	struct _Unwind_Exception {
		uint64_t class;
		void (*cleanup)(
		void (*cleanup)(_Unwind_Reason_Code, struct _Unwind_Exception*);
		    _Unwind_Reason_Code, struct _Unwind_Exception *);
#ifndef HAVE_ARM_EHABI_EXCEPTIONS
# ifndef HAVE_SEH_EXCEPTIONS
		/*
		 * The Itanium Exception ABI says to have those and never touch
		 * them.
		 */
		uint64_t private1, private2;
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
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







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




-
-
-
+
+
+

-
-
-
-
+
+
+
+
+
+







	uint8_t typestable_enc;
	const uint8_t *typestable;
	uintptr_t typestable_base;
	uint8_t callsites_enc;
	const uint8_t *callsites, *actiontable;
};

extern _Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception*);
extern void _Unwind_DeleteException(struct _Unwind_Exception*);
extern void* _Unwind_GetLanguageSpecificData(struct _Unwind_Context*);
extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context*);
extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context*);
extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context*);
extern _Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *);
extern void _Unwind_DeleteException(struct _Unwind_Exception *);
extern void *_Unwind_GetLanguageSpecificData(struct _Unwind_Context *);
extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *);
extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *);
extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *);

#ifndef HAVE_ARM_EHABI_EXCEPTIONS
# define CONTINUE_UNWIND return _URC_CONTINUE_UNWIND

extern uintptr_t _Unwind_GetIP(struct _Unwind_Context*);
extern void _Unwind_SetIP(struct _Unwind_Context*, uintptr_t);
extern void _Unwind_SetGR(struct _Unwind_Context*, int, uintptr_t);
extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *);
extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t);
extern void _Unwind_SetGR(struct _Unwind_Context *, int, uintptr_t);
#else
extern _Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception*,
    struct _Unwind_Context*);
extern int _Unwind_VRS_Get(struct _Unwind_Context*, int, uint32_t, int, void*);
extern int _Unwind_VRS_Set(struct _Unwind_Context*, int, uint32_t, int, void*);
extern _Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception *,
    struct _Unwind_Context *);
extern int _Unwind_VRS_Get(struct _Unwind_Context *, int, uint32_t, int,
    void *);
extern int _Unwind_VRS_Set(struct _Unwind_Context *, int, uint32_t, int,
    void *);

# define CONTINUE_UNWIND					\
	{							\
		if (__gnu_unwind_frame(ex, ctx) != _URC_OK)	\
			return _URC_FAILURE;			\
								\
		return _URC_CONTINUE_UNWIND;			\
221
222
223
224
225
226
227
228
229
230



231
232
233
234
235
236
237
224
225
226
227
228
229
230



231
232
233
234
235
236
237
238
239
240







-
-
-
+
+
+







#endif

#ifdef CXX_PERSONALITY
static PERSONALITY_FUNC(cxx_personality) OF_WEAK_REF(CXX_PERSONALITY_STR);
#endif

#ifdef HAVE_SEH_EXCEPTIONS
extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void*,
    PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code(*)(int, int, uint64_t,
    struct _Unwind_Exception*, struct _Unwind_Context*));
extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *,
    PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code (*)(int, int, uint64_t,
    struct _Unwind_Exception *, struct _Unwind_Context *));
#endif

static objc_uncaught_exception_handler uncaught_exception_handler;
static struct objc_exception emergency_exceptions[NUM_EMERGENCY_EXCEPTIONS];
#ifdef OF_HAVE_THREADS
static of_spinlock_t emergency_exceptions_spinlock;

299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316







-
+







size_for_encoding(uint8_t enc)
{
	if (enc == DW_EH_PE_omit)
		return 0;

	switch (enc & 0x07) {
	case DW_EH_PE_absptr:
		return sizeof(void*);
		return sizeof(void *);
	case DW_EH_PE_udata2:
		return 2;
	case DW_EH_PE_udata4:
		return 4;
	case DW_EH_PE_udata8:
		return 8;
	}
321
322
323
324
325
326
327
328

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

331
332
333
334
335
336
337
338







-
+







	uint64_t value;

	if (enc == DW_EH_PE_aligned)
		OBJC_ERROR("DW_EH_PE_aligned is not implemented!")

#define READ(type)				\
	{					\
		value = *(type*)(void*)*ptr;	\
		value = *(type *)(void *)*ptr;	\
		*ptr += size_for_encoding(enc);	\
		break;				\
	}
	switch (enc & 0x0F) {
	case DW_EH_PE_absptr:
		READ(uintptr_t)
	case DW_EH_PE_uleb128:
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381







-
+







{
	if (value == 0)
		return 0;

	value += ((enc & 0x70) == DW_EH_PE_pcrel ? (uintptr_t)start : base);

	if (enc & DW_EH_PE_indirect)
		value = *(uintptr_t*)(uintptr_t)value;
		value = *(uintptr_t *)(uintptr_t)value;

	return value;
}
#endif

static void
read_lsda(struct _Unwind_Context *ctx, const uint8_t *ptr, struct lsda *lsda)
511
512
513
514
515
516
517
518

519
520
521
522
523

524
525
526
527
528

529
530
531
532
533
534
535
514
515
516
517
518
519
520

521
522
523
524
525

526
527
528
529
530

531
532
533
534
535
536
537
538







-
+




-
+




-
+







			i = filter * size_for_encoding(lsda->typestable_enc);
			tmp = lsda->typestable - i;
			c = (uintptr_t)read_value(lsda->typestable_enc, &tmp);
			c = (uintptr_t)resolve_value(c, lsda->typestable_enc,
			    lsda->typestable - i, lsda->typestable_base);
#else
			tmp = lsda->typestable - (filter * 4);
			c = *(uintptr_t*)(void*)tmp;
			c = *(uintptr_t *)(void *)tmp;

			if (c != 0) {
				c += (uintptr_t)tmp;
# if defined(OF_LINUX) || defined(OF_NETBSD)
				c = *(uintptr_t*)c;
				c = *(uintptr_t *)c;
# endif
			}
#endif

			className = (const char*)c;
			className = (const char *)c;

			if (className != NULL && *className != '\0' &&
			    strcmp(className, "@id") != 0)
				class = objc_getRequiredClass(className);
			else
				class = Nil;

569
570
571
572
573
574
575
576

577
578
579
580
581
582
583
572
573
574
575
576
577
578

579
580
581
582
583
584
585
586







-
+







		CONTINUE_UNWIND;
	default:
		return _URC_FAILURE;
	}

	_Unwind_SetGR(ctx, 12, (uintptr_t)ex);
#endif
	struct objc_exception *e = (struct objc_exception*)ex;
	struct objc_exception *e = (struct objc_exception *)ex;
	bool foreign = (ex_class != GNUCOBJC_EXCEPTION_CLASS);
	const uint8_t *lsda_addr, *actionrecords;
	struct lsda lsda;
	uintptr_t landingpad = 0;
	uint8_t found = 0;
	intptr_t filter = 0;

746
747
748
749
750
751
752
753

754
755
756
757
758
759
760
749
750
751
752
753
754
755

756
757
758
759
760
761
762
763







-
+







	objc_uncaught_exception_handler old = uncaught_exception_handler;
	uncaught_exception_handler = handler;

	return old;
}

#ifdef HAVE_SEH_EXCEPTIONS
typedef EXCEPTION_DISPOSITION (*seh_personality_fn)(PEXCEPTION_RECORD, void*,
typedef EXCEPTION_DISPOSITION (*seh_personality_fn)(PEXCEPTION_RECORD, void *,
    PCONTEXT, PDISPATCHER_CONTEXT);
static seh_personality_fn __gxx_personality_seh0;

OF_CONSTRUCTOR()
{
	/*
	 * This only works if the application uses libstdc++-6.dll.
771
772
773
774
775
776
777
778

779
780
781
782
783
784
785
786
787
788
789
790
791
774
775
776
777
778
779
780

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







-
+













}

EXCEPTION_DISPOSITION
__gnu_objc_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame,
    PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp)
{
	struct _Unwind_Exception *ex =
	    (struct _Unwind_Exception*)ms_exc->ExceptionInformation[0];
	    (struct _Unwind_Exception *)ms_exc->ExceptionInformation[0];

	switch (ex->class) {
	case GNUCCXX0_EXCEPTION_CLASS:
	case CLNGCXX0_EXCEPTION_CLASS:
		if (__gxx_personality_seh0 != NULL)
			return __gxx_personality_seh0(ms_exc, this_frame,
			    ms_orig_context, ms_disp);
	}

	return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
	    ms_disp, PERSONALITY);
}
#endif

Modified src/runtime/hashtable.m from [38fe5a0cfe] to [8166d9c683].

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







-
-
-
+
+
+











-
+








bool
objc_equal_string(const void *obj1, const void *obj2)
{
	return (strcmp(obj1, obj2) == 0);
}

struct objc_hashtable*
objc_hashtable_new(uint32_t (*hash)(const void*),
    bool (*equal)(const void*, const void*), uint32_t size)
struct objc_hashtable *
objc_hashtable_new(uint32_t (*hash)(const void *),
    bool (*equal)(const void *, const void *), uint32_t size)
{
	struct objc_hashtable *table;

	if ((table = malloc(sizeof(struct objc_hashtable))) == NULL)
		OBJC_ERROR("Not enough memory to allocate hash table!");

	table->hash = hash;
	table->equal = equal;

	table->count = 0;
	table->size = size;
	table->data = calloc(size, sizeof(struct objc_hashtable_bucket*));
	table->data = calloc(size, sizeof(struct objc_hashtable_bucket *));

	if (table->data == NULL)
		OBJC_ERROR("Not enough memory to allocate hash table!");

	return table;
}

200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
200
201
202
203
204
205
206

207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222







-
+







-
+







	bucket->hash = hash;
	bucket->obj = obj;

	table->data[i] = bucket;
	table->count++;
}

void*
void *
objc_hashtable_get(struct objc_hashtable *table, const void *key)
{
	uint32_t idx;

	if (!index_for_key(table, key, &idx))
		return NULL;

	return (void*)table->data[idx]->obj;
	return (void *)table->data[idx]->obj;
}

void
objc_hashtable_delete(struct objc_hashtable *table, const void *key)
{
	uint32_t idx;

Modified src/runtime/property.m from [79dd5a258d] to [f610db3f7e].

39
40
41
42
43
44
45
46

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

62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
39
40
41
42
43
44
45

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

61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76







-
+














-
+







-
+







}
#endif

id
objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic)
{
	if (atomic) {
		id *ptr = (id*)(void*)((char*)self + offset);
		id *ptr = (id *)(void *)((char *)self + offset);
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		@try {
			return [[*ptr retain] autorelease];
		} @finally {
			OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
		}
#else
		return [[*ptr retain] autorelease];
#endif
	}

	return *(id*)(void*)((char*)self + offset);
	return *(id *)(void *)((char *)self + offset);
}

void
objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id value, BOOL atomic,
    signed char copy)
{
	if (atomic) {
		id *ptr = (id*)(void*)((char*)self + offset);
		id *ptr = (id *)(void *)((char *)self + offset);
#ifdef OF_HAVE_THREADS
		unsigned hash = SPINLOCK_HASH(ptr);

		OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
		@try {
#endif
			id old = *ptr;
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106







-
+







			OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
		}
#endif

		return;
	}

	id *ptr = (id*)(void*)((char*)self + offset);
	id *ptr = (id *)(void *)((char *)self + offset);
	id old = *ptr;

	switch (copy) {
	case 0:
		*ptr = [value retain];
		break;
	case 2:

Modified src/runtime/protocol.m from [6bd4883458] to [a6710fd48b].

20
21
22
23
24
25
26
27

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

27
28
29
30
31
32
33
34







-
+








#import "runtime.h"
#import "runtime-private.h"

@implementation Protocol
@end

const char*
const char *
protocol_getName(Protocol *p)
{
	return p->name;
}

bool
protocol_isEqual(Protocol *a, Protocol *b)

Modified src/runtime/runtime-private.h from [8959ceec24] to [a994a21929].

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







-
-
+
+



-
-
+
+


-
-
-
-
+
+
+
+

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

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

-
+







		} *buckets[256];
#else
		IMP buckets[256];
#endif
	} *buckets[256];
};

extern void objc_register_all_categories(struct objc_abi_symtab*);
extern struct objc_category** objc_categories_for_class(Class);
extern void objc_register_all_categories(struct objc_abi_symtab *);
extern struct objc_category **objc_categories_for_class(Class);
extern void objc_unregister_all_categories(void);
extern void objc_initialize_class(Class);
extern void objc_update_dtable(Class);
extern void objc_register_all_classes(struct objc_abi_symtab*);
extern Class objc_classname_to_class(const char*, bool);
extern void objc_register_all_classes(struct objc_abi_symtab *);
extern Class objc_classname_to_class(const char *, bool);
extern void objc_unregister_class(Class);
extern void objc_unregister_all_classes(void);
extern uint32_t objc_hash_string(const void*);
extern bool objc_equal_string(const void*, const void*);
extern struct objc_hashtable* objc_hashtable_new(uint32_t (*)(const void*),
    bool (*)(const void*, const void*), uint32_t);
extern uint32_t objc_hash_string(const void *);
extern bool objc_equal_string(const void *, const void *);
extern struct objc_hashtable *objc_hashtable_new(uint32_t (*)(const void *),
    bool (*)(const void *, const void *), uint32_t);
extern struct objc_hashtable_bucket objc_deleted_bucket;
extern void objc_hashtable_set(struct objc_hashtable*, const void*,
    const void*);
extern void* objc_hashtable_get(struct objc_hashtable*, const void*);
extern void objc_hashtable_delete(struct objc_hashtable*, const void*);
extern void objc_hashtable_free(struct objc_hashtable*);
extern void objc_register_selector(struct objc_abi_selector*);
extern void objc_register_all_selectors(struct objc_abi_symtab*);
extern void objc_hashtable_set(struct objc_hashtable *, const void *,
    const void *);
extern void *objc_hashtable_get(struct objc_hashtable *, const void *);
extern void objc_hashtable_delete(struct objc_hashtable *, const void *);
extern void objc_hashtable_free(struct objc_hashtable *);
extern void objc_register_selector(struct objc_abi_selector *);
extern void objc_register_all_selectors(struct objc_abi_symtab *);
extern void objc_unregister_all_selectors(void);
extern struct objc_sparsearray* objc_sparsearray_new(uint8_t);
extern void* objc_sparsearray_get(struct objc_sparsearray*, uintptr_t);
extern void objc_sparsearray_set(struct objc_sparsearray*, uintptr_t, void*);
extern void objc_sparsearray_free(struct objc_sparsearray*);
extern struct objc_dtable* objc_dtable_new(void);
extern void objc_dtable_copy(struct objc_dtable*, struct objc_dtable*);
extern void objc_dtable_set(struct objc_dtable*, uint32_t, IMP);
extern void objc_dtable_free(struct objc_dtable*);
extern struct objc_sparsearray *objc_sparsearray_new(uint8_t);
extern void *objc_sparsearray_get(struct objc_sparsearray *, uintptr_t);
extern void objc_sparsearray_set(struct objc_sparsearray *, uintptr_t, void *);
extern void objc_sparsearray_free(struct objc_sparsearray *);
extern struct objc_dtable *objc_dtable_new(void);
extern void objc_dtable_copy(struct objc_dtable *, struct objc_dtable *);
extern void objc_dtable_set(struct objc_dtable *, uint32_t, IMP);
extern void objc_dtable_free(struct objc_dtable *);
extern void objc_dtable_cleanup(void);
extern void objc_init_static_instances(struct objc_abi_symtab*);
extern void objc_init_static_instances(struct objc_abi_symtab *);
extern void objc_forget_pending_static_instances(void);
#ifdef OF_HAVE_THREADS
extern void objc_global_mutex_lock(void);
extern void objc_global_mutex_unlock(void);
extern void objc_global_mutex_free(void);
#else
# define objc_global_mutex_lock()

Modified src/runtime/runtime.h from [35cbcdf16d] to [bd21f431a6].

49
50
51
52
53
54
55
56
57
58



59
60
61
62
63
64
65
49
50
51
52
53
54
55



56
57
58
59
60
61
62
63
64
65







-
-
-
+
+
+







#endif

#define Nil (Class)0
#define nil (id)0
#define YES (BOOL)1
#define NO  (BOOL)0

typedef struct objc_class* Class;
typedef struct objc_object* id;
typedef const struct objc_selector* SEL;
typedef struct objc_class *Class;
typedef struct objc_object *id;
typedef const struct objc_selector *SEL;
typedef signed char BOOL;
typedef id (*IMP)(id, SEL, ...);
typedef void (*objc_uncaught_exception_handler)(id);

struct objc_class {
	Class isa;
	Class superclass;
194
195
196
197
198
199
200
201
202


203
204

205
206
207
208
209
210





211
212

213
214
215
216

217
218
219
220
221



222
223
224
225
226
227




228
229
230
231
232
233
234


235
236
237
238
239
240
241
242
243
244
245

246
247
248
249


250
251
252
253
254
255
256


257
258
259
260
261
262
263
264
265
266
194
195
196
197
198
199
200


201
202
203

204
205





206
207
208
209
210
211

212
213
214
215

216
217
218



219
220
221
222
223




224
225
226
227
228
229
230
231
232


233
234
235
236
237
238
239
240
241
242
243
244

245
246
247


248
249
250
251
252
253
254


255
256
257
258
259
260
261
262
263
264
265
266







-
-
+
+

-
+

-
-
-
-
-
+
+
+
+
+

-
+



-
+


-
-
-
+
+
+


-
-
-
-
+
+
+
+





-
-
+
+










-
+


-
-
+
+





-
-
+
+










	long count;
	Protocol *OBJC_UNSAFE_UNRETAINED list[1];
};

#ifdef __cplusplus
extern "C" {
#endif
extern SEL sel_registerName(const char*);
extern const char* sel_getName(SEL);
extern SEL sel_registerName(const char *);
extern const char *sel_getName(SEL);
extern bool sel_isEqual(SEL, SEL);
extern Class objc_allocateClassPair(Class, const char*, size_t);
extern Class objc_allocateClassPair(Class, const char *, size_t);
extern void objc_registerClassPair(Class);
extern id objc_lookUpClass(const char*);
extern id objc_getClass(const char*);
extern id objc_getRequiredClass(const char*);
extern unsigned int objc_getClassList(Class*, unsigned int);
extern Class* objc_copyClassList(unsigned int*);
extern id objc_lookUpClass(const char *);
extern id objc_getClass(const char *);
extern id objc_getRequiredClass(const char *);
extern unsigned int objc_getClassList(Class *, unsigned int);
extern Class *objc_copyClassList(unsigned int *);
extern bool class_isMetaClass(Class);
extern const char* class_getName(Class);
extern const char *class_getName(Class);
extern Class class_getSuperclass(Class);
extern unsigned long class_getInstanceSize(Class);
extern bool class_respondsToSelector(Class, SEL);
extern bool class_conformsToProtocol(Class, Protocol*);
extern bool class_conformsToProtocol(Class, Protocol *);
extern IMP class_getMethodImplementation(Class, SEL);
extern IMP class_getMethodImplementation_stret(Class, SEL);
extern const char* class_getMethodTypeEncoding(Class, SEL);
extern bool class_addMethod(Class, SEL, IMP, const char*);
extern IMP class_replaceMethod(Class, SEL, IMP, const char*);
extern const char *class_getMethodTypeEncoding(Class, SEL);
extern bool class_addMethod(Class, SEL, IMP, const char *);
extern IMP class_replaceMethod(Class, SEL, IMP, const char *);
extern Class object_getClass(id);
extern Class object_setClass(id, Class);
extern const char* object_getClassName(id);
extern const char* protocol_getName(Protocol*);
extern bool protocol_isEqual(Protocol*, Protocol*);
extern bool protocol_conformsToProtocol(Protocol*, Protocol*);
extern const char *object_getClassName(id);
extern const char *protocol_getName(Protocol *);
extern bool protocol_isEqual(Protocol *, Protocol *);
extern bool protocol_conformsToProtocol(Protocol *, Protocol *);
extern void objc_exit(void);
extern objc_uncaught_exception_handler objc_setUncaughtExceptionHandler(
    objc_uncaught_exception_handler);
extern void objc_setForwardHandler(IMP, IMP);
extern id objc_autorelease(id);
extern void* objc_autoreleasePoolPush(void);
extern void objc_autoreleasePoolPop(void*);
extern void *objc_autoreleasePoolPush(void);
extern void objc_autoreleasePoolPop(void *);
extern id _objc_rootAutorelease(id);
extern void objc_zero_weak_references(id);

/*
 * Used by the compiler, but can also be called manually.
 *
 * These declarations are also required to prevent Clang's implicit
 * declarations which include __declspec(dllimport) on Windows.
 */
struct objc_abi_module;
extern void __objc_exec_class(void*);
extern void __objc_exec_class(void *);
extern IMP objc_msg_lookup(id, SEL);
extern IMP objc_msg_lookup_stret(id, SEL);
extern IMP objc_msg_lookup_super(struct objc_super*, SEL);
extern IMP objc_msg_lookup_super_stret(struct objc_super*, SEL);
extern IMP objc_msg_lookup_super(struct objc_super *, SEL);
extern IMP objc_msg_lookup_super_stret(struct objc_super *, SEL);
extern void objc_exception_throw(id);
extern int objc_sync_enter(id);
extern int objc_sync_exit(id);
extern id objc_getProperty(id, SEL, ptrdiff_t, BOOL);
extern void objc_setProperty(id, SEL, ptrdiff_t, id, BOOL, signed char);
extern void objc_getPropertyStruct(void*, const void*, ptrdiff_t, BOOL, BOOL);
extern void objc_setPropertyStruct(void*, const void*, ptrdiff_t, BOOL, BOOL);
extern void objc_getPropertyStruct(void *, const void *, ptrdiff_t, BOOL, BOOL);
extern void objc_setPropertyStruct(void *, const void *, ptrdiff_t, BOOL, BOOL);
extern void objc_enumerationMutation(id);
extern void objc_setEnumerationMutationHandler(void (*handler)(id));
#ifdef __cplusplus
}
#endif

#undef OBJC_UNSAFE_UNRETAINED
#undef OBJC_ROOT_CLASS

#endif

Modified src/runtime/selector.m from [b4065297e3] to [57debffc40].

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







-
+







-
+



-
+







	if (selectors_cnt > SEL_MAX)
		OBJC_ERROR("Out of selector slots!");

	if (selectors == NULL)
		selectors = objc_hashtable_new(
		    objc_hash_string, objc_equal_string, 2);
	else if ((rsel = objc_hashtable_get(selectors, sel->name)) != NULL) {
		((struct objc_selector*)sel)->uid = rsel->uid;
		((struct objc_selector *)sel)->uid = rsel->uid;
		return;
	}

	if (selector_names == NULL)
		selector_names = objc_sparsearray_new(SEL_SIZE);

	name = sel->name;
	rsel = (struct objc_selector*)sel;
	rsel = (struct objc_selector *)sel;
	rsel->uid = selectors_cnt++;

	objc_hashtable_set(selectors, name, rsel);
	objc_sparsearray_set(selector_names, (uint32_t)rsel->uid, (void*)name);
	objc_sparsearray_set(selector_names, (uint32_t)rsel->uid, (void *)name);
}

SEL
sel_registerName(const char *name)
{
	const struct objc_abi_selector *rsel;
	struct objc_abi_selector *sel;
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
86
87
88
89
90
91
92

93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124







-
+



-
+



















-
+








	if ((sel->name = of_strdup(name)) == NULL)
		OBJC_ERROR("Not enough memory to allocate selector!");

	sel->types = NULL;

	if ((free_list = realloc(free_list,
	    sizeof(void*) * (free_list_cnt + 2))) == NULL)
	    sizeof(void *) * (free_list_cnt + 2))) == NULL)
		OBJC_ERROR("Not enough memory to allocate selector!");

	free_list[free_list_cnt++] = sel;
	free_list[free_list_cnt++] = (char*)sel->name;
	free_list[free_list_cnt++] = (char *)sel->name;

	objc_register_selector(sel);

	objc_global_mutex_unlock();
	return (SEL)sel;
}

void
objc_register_all_selectors(struct objc_abi_symtab *symtab)
{
	struct objc_abi_selector *sel;

	if (symtab->sel_refs == NULL)
		return;

	for (sel = symtab->sel_refs; sel->name != NULL; sel++)
		objc_register_selector(sel);
}

const char*
const char *
sel_getName(SEL sel)
{
	const char *ret;

	objc_global_mutex_lock();
	ret = objc_sparsearray_get(selector_names, (uint32_t)sel->uid);
	objc_global_mutex_unlock();

Modified src/runtime/sparsearray.m from [4c093ce050] to [5adec15068].

18
19
20
21
22
23
24
25

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

42
43
44
45
46
47
48
18
19
20
21
22
23
24

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

41
42
43
44
45
46
47
48







-
+















-
+








#include <stdio.h>
#include <stdlib.h>

#import "runtime.h"
#import "runtime-private.h"

struct objc_sparsearray*
struct objc_sparsearray *
objc_sparsearray_new(uint8_t index_size)
{
	struct objc_sparsearray *sparsearray;

	if ((sparsearray = calloc(1, sizeof(*sparsearray))) == NULL)
		OBJC_ERROR("Failed to allocate memory for sparse array!");

	if ((sparsearray->data = calloc(1, sizeof(*sparsearray->data))) == NULL)
		OBJC_ERROR("Failed to allocate memory for sparse array!");

	sparsearray->index_size = index_size;

	return sparsearray;
}

void*
void *
objc_sparsearray_get(struct objc_sparsearray *sparsearray, uintptr_t idx)
{
	struct objc_sparsearray_data *iter = sparsearray->data;

	for (uint8_t i = 0; i < sparsearray->index_size - 1; i++) {
		uintptr_t j =
		    (idx >> ((sparsearray->index_size - i - 1) * 8)) & 0xFF;

Modified src/runtime/static-instances.m from [ef2f011243] to [e637d2916b].

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







-
+








-
+














-
+







				continue;
			}

			static_instances[i] =
			    static_instances[static_instances_cnt];

			static_instances = realloc(static_instances,
			    sizeof(struct objc_abi_static_instances*) *
			    sizeof(struct objc_abi_static_instances *) *
			    static_instances_cnt);

			if (static_instances == NULL)
				OBJC_ERROR("Not enough memory for list of "
				    "static instances!");
		}
	}

	si = (struct objc_abi_static_instances**)
	si = (struct objc_abi_static_instances **)
	    symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];

	if (si == NULL)
		return;

	for (; *si != NULL; si++) {
		Class cls = objc_lookUpClass((*si)->class_name);

		if (cls != Nil) {
			for (id *instances = (*si)->instances;
			    *instances != nil; instances++)
				object_setClass(*instances, cls);
		} else {
			static_instances = realloc(static_instances,
			    sizeof(struct objc_abi_static_instances*) *
			    sizeof(struct objc_abi_static_instances *) *
			    (static_instances_cnt + 1));

			if (static_instances == NULL)
				OBJC_ERROR("Not enough memory for list of "
				    "static instances!");

			static_instances[static_instances_cnt++] = *si;

Modified src/scrypt.m from [cb91073b60] to [41ace0d09a].

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







-
+





-
+












			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: parallelization * 128 *
							blockSize];

		HMAC = [[OFHMAC alloc] initWithHashClass: [OFSHA256Hash class]];

		of_pbkdf2(HMAC, 1, salt, saltLength, password, passwordLength,
		    (unsigned char*)buffer, parallelization * 128 * blockSize);
		    (unsigned char *)buffer, parallelization * 128 * blockSize);

		for (size_t i = 0; i < parallelization; i++)
			of_scrypt_romix(buffer + i * 32 * blockSize, blockSize,
			    costFactor, tmp);

		of_pbkdf2(HMAC, 1, (unsigned char*)buffer, parallelization *
		of_pbkdf2(HMAC, 1, (unsigned char *)buffer, parallelization *
		    128 * blockSize, password, passwordLength, key, keyLength);
	} @finally {
		of_explicit_memset(tmp, 0, (costFactor + 1) * blockSize * 128);
		free(tmp);

		of_explicit_memset(buffer, 0,
		    parallelization * 128 * blockSize);
		free(buffer);

		[HMAC release];
	}
}

Modified src/socket.m from [798d29602d] to [c5f416940a].

59
60
61
62
63
64
65
66

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

66
67
68
69
70
71
72
73







-
+








	if ((ctx = memalign(0x1000, 0x100000)) == NULL)
		return;

	if (socInit(ctx, 0x100000) != 0)
		return;

	atexit((void(*))socExit);
	atexit((void (*)(void))socExit);
#endif

#ifdef OF_HAVE_THREADS
	if (!of_mutex_new(&mutex))
		return;

# ifdef OF_WII

Modified src/threading.h from [774a47eec4] to [f3dd04ca64].

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







-
+











-
+







extern bool of_condition_timed_wait(of_condition_t *condition,
    of_mutex_t *mutex, of_time_interval_t timeout);
extern bool of_condition_free(of_condition_t *condition);

/* TLS keys and spinlocks are inlined for performance. */

#if defined(OF_HAVE_PTHREADS)
static OF_INLINE void*
static OF_INLINE void *
of_tlskey_get(of_tlskey_t key)
{
	return pthread_getspecific(key);
}

static OF_INLINE bool
of_tlskey_set(of_tlskey_t key, void *ptr)
{
	return !pthread_setspecific(key, ptr);
}
#elif defined(OF_WINDOWS)
static OF_INLINE void*
static OF_INLINE void *
of_tlskey_get(of_tlskey_t key)
{
	return TlsGetValue(key);
}

static OF_INLINE bool
of_tlskey_set(of_tlskey_t key, void *ptr)

Modified src/threading.m from [df2361523e] to [47e6377b9c].

57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96

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

111
112
113
114
115
116

117
118
119
120
121
122
123
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72

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

87
88
89
90
91
92
93
94
95

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

110
111
112
113
114
115

116
117
118
119
120
121
122
123







-
+








-
+













-
+








-
+













-
+





-
+








bool
of_rmutex_lock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);

	if (count > 0) {
		if (!of_tlskey_set(rmutex->count, (void*)(count + 1)))
		if (!of_tlskey_set(rmutex->count, (void *)(count + 1)))
			return false;

		return true;
	}

	if (!of_mutex_lock(&rmutex->mutex))
		return false;

	if (!of_tlskey_set(rmutex->count, (void*)1)) {
	if (!of_tlskey_set(rmutex->count, (void *)1)) {
		of_mutex_unlock(&rmutex->mutex);
		return false;
	}

	return true;
}

bool
of_rmutex_trylock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);

	if (count > 0) {
		if (!of_tlskey_set(rmutex->count, (void*)(count + 1)))
		if (!of_tlskey_set(rmutex->count, (void *)(count + 1)))
			return false;

		return true;
	}

	if (!of_mutex_trylock(&rmutex->mutex))
		return false;

	if (!of_tlskey_set(rmutex->count, (void*)1)) {
	if (!of_tlskey_set(rmutex->count, (void *)1)) {
		of_mutex_unlock(&rmutex->mutex);
		return false;
	}

	return true;
}

bool
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);

	if (count > 1) {
		if (!of_tlskey_set(rmutex->count, (void*)(count - 1)))
		if (!of_tlskey_set(rmutex->count, (void *)(count - 1)))
			return false;

		return true;
	}

	if (!of_tlskey_set(rmutex->count, (void*)0))
	if (!of_tlskey_set(rmutex->count, (void *)0))
		return false;

	if (!of_mutex_unlock(&rmutex->mutex))
		return false;

	return true;
}

Modified src/threading_pthread.m from [430c90cbfe] to [9d56adf88b].

50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64







-
+







	OF_ENSURE(pthread_attr_getschedparam(&pattr, &param) == 0);

	normalPrio = param.sched_priority;

	pthread_attr_destroy(&pattr);
}

static void*
static void *
function_wrapper(void *data)
{
	struct thread_ctx *ctx = data;

	pthread_cleanup_push(free, data);

	ctx->function(ctx->object);

Modified src/threading_winapi.m from [0dde3aa656] to [f624bdcb51].

28
29
30
31
32
33
34
35

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

35
36
37
38
39
40
41
42







-
+







}

bool
of_thread_new(of_thread_t *thread, void (*function)(id), id object,
    const of_thread_attr_t *attr)
{
	*thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0),
	    (LPTHREAD_START_ROUTINE)function, (__bridge void*)object, 0, NULL);
	    (LPTHREAD_START_ROUTINE)function, (__bridge void *)object, 0, NULL);

	if (thread == NULL)
		return false;

	if (attr != NULL && attr->priority != 0) {
		DWORD priority;

Modified tests/ForwardingTests.m from [fc741f89e7] to [cf2379237f].

45
46
47
48
49
50
51
52

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

52
53
54
55
56
57
58
59







-
+







@interface ForwardingTest (Test)
+ (void)test;
- (void)test;
- (uint32_t)forwardingTargetTest: (intptr_t)a0
				: (intptr_t)a1
				: (double)a2
				: (double)a3;
- (OFString*)forwardingTargetVarArgTest: (OFConstantString*)fmt, ...;
- (OFString *)forwardingTargetVarArgTest: (OFConstantString *)fmt, ...;
- (long double)forwardingTargetFPRetTest;
- (struct stret_test)forwardingTargetStRetTest;
- (void)forwardingTargetNilTest;
- (void)forwardingTargetSelfTest;
- (struct stret_test)forwardingTargetNilStRetTest;
- (struct stret_test)forwardingTargetSelfStRetTest;
@end
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124







-
+







	double add = r0 * r1 * r2 * r3 * r4 * r5 * r6 * r7 * r8 * r9 * r10 *
	    r11 * f0 * f1 * f2 * f3 * f4 * f5 * f6 * f7 * f8 * f9 * f10 * f11;

	if (sel_isEqual(selector, @selector(forwardingTargetTest::::)) ||
	    sel_isEqual(selector, @selector(forwardingTargetVarArgTest:)) ||
	    sel_isEqual(selector, @selector(forwardingTargetFPRetTest)) ||
	    sel_isEqual(selector, @selector(forwardingTargetStRetTest)))
		return (id)((char*)target + (ptrdiff_t)add);
		return (id)((char *)target + (ptrdiff_t)add);

	if (sel_isEqual(selector, @selector(forwardingTargetNilTest)) ||
	    sel_isEqual(selector, @selector(forwardingTargetNilStRetTest)))
		return nil;

	if (sel_isEqual(selector, @selector(forwardingTargetSelfTest)) ||
	    sel_isEqual(selector, @selector(forwardingTargetSelfStRetTest)))
144
145
146
147
148
149
150
151

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

151
152
153
154
155
156
157
158







-
+







		return 0;
	if (a3 != 2.75)
		return 0;

	return 0x12345678;
}

- (OFString*)forwardingTargetVarArgTest: (OFConstantString*)fmt, ...
- (OFString *)forwardingTargetVarArgTest: (OFConstantString *)fmt, ...
{
	va_list args;
	OFString *ret;

	OF_ENSURE(self == target);

	va_start(args, fmt);

Modified tests/OFArrayTests.m from [c99073b249] to [9dfa280d32].

73
74
75
76
77
78
79
80

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

80
81
82
83
84
85
86
87







-
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		_array = [[OFMutableArray alloc] initWithObjects: objects
							   count: count];

Modified tests/OFDataArrayTests.m from [07c61622f6] to [bcbf5eac2f].

123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137







-
+








	TEST(@"+[dataArrayWithBase64EncodedString:]",
	    !memcmp([[class dataArrayWithBase64EncodedString: @"YWJjZGU="]
	    items], "abcde", 5))

	TEST(@"Building strings",
	    (array[0] = [class dataArray]) &&
	    R([array[0] addItems: (void*)str
	    R([array[0] addItems: (void *)str
			   count: 6]) && R([array[0] addItem: ""]) &&
	    !strcmp([array[0] items], str))

	EXPECT_EXCEPTION(@"Detect out of range in -[itemAtIndex:]",
	    OFOutOfRangeException, [array[0] itemAtIndex: [array[0] count]])

	EXPECT_EXCEPTION(@"Detect out of range in -[addItems:count:]",

Modified tests/OFDictionaryTests.m from [6cb38442bb] to [b05d0d80fb].

77
78
79
80
81
82
83
84
85


86
87
88
89
90
91
92
77
78
79
80
81
82
83


84
85
86
87
88
89
90
91
92







-
-
+
+







		[self release];
		@throw e;
	}

	return self;
}

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

	@try {
		_dictionary = [[OFMutableDictionary alloc]
		    initWithObjects: objects
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
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







-
+




-
+




-
-
+
+







}

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

- (OFEnumerator*)keyEnumerator
- (OFEnumerator *)keyEnumerator
{
	return [_dictionary keyEnumerator];
}

- (OFEnumerator*)objectEnumerator
- (OFEnumerator *)objectEnumerator
{
	return [_dictionary objectEnumerator];
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state
			   objects: (id *)objects
			     count: (int)count
{
	return [_dictionary countByEnumeratingWithState: state
						objects: objects
						  count: count];
}
@end

Modified tests/OFKernelEventObserverTests.m from [26a483d9d8] to [f2b6e225cb].

51
52
53
54
55
56
57
58

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

58
59
60
61
62
63
64
65







-
+







	int _fails;
}

- (void)run;
@end

@implementation ObserverTest
- initWithTestsAppDelegate: (TestsAppDelegate*)testsAppDelegate
- initWithTestsAppDelegate: (TestsAppDelegate *)testsAppDelegate
{
	self = [super init];

	@try {
		uint16_t port;

		_testsAppDelegate = testsAppDelegate;

Modified tests/OFStreamTests.m from [d45edb3a8c] to [ef2c49709d].

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







-
+


















-
+








@implementation StreamTester
- (bool)lowlevelIsAtEndOfStream
{
	return (state > 1);
}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer
- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)size
{
	size_t pageSize = [OFSystemInfo pageSize];

	switch (state) {
	case 0:
		if (size < 1)
			return 0;

		memcpy(buffer, "f", 1);

		state++;
		return 1;
	case 1:
		if (size < pageSize)
			return 0;

		memcpy(buffer, "oo\n", 3);
		memset((char*)buffer + 3, 'X', pageSize - 3);
		memset((char *)buffer + 3, 'X', pageSize - 3);

		state++;
		return pageSize;
	}

	return 0;
}

Modified tests/OFStringTests.m from [c38d6eca4f] to [1397ae7a5c].

31
32
33
34
35
36
37
38

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

38
39
40
41
42
43
44
45







-
+







#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"
#import "OFUnknownXMLEntityException.h"

#import "TestsAppDelegate.h"

static OFString *module = nil;
static OFString* whitespace[] = {
static OFString *whitespace[] = {
	@" \r \t\n\t \tasd  \t \t\t\r\n",
	@" \t\t  \t\t  \t \t"
};
static of_unichar_t ucstr[] = {
	0xFEFF, 'f', 0xF6, 0xF6, 'b', 0xE4, 'r', 0x1F03A, 0
};
static of_unichar_t sucstr[] = {
77
78
79
80
81
82
83
84

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

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
77
78
79
80
81
82
83

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

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161







-
+













-
+

















-
+


















-
+


















-
+







		[self release];
		@throw e;
	}

	return self;
}

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

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

	return self;
}

- initWithCString: (const char*)cString
- initWithCString: (const char *)cString
	 encoding: (of_string_encoding_t)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;
}

- initWithUTF16String: (const of_char16_t*)UTF16String
- initWithUTF16String: (const of_char16_t *)UTF16String
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc]
		    initWithUTF16String: UTF16String
				 length: length
			      byteOrder: byteOrder];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithUTF32String: (const of_char32_t*)UTF32String
- initWithUTF32String: (const of_char32_t *)UTF32String
	       length: (size_t)length
	    byteOrder: (of_byte_order_t)byteOrder
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc]
		    initWithUTF32String: UTF32String
				 length: length
			      byteOrder: byteOrder];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithFormat: (OFConstantString*)format
- initWithFormat: (OFConstantString *)format
       arguments: (va_list)arguments
{
	self = [super init];

	@try {
		_string = [[OFMutableString alloc] initWithFormat: format
							arguments: arguments];
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208


209
210
211
212
213
214
215
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204
205
206


207
208
209
210
211
212
213
214
215







-
+










-
-
+
+







+ (void)initialize
{
	if (self == [SimpleMutableString class])
		[self inheritMethodsFromClass: [SimpleString class]];
}

- (void)replaceCharactersInRange: (of_range_t)range
		      withString: (OFString*)string
		      withString: (OFString *)string
{
	[_string replaceCharactersInRange: range
			       withString: string];
}
@end

@interface EntityHandler: OFObject <OFStringXMLUnescapingDelegate>
@end

@implementation EntityHandler
-	   (OFString*)string: (OFString*)string
  containsUnknownEntityNamed: (OFString*)entity
-	  (OFString *)string: (OFString *)string
  containsUnknownEntityNamed: (OFString *)entity
{
	if ([entity isEqual: @"foo"])
		return @"bar";

	return nil;
}
@end
929
930
931
932
933
934
935
936

937
938
939
940
941
942
943
929
930
931
932
933
934
935

936
937
938
939
940
941
942
943







-
+







	    (h = [[[EntityHandler alloc] init] autorelease]) &&
	    [[C(@"x&foo;y") stringByXMLUnescapingWithDelegate: h]
	    isEqual: @"xbary"])

#ifdef OF_HAVE_BLOCKS
	TEST(@"-[stringByXMLUnescapingWithBlock:]",
	    [[C(@"x&foo;y") stringByXMLUnescapingWithBlock:
	        ^ OFString* (OFString *str, OFString *entity) {
	        ^ OFString *(OFString *str, OFString *entity) {
		    if ([entity isEqual: @"foo"])
			    return @"bar";

		    return nil;
	    }] isEqual: @"xbary"])

	j = 0;

Modified tests/OFXMLElementBuilderTests.m from [93fff9b69c] to [edaf2396cf].

24
25
26
27
28
29
30
31
32


33
34
35
36
37
38
39


40
41
42
43
44
45
46
24
25
26
27
28
29
30


31
32
33
34
35
36
37


38
39
40
41
42
43
44
45
46







-
-
+
+





-
-
+
+







#import "TestsAppDelegate.h"

static OFString *module = @"OFXMLElementBuilder";
static OFXMLNode *nodes[2];
static size_t i = 0;

@implementation TestsAppDelegate (OFXMLElementBuilderTests)
- (void)elementBuilder: (OFXMLElementBuilder*)builder
       didBuildElement: (OFXMLElement*)element
- (void)elementBuilder: (OFXMLElementBuilder *)builder
       didBuildElement: (OFXMLElement *)element
{
	OF_ENSURE(i == 0);
	nodes[i++] = [element retain];
}

-   (void)elementBuilder: (OFXMLElementBuilder*)builder
  didBuildParentlessNode: (OFXMLNode*)node
-   (void)elementBuilder: (OFXMLElementBuilder *)builder
  didBuildParentlessNode: (OFXMLNode *)node
{
	OF_ENSURE(i == 1);
	nodes[i++] = [node retain];
}

- (void)XMLElementBuilderTests
{

Modified tests/OFXMLParserTests.m from [b4df7e9977] to [278894d6bc].

40
41
42
43
44
45
46
47
48
49
50
51





52
53
54
55
56
57
58
40
41
42
43
44
45
46





47
48
49
50
51
52
53
54
55
56
57
58







-
-
-
-
-
+
+
+
+
+







	STRING,
	CDATA,
	COMMENT
};

@implementation TestsAppDelegate (OFXMLParser)
- (void)parserCallbackWithEventType: (enum event_type)et
			       name: (OFString*)name
			     prefix: (OFString*)prefix
			  namespace: (OFString*)ns
			 attributes: (OFArray*)attrs
			     string: (OFString*)string
			       name: (OFString *)name
			     prefix: (OFString *)prefix
			  namespace: (OFString *)ns
			 attributes: (OFArray *)attrs
			     string: (OFString *)string
{
	OFString *msg;

	i++;
	msg = [OFString stringWithFormat: @"Parsing part #%d", i];

	switch (i) {
237
238
239
240
241
242
243
244
245


246
247
248
249
250
251
252
253
254
255
256
257
258
259





260
261
262
263
264
265
266
267
268
269
270
271
272




273
274
275
276
277
278
279
280
281
282
283


284
285
286
287
288
289
290
291
292
293
294


295
296
297
298
299
300
301
302
303
304
305


306
307
308
309
310
311
312
313
314
315
316


317
318
319
320
321
322
323
237
238
239
240
241
242
243


244
245
246
247
248
249
250
251
252
253
254





255
256
257
258
259
260
261
262
263
264
265
266
267
268




269
270
271
272
273
274
275
276
277
278
279
280
281


282
283
284
285
286
287
288
289
290
291
292


293
294
295
296
297
298
299
300
301
302
303


304
305
306
307
308
309
310
311
312
313
314


315
316
317
318
319
320
321
322
323







-
-
+
+









-
-
-
-
-
+
+
+
+
+









-
-
-
-
+
+
+
+









-
-
+
+









-
-
+
+









-
-
+
+









-
-
+
+







	case 32:
		TEST(msg, et == TAG_END && [name isEqual: @"root"] &&
		    prefix == nil && ns == nil);
		break;
	}
}

-		 (void)parser: (OFXMLParser*)parser
  foundProcessingInstructions: (OFString*)pi
-		 (void)parser: (OFXMLParser *)parser
  foundProcessingInstructions: (OFString *)pi
{
	[self parserCallbackWithEventType: PROCESSING_INSTRUCTIONS
				     name: nil
				   prefix: nil
				namespace: nil
			       attributes: nil
				   string: pi];
}

-    (void)parser: (OFXMLParser*)parser
  didStartElement: (OFString*)name
	   prefix: (OFString*)prefix
	namespace: (OFString*)ns
       attributes: (OFArray*)attrs
-    (void)parser: (OFXMLParser *)parser
  didStartElement: (OFString *)name
	   prefix: (OFString *)prefix
	namespace: (OFString *)ns
       attributes: (OFArray *)attrs
{
	[self parserCallbackWithEventType: TAG_START
				     name: name
				   prefix: prefix
				namespace: ns
			       attributes: attrs
				   string: nil];
}

-  (void)parser: (OFXMLParser*)parser
  didEndElement: (OFString*)name
	 prefix: (OFString*)prefix
      namespace: (OFString*)ns
-  (void)parser: (OFXMLParser *)parser
  didEndElement: (OFString *)name
	 prefix: (OFString *)prefix
      namespace: (OFString *)ns
{
	[self parserCallbackWithEventType: TAG_END
				     name: name
				   prefix: prefix
				namespace: ns
			       attributes: nil
				   string: nil];
}

-    (void)parser: (OFXMLParser*)parser
  foundCharacters: (OFString*)string
-    (void)parser: (OFXMLParser *)parser
  foundCharacters: (OFString *)string
{
	[self parserCallbackWithEventType: STRING
				     name: nil
				   prefix: nil
				namespace: nil
			       attributes: nil
				   string: string];
}

- (void)parser: (OFXMLParser*)parser
    foundCDATA: (OFString*)cdata
- (void)parser: (OFXMLParser *)parser
    foundCDATA: (OFString *)cdata
{
	[self parserCallbackWithEventType: CDATA
				     name: nil
				   prefix: nil
				namespace: nil
			       attributes: nil
				   string: cdata];
}

- (void)parser: (OFXMLParser*)parser
  foundComment: (OFString*)comment
- (void)parser: (OFXMLParser *)parser
  foundComment: (OFString *)comment
{
	[self parserCallbackWithEventType: COMMENT
				     name: nil
				   prefix: nil
				namespace: nil
			       attributes: nil
				   string: comment];
}

-	(OFString*)parser: (OFXMLParser*)parser
  foundUnknownEntityNamed: (OFString*)entity
-      (OFString *)parser: (OFXMLParser *)parser
  foundUnknownEntityNamed: (OFString *)entity
{
	if ([entity isEqual: @"foo"])
		return @"foobar";

	return nil;
}

Modified tests/PBKDF2Tests.m from [1a9b926561] to [7976571f99].

35
36
37
38
39
40
41
42

43
44
45
46
47
48

49
50
51
52
53
54

55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70

71
72
73
74
75
76

77
78
79
80
81
82
83
35
36
37
38
39
40
41

42
43
44
45
46
47

48
49
50
51
52
53

54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69

70
71
72
73
74
75

76
77
78
79
80
81
82
83







-
+





-
+





-
+







-
+







-
+





-
+







	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFHMAC *HMAC = [OFHMAC HMACWithHashClass: [OFSHA1Hash class]];
	unsigned char key[25];

	/* Test vectors from RFC 6070 */

	TEST(@"PBKDF2-SHA1, 1 iteration",
	    R(of_pbkdf2(HMAC, 1, (unsigned char*)"salt", 4, "password", 8, key,
	    R(of_pbkdf2(HMAC, 1, (unsigned char *)"salt", 4, "password", 8, key,
	     20)) &&
	    memcmp(key, "\x0C\x60\xC8\x0F\x96\x1F\x0E\x71\xF3\xA9\xB5\x24\xAF"
		"\x60\x12\x06\x2F\xE0\x37\xA6", 20) == 0)

	TEST(@"PBKDF2-SHA1, 2 iterations",
	    R(of_pbkdf2(HMAC, 2, (unsigned char*)"salt", 4, "password", 8, key,
	    R(of_pbkdf2(HMAC, 2, (unsigned char *)"salt", 4, "password", 8, key,
	    20)) &&
	    memcmp(key, "\xEA\x6C\x01\x4D\xC7\x2D\x6F\x8C\xCD\x1E\xD9\x2A\xCE"
		"\x1D\x41\xF0\xD8\xDE\x89\x57", 20) == 0)

	TEST(@"PBKDF2-SHA1, 4096 iterations",
	    R(of_pbkdf2(HMAC, 4096, (unsigned char*)"salt", 4, "password", 8,
	    R(of_pbkdf2(HMAC, 4096, (unsigned char *)"salt", 4, "password", 8,
	    key, 20)) &&
	    memcmp(key, "\x4B\x00\x79\x01\xB7\x65\x48\x9A\xBE\xAD\x49\xD9\x26"
		"\xF7\x21\xD0\x65\xA4\x29\xC1", 20) == 0)

	/* This test takes too long, even on a fast machine. */
#if 0
	TEST(@"PBKDF2-SHA1, 16777216 iterations",
	    R(of_pbkdf2(HMAC, 16777216, (unsigned char*)"salt", 4, "password",
	    R(of_pbkdf2(HMAC, 16777216, (unsigned char *)"salt", 4, "password",
	    8, key, 20)) &&
	    memcmp(key, "\xEE\xFE\x3D\x61\xCD\x4D\xA4\xE4\xE9\x94\x5B\x3D\x6B"
		"\xA2\x15\x8C\x26\x34\xE9\x84", 20) == 0)
#endif

	TEST(@"PBKDF2-SHA1, 4096 iterations, key > 1 block",
	    R(of_pbkdf2(HMAC, 4096,
	    (unsigned char*)"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
	    (unsigned char *)"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
	    "passwordPASSWORDpassword", 24, key, 25)) &&
	    memcmp(key, "\x3D\x2E\xEC\x4F\xE4\x1C\x84\x9B\x80\xC8\xD8\x36\x62"
		"\xC0\xE4\x4A\x8B\x29\x1A\x96\x4C\xF2\xF0\x70\x38", 25) == 0)

	TEST(@"PBKDF2-SHA1, 4096 iterations, key < 1 block",
	    R(of_pbkdf2(HMAC, 4096, (unsigned char*)"sa\0lt", 5, "pass\0word",
	    R(of_pbkdf2(HMAC, 4096, (unsigned char *)"sa\0lt", 5, "pass\0word",
	    9, key, 16)) &&
	    memcmp(key, "\x56\xFA\x6A\xA7\x55\x48\x09\x9D\xCC\x37\xD7\xF0\x34"
		"\x25\xE0\xC3", 16) == 0)

	[pool drain];
}
@end

Modified tests/ScryptTests.m from [c36f9bdb93] to [1b8de25397].

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
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







-
+



-
+



-
+






-
+








	TEST(@"ROMix",
	    R(memcpy(ROMixBuffer, ROMixInput, 128)) &&
	    R(of_scrypt_romix(ROMixBuffer, 1, 16, ROMixTmp)) &&
	    memcmp(ROMixBuffer, ROMixOutput, 128) == 0)

	TEST(@"scrypt test vector #1",
	    R(of_scrypt(1, 16, 1, (unsigned char*)"", 0, "", 0, output, 64)) &&
	    R(of_scrypt(1, 16, 1, (unsigned char *)"", 0, "", 0, output, 64)) &&
	    memcmp(output, testVector1, 64) == 0)

	TEST(@"scrypt test vector #2",
	    R(of_scrypt(8, 1024, 16, (unsigned char*)"NaCl", 4, "password", 8,
	    R(of_scrypt(8, 1024, 16, (unsigned char *)"NaCl", 4, "password", 8,
	    output, 64)) && memcmp(output, testVector2, 64) == 0)

	TEST(@"scrypt test vector #3",
	    R(of_scrypt(8, 16384, 1, (unsigned char*)"SodiumChloride", 14,
	    R(of_scrypt(8, 16384, 1, (unsigned char *)"SodiumChloride", 14,
	    "pleaseletmein", 13, output, 64)) &&
	    memcmp(output, testVector3, 64) == 0)

	/* The forth test vector is too expensive to include it in the tests. */
#if 0
	TEST(@"scrypt test vector #4",
	    R(of_scrypt(8, 1048576, 1, (unsigned char*)"SodiumChloride", 14,
	    R(of_scrypt(8, 1048576, 1, (unsigned char *)"SodiumChloride", 14,
	    "pleaseletmein", 13, output, 64)) &&
	    memcmp(output, testVector4, 64) == 0)
#endif

	[pool drain];
}
@end

Modified tests/TestsAppDelegate.h from [59f0e48189] to [3fcd3b5e9a].

58
59
60
61
62
63
64
65

66
67
68
69
70
71
72






73
74
75
76
77
78
79
58
59
60
61
62
63
64

65
66






67
68
69
70
71
72
73
74
75
76
77
78
79







-
+

-
-
-
-
-
-
+
+
+
+
+
+







@class OFString;

@interface TestsAppDelegate: OFObject <OFApplicationDelegate>
{
	int _fails;
}

- (void)outputString: (OFString*)str
- (void)outputString: (OFString *)str
	     inColor: (int)color;
- (void)outputTesting: (OFString*)test
	     inModule: (OFString*)module;
- (void)outputSuccess: (OFString*)test
	     inModule: (OFString*)module;
- (void)outputFailure: (OFString*)test
	     inModule: (OFString*)module;
- (void)outputTesting: (OFString *)test
	     inModule: (OFString *)module;
- (void)outputSuccess: (OFString *)test
	     inModule: (OFString *)module;
- (void)outputFailure: (OFString *)test
	     inModule: (OFString *)module;
@end

@interface TestsAppDelegate (OFArrayTests)
- (void)arrayTests;
@end

@interface TestsAppDelegate (OFBlockTests)

Modified tests/TestsAppDelegate.m from [fb941f8116] to [5233b264a3].

201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215







-
+







	}
#else
	return of_application_main(&argc, &argv, [TestsAppDelegate class]);
#endif
}

@implementation TestsAppDelegate
- (void)outputString: (OFString*)str
- (void)outputString: (OFString *)str
	     inColor: (int)color
{
#if defined(OF_PSP)
	char space = ' ';
	int y = pspDebugScreenGetY();

	pspDebugScreenSetXY(0, y);
257
258
259
260
261
262
263
264
265


266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281


282
283
284
285
286
287
288
289
290
291
292
293
294
295
296


297
298
299
300
301
302
303
257
258
259
260
261
262
263


264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279


280
281
282
283
284
285
286
287
288
289
290
291
292
293
294


295
296
297
298
299
300
301
302
303







-
-
+
+














-
-
+
+













-
-
+
+







#elif defined(STDOUT_SIMPLE)
	[of_stdout writeString: str];
#else
# error No output method!
#endif
}

- (void)outputTesting: (OFString*)test
	     inModule: (OFString*)module
- (void)outputTesting: (OFString *)test
	     inModule: (OFString *)module
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
#ifndef STDOUT_SIMPLE
	[self outputString: [OFString stringWithFormat: @"[%@] %@: testing...",
							module, test]
		   inColor: YELLOW];
#else
	[self outputString: [OFString stringWithFormat: @"[%@] %@: ",
							module, test]
		   inColor: YELLOW];
#endif
	[pool release];
}

- (void)outputSuccess: (OFString*)test
	     inModule: (OFString*)module
- (void)outputSuccess: (OFString *)test
	     inModule: (OFString *)module
{
#ifndef STDOUT_SIMPLE
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	[self outputString: [OFString stringWithFormat: @"[%@] %@: ok\n",
							module, test]
		   inColor: GREEN];
	[pool release];
#else
	[self outputString: @"ok\n"
		   inColor: GREEN];
#endif
}

- (void)outputFailure: (OFString*)test
	     inModule: (OFString*)module
- (void)outputFailure: (OFString *)test
	     inModule: (OFString *)module
{
#ifndef STDOUT_SIMPLE
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	[self outputString: [OFString stringWithFormat: @"[%@] %@: failed\n",
							module, test]
		   inColor: RED];
	[pool release];
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382







-
+







	if (!CFURLGetFileSystemRepresentation(resourcesURL, true, resourcesPath,
	    PATH_MAX)) {
		[of_stderr writeString: @"Failed to locate resources!\n"];
		[OFApplication terminateWithStatus: 1];
	}

	[[OFFileManager defaultManager] changeCurrentDirectoryPath:
	    [OFString stringWithUTF8String: (const char*)resourcesPath]];
	    [OFString stringWithUTF8String: (const char *)resourcesPath]];
#endif
#if defined(OF_WII) && defined(OF_HAVE_FILES)
	[[OFFileManager defaultManager]
	    changeCurrentDirectoryPath: @"/apps/objfw-tests"];
#endif

	[self runtimeTests];

Modified utils/ofhash/OFHash.m from [edd9d8236f] to [7a5a5d9642].

69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83







-
+








	return nil;
}

@implementation OFHash
- (void)applicationDidFinishLaunching
{
	OFArray OF_GENERIC(OFString*) *arguments = [OFApplication arguments];
	OFArray OF_GENERIC(OFString *) *arguments = [OFApplication arguments];
	id <OFCryptoHash> hash;
	bool first = true;
	int exitStatus = 0;

#ifdef OF_HAVE_SANDBOX
	OFSandbox *sandbox = [[OFSandbox alloc] init];
	@try {

Modified utils/ofhttp/OFHTTP.m from [9d1be742e3] to [fd3994865b].

50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64







-
+








#define GIBIBYTE (1024 * 1024 * 1024)
#define MEBIBYTE (1024 * 1024)
#define KIBIBYTE (1024)

@interface OFHTTP: OFObject <OFHTTPClientDelegate>
{
	OFArray OF_GENERIC(OFString*) *_URLs;
	OFArray OF_GENERIC(OFString *) *_URLs;
	size_t _URLIndex;
	int _errorCode;
	OFString *_outputPath;
	bool _continue, _force, _detectFileName, _quiet, _verbose, _insecure;
	OFDataArray *_body;
	of_http_request_method_t _method;
	OFMutableDictionary *_clientHeaders;
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147







-
+







		[self release];
		@throw e;
	}

	return self;
}

- (void)addHeader: (OFString*)header
- (void)addHeader: (OFString *)header
{
	size_t pos = [header rangeOfString: @":"].location;
	OFString *name, *value;

	if (pos == OF_NOT_FOUND) {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_input_header",
		    @"%[prog]: Headers must to be in format name:value!",
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
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







-
+













-
+







	    of_range(pos + 1, [header length] - pos - 1)];
	value = [value stringByDeletingEnclosingWhitespaces];

	[_clientHeaders setObject: value
			   forKey: name];
}

- (void)setBody: (OFString*)file
- (void)setBody: (OFString *)file
{
	[_body release];

	if ([file isEqual: @"-"]) {
		void *pool = objc_autoreleasePoolPush();

		_body = [[of_stdin readDataArrayTillEndOfStream] retain];

		objc_autoreleasePoolPop(pool);
	} else
		_body = [[OFDataArray alloc] initWithContentsOfFile: file];
}

- (void)setMethod: (OFString*)method
- (void)setMethod: (OFString *)method
{
	void *pool = objc_autoreleasePoolPush();

	method = [method uppercaseString];

	if ([method isEqual: @"GET"])
		_method = OF_HTTP_REQUEST_METHOD_GET;
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213







-
+







		    @"method", method)];
		[OFApplication terminateWithStatus: 1];
	}

	objc_autoreleasePoolPop(pool);
}

- (void)setProxy: (OFString*)proxy
- (void)setProxy: (OFString *)proxy
{
	@try {
		size_t pos = [proxy
		    rangeOfString: @":"
			  options: OF_STRING_SEARCH_BACKWARDS].location;
		OFString *host;
		intmax_t port;
367
368
369
370
371
372
373
374
375
376



377
378
379
380
381
382
383
384


385
386
387


388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
367
368
369
370
371
372
373



374
375
376
377
378
379
380
381
382


383
384
385


386
387
388
389
390
391
392
393

394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

415
416
417
418
419
420
421
422







-
-
-
+
+
+






-
-
+
+

-
-
+
+






-
+




















-
+







		[OFApplication terminateWithStatus: 1];
	}

	[self performSelector: @selector(downloadNextURL)
		   afterDelay: 0];
}

-    (void)client: (OFHTTPClient*)client
  didCreateSocket: (OF_KINDOF(OFTCPSocket*))socket
	  request: (OFHTTPRequest*)request
-    (void)client: (OFHTTPClient *)client
  didCreateSocket: (OF_KINDOF(OFTCPSocket *))socket
	  request: (OFHTTPRequest *)request
{
	if (_insecure && [socket respondsToSelector:
	    @selector(setCertificateVerificationEnabled:)])
		[socket setCertificateVerificationEnabled: false];
}

-	  (bool)client: (OFHTTPClient*)client
  shouldFollowRedirect: (OFURL*)URL
-	  (bool)client: (OFHTTPClient *)client
  shouldFollowRedirect: (OFURL *)URL
	    statusCode: (int)statusCode
	       request: (OFHTTPRequest*)request
	      response: (OFHTTPResponse*)response
	       request: (OFHTTPRequest *)request
	      response: (OFHTTPResponse *)response
{
	if (!_quiet)
		[of_stdout writeFormat: @" ➜ %d\n", statusCode];

	if (_verbose) {
		void *pool = objc_autoreleasePoolPush();
		OFDictionary OF_GENERIC(OFString*, OFString*) *headers =
		OFDictionary OF_GENERIC(OFString *, OFString *) *headers =
		    [response headers];
		OFEnumerator *keyEnumerator = [headers keyEnumerator];
		OFEnumerator *objectEnumerator =
		    [headers objectEnumerator];
		OFString *key, *object;

		while ((key = [keyEnumerator nextObject]) != nil &&
		    (object = [objectEnumerator nextObject]) != nil)
			[of_stdout writeFormat: @"  %@: %@\n",
						key, object];

		objc_autoreleasePoolPop(pool);
	}

	if (!_quiet)
		[of_stdout writeFormat: @"☇ %@", [URL string]];

	return true;
}

- (OFHTTPResponse*)performRequest: (OFHTTPRequest*)request
- (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request
{
	OFHTTPResponse *response = nil;

	@try {
		response = [_HTTPClient performRequest: request];
	} @catch (OFAddressTranslationFailedException *e) {
		if (!_quiet)
498
499
500
501
502
503
504
505

506
507
508
509
510
511
512
498
499
500
501
502
503
504

505
506
507
508
509
510
511
512







-
+








	if (!_quiet && response != nil)
		[of_stdout writeFormat: @" ➜ %d\n", [response statusCode]];

	return response;
}

- (OFString*)fileNameFromContentDisposition: (OFString*)contentDisposition
- (OFString *)fileNameFromContentDisposition: (OFString *)contentDisposition
{
	void *pool;
	const char *UTF8String;
	size_t UTF8StringLength;
	enum {
		DISPOSITION_TYPE,
		DISPOSITION_TYPE_SEMICOLON,
618
619
620
621
622
623
624
625
626


627
628

629
630
631
632
633
634
635
618
619
620
621
622
623
624


625
626
627

628
629
630
631
632
633
634
635







-
-
+
+

-
+







	fileName = [fileName lastPathComponent];

	[fileName retain];
	objc_autoreleasePoolPop(pool);
	return [fileName autorelease];
}

-      (bool)stream: (OFHTTPResponse*)response
  didReadIntoBuffer: (void*)buffer
-      (bool)stream: (OFHTTPResponse *)response
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length
	  exception: (OFException*)e
	  exception: (OFException *)e
{
	if (e != nil) {
		OFString *URL;

		[_progressBar stop];
		[_progressBar draw];
		[_progressBar release];
685
686
687
688
689
690
691
692

693
694
695
696
697
698
699
685
686
687
688
689
690
691

692
693
694
695
696
697
698
699







-
+







{
	OFFileManager *fileManager = [OFFileManager defaultManager];
	OFString *URLString = nil;
	OFURL *URL;
	OFMutableDictionary *clientHeaders;
	OFHTTPRequest *request;
	OFHTTPResponse *response;
	OFDictionary OF_GENERIC(OFString*, OFString*) *headers;
	OFDictionary OF_GENERIC(OFString *, OFString *) *headers;
	OFString *fileName = nil, *lengthString, *type;

	_length = -1;
	_received = _resumedFrom = 0;

	if (_output != of_stdout)
		[_output release];
825
826
827
828
829
830
831
832
833


834
835
836
837
838
839
840
825
826
827
828
829
830
831


832
833
834
835
836
837
838
839
840







-
-
+
+







			}
		} else
			lengthString =
			    OF_LOCALIZED(@"size_unknown", @"unknown");

		if (_verbose) {
			void *pool = objc_autoreleasePoolPush();
			OFDictionary OF_GENERIC(OFString*, OFString*) *headers =
			    [response headers];
			OFDictionary OF_GENERIC(OFString *, OFString *)
			    *headers = [response headers];
			OFEnumerator *keyEnumerator = [headers keyEnumerator];
			OFEnumerator *objectEnumerator =
			    [headers objectEnumerator];
			OFString *key, *object;

			[of_stdout writeString: @"  "];
			[of_stdout writeLine: OF_LOCALIZED(

Modified utils/ofzip/Archive.h from [d56995be03] to [9f8454bed8].

15
16
17
18
19
20
21
22
23


24
25
26


27
15
16
17
18
19
20
21


22
23
24


25
26
27







-
-
+
+

-
-
+
+

 */

#import "OFObject.h"
#import "OFFile.h"
#import "OFArray.h"

@protocol Archive <OFObject>
+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream*))stream;
- initWithStream: (OF_KINDOF(OFStream*))stream;
+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream;
- initWithStream: (OF_KINDOF(OFStream *))stream;
- (void)listFiles;
- (void)extractFiles: (OFArray OF_GENERIC(OFString*)*)files;
- (void)printFiles: (OFArray OF_GENERIC(OFString*)*)files;
- (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files;
- (void)printFiles: (OFArray OF_GENERIC(OFString* ) *)files;
@end

Modified utils/ofzip/GZIPArchive.m from [0352ca14b6] to [b72f242916].

41
42
43
44
45
46
47
48

49
50
51

52
53
54
55
56

57
58
59
60
61
62
63
41
42
43
44
45
46
47

48
49
50

51
52
53
54
55

56
57
58
59
60
61
62
63







-
+


-
+




-
+







#endif
}

@implementation GZIPArchive
+ (void)initialize
{
	if (self == [GZIPArchive class])
		app = (OFZIP*)[[OFApplication sharedApplication] delegate];
		app = (OFZIP *)[[OFApplication sharedApplication] delegate];
}

+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream*))stream
+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream
{
	return [[[self alloc] initWithStream: stream] autorelease];
}

- initWithStream: (OF_KINDOF(OFStream*))stream
- initWithStream: (OF_KINDOF(OFStream *))stream
{
	self = [super init];

	@try {
		_stream = [[OFGZIPStream alloc] initWithStream: stream];
	} @catch (id e) {
		[self release];
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91







-
+







- (void)listFiles
{
	[of_stderr writeLine: OF_LOCALIZED(@"cannot_list_gz",
	    @"Cannot list files of a .gz archive!")];
	app->_exitStatus = 1;
}

- (void)extractFiles: (OFArray OF_GENERIC(OFString*)*)files
- (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFString *fileName;
	OFFile *output;

	if ([files count] != 0) {
		[of_stderr writeLine:
		    OF_LOCALIZED(@"cannot_extract_specific_file_from_gz",
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139







-
+







		[of_stdout writeString: @"\r"];
		[of_stdout writeLine: OF_LOCALIZED(@"extracting_file_done",
		    @"Extracting %[file]... done",
		    @"file", fileName)];
	}
}

- (void)printFiles: (OFArray OF_GENERIC(OFString*)*)files
- (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFString *fileName = [[app->_archivePath lastPathComponent]
	    stringByDeletingPathExtension];

	if ([files count] > 0) {
		[of_stderr writeLine: OF_LOCALIZED(
		    @"cannot_print_specific_file_from_gz",

Modified utils/ofzip/OFZIP.h from [50af7478a6] to [13ab30e52b].

33
34
35
36
37
38
39
40
41
42
43
44
45
46







47
33
34
35
36
37
38
39







40
41
42
43
44
45
46
47







-
-
-
-
-
-
-
+
+
+
+
+
+
+

	int8_t _overwrite;
@public
	int8_t _outputLevel;
	OFString *_archivePath;
	int _exitStatus;
}

- (id <Archive>)openArchiveWithPath: (OFString*)path
			       type: (OFString*)type;
- (bool)shouldExtractFile: (OFString*)fileName
	      outFileName: (OFString*)outFileName;
- (ssize_t)copyBlockFromStream: (OFStream*)input
		      toStream: (OFStream*)output
		      fileName: (OFString*)fileName;
- (id <Archive>)openArchiveWithPath: (OFString *)path
			       type: (OFString *)type;
- (bool)shouldExtractFile: (OFString *)fileName
	      outFileName: (OFString *)outFileName;
- (ssize_t)copyBlockFromStream: (OFStream *)input
		      toStream: (OFStream *)output
		      fileName: (OFString *)fileName;
@end

Modified utils/ofzip/OFZIP.m from [fee5d710b7] to [be1781ac4e].

132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146







-
+







		{ 't', @"type", 1, NULL, &type },
		{ 'v', @"verbose", 0, NULL, NULL },
		{ 'x', @"extract", 0, NULL, NULL },
		{ '\0', nil, 0, NULL, NULL }
	};
	OFOptionsParser *optionsParser;
	of_unichar_t option, mode = '\0';
	OFArray OF_GENERIC(OFString*) *remainingArguments, *files;
	OFArray OF_GENERIC(OFString *) *remainingArguments, *files;
	id <Archive> archive;

#ifdef OF_HAVE_SANDBOX
	OFSandbox *sandbox = [[OFSandbox alloc] init];
	@try {
		[sandbox setAllowsStdIO: true];
		[sandbox setAllowsReadingFiles: true];
293
294
295
296
297
298
299
300
301


302
303
304
305
306
307
308
293
294
295
296
297
298
299


300
301
302
303
304
305
306
307
308







-
-
+
+







		help(of_stderr, true, 1);
		break;
	}

	[OFApplication terminateWithStatus: _exitStatus];
}

- (id <Archive>)openArchiveWithPath: (OFString*)path
			       type: (OFString*)type
- (id <Archive>)openArchiveWithPath: (OFString *)path
			       type: (OFString *)type
{
	OFFile *file = nil;
	id <Archive> archive = nil;

	[_archivePath release];
	_archivePath = [path copy];

380
381
382
383
384
385
386
387
388


389
390
391
392
393
394
395
380
381
382
383
384
385
386


387
388
389
390
391
392
393
394
395







-
-
+
+







		    @"file", path)];
		[OFApplication terminateWithStatus: 1];
	}

	return archive;
}

- (bool)shouldExtractFile: (OFString*)fileName
	      outFileName: (OFString*)outFileName
- (bool)shouldExtractFile: (OFString *)fileName
	      outFileName: (OFString *)outFileName
{
	OFString *line;

	if (_overwrite == 1 ||
	    ![[OFFileManager defaultManager] fileExistsAtPath: outFileName])
		return true;

438
439
440
441
442
443
444
445
446
447



448
449
450
451
452
453
454
438
439
440
441
442
443
444



445
446
447
448
449
450
451
452
453
454







-
-
-
+
+
+







		[of_stdout writeString: OF_LOCALIZED(@"extracting_file",
		    @"Extracting %[file]...",
		    @"file", fileName)];

	return true;
}

- (ssize_t)copyBlockFromStream: (OFStream*)input
		      toStream: (OFStream*)output
		      fileName: (OFString*)fileName
- (ssize_t)copyBlockFromStream: (OFStream *)input
		      toStream: (OFStream *)output
		      fileName: (OFString *)fileName
{
	char buffer[BUFFER_SIZE];
	size_t length;

	@try {
		length = [input readIntoBuffer: buffer
					length: BUFFER_SIZE];

Modified utils/ofzip/TarArchive.m from [de5d10a91b] to [fe3cb3604c].

52
53
54
55
56
57
58
59

60
61
62

63
64
65
66
67

68
69
70
71
72
73
74
52
53
54
55
56
57
58

59
60
61

62
63
64
65
66

67
68
69
70
71
72
73
74







-
+


-
+




-
+







#endif
}

@implementation TarArchive
+ (void)initialize
{
	if (self == [TarArchive class])
		app = (OFZIP*)[[OFApplication sharedApplication] delegate];
		app = (OFZIP *)[[OFApplication sharedApplication] delegate];
}

+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream*))stream
+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream
{
	return [[[self alloc] initWithStream: stream] autorelease];
}

- initWithStream: (OF_KINDOF(OFStream*))stream
- initWithStream: (OF_KINDOF(OFStream *))stream
{
	self = [super init];

	@try {
		_archive = [[OFTarArchive alloc] initWithStream: stream];
	} @catch (id e) {
		[self release];
231
232
233
234
235
236
237
238

239
240
241
242

243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
231
232
233
234
235
236
237

238
239
240
241

242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257







-
+



-
+







-
+







			}
		}

		objc_autoreleasePoolPop(pool);
	}
}

- (void)extractFiles: (OFArray OF_GENERIC(OFString*)*)files
- (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFFileManager *fileManager = [OFFileManager defaultManager];
	bool all = ([files count] == 0);
	OFMutableSet OF_GENERIC(OFString*) *missing =
	OFMutableSet OF_GENERIC(OFString *) *missing =
	    [OFMutableSet setWithArray: files];
	OFTarArchiveEntry *entry;

	while ((entry = [_archive nextEntry]) != nil) {
		void *pool = objc_autoreleasePoolPush();
		OFString *fileName = [entry fileName];
		OFString *outFileName = [fileName stringByStandardizingPath];
		OFArray OF_GENERIC(OFString*) *pathComponents;
		OFArray OF_GENERIC(OFString *) *pathComponents;
		OFString *directory;
		OFFile *output;
		uint64_t written = 0, size = [entry size];
		int8_t percent = -1, newPercent;

		if (!all && ![files containsObject: fileName])
			continue;
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393







-
+







			    @"File %[file] is not in the archive!",
			    @"file", file)];

		app->_exitStatus = 1;
	}
}

- (void)printFiles: (OFArray OF_GENERIC(OFString*)*)files_
- (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files_
{
	OFMutableSet *files;
	OFTarArchiveEntry *entry;

	if ([files_ count] < 1) {
		[of_stderr writeLine: OF_LOCALIZED(@"print_no_file_specified",
		    @"Need one or more files to print!")];

Modified utils/ofzip/ZIPArchive.m from [d50f922fb2] to [75562dbfa9].

52
53
54
55
56
57
58
59

60
61
62

63
64
65
66
67

68
69
70
71
72
73
74
52
53
54
55
56
57
58

59
60
61

62
63
64
65
66

67
68
69
70
71
72
73
74







-
+


-
+




-
+







#endif
}

@implementation ZIPArchive
+ (void)initialize
{
	if (self == [ZIPArchive class])
		app = (OFZIP*)[[OFApplication sharedApplication] delegate];
		app = (OFZIP *)[[OFApplication sharedApplication] delegate];
}

+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream*))stream
+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream
{
	return [[[self alloc] initWithStream: stream] autorelease];
}

- initWithStream: (OF_KINDOF(OFStream*))stream
- initWithStream: (OF_KINDOF(OFStream *))stream
{
	self = [super init];

	@try {
		_archive = [[OFZIPArchive alloc]
		    initWithSeekableStream: stream];
	} @catch (id e) {
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
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







-
+



-
+






-
+







			}
		}

		objc_autoreleasePoolPop(pool);
	}
}

- (void)extractFiles: (OFArray OF_GENERIC(OFString*)*)files
- (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFFileManager *fileManager = [OFFileManager defaultManager];
	bool all = ([files count] == 0);
	OFMutableSet OF_GENERIC(OFString*) *missing =
	OFMutableSet OF_GENERIC(OFString *) *missing =
	    [OFMutableSet setWithArray: files];

	for (OFZIPArchiveEntry *entry in [_archive entries]) {
		void *pool = objc_autoreleasePoolPush();
		OFString *fileName = [entry fileName];
		OFString *outFileName = [fileName stringByStandardizingPath];
		OFArray OF_GENERIC(OFString*) *pathComponents;
		OFArray OF_GENERIC(OFString *) *pathComponents;
		OFString *directory;
		OFStream *stream;
		OFFile *output;
		uint64_t written = 0, size = [entry uncompressedSize];
		int8_t percent = -1, newPercent;

		if (!all && ![files containsObject: fileName])
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
323
324
325
326
327
328
329

330
331
332
333
334
335
336
337







-
+







			    @"File %[file] is not in the archive!",
			    @"file", file)];

		app->_exitStatus = 1;
	}
}

- (void)printFiles: (OFArray OF_GENERIC(OFString*)*)files
- (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFStream *stream;

	if ([files count] < 1) {
		[of_stderr writeLine: OF_LOCALIZED(@"print_no_file_specified",
		    @"Need one or more files to print!")];
		app->_exitStatus = 1;