ObjFW  Check-in [7061b887af]

Overview
Comment:Merge trunk into 1.0 branch
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | 1.0
Files: files | file ages | folders
SHA3-256: 7061b887af9324726efcdb5442651bc88f57815d89c5aa95254fe4b59042e38c
User & Date: js on 2023-08-09 11:41:21
Other Links: branch diff | manifest | tags
Context
2023-08-09
11:47
Update version for 1.0 including shared lib check-in: 4d747f46f7 user: js tags: 1.0
11:41
Merge trunk into 1.0 branch check-in: 7061b887af user: js tags: 1.0
11:30
OFData: Ensure init methods return correct class check-in: f42a4471b9 user: js tags: trunk
2023-07-20
20:17
configure: Change the default for -Werror check-in: b20268e251 user: js tags: 1.0
Changes

Modified Doxyfile from [3c7cbc0d44] to [68a4cb7d92].

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
26
27
28

29
30
31

32
33
34
35
36
37
38
PROJECT_NAME = "ObjFW"
OUTPUT_DIRECTORY = docs/
INPUT = src src/exceptions src/runtime
FILE_PATTERNS = *.h *.m
HTML_OUTPUT = .
HAVE_DOT = NO
GENERATE_LATEX = NO
HIDE_UNDOC_CLASSES = YES
HIDE_UNDOC_MEMBERS = YES
TYPEDEF_HIDES_STRUCT = YES
PREDEFINED = __OBJC__						\
	     _Nonnull=						\
	     _Nullable=						\
	     DOXYGEN						\
	     OF_BOXABLE=					\
	     OF_CONSUMED=					\
	     OF_DESIGNATED_INITIALIZER=				\
	     OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES	\
	     OF_FILE_MANAGER_SUPPORTS_LINKS			\
	     OF_FILE_MANAGER_SUPPORTS_OWNER			\
	     OF_FILE_MANAGER_SUPPORTS_PERMISSIONS		\
	     OF_FILE_MANAGER_SUPPORTS_SYMLINKS			\
	     OF_GENERIC(...)=					\
	     OF_HAVE_APPLETALK					\
	     OF_HAVE_BLOCKS					\
	     OF_HAVE_FILES					\
	     OF_HAVE_IPV6					\
	     OF_HAVE_IPX					\

	     OF_HAVE_SANDBOX					\
	     OF_HAVE_SOCKETS					\
	     OF_HAVE_THREADS					\

	     OF_KINDOF(...)=					\
	     OF_NO_RETURN=					\
	     OF_NO_RETURN_FUNC=					\
	     OF_NULLABLE_PROPERTY(...)=				\
	     OF_NULL_RESETTABLE_PROPERTY(...)=			\
	     OF_REQUIRES_SUPER=					\
	     OF_RETURNS_INNER_POINTER=				\










<
|
















>



>







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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
PROJECT_NAME = "ObjFW"
OUTPUT_DIRECTORY = docs/
INPUT = src src/exceptions src/runtime
FILE_PATTERNS = *.h *.m
HTML_OUTPUT = .
HAVE_DOT = NO
GENERATE_LATEX = NO
HIDE_UNDOC_CLASSES = YES
HIDE_UNDOC_MEMBERS = YES
TYPEDEF_HIDES_STRUCT = YES

PREDEFINED = _Nonnull=						\
	     _Nullable=						\
	     DOXYGEN						\
	     OF_BOXABLE=					\
	     OF_CONSUMED=					\
	     OF_DESIGNATED_INITIALIZER=				\
	     OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES	\
	     OF_FILE_MANAGER_SUPPORTS_LINKS			\
	     OF_FILE_MANAGER_SUPPORTS_OWNER			\
	     OF_FILE_MANAGER_SUPPORTS_PERMISSIONS		\
	     OF_FILE_MANAGER_SUPPORTS_SYMLINKS			\
	     OF_GENERIC(...)=					\
	     OF_HAVE_APPLETALK					\
	     OF_HAVE_BLOCKS					\
	     OF_HAVE_FILES					\
	     OF_HAVE_IPV6					\
	     OF_HAVE_IPX					\
	     OF_HAVE_PLUGINS					\
	     OF_HAVE_SANDBOX					\
	     OF_HAVE_SOCKETS					\
	     OF_HAVE_THREADS					\
	     OF_HAVE_UNICODE_TABLES				\
	     OF_KINDOF(...)=					\
	     OF_NO_RETURN=					\
	     OF_NO_RETURN_FUNC=					\
	     OF_NULLABLE_PROPERTY(...)=				\
	     OF_NULL_RESETTABLE_PROPERTY(...)=			\
	     OF_REQUIRES_SUPER=					\
	     OF_RETURNS_INNER_POINTER=				\

Modified README.md from [2681c29664] to [ebb217e96c].

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
    $ ./configure --host=powerpc-eabi --with-wii

<h2 id="amiga">Amiga</h2>

  Install [amiga-gcc](https://github.com/bebbo/amiga-gcc). Then follow the
  normal process, but instead of `./configure` run:

    $ ./configure --host=m68k-amigaos


<h1 id="first-app">Writing your first application with ObjFW</h1>

  To create your first, empty application, you can use `objfw-new`:

    $ objfw-new --app MyFirstApp







|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
    $ ./configure --host=powerpc-eabi --with-wii

<h2 id="amiga">Amiga</h2>

  Install [amiga-gcc](https://github.com/bebbo/amiga-gcc). Then follow the
  normal process, but instead of `./configure` run:

    $ ./configure --host=m68k-amigaos OBJC=m68k-amigaos-g++


<h1 id="first-app">Writing your first application with ObjFW</h1>

  To create your first, empty application, you can use `objfw-new`:

    $ objfw-new --app MyFirstApp

Modified configure.ac from [bb2f09756e] to [283f59d474].

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

	enable_shared="no"
	enable_threads="no"
	enable_sockets="no"
	enable_files="no"
	;;
m68k-*-amigaos*)
	AS_IF([test x"$OBJCFLAGS" = x""], [OBJCFLAGS="-O0"])
	OBJCFLAGS="$OBJCFLAGS -noixemul"
	OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -noixemul"
	CPPFLAGS="$CPPFLAGS -D__NO_NET_API"
	LDFLAGS="$LDFLAGS -noixemul"
	LIBS="$LIBS -ldebug"

	enable_files="yes"	# Required for reading ENV:







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

	enable_shared="no"
	enable_threads="no"
	enable_sockets="no"
	enable_files="no"
	;;
m68k-*-amigaos*)
	AS_IF([test x"$OBJCFLAGS" = x""], [OBJCFLAGS="-O0 -g"])
	OBJCFLAGS="$OBJCFLAGS -noixemul"
	OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -noixemul"
	CPPFLAGS="$CPPFLAGS -D__NO_NET_API"
	LDFLAGS="$LDFLAGS -noixemul"
	LIBS="$LIBS -ldebug"

	enable_files="yes"	# Required for reading ENV:
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412










1413
1414
1415
1416
1417
1418
1419
		AC_DEFINE(OF_HAVE_NETINET_IN_H, 1,
			[Whether we have netinet/in.h])
	])
	AC_CHECK_HEADER(netinet/tcp.h, [
		AC_DEFINE(OF_HAVE_NETINET_TCP_H, 1,
			[Whether we have netinet/tcp.h])
	])
	AC_CHECK_HEADERS([arpa/inet.h netdb.h])
	AC_CHECK_HEADERS([net/if.h net/if_arp.h net/if_dl.h net/if_types.h])
	AC_CHECK_FUNCS([if_indextoname if_nametoindex])
	AC_CHECK_TYPES([struct sockaddr_dl], [], [], [
		#ifdef HAVAE_SYS_TYPES_H
		# include <sys/types.h>
		#endif
		#ifdef HAVE_NET_IF_DL_H
		# include <net/if_dl.h>
		#endif










	])
	AC_CHECK_HEADER(sys/un.h, [
		AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h])
	])
	AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [
		AC_EGREP_CPP(egrep_cpp_yes, [
			#ifdef _WIN32







|

|

|





>
>
>
>
>
>
>
>
>
>







1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
		AC_DEFINE(OF_HAVE_NETINET_IN_H, 1,
			[Whether we have netinet/in.h])
	])
	AC_CHECK_HEADER(netinet/tcp.h, [
		AC_DEFINE(OF_HAVE_NETINET_TCP_H, 1,
			[Whether we have netinet/tcp.h])
	])
	AC_CHECK_HEADERS([arpa/inet.h netdb.h sys/sockio.h])
	AC_CHECK_HEADERS([net/if.h net/if_arp.h net/if_dl.h net/if_types.h])
	AC_CHECK_FUNCS([if_indextoname if_nametoindex if_nameindex])
	AC_CHECK_TYPES([struct sockaddr_dl], [], [], [
		#ifdef HAVE_SYS_TYPES_H
		# include <sys/types.h>
		#endif
		#ifdef HAVE_NET_IF_DL_H
		# include <net/if_dl.h>
		#endif
	])
	AC_CHECK_TYPES([struct lifconf], [], [], [
		#ifdef HAVE_NET_IF_H
		# include <net/if.h>
		#endif
	])
	AC_CHECK_MEMBERS([struct ifreq.ifr_hwaddr], [], [], [
		#ifdef HAVE_NET_IF_H
		# include <net/if.h>
		#endif
	])
	AC_CHECK_HEADER(sys/un.h, [
		AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h])
	])
	AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [
		AC_EGREP_CPP(egrep_cpp_yes, [
			#ifdef _WIN32
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
				[Whether we have select() or similar])
			AC_SUBST(OF_SELECT_KERNEL_EVENT_OBSERVER_M,
				"OFSelectKernelEventObserver.m")
		])
		;;
	esac

	AC_CHECK_HEADERS(net/if.h)
	AC_CHECK_FUNCS(if_nameindex)

	AC_ARG_WITH(tls,
		AS_HELP_STRING([--with-tls], [
			enable TLS support using the specified library
			(yes, openssl, gnutls, securetransport or no)]))
	AS_IF([test x"$with_tls" = x""], [with_tls="yes"])
	tls_support="no"








<
<
<







1757
1758
1759
1760
1761
1762
1763



1764
1765
1766
1767
1768
1769
1770
				[Whether we have select() or similar])
			AC_SUBST(OF_SELECT_KERNEL_EVENT_OBSERVER_M,
				"OFSelectKernelEventObserver.m")
		])
		;;
	esac




	AC_ARG_WITH(tls,
		AS_HELP_STRING([--with-tls], [
			enable TLS support using the specified library
			(yes, openssl, gnutls, securetransport or no)]))
	AS_IF([test x"$with_tls" = x""], [with_tls="yes"])
	tls_support="no"

Modified src/Makefile from [b7c9d5d7ff] to [29dc8f24f3].

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
	    ObjFW.h				\
	    macros.h				\
	    objfw-defs.h			\
	    platform.h				\
	    ${USE_INCLUDES_ATOMIC}

SRCS += OFASPrintF.m			\
	OFAdjacentArray.m		\
	OFAdjacentSubarray.m		\
	OFArchiveIRIHandler.m		\
	OFBase64.m			\
	OFBitSetCharacterSet.m		\
	OFBytesValue.m			\
	OFCRC16.m			\
	OFCRC32.m			\








	OFCountedMapTableSet.m		\


	OFEmbeddedIRIHandler.m		\
	OFHuffmanTree.m			\
	OFINIFileSettings.m		\
	OFInvertedCharacterSet.m	\
	OFLHADecompressingStream.m	\
	OFMapTableDictionary.m		\
	OFMapTableSet.m			\
	OFMutableAdjacentArray.m	\
	OFMutableMapTableDictionary.m	\
	OFMutableMapTableSet.m		\
	OFMutableUTF8String.m		\
	OFNonretainedObjectValue.m	\
	OFPointValue.m			\
	OFPointerValue.m		\
	OFRangeCharacterSet.m		\
	OFRangeValue.m			\
	OFRectValue.m			\
	OFSandbox.m			\
	OFSizeValue.m			\
	OFStrPTime.m			\
	OFSubarray.m			\


	OFUTF8String.m			\
	${LIBBASES_M}			\
	${RUNTIME_AUTORELEASE_M}	\
	${RUNTIME_INSTANCE_M}		\
	${UNICODE_M}
SRCS_FILES += OFFileIRIHandler.m
SRCS_SOCKETS += OFAsyncIPSocketConnector.m		\







<
<






>
>
>
>
>
>
>
>
|
>
>





<
<
<
<
<











>
>







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
	    ObjFW.h				\
	    macros.h				\
	    objfw-defs.h			\
	    platform.h				\
	    ${USE_INCLUDES_ATOMIC}

SRCS += OFASPrintF.m			\


	OFArchiveIRIHandler.m		\
	OFBase64.m			\
	OFBitSetCharacterSet.m		\
	OFBytesValue.m			\
	OFCRC16.m			\
	OFCRC32.m			\
	OFConcreteArray.m		\
	OFConcreteColor.m		\
	OFConcreteCountedSet.m		\
	OFConcreteData.m		\
	OFConcreteDictionary.m		\
	OFConcreteMutableArray.m	\
	OFConcreteMutableData.m		\
	OFConcreteMutableDictionary.m	\
	OFConcreteMutableSet.m		\
	OFConcreteSet.m			\
	OFConcreteSubarray.m		\
	OFEmbeddedIRIHandler.m		\
	OFHuffmanTree.m			\
	OFINIFileSettings.m		\
	OFInvertedCharacterSet.m	\
	OFLHADecompressingStream.m	\





	OFMutableUTF8String.m		\
	OFNonretainedObjectValue.m	\
	OFPointValue.m			\
	OFPointerValue.m		\
	OFRangeCharacterSet.m		\
	OFRangeValue.m			\
	OFRectValue.m			\
	OFSandbox.m			\
	OFSizeValue.m			\
	OFStrPTime.m			\
	OFSubarray.m			\
	OFSubdata.m			\
	OFTaggedPointerColor.m		\
	OFUTF8String.m			\
	${LIBBASES_M}			\
	${RUNTIME_AUTORELEASE_M}	\
	${RUNTIME_INSTANCE_M}		\
	${UNICODE_M}
SRCS_FILES += OFFileIRIHandler.m
SRCS_SOCKETS += OFAsyncIPSocketConnector.m		\

Modified src/OFArray.m from [b025a39cbb] to [a991103c76].

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "config.h"

#include <stdarg.h>
#include <stdlib.h>

#import "OFArray.h"
#import "OFArray+Private.h"
#import "OFAdjacentArray.h"
#import "OFData.h"
#import "OFNull.h"
#import "OFString.h"
#import "OFSubarray.h"

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







|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "config.h"

#include <stdarg.h>
#include <stdlib.h>

#import "OFArray.h"
#import "OFArray+Private.h"
#import "OFConcreteArray.h"
#import "OFData.h"
#import "OFNull.h"
#import "OFString.h"
#import "OFSubarray.h"

#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
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

@interface OFPlaceholderArray: OFArray
@end

@implementation OFPlaceholderArray
- (instancetype)init
{
	return (id)[[OFAdjacentArray alloc] init];
}

- (instancetype)initWithObject: (id)object
{
	return (id)[[OFAdjacentArray alloc] initWithObject: object];
}

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

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

	return ret;
}

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

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

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

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end

@implementation OFArray
+ (void)initialize
{
	if (self == [OFArray class])
		placeholder.isa = [OFPlaceholderArray class];
}

+ (instancetype)alloc
{
	if (self == [OFArray class])
		return (id)&placeholder;








|




|








|









|





|





|



<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<






|







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

@interface OFPlaceholderArray: OFArray
@end

@implementation OFPlaceholderArray
- (instancetype)init
{
	return (id)[[OFConcreteArray alloc] init];
}

- (instancetype)initWithObject: (id)object
{
	return (id)[[OFConcreteArray alloc] initWithObject: object];
}

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

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

	return ret;
}

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

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

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





OF_SINGLETON_METHODS













@end

@implementation OFArray
+ (void)initialize
{
	if (self == [OFArray class])
		object_setClass((id)&placeholder, [OFPlaceholderArray class]);
}

+ (instancetype)alloc
{
	if (self == [OFArray class])
		return (id)&placeholder;

154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
{
	return [[[self alloc] initWithObjects: objects
					count: count] autorelease];
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFArray class]]) {

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








|
>







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
{
	return [[[self alloc] initWithObjects: objects
					count: count] autorelease];
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFArray class]] ||
	    [self isMemberOfClass: [OFMutableArray class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
		} @catch (id e) {
			[self release];
			@throw e;
		}

360
361
362
363
364
365
366

367
368
369
370
371
372
373
374
	id *buffer;

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

	if (![self isKindOfClass: [OFMutableArray class]])

		return [OFSubarray arrayWithArray: self range: range];

	buffer = OFAllocMemory(range.length, sizeof(*buffer));
	@try {
		[self getObjects: buffer inRange: range];

		ret = [OFArray arrayWithObjects: buffer count: range.length];
	} @finally {







>
|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
	id *buffer;

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

	if (![self isKindOfClass: [OFMutableArray class]])
		return [[[OFSubarray alloc] initWithArray: self
						    range: range] autorelease];

	buffer = OFAllocMemory(range.length, sizeof(*buffer));
	@try {
		[self getObjects: buffer inRange: range];

		ret = [OFArray arrayWithObjects: buffer count: range.length];
	} @finally {

Modified src/OFBlock.m from [d7b2cab799] to [4c4dfcbe66].

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
struct class _NSConcreteGlobalBlock_metaclass;
struct class _NSConcreteMallocBlock_metaclass;
# endif
#endif

static struct {
	Class isa;
} alloc_failed_exception;

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

void *
_Block_copy(const void *block_)
{
	struct Block *block = (struct Block *)block_;

	if ([(id)block isMemberOfClass: (Class)&_NSConcreteStackBlock]) {
		struct Block *copy;

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

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

		if (block->flags & OFBlockHasCopyDispose)







|

















|
|
|
<







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
struct class _NSConcreteGlobalBlock_metaclass;
struct class _NSConcreteMallocBlock_metaclass;
# endif
#endif

static struct {
	Class isa;
} allocFailedException;

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

void *
_Block_copy(const void *block_)
{
	struct Block *block = (struct Block *)block_;

	if ([(id)block isMemberOfClass: (Class)&_NSConcreteStackBlock]) {
		struct Block *copy;

		if ((copy = malloc(block->descriptor->size)) == NULL) {
			object_setClass((id)&allocFailedException,
			    [OFAllocFailedException class]);
			@throw (OFAllocFailedException *)&allocFailedException;

		}
		memcpy(copy, block, block->descriptor->size);

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

		if (block->flags & OFBlockHasCopyDispose)
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
		struct Byref *src = (struct Byref *)src_;
		struct Byref **dst = (struct Byref **)dst_;

		src = src->forwarding;

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

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








|
|

|







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
		struct Byref *src = (struct Byref *)src_;
		struct Byref **dst = (struct Byref **)dst_;

		src = src->forwarding;

		if ((src->flags & OFBlockRefCountMask) == 0) {
			if ((*dst = malloc(src->size)) == NULL) {
				object_setClass((id)&allocFailedException,
				    [OFAllocFailedException class]);
				@throw (OFAllocFailedException *)
				    &allocFailedException;
			}

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

Modified src/OFCharacterSet.m from [272d843979] to [b3736a5eb2].

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
}

- (instancetype)initWithRange: (OFRange)range
{
	return (id)[[OFRangeCharacterSet alloc] initWithRange: range];
}

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end

@implementation OFCharacterSet
+ (void)initialize
{
	if (self != [OFCharacterSet class])
		return;

	placeholder.isa = [OFPlaceholderCharacterSet class];
}

+ (instancetype)alloc
{
	if (self == [OFCharacterSet class])
		return (id)&placeholder;








<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<





|
<
|
|







52
53
54
55
56
57
58




59













60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
}

- (instancetype)initWithRange: (OFRange)range
{
	return (id)[[OFRangeCharacterSet alloc] initWithRange: range];
}





OF_SINGLETON_METHODS













@end

@implementation OFCharacterSet
+ (void)initialize
{
	if (self == [OFCharacterSet class])

		object_setClass((id)&placeholder,
		    [OFPlaceholderCharacterSet class]);
}

+ (instancetype)alloc
{
	if (self == [OFCharacterSet class])
		return (id)&placeholder;

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
{
	return [[[OFInvertedCharacterSet alloc]
	    initWithCharacterSet: self] autorelease];
}
@end

@implementation OFWhitespaceCharacterSet
- (instancetype)autorelease
{
	return self;
}

- (instancetype)retain
{
	return self;
}

- (void)release
{
}

- (unsigned int)retainCount
{
	return OFMaxRetainCount;
}

- (bool)characterIsMember: (OFUnichar)character
{
	switch (character) {
	case 0x0009:
	case 0x0020:
	case 0x00A0:
	case 0x1680:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







129
130
131
132
133
134
135



















136
137
138
139
140
141
142
{
	return [[[OFInvertedCharacterSet alloc]
	    initWithCharacterSet: self] autorelease];
}
@end

@implementation OFWhitespaceCharacterSet



















- (bool)characterIsMember: (OFUnichar)character
{
	switch (character) {
	case 0x0009:
	case 0x0020:
	case 0x00A0:
	case 0x1680:
192
193
194
195
196
197
198


199
	case 0x205F:
	case 0x3000:
		return true;
	default:
		return false;
	}
}


@end







>
>

155
156
157
158
159
160
161
162
163
164
	case 0x205F:
	case 0x3000:
		return true;
	default:
		return false;
	}
}

OF_SINGLETON_METHODS
@end

Modified src/OFColor.h from [de724e96d7] to [180c6dda05].

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

/**
 * @class OFColor OFColor.h ObjFW/OFColor.h
 *
 * @brief A class for storing a color.
 */
@interface OFColor: OFObject
{
	float _red, _green, _blue, _alpha;
	OF_RESERVE_IVARS(OFColor, 4)
}

#ifdef OF_HAVE_CLASS_PROPERTIES
@property (class, readonly, nonatomic) OFColor *black;
@property (class, readonly, nonatomic) OFColor *silver;
@property (class, readonly, nonatomic) OFColor *grey;
@property (class, readonly, nonatomic) OFColor *white;
@property (class, readonly, nonatomic) OFColor *maroon;
@property (class, readonly, nonatomic) OFColor *red;







<
<
<
<
<







19
20
21
22
23
24
25





26
27
28
29
30
31
32

/**
 * @class OFColor OFColor.h ObjFW/OFColor.h
 *
 * @brief A class for storing a color.
 */
@interface OFColor: OFObject





#ifdef OF_HAVE_CLASS_PROPERTIES
@property (class, readonly, nonatomic) OFColor *black;
@property (class, readonly, nonatomic) OFColor *silver;
@property (class, readonly, nonatomic) OFColor *grey;
@property (class, readonly, nonatomic) OFColor *white;
@property (class, readonly, nonatomic) OFColor *maroon;
@property (class, readonly, nonatomic) OFColor *red;

Modified src/OFColor.m from [2f23670cfa] to [a2a90d4c7a].

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
 */

#include "config.h"

#include <math.h>

#import "OFColor.h"
#import "OFOnce.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"

@interface OFColor ()
+ (instancetype)of_alloc;
@end

@interface OFColorSingleton: OFColor
@end

@interface OFColorPlaceholder: OFColorSingleton
@end

#ifdef OF_OBJFW_RUNTIME
@interface OFTaggedPointerColor: OFColorSingleton
@end

static const float allowedImprecision = 0.0000001;
#endif

static struct {
	Class isa;
} placeholder;

#ifdef OF_OBJFW_RUNTIME
static int colorTag;
#endif

@implementation OFColorSingleton
- (instancetype)autorelease
{
	return self;
}

- (instancetype)retain
{
	return self;
}

- (void)release
{
}

- (unsigned int)retainCount
{
	return OFMaxRetainCount;
}
@end

@implementation OFColorPlaceholder
- (instancetype)initWithRed: (float)red
		      green: (float)green
		       blue: (float)blue
		      alpha: (float)alpha
{
#ifdef OF_OBJFW_RUNTIME
	uint8_t redInt = nearbyintf(red * 255);
	uint8_t greenInt = nearbyintf(green * 255);
	uint8_t blueInt = nearbyintf(blue * 255);

	if (fabsf(red * 255 - redInt) < allowedImprecision &&
	    fabsf(green * 255 - greenInt) < allowedImprecision &&
	    fabsf(blue * 255 - blueInt) < allowedImprecision && alpha == 1) {
		id ret = objc_createTaggedPointer(colorTag,
		    (uintptr_t)redInt << 16 | (uintptr_t)greenInt << 8 |
		    (uintptr_t)blueInt);

		if (ret != nil)
			return ret;
	}
#endif

	return (id)[[OFColor of_alloc] initWithRed: red
					     green: green
					      blue: blue
					     alpha: alpha];
}


@end

#ifdef OF_OBJFW_RUNTIME
@implementation OFTaggedPointerColor
- (void)getRed: (float *)red
	 green: (float *)green
	  blue: (float *)blue
	 alpha: (float *)alpha
{
	uintptr_t value = object_getTaggedPointerValue(self);

	*red = (float)(value >> 16) / 255;
	*green = (float)((value >> 8) & 0xFF) / 255;
	*blue = (float)(value & 0xFF) / 255;

	if (alpha != NULL)
		*alpha = 1;
}
@end
#endif

@implementation OFColor
+ (void)initialize
{
	if (self != [OFColor class])
		return;

	placeholder.isa = [OFColorPlaceholder class];
#ifdef OF_OBJFW_RUNTIME
	colorTag =
	    objc_registerTaggedPointerClass([OFTaggedPointerColor class]);
#endif
}

+ (instancetype)of_alloc
{
	return [super alloc];
}

+ (instancetype)alloc
{
	if (self == [OFColor class])
		return (id)&placeholder;








|
|
<
|
|
<
<
<

|


<
<
|
<
<

<
<
<






|


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













|
|
|






|
|
|
|

>
>


<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<

<




|
<
|
<
<
<
<
<
<
<
<
<
<







14
15
16
17
18
19
20
21
22

23
24



25
26
27
28


29


30



31
32
33
34
35
36
37
38
39
40





















41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

72






73







74

75
76
77
78
79

80










81
82
83
84
85
86
87
 */

#include "config.h"

#include <math.h>

#import "OFColor.h"
#import "OFConcreteColor.h"
#import "OFOnce.h"

#import "OFString.h"
#import "OFTaggedPointerColor.h"




@interface OFColorSingleton: OFConcreteColor
@end



@interface OFPlaceholderColor: OFColor


@end




static struct {
	Class isa;
} placeholder;

#ifdef OF_OBJFW_RUNTIME
static const float allowedImprecision = 0.0000001;
#endif

@implementation OFPlaceholderColor





















- (instancetype)initWithRed: (float)red
		      green: (float)green
		       blue: (float)blue
		      alpha: (float)alpha
{
#ifdef OF_OBJFW_RUNTIME
	uint8_t redInt = nearbyintf(red * 255);
	uint8_t greenInt = nearbyintf(green * 255);
	uint8_t blueInt = nearbyintf(blue * 255);

	if (fabsf(red * 255 - redInt) < allowedImprecision &&
	    fabsf(green * 255 - greenInt) < allowedImprecision &&
	    fabsf(blue * 255 - blueInt) < allowedImprecision && alpha == 1) {
		id ret = [OFTaggedPointerColor colorWithRed: redInt
						      green: greenInt
						       blue: blueInt];

		if (ret != nil)
			return ret;
	}
#endif

	return (id)[[OFConcreteColor alloc] initWithRed: red
						  green: green
						   blue: blue
						  alpha: alpha];
}

OF_SINGLETON_METHODS
@end


@implementation OFColorSingleton






OF_SINGLETON_METHODS







@end


@implementation OFColor
+ (void)initialize
{
	if (self == [OFColor class])

		object_setClass((id)&placeholder, [OFPlaceholderColor class]);










}

+ (instancetype)alloc
{
	if (self == [OFColor class])
		return (id)&placeholder;

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
}

- (instancetype)initWithRed: (float)red
		      green: (float)green
		       blue: (float)blue
		      alpha: (float)alpha
{
	self = [super init];

	@try {
		if (red < 0.0 || red > 1.0 ||
		    green < 0.0 || green > 1.0 ||
		    blue < 0.0 || blue > 1.0 ||
		    alpha < 0.0 || alpha > 1.0)
			@throw [OFInvalidArgumentException exception];

		_red = red;
		_green = green;
		_blue = blue;
		_alpha = alpha;
	} @catch (id e) {
		[self release];
		@throw e;
	}




	return self;
}

- (bool)isEqual: (id)object
{
	OFColor *other;



	if (object == self)
		return true;

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

	other = object;






	if (other->_red != _red)
		return false;
	if (other->_green != _green)
		return false;
	if (other->_blue != _blue)
		return false;
	if (other->_alpha != _alpha)
		return false;

	return true;
}

- (unsigned long)hash
{

	unsigned long hash;
	float tmp;



	OFHashInit(&hash);

	tmp = OFToLittleEndianFloat(_red);




	for (uint_fast8_t i = 0; i < sizeof(float); i++)
		OFHashAddByte(&hash, ((char *)&tmp)[i]);

	tmp = OFToLittleEndianFloat(_green);
	for (uint_fast8_t i = 0; i < sizeof(float); i++)
		OFHashAddByte(&hash, ((char *)&tmp)[i]);

	tmp = OFToLittleEndianFloat(_blue);
	for (uint_fast8_t i = 0; i < sizeof(float); i++)
		OFHashAddByte(&hash, ((char *)&tmp)[i]);

	tmp = OFToLittleEndianFloat(_alpha);
	for (uint_fast8_t i = 0; i < sizeof(float); i++)
		OFHashAddByte(&hash, ((char *)&tmp)[i]);

	OFHashFinalize(&hash);

	return hash;
}

- (void)getRed: (float *)red
	 green: (float *)green
	  blue: (float *)blue
	 alpha: (float *)alpha
{
	*red = _red;
	*green = _green;
	*blue = _blue;

	if (alpha != NULL)
		*alpha = _alpha;
}

- (OFString *)description
{
	float red, green, blue, alpha;

	[self getRed: &red green: &green blue: &blue alpha: &alpha];

	return [OFString stringWithFormat:
	    @"<%@ red=%f green=%f blue=%f alpha=%f>",
	    self.class, red, green, blue, alpha];
}
@end







<
|
|
<
<
<
<
<
|
<
<
<
<
|
|
|
|

>
>
>
|





>
>








>
>
>
>
>

|

|

|

|







>



>
>


|
>
>
>
>



|



|
<
<
<
<













<
<
<
|
<
<













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
}

- (instancetype)initWithRed: (float)red
		      green: (float)green
		       blue: (float)blue
		      alpha: (float)alpha
{

	if ([self isMemberOfClass: [OFColor class]]) {
		@try {





			[self doesNotRecognizeSelector: _cmd];




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

		abort();
	}

	return [super init];
}

- (bool)isEqual: (id)object
{
	OFColor *other;
	float red, green, blue, alpha;
	float otherRed, otherGreen, otherBlue, otherAlpha;

	if (object == self)
		return true;

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

	other = object;
	[self getRed: &red green: &green blue: &blue alpha: &alpha];
	[other getRed: &otherRed
		green: &otherGreen
		 blue: &otherBlue
		alpha: &otherAlpha];

	if (otherRed != red)
		return false;
	if (otherGreen != green)
		return false;
	if (otherBlue != blue)
		return false;
	if (otherAlpha != alpha)
		return false;

	return true;
}

- (unsigned long)hash
{
	float red, green, blue, alpha;
	unsigned long hash;
	float tmp;

	[self getRed: &red green: &green blue: &blue alpha: &alpha];

	OFHashInit(&hash);

	tmp = OFToLittleEndianFloat(red);
	for (uint_fast8_t i = 0; i < sizeof(float); i++)
		OFHashAddByte(&hash, ((char *)&tmp)[i]);

	tmp = OFToLittleEndianFloat(green);
	for (uint_fast8_t i = 0; i < sizeof(float); i++)
		OFHashAddByte(&hash, ((char *)&tmp)[i]);

	tmp = OFToLittleEndianFloat(blue);
	for (uint_fast8_t i = 0; i < sizeof(float); i++)
		OFHashAddByte(&hash, ((char *)&tmp)[i]);

	tmp = OFToLittleEndianFloat(alpha);




	for (uint_fast8_t i = 0; i < sizeof(float); i++)
		OFHashAddByte(&hash, ((char *)&tmp)[i]);

	OFHashFinalize(&hash);

	return hash;
}

- (void)getRed: (float *)red
	 green: (float *)green
	  blue: (float *)blue
	 alpha: (float *)alpha
{



	OF_UNRECOGNIZED_SELECTOR


}

- (OFString *)description
{
	float red, green, blue, alpha;

	[self getRed: &red green: &green blue: &blue alpha: &alpha];

	return [OFString stringWithFormat:
	    @"<%@ red=%f green=%f blue=%f alpha=%f>",
	    self.class, red, green, blue, alpha];
}
@end

Renamed and modified src/OFAdjacentArray.h [e6ee87088b] to src/OFConcreteArray.h [dabce2fdfc].

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

#import "OFArray.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMutableData;

@interface OFAdjacentArray: OFArray
{
	OFMutableData *_array;
}
@end

OF_ASSUME_NONNULL_END







|






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

#import "OFArray.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMutableData;

@interface OFConcreteArray: OFArray
{
	OFMutableData *_array;
}
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFAdjacentArray.m [6443cda90f] to src/OFConcreteArray.m [5f63cf2e4a].

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 * file.
 */

#include "config.h"

#include <stdarg.h>

#import "OFAdjacentArray.h"
#import "OFAdjacentSubarray.h"
#import "OFData.h"
#import "OFMutableAdjacentArray.h"
#import "OFString.h"

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

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

	@try {
		_array = [[OFMutableData alloc] initWithItemSize: sizeof(id)];
	} @catch (id e) {







|
|
|
|






|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 * file.
 */

#include "config.h"

#include <stdarg.h>

#import "OFConcreteArray.h"
#import "OFConcreteMutableArray.h"
#import "OFConcreteSubarray.h"
#import "OFData.h"
#import "OFString.h"

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

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

	@try {
		_array = [[OFMutableData alloc] initWithItemSize: sizeof(id)];
	} @catch (id e) {
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
		@throw [OFOutOfRangeException exception];

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


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

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

	if (object == self)
		return true;

	if (![object isKindOfClass: [OFAdjacentArray class]] &&
	    ![object isKindOfClass: [OFMutableAdjacentArray class]])
		return [super isEqual: object];

	otherArray = object;

	count = _array.count;

	if (count != otherArray.count)







>
|











|
|







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
		@throw [OFOutOfRangeException exception];

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

	return [[[OFConcreteSubarray alloc] initWithArray: self
						    range: range] autorelease];
}

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

	if (object == self)
		return true;

	if (![object isKindOfClass: [OFConcreteArray class]] &&
	    ![object isKindOfClass: [OFConcreteMutableArray class]])
		return [super isEqual: object];

	otherArray = object;

	count = _array.count;

	if (count != otherArray.count)

Added src/OFConcreteColor.h version [c6e319d32e].





















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
26
/*
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFColor.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFConcreteColor: OFColor
{
	float _red, _green, _blue, _alpha;
}
@end

OF_ASSUME_NONNULL_END

Added src/OFConcreteColor.m version [fac76ba952].





























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
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
/*
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFConcreteColor.h"

#import "OFInvalidArgumentException.h"

@implementation OFConcreteColor
- (instancetype)initWithRed: (float)red
		      green: (float)green
		       blue: (float)blue
		      alpha: (float)alpha
{
	self = [super init];

	@try {
		if (red < 0.0 || red > 1.0 ||
		    green < 0.0 || green > 1.0 ||
		    blue < 0.0 || blue > 1.0 ||
		    alpha < 0.0 || alpha > 1.0)
			@throw [OFInvalidArgumentException exception];

		_red = red;
		_green = green;
		_blue = blue;
		_alpha = alpha;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)getRed: (float *)red
	 green: (float *)green
	  blue: (float *)blue
	 alpha: (float *)alpha
{
	*red = _red;
	*green = _green;
	*blue = _blue;

	if (alpha != NULL)
		*alpha = _alpha;
}
@end

Renamed and modified src/OFCountedMapTableSet.h [05ce680e3e] to src/OFConcreteCountedSet.h [df72e24841].

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

#import "OFCountedSet.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMapTable;

@interface OFCountedMapTableSet: OFCountedSet
{
	OFMapTable *_mapTable;
}
@end

OF_ASSUME_NONNULL_END







|






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

#import "OFCountedSet.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMapTable;

@interface OFConcreteCountedSet: OFCountedSet
{
	OFMapTable *_mapTable;
}
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFCountedMapTableSet.m [7a63d8437b] to src/OFConcreteCountedSet.m [b73b47c42b].

11
12
13
14
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
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFCountedMapTableSet.h"
#import "OFArray.h"
#import "OFMapTable.h"
#import "OFMutableMapTableSet.h"
#import "OFString.h"
#import "OFXMLAttribute.h"

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

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

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

	@try {







|

|
|








|


|
|







11
12
13
14
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
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFConcreteCountedSet.h"
#import "OFArray.h"
#import "OFConcreteMutableSet.h"
#import "OFMapTable.h"
#import "OFString.h"
#import "OFXMLAttribute.h"

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

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

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

	@try {

Added src/OFConcreteData.h version [fc283ba5a6].

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
26
27
28
/*
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFData.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFConcreteData: OFData
{
	unsigned char *_Nullable _items;
	size_t _capacity, _count, _itemSize;
	bool _freeWhenDone;
}
@end

OF_ASSUME_NONNULL_END

Added src/OFConcreteData.m version [2174d3a707].













































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <limits.h>
#include <string.h>

#import "OFConcreteData.h"

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

@implementation OFConcreteData
- (instancetype)init
{
	return [self initWithItemSize: 1];
}

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

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_itemSize = itemSize;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	self = [super init];

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_items = OFAllocMemory(count, itemSize);
		_capacity = _count = count;
		_itemSize = itemSize;
		_freeWhenDone = true;

		memcpy(_items, items, count * itemSize);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	self = [super init];

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_items = (unsigned char *)items;
		_capacity = _count = count;
		_itemSize = itemSize;
		_freeWhenDone = freeWhenDone;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	if (_freeWhenDone)
		OFFreeMemory(_items);

	[super dealloc];
}

- (size_t)count
{
	return _count;
}

- (size_t)itemSize
{
	return _itemSize;
}

- (const void *)items
{
	return _items;
}
@end

Renamed and modified src/OFMapTableDictionary.h [f2de5e0f29] to src/OFConcreteDictionary.h [983e5c5cf8].

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#import "OFDictionary.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMapTable;
@class OFMapTableEnumerator;

@interface OFMapTableDictionary: OFDictionary
{
	OFMapTable *_mapTable;
}

- (instancetype)initWithCapacity: (size_t)capacity;
@end

OF_ASSUME_NONNULL_END







|








16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#import "OFDictionary.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMapTable;
@class OFMapTableEnumerator;

@interface OFConcreteDictionary: OFDictionary
{
	OFMapTable *_mapTable;
}

- (instancetype)initWithCapacity: (size_t)capacity;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFMapTableDictionary.m [7d4c6241d2] to src/OFConcreteDictionary.m [8171774da2].

11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFMapTableDictionary.h"
#import "OFArray.h"

#import "OFMapTable+Private.h"
#import "OFMapTable.h"
#import "OFMutableMapTableDictionary.h"
#import "OFString.h"

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

static void *







|

>


<







11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFConcreteDictionary.h"
#import "OFArray.h"
#import "OFConcreteMutableDictionary.h"
#import "OFMapTable+Private.h"
#import "OFMapTable.h"

#import "OFString.h"

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

static void *
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
static const OFMapTableFunctions objectFunctions = {
	.retain = retain,
	.release = release,
	.hash = hash,
	.equal = equal
};

@implementation OFMapTableDictionary
- (instancetype)init
{
	return [self initWithCapacity: 0];
}

- (instancetype)initWithCapacity: (size_t)capacity
{







|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
static const OFMapTableFunctions objectFunctions = {
	.retain = retain,
	.release = release,
	.hash = hash,
	.equal = equal
};

@implementation OFConcreteDictionary
- (instancetype)init
{
	return [self initWithCapacity: 0];
}

- (instancetype)initWithCapacity: (size_t)capacity
{
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
- (instancetype)initWithDictionary: (OFDictionary *)dictionary
{
	size_t count;

	if (dictionary == nil)
		return [self init];

	if ([dictionary isKindOfClass: [OFMapTableDictionary class]] ||
	    [dictionary isKindOfClass: [OFMutableMapTableDictionary class]]) {
		self = [super init];

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

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








|
|



|
|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
- (instancetype)initWithDictionary: (OFDictionary *)dictionary
{
	size_t count;

	if (dictionary == nil)
		return [self init];

	if ([dictionary isKindOfClass: [OFConcreteDictionary class]] ||
	    [dictionary isKindOfClass: [OFConcreteMutableDictionary class]]) {
		self = [super init];

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

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

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
- (size_t)count
{
	return _mapTable.count;
}

- (bool)isEqual: (id)object
{
	OFMapTableDictionary *dictionary;

	if (object == self)
		return true;

	if (![object isKindOfClass: [OFMapTableDictionary class]] &&
	    ![object isKindOfClass: [OFMutableMapTableDictionary class]])
		return [super isEqual: object];

	dictionary = (OFMapTableDictionary *)object;

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

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







|




|
|


|







244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
- (size_t)count
{
	return _mapTable.count;
}

- (bool)isEqual: (id)object
{
	OFConcreteDictionary *dictionary;

	if (object == self)
		return true;

	if (![object isKindOfClass: [OFConcreteDictionary class]] &&
	    ![object isKindOfClass: [OFConcreteMutableDictionary class]])
		return [super isEqual: object];

	dictionary = (OFConcreteDictionary *)object;

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

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

Renamed and modified src/OFMutableAdjacentArray.h [bd2f97a834] to src/OFConcreteMutableArray.h [46129739e1].

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

#import "OFArray.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMutableData;

@interface OFMutableAdjacentArray: OFMutableArray
{
	OFMutableData *_array;
	unsigned long _mutations;
}
@end

OF_ASSUME_NONNULL_END







|







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

#import "OFArray.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMutableData;

@interface OFConcreteMutableArray: OFMutableArray
{
	OFMutableData *_array;
	unsigned long _mutations;
}
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFMutableAdjacentArray.m [da5d41d53e] to src/OFConcreteMutableArray.m [3bbe83e7a7].

13
14
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
 * file.
 */

#include "config.h"

#include <string.h>

#import "OFMutableAdjacentArray.h"
#import "OFAdjacentArray.h"
#import "OFArray+Private.h"
#import "OFData.h"

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

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

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

	@try {







|
|







|


|
|







13
14
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
 * file.
 */

#include "config.h"

#include <string.h>

#import "OFConcreteMutableArray.h"
#import "OFConcreteArray.h"
#import "OFArray+Private.h"
#import "OFData.h"

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

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

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

	@try {
374
375
376
377
378
379
380
381
382
383
		}
	}
}
#endif

- (void)makeImmutable
{
	object_setClass(self, [OFAdjacentArray class]);
}
@end







|


374
375
376
377
378
379
380
381
382
383
		}
	}
}
#endif

- (void)makeImmutable
{
	object_setClass(self, [OFConcreteArray class]);
}
@end

Added src/OFConcreteMutableData.h version [e000b4c25d].

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
26
27
28
/*
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFMutableData.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFConcreteMutableData: OFMutableData
{
	unsigned char *_Nullable _items;
	size_t _capacity, _count, _itemSize;
	bool _freeWhenDone;
}
@end

OF_ASSUME_NONNULL_END

Added src/OFConcreteMutableData.m version [bfb6cd5ccd].



























































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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
/*
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <limits.h>
#include <string.h>

#import "OFConcreteMutableData.h"
#import "OFConcreteData.h"

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

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

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

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_items = OFAllocMemory(capacity, itemSize);
		_itemSize = itemSize;
		_capacity = capacity;
		_freeWhenDone = true;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	self = [self initWithItems: items count: count itemSize: itemSize];

	if (freeWhenDone)
		OFFreeMemory(items);

	return self;
}

- (void *)mutableItems
{
	return _items;
}

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

	if (_count + 1 > _capacity) {
		_items = OFResizeMemory(_items, _count + 1, _itemSize);
		_capacity = _count + 1;
	}

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

	_count++;
}

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

	if (_count + count > _capacity) {
		_items = OFResizeMemory(_items, _count + count, _itemSize);
		_capacity = _count + count;
	}

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

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

	if (_count + count > _capacity) {
		_items = OFResizeMemory(_items, _count + count, _itemSize);
		_capacity = _count + count;
	}

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

	_count += count;
}

- (void)increaseCountBy: (size_t)count
{
	if (count > SIZE_MAX - _count)
		@throw [OFOutOfRangeException exception];

	if (_count + count > _capacity) {
		_items = OFResizeMemory(_items, _count + count, _itemSize);
		_capacity = _count + count;
	}

	memset(_items + _count * _itemSize, '\0', count * _itemSize);
	_count += count;
}

- (void)removeItemsInRange: (OFRange)range
{
	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > _count)
		@throw [OFOutOfRangeException exception];

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

	_count -= range.length;
	@try {
		_items = OFResizeMemory(_items, _count, _itemSize);
		_capacity = _count;
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
	}
}

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

	_count--;
	@try {
		_items = OFResizeMemory(_items, _count, _itemSize);
		_capacity = _count;
	} @catch (OFOutOfMemoryException *e) {
		/* We don't care, as we only made it smaller */
	}
}

- (void)removeAllItems
{
	OFFreeMemory(_items);
	_items = NULL;
	_count = 0;
	_capacity = 0;
}

- (void)makeImmutable
{
	if (_capacity != _count) {
		@try {
			_items = OFResizeMemory(_items, _count, _itemSize);
			_capacity = _count;
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only made it smaller */
		}
	}

	object_setClass(self, [OFConcreteData class]);
}
@end

Renamed and modified src/OFMutableMapTableDictionary.h [56771d5148] to src/OFConcreteMutableDictionary.h [20db8412b1].

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

#import "OFDictionary.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMapTable;

@interface OFMutableMapTableDictionary: OFMutableDictionary
{
	OFMapTable *_mapTable;
}
@end

OF_ASSUME_NONNULL_END







|






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

#import "OFDictionary.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMapTable;

@interface OFConcreteMutableDictionary: OFMutableDictionary
{
	OFMapTable *_mapTable;
}
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFMutableMapTableDictionary.m [0658abc2dc] to src/OFConcreteMutableDictionary.m [728a3cf89d].

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * file.
 */

#include "config.h"

#include <string.h>

#import "OFMutableMapTableDictionary.h"
#import "OFMapTable.h"
#import "OFMapTableDictionary.h"

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

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

- (void)setObject: (id)object forKey: (id)key
{
	[_mapTable setObject: object forKey: key];
}








|
|
|




|


|
|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * file.
 */

#include "config.h"

#include <string.h>

#import "OFConcreteMutableDictionary.h"
#import "OFConcreteDictionary.h"
#import "OFMapTable.h"

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

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

- (void)setObject: (id)object forKey: (id)key
{
	[_mapTable setObject: object forKey: key];
}

59
60
61
62
63
64
65
66
67
68
		    exceptionWithObject: self];
	}
}
#endif

- (void)makeImmutable
{
	object_setClass(self, [OFMapTableDictionary class]);
}
@end







|


59
60
61
62
63
64
65
66
67
68
		    exceptionWithObject: self];
	}
}
#endif

- (void)makeImmutable
{
	object_setClass(self, [OFConcreteDictionary class]);
}
@end

Renamed and modified src/OFMutableMapTableSet.h [4eae6d1c54] to src/OFConcreteMutableSet.h [e35eb70f3b].

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

#import "OFMutableSet.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMapTable;

@interface OFMutableMapTableSet: OFMutableSet
{
	OFMapTable *_mapTable;
}
@end

OF_ASSUME_NONNULL_END







|






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

#import "OFMutableSet.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMapTable;

@interface OFConcreteMutableSet: OFMutableSet
{
	OFMapTable *_mapTable;
}
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFMutableMapTableSet.m [3dd4e2c006] to src/OFConcreteMutableSet.m [da1e112dc4].

11
12
13
14
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
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFMutableMapTableSet.h"
#import "OFMapTableSet.h"
#import "OFMapTable.h"

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

- (void)addObject: (id)object
{
	[_mapTable setObject: (void *)1 forKey: object];
}

- (void)removeObject: (id)object
{
	[_mapTable removeObjectForKey: object];
}

- (void)removeAllObjects
{
	[_mapTable removeAllObjects];
}

- (void)makeImmutable
{
	object_setClass(self, [OFMapTableSet class]);
}
@end







|
|


|


|
|



















|


11
12
13
14
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
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFConcreteMutableSet.h"
#import "OFConcreteSet.h"
#import "OFMapTable.h"

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

- (void)addObject: (id)object
{
	[_mapTable setObject: (void *)1 forKey: object];
}

- (void)removeObject: (id)object
{
	[_mapTable removeObjectForKey: object];
}

- (void)removeAllObjects
{
	[_mapTable removeAllObjects];
}

- (void)makeImmutable
{
	object_setClass(self, [OFConcreteSet class]);
}
@end

Renamed and modified src/OFMapTableSet.h [98f1d6ac4b] to src/OFConcreteSet.h [87d40dbfde].

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

#import "OFSet.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMapTable;

@interface OFMapTableSet: OFSet
{
	OFMapTable *_mapTable;
}

- (instancetype)initWithCapacity: (size_t)capacity;
@end

OF_ASSUME_NONNULL_END







|








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

#import "OFSet.h"

OF_ASSUME_NONNULL_BEGIN

@class OFMapTable;

@interface OFConcreteSet: OFSet
{
	OFMapTable *_mapTable;
}

- (instancetype)initWithCapacity: (size_t)capacity;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFMapTableSet.m [c087e53711] to src/OFConcreteSet.m [86fb079ff7].

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFMapTableSet.h"
#import "OFArray.h"
#import "OFCountedMapTableSet.h"
#import "OFMapTable.h"
#import "OFMapTable+Private.h"
#import "OFMutableMapTableSet.h"
#import "OFString.h"

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

static void *
retain(void *object)







|

|
|

|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFConcreteSet.h"
#import "OFArray.h"
#import "OFConcreteCountedSet.h"
#import "OFConcreteMutableSet.h"
#import "OFMapTable+Private.h"
#import "OFMapTable.h"
#import "OFString.h"

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

static void *
retain(void *object)
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
	.retain = retain,
	.release = release,
	.hash = hash,
	.equal = equal
};
static const OFMapTableFunctions objectFunctions = { NULL };

@implementation OFMapTableSet
- (instancetype)init
{
	return [self initWithCapacity: 0];
}

- (instancetype)initWithCapacity: (size_t)capacity
{







|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
	.retain = retain,
	.release = release,
	.hash = hash,
	.equal = equal
};
static const OFMapTableFunctions objectFunctions = { NULL };

@implementation OFConcreteSet
- (instancetype)init
{
	return [self initWithCapacity: 0];
}

- (instancetype)initWithCapacity: (size_t)capacity
{
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
		return false;

	return ([_mapTable objectForKey: object] != nil);
}

- (bool)isEqual: (id)object
{
	OFMapTableSet *set;

	if (object == self)
		return true;

	if (![object isKindOfClass: [OFMapTableSet class]] &&
	    ![object isKindOfClass: [OFMutableMapTableSet class]] &&
	    ![object isKindOfClass: [OFCountedMapTableSet class]])
		return [super isEqual: object];

	set = object;

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








|




|
|
|







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
		return false;

	return ([_mapTable objectForKey: object] != nil);
}

- (bool)isEqual: (id)object
{
	OFConcreteSet *set;

	if (object == self)
		return true;

	if (![object isKindOfClass: [OFConcreteSet class]] &&
	    ![object isKindOfClass: [OFConcreteMutableSet class]] &&
	    ![object isKindOfClass: [OFConcreteCountedSet class]])
		return [super isEqual: object];

	set = object;

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

Renamed and modified src/OFAdjacentSubarray.h [abbd5bb00b] to src/OFConcreteSubarray.h [a7f31fb972].

13
14
15
16
17
18
19
20
21
22
23
 * file.
 */

#import "OFSubarray.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFAdjacentSubarray: OFSubarray
@end

OF_ASSUME_NONNULL_END







|



13
14
15
16
17
18
19
20
21
22
23
 * file.
 */

#import "OFSubarray.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFConcreteSubarray: OFSubarray
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFAdjacentSubarray.m [c5bbd0c071] to src/OFConcreteSubarray.m [bef23c745d].

11
12
13
14
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
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFAdjacentSubarray.h"
#import "OFAdjacentArray.h"
#import "OFMutableAdjacentArray.h"

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

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

	if (object == self)
		return true;

	if (![object isKindOfClass: [OFAdjacentArray class]] &&
	    ![object isKindOfClass: [OFMutableAdjacentArray class]])
		return [super isEqual: object];

	otherArray = object;

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








|
|
|

|













|
|







11
12
13
14
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
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFConcreteSubarray.h"
#import "OFConcreteArray.h"
#import "OFConcreteMutableArray.h"

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

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

	if (object == self)
		return true;

	if (![object isKindOfClass: [OFConcreteArray class]] &&
	    ![object isKindOfClass: [OFConcreteMutableArray class]])
		return [super isEqual: object];

	otherArray = object;

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

Modified src/OFCondition.h from [e9f86d3ccf] to [107d4b7019].

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 * @note Waiting might have been interrupted by a signal. It is thus recommended
 *	 to check the condition again after @ref wait returned!
 *
 * @throw OFWaitForConditionFailedException Waiting for the condition failed
 */
- (void)wait;

#ifdef OF_AMIGAOS
/**
 * @brief Blocks the current thread until another thread calls @ref signal,
 *	  @ref broadcast or an Exec Signal is received.
 *
 * @note This is only available on AmigaOS!
 *
 * @param signalMask A pointer to a signal mask of Exec Signals to receive.







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 * @note Waiting might have been interrupted by a signal. It is thus recommended
 *	 to check the condition again after @ref wait returned!
 *
 * @throw OFWaitForConditionFailedException Waiting for the condition failed
 */
- (void)wait;

#if defined(OF_AMIGAOS) || defined(DOXYGEN)
/**
 * @brief Blocks the current thread until another thread calls @ref signal,
 *	  @ref broadcast or an Exec Signal is received.
 *
 * @note This is only available on AmigaOS!
 *
 * @param signalMask A pointer to a signal mask of Exec Signals to receive.
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 *
 * @param timeInterval The time interval until the timeout is reached
 * @return Whether the condition has been signaled
 * @throw OFWaitForConditionFailedException Waiting for the condition failed
 */
- (bool)waitForTimeInterval: (OFTimeInterval)timeInterval;

#ifdef OF_AMIGAOS
/**
 * @brief Blocks the current thread until another thread calls @ref signal,
 *	  @ref broadcast, the timeout is reached or an Exec Signal is received.
 *
 * @note This is only available on AmigaOS!
 *
 * @param timeInterval The time interval until the timeout is reached







|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 *
 * @param timeInterval The time interval until the timeout is reached
 * @return Whether the condition has been signaled
 * @throw OFWaitForConditionFailedException Waiting for the condition failed
 */
- (bool)waitForTimeInterval: (OFTimeInterval)timeInterval;

#if defined(OF_AMIGAOS) || defined(DOXYGEN)
/**
 * @brief Blocks the current thread until another thread calls @ref signal,
 *	  @ref broadcast, the timeout is reached or an Exec Signal is received.
 *
 * @note This is only available on AmigaOS!
 *
 * @param timeInterval The time interval until the timeout is reached
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
 *
 * @param date The date at which the timeout is reached
 * @return Whether the condition has been signaled
 * @throw OFWaitForConditionFailedException Waiting for the condition failed
 */
- (bool)waitUntilDate: (OFDate *)date;

#ifdef OF_AMIGAOS
/**
 * @brief Blocks the current thread until another thread calls @ref signal,
 *	  @ref broadcast, the timeout is reached or an Exec Signal is received.
 *
 * @note This is only available on AmigaOS!
 *
 * @param date The date at which the timeout is reached







|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
 *
 * @param date The date at which the timeout is reached
 * @return Whether the condition has been signaled
 * @throw OFWaitForConditionFailedException Waiting for the condition failed
 */
- (bool)waitUntilDate: (OFDate *)date;

#if defined(OF_AMIGAOS) || defined(DOXYGEN)
/**
 * @brief Blocks the current thread until another thread calls @ref signal,
 *	  @ref broadcast, the timeout is reached or an Exec Signal is received.
 *
 * @note This is only available on AmigaOS!
 *
 * @param date The date at which the timeout is reached

Modified src/OFConstantString.h from [bf7c0894b9] to [7b32d663ec].

9
10
11
12
13
14
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
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#ifndef OBJFW_OF_CONSTANT_STRING_H
#define OBJFW_OF_CONSTANT_STRING_H

#include "OFString.h"

OF_ASSUME_NONNULL_BEGIN

#if !defined(OF_CONSTANT_STRING_M) && \
    defined(OF_APPLE_RUNTIME) && !defined(__OBJC2__)
# ifdef __cplusplus
extern "C" {
# endif
extern void *_OFConstantStringClassReference;
# ifdef __cplusplus
}
# endif
#endif

#ifdef __OBJC__
/**
 * @class OFConstantString OFConstantString.h ObjFW/OFConstantString.h
 *
 * @brief A class for storing constant strings using the `@""` literal.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFConstantString: OFString
{
	char *_cString;
	unsigned int _cStringLength;
}
@end
#endif

OF_ASSUME_NONNULL_END

#endif







<
<
<
|














<












<


<
<
9
10
11
12
13
14
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


 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */




#import "OFString.h"

OF_ASSUME_NONNULL_BEGIN

#if !defined(OF_CONSTANT_STRING_M) && \
    defined(OF_APPLE_RUNTIME) && !defined(__OBJC2__)
# ifdef __cplusplus
extern "C" {
# endif
extern void *_OFConstantStringClassReference;
# ifdef __cplusplus
}
# endif
#endif


/**
 * @class OFConstantString OFConstantString.h ObjFW/OFConstantString.h
 *
 * @brief A class for storing constant strings using the `@""` literal.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFConstantString: OFString
{
	char *_cString;
	unsigned int _cStringLength;
}
@end


OF_ASSUME_NONNULL_END


Modified src/OFConstantString.m from [01f4965770] to [58e75bd4ee].

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 OFConstantUTF8String
+ (instancetype)alloc
{
	OF_UNRECOGNIZED_SELECTOR
}

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (unsigned int)retainCount
{
	return OFMaxRetainCount;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end

@implementation OFConstantString
+ (void)load
{
#if defined(OF_APPLE_RUNTIME) && !defined(__OBJC2__)
	/*







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







48
49
50
51
52
53
54




55


















56
57
58
59
60
61
62

@implementation OFConstantUTF8String
+ (instancetype)alloc
{
	OF_UNRECOGNIZED_SELECTOR
}





OF_SINGLETON_METHODS


















@end

@implementation OFConstantString
+ (void)load
{
#if defined(OF_APPLE_RUNTIME) && !defined(__OBJC2__)
	/*
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
}

+ (instancetype)alloc
{
	OF_UNRECOGNIZED_SELECTOR
}

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (unsigned int)retainCount
{
	return OFMaxRetainCount;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}

/*
 * In all following methods, the constant string is converted to an
 * OFConstantUTF8String and the message sent again.
 */

/* From protocol OFCopying */







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







109
110
111
112
113
114
115




116


















117
118
119
120
121
122
123
}

+ (instancetype)alloc
{
	OF_UNRECOGNIZED_SELECTOR
}





OF_SINGLETON_METHODS



















/*
 * In all following methods, the constant string is converted to an
 * OFConstantUTF8String and the message sent again.
 */

/* From protocol OFCopying */

Modified src/OFCountedSet.m from [2550c38e59] to [3de39a28c5].

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
 */

#include "config.h"

#include <stdlib.h>

#import "OFCountedSet.h"
#import "OFCountedMapTableSet.h"
#import "OFNumber.h"
#import "OFString.h"

static struct {
	Class isa;
} placeholder;

@interface OFCountedSetPlaceholder: OFCountedSet
@end

@implementation OFCountedSetPlaceholder
- (instancetype)init
{
	return (id)[[OFCountedMapTableSet alloc] init];
}

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

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

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

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

	return ret;
}

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

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

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end

@implementation OFCountedSet
+ (void)initialize
{
	if (self == [OFCountedSet class])
		placeholder.isa = [OFCountedSetPlaceholder class];

}

+ (instancetype)alloc
{
	if (self == [OFCountedSet class])
		return (id)&placeholder;

	return [super alloc];
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFCountedSet class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
		} @catch (id e) {
			[self release];
			@throw e;
		}

		abort();
	}

	return [super init];
}

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

- (OFString *)description
{







|







|


|


|




|




|








|








|





|



<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<






|
>










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72




73













74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
















92
93
94
95
96
97
98
 */

#include "config.h"

#include <stdlib.h>

#import "OFCountedSet.h"
#import "OFConcreteCountedSet.h"
#import "OFNumber.h"
#import "OFString.h"

static struct {
	Class isa;
} placeholder;

@interface OFPlaceholderCountedSet: OFCountedSet
@end

@implementation OFPlaceholderCountedSet
- (instancetype)init
{
	return (id)[[OFConcreteCountedSet alloc] init];
}

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

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

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

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

	return ret;
}

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

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





OF_SINGLETON_METHODS













@end

@implementation OFCountedSet
+ (void)initialize
{
	if (self == [OFCountedSet class])
		object_setClass((id)&placeholder,
		    [OFPlaceholderCountedSet class]);
}

+ (instancetype)alloc
{
	if (self == [OFCountedSet class])
		return (id)&placeholder;

	return [super alloc];
}

















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

- (OFString *)description
{

Modified src/OFDNSResolverSettings.m from [179fc83ef4] to [9b675f9c8d].

18
19
20
21
22
23
24

25


26
27
28
29
30
31
32
#include "unistd_wrapper.h"

#import "OFDNSResolverSettings.h"
#import "OFArray.h"
#import "OFCharacterSet.h"
#import "OFDate.h"
#import "OFDictionary.h"

#import "OFFile.h"


#import "OFLocale.h"
#import "OFSocket+Private.h"
#import "OFString.h"
#ifdef OF_WINDOWS
# import "OFWindowsRegistryKey.h"
#endif








>
|
>
>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "unistd_wrapper.h"

#import "OFDNSResolverSettings.h"
#import "OFArray.h"
#import "OFCharacterSet.h"
#import "OFDate.h"
#import "OFDictionary.h"
#ifdef OF_HAVE_FILES
# import "OFFile.h"
# import "OFFileManager.h"
#endif
#import "OFLocale.h"
#import "OFSocket+Private.h"
#import "OFString.h"
#ifdef OF_WINDOWS
# import "OFWindowsRegistryKey.h"
#endif

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
#ifdef OF_NINTENDO_3DS
/* Newer versions of libctru started using id as a parameter name. */
# define id id_3ds
# include <3ds.h>
# undef id
#endif






#ifdef OF_MORPHOS
# include <proto/rexxsyslib.h>
# include <rexx/errors.h>
# include <rexx/storage.h>
#endif

#if defined(OF_HAIKU)
# define HOSTS_PATH @"/system/settings/network/hosts"
# define RESOLV_CONF_PATH @"/system/settings/network/resolv.conf"
#elif defined(OF_AMIGAOS4)
# define HOSTS_PATH @"DEVS:Internet/hosts"
#elif defined(OF_AMIGAOS)
# define HOSTS_PATH @"AmiTCP:db/hosts"
# define RESOLV_CONF_PATH @"AmiTCP:db/resolv.conf"
#else
# define HOSTS_PATH @"/etc/hosts"
# define RESOLV_CONF_PATH @"/etc/resolv.conf"
#endif

#ifndef HOST_NAME_MAX
# define HOST_NAME_MAX 255







>
>
>
>
>









<
<
<
<
<







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
#ifdef OF_NINTENDO_3DS
/* Newer versions of libctru started using id as a parameter name. */
# define id id_3ds
# include <3ds.h>
# undef id
#endif

#if defined(OF_AMIGAOS_M68K) || defined(OF_AMIGAOS4)
# define Class IntuitionClass
# include <proto/dos.h>
# undef Class
#endif
#ifdef OF_MORPHOS
# include <proto/rexxsyslib.h>
# include <rexx/errors.h>
# include <rexx/storage.h>
#endif

#if defined(OF_HAIKU)
# define HOSTS_PATH @"/system/settings/network/hosts"
# define RESOLV_CONF_PATH @"/system/settings/network/resolv.conf"





#else
# define HOSTS_PATH @"/etc/hosts"
# define RESOLV_CONF_PATH @"/etc/resolv.conf"
#endif

#ifndef HOST_NAME_MAX
# define HOST_NAME_MAX 255
115
116
117
118
119
120
121











122
123
124
125
126
127
128
	if (gethostname(hostname, HOST_NAME_MAX + 1) != 0)
		return nil;

	return [OFString stringWithCString: hostname
				  encoding: [OFLocale encoding]];
}
#endif












#ifdef OF_MORPHOS
static OFString *
arexxCommand(const char *port, const char *command)
{
	struct Library *RexxSysBase;
	struct MsgPort *replyPort = NULL;







>
>
>
>
>
>
>
>
>
>
>







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
	if (gethostname(hostname, HOST_NAME_MAX + 1) != 0)
		return nil;

	return [OFString stringWithCString: hostname
				  encoding: [OFLocale encoding]];
}
#endif

#ifdef OF_AMIGAOS_M68K
static bool
assignExists(const char *assign)
{
	struct DosList *list = LockDosList(LDF_ASSIGNS | LDF_READ);
	bool found = (FindDosEntry(list, assign, LDF_ASSIGNS) != NULL);
	UnLockDosList(LDF_ASSIGNS | LDF_READ);
	return found;
}
#endif

#ifdef OF_MORPHOS
static OFString *
arexxCommand(const char *port, const char *command)
{
	struct Library *RexxSysBase;
	struct MsgPort *replyPort = NULL;
255
256
257
258
259
260
261


262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

#if defined(OF_HAVE_FILES) && !defined(OF_MORPHOS) && !defined(OF_NINTENDO_3DS)
- (void)parseHosts: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFCharacterSet *whitespaceCharacterSet =
	    [OFCharacterSet whitespaceCharacterSet];


	OFMutableDictionary *staticHosts;
	OFFile *file;
	OFString *line;

	@try {
		file = [OFFile fileWithPath: path mode: @"r"];
	} @catch (OFOpenItemFailedException *e) {
		objc_autoreleasePoolPop(pool);
		return;
	}

	staticHosts = [OFMutableDictionary dictionary];

	while ((line =
	    [file readLineWithEncoding: [OFLocale encoding]]) != nil) {
		OFArray *components, *hosts;
		size_t pos;
		OFString *address;

		pos = [line rangeOfString: @"#"].location;
		if (pos != OFNotFound)
			line = [line substringToIndex: pos];

		components = [line
		    componentsSeparatedByCharactersInSet: whitespaceCharacterSet
		    options: OFStringSkipEmptyComponents];








>
>



















|







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

#if defined(OF_HAVE_FILES) && !defined(OF_MORPHOS) && !defined(OF_NINTENDO_3DS)
- (void)parseHosts: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFCharacterSet *whitespaceCharacterSet =
	    [OFCharacterSet whitespaceCharacterSet];
	OFCharacterSet *commentCharacters =
	    [OFCharacterSet characterSetWithCharactersInString: @"#;"];
	OFMutableDictionary *staticHosts;
	OFFile *file;
	OFString *line;

	@try {
		file = [OFFile fileWithPath: path mode: @"r"];
	} @catch (OFOpenItemFailedException *e) {
		objc_autoreleasePoolPop(pool);
		return;
	}

	staticHosts = [OFMutableDictionary dictionary];

	while ((line =
	    [file readLineWithEncoding: [OFLocale encoding]]) != nil) {
		OFArray *components, *hosts;
		size_t pos;
		OFString *address;

		pos = [line indexOfCharacterFromSet: commentCharacters];
		if (pos != OFNotFound)
			line = [line substringToIndex: pos];

		components = [line
		    componentsSeparatedByCharactersInSet: whitespaceCharacterSet
		    options: OFStringSkipEmptyComponents];

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

	[staticHosts makeImmutable];
	_staticHosts = [staticHosts copy];

	objc_autoreleasePoolPop(pool);
}

# if !defined(OF_WINDOWS) && !defined(OF_AMIGAOS4)
- (void)parseResolvConfOption: (OFString *)option
{
	@try {
		if ([option hasPrefix: @"ndots:"]) {
			unsigned long long number;

			option = [option substringFromIndex: 6];







|







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

	[staticHosts makeImmutable];
	_staticHosts = [staticHosts copy];

	objc_autoreleasePoolPop(pool);
}

# ifndef OF_WINDOWS
- (void)parseResolvConfOption: (OFString *)option
{
	@try {
		if ([option hasPrefix: @"ndots:"]) {
			unsigned long long number;

			option = [option substringFromIndex: 6];
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
		    options: OFStringSkipEmptyComponents];

		if (components.count < 2) {
			objc_autoreleasePoolPop(pool2);
			continue;
		}

		option = components.firstObject;
		arguments = [components objectsInRange:
		    OFMakeRange(1, components.count - 1)];

		if ([option isEqual: @"nameserver"]) {
			if (arguments.count != 1) {
				objc_autoreleasePoolPop(pool2);
				continue;







|







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
		    options: OFStringSkipEmptyComponents];

		if (components.count < 2) {
			objc_autoreleasePoolPop(pool2);
			continue;
		}

		option = [components.firstObject lowercaseString];
		arguments = [components objectsInRange:
		    OFMakeRange(1, components.count - 1)];

		if ([option isEqual: @"nameserver"]) {
			if (arguments.count != 1) {
				objc_autoreleasePoolPop(pool2);
				continue;
523
524
525
526
527
528
529
530
531
532
533
534
535
536









537
538
539
540
541
542
543
	[staticHosts makeImmutable];
	_staticHosts = [staticHosts copy];

	objc_autoreleasePoolPop(pool);
}
#endif

#ifdef OF_AMIGAOS4
- (void)obtainAmigaOS4SystemConfig
{
	OFMutableArray *nameServers = [OFMutableArray array];
	OFStringEncoding encoding = [OFLocale encoding];
	struct List *nameServerList = ObtainDomainNameServerList();
	char buffer[MAXHOSTNAMELEN];










	if (nameServerList == NULL)
		@throw [OFOutOfMemoryException exception];

	@try {
		struct DomainNameServerNode *iter =
		    (struct DomainNameServerNode *)&nameServerList->lh_Head;







|
|

|
|
|

>
>
>
>
>
>
>
>
>







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
	[staticHosts makeImmutable];
	_staticHosts = [staticHosts copy];

	objc_autoreleasePoolPop(pool);
}
#endif

#if defined(OF_AMIGAOS_M68K) || defined(OF_AMIGAOS4)
- (bool)obtainRoadshowSystemConfig
{
	OFMutableArray *nameServers;
	OFStringEncoding encoding;
	struct List *nameServerList;
	char buffer[MAXHOSTNAMELEN];
	LONG hasDNSAPI;

	if (SocketBaseTags(SBTM_GETREF(SBTC_HAVE_DNS_API), (ULONG)&hasDNSAPI,
	    TAG_END) != 0 || !hasDNSAPI)
		return false;

	nameServers = [OFMutableArray array];
	encoding = [OFLocale encoding];
	nameServerList = ObtainDomainNameServerList();

	if (nameServerList == NULL)
		@throw [OFOutOfMemoryException exception];

	@try {
		struct DomainNameServerNode *iter =
		    (struct DomainNameServerNode *)&nameServerList->lh_Head;
563
564
565
566
567
568
569


570
571
572
573
574
575
576
		[nameServers makeImmutable];
		_nameServers = [nameServers copy];
	}

	if (GetDefaultDomainName(buffer, sizeof(buffer)))
		_localDomain = [[OFString alloc] initWithCString: buffer
							encoding: encoding];


}
#endif

#ifdef OF_NINTENDO_3DS
- (void)obtainNintendo3DSSytemConfig
{
	OFMutableArray *nameServers = [OFMutableArray array];







>
>







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
		[nameServers makeImmutable];
		_nameServers = [nameServers copy];
	}

	if (GetDefaultDomainName(buffer, sizeof(buffer)))
		_localDomain = [[OFString alloc] initWithCString: buffer
							encoding: encoding];

	return true;
}
#endif

#ifdef OF_NINTENDO_3DS
- (void)obtainNintendo3DSSytemConfig
{
	OFMutableArray *nameServers = [OFMutableArray array];
614
615
616
617
618
619
620



621
622
623
624
625
626
627
#endif

- (void)reload
{
#ifdef OF_WINDOWS
	OFString *path = nil;
#endif



	void *pool;

	/*
	 * TODO: Rather than reparsing every time, check what actually changed
	 *	 (mtime) and only reset those.
	 */








>
>
>







641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
#endif

- (void)reload
{
#ifdef OF_WINDOWS
	OFString *path = nil;
#endif
#if (defined(OF_AMIGAOS_M68K) || defined(OF_AMIGAOS4)) && defined(OF_HAVE_FILES)
	OFFileManager *fileManager = [OFFileManager defaultManager];
#endif
	void *pool;

	/*
	 * TODO: Rather than reparsing every time, check what actually changed
	 *	 (mtime) and only reset those.
	 */

655
656
657
658
659
660
661
662














663

664

665
666
667
668
669
670
671
	if (path != nil)
		[self parseHosts: path];
# endif

	[self obtainWindowsSystemConfig];
#elif defined(OF_MORPHOS)
	[self obtainMorphOSSystemConfig];
#elif defined(OF_AMIGAOS4)














	[self parseHosts: HOSTS_PATH];

	[self obtainAmigaOS4SystemConfig];

#elif defined(OF_NINTENDO_3DS)
	[self obtainNintendo3DSSytemConfig];
#elif defined(OF_HAVE_FILES)
	[self parseHosts: HOSTS_PATH];
	[self parseResolvConf: RESOLV_CONF_PATH];
#endif








|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>







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
	if (path != nil)
		[self parseHosts: path];
# endif

	[self obtainWindowsSystemConfig];
#elif defined(OF_MORPHOS)
	[self obtainMorphOSSystemConfig];
#elif defined(OF_AMIGAOS_M68K) || defined(OF_AMIGAOS4)
# ifdef OF_HAVE_FILES
	if (![self obtainRoadshowSystemConfig]) {
		if (assignExists("AmiTCP"))
			/*
			 * FIXME: The installer puts it there, but theoretically
			 *	  it could also be in AmiTCP:db/netdb or any of
			 *	  the files included there.
			 */
			[self parseResolvConf: @"AmiTCP:db/netdb-myhost"];
	}

	if ([fileManager fileExistsAtPath: @"DEVS:Internet/hosts"])
		[self parseHosts: @"DEVS:Internet/hosts"];
	else if (assignExists("AmiTCP"))
		[self parseHosts: @"AmiTCP:db/hosts"];
# else
	[self obtainRoadshowSystemConfig];
# endif
#elif defined(OF_NINTENDO_3DS)
	[self obtainNintendo3DSSytemConfig];
#elif defined(OF_HAVE_FILES)
	[self parseHosts: HOSTS_PATH];
	[self parseResolvConf: RESOLV_CONF_PATH];
#endif

Modified src/OFData+CryptographicHashing.m from [d27651b9f8] to [7ae571e356].

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
	void *pool = objc_autoreleasePoolPush();
	id <OFCryptographicHash> hash =
	    [class hashWithAllowsSwappableMemory: true];
	size_t digestSize = [class digestSize];
	const unsigned char *digest;
	char cString[digestSize * 2];

	[hash updateWithBuffer: self->_items
			length: self->_count * self->_itemSize];
	[hash calculate];
	digest = hash.digest;

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

		high = digest[i] >> 4;







|
|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
	void *pool = objc_autoreleasePoolPush();
	id <OFCryptographicHash> hash =
	    [class hashWithAllowsSwappableMemory: true];
	size_t digestSize = [class digestSize];
	const unsigned char *digest;
	char cString[digestSize * 2];

	[hash updateWithBuffer: self.items
			length: self.count * self.itemSize];
	[hash calculate];
	digest = hash.digest;

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

		high = digest[i] >> 4;

Modified src/OFData.h from [c6b9b129b7] to [3b565bfb8e].

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * @class OFData OFData.h ObjFW/OFData.h
 *
 * @brief A class for storing arbitrary data in an array.
 */
@interface OFData: OFObject <OFCopying, OFMutableCopying, OFComparing,
    OFMessagePackRepresentation>
{
	unsigned char *_Nullable _items;
	size_t _count, _itemSize;
	bool _freeWhenDone;
@private
	OFData *_Nullable _parentData;
	OF_RESERVE_IVARS(OFData, 4)
}

/**
 * @brief The size of a single item in the OFData in bytes.
 */
@property (readonly, nonatomic) size_t itemSize;

/**
 * @brief The number of items in the OFData.







<
<
<
<
<
<
<
<
<







36
37
38
39
40
41
42









43
44
45
46
47
48
49
/**
 * @class OFData OFData.h ObjFW/OFData.h
 *
 * @brief A class for storing arbitrary data in an array.
 */
@interface OFData: OFObject <OFCopying, OFMutableCopying, OFComparing,
    OFMessagePackRepresentation>









/**
 * @brief The size of a single item in the OFData in bytes.
 */
@property (readonly, nonatomic) size_t itemSize;

/**
 * @brief The number of items in the OFData.
88
89
90
91
92
93
94















95
96
97
98
99
100
101
@property (readonly, nonatomic) OFString *stringRepresentation;

/**
 * @brief A string containing the data in Base64 encoding.
 */
@property (readonly, nonatomic) OFString *stringByBase64Encoding;
















/**
 * @brief Creates a new OFData with the specified `count` items of size 1.
 *
 * @param items The items to store in the OFData
 * @param count The number of items
 * @return A new autoreleased OFData
 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
@property (readonly, nonatomic) OFString *stringRepresentation;

/**
 * @brief A string containing the data in Base64 encoding.
 */
@property (readonly, nonatomic) OFString *stringByBase64Encoding;

/**
 * @brief Creates a new OFData that is empty with an item size of 1.
 *
 * @return A new autoreleased OFData
 */
+ (instancetype)data;

/**
 * @brief Creates a new OFData that is empty with the specified item size.
 *
 * @param itemSize The size of a single element in the OFData
 * @return A new autoreleased OFData
 */
+ (instancetype)dataWithItemSize: (size_t)itemSize;

/**
 * @brief Creates a new OFData with the specified `count` items of size 1.
 *
 * @param items The items to store in the OFData
 * @param count The number of items
 * @return A new autoreleased OFData
 */
188
189
190
191
192
193
194

















195
196
197
198
199
200
201
 * @param string The string with the Base64-encoded data
 * @return A new autoreleased OFData
 * @throw OFInvalidFormatException The specified string is not correctly
 *				   formatted
 */
+ (instancetype)dataWithBase64EncodedString: (OFString *)string;


















/**
 * @brief Initializes an already allocated OFData with the specified `count`
 *	  items of size 1.
 *
 * @param items The items to store in the OFData
 * @param count The number of items
 * @return An initialized OFData







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
 * @param string The string with the Base64-encoded data
 * @return A new autoreleased OFData
 * @throw OFInvalidFormatException The specified string is not correctly
 *				   formatted
 */
+ (instancetype)dataWithBase64EncodedString: (OFString *)string;

/**
 * @brief Initializes an already allocated OFData to be empty with an item size
 *	  of 1.
 *
 * @return An initialized OFData
 */
- (instancetype)init;

/**
 * @brief Initializes an already allocated OFData to be empty with the
 *	  specified item size.
 *
 * @param itemSize The size of a single element in the OFData
 * @return An initialized OFData
 */
- (instancetype)initWithItemSize: (size_t)itemSize;

/**
 * @brief Initializes an already allocated OFData with the specified `count`
 *	  items of size 1.
 *
 * @param items The items to store in the OFData
 * @param count The number of items
 * @return An initialized OFData

Modified src/OFData.m from [fedaecf95c] to [6b96716473].

17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42







43
44
45
46
47
48
49
50







































































51





52

















53
54
55
56
57
58
59

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

#import "OFData.h"
#import "OFBase64.h"

#import "OFDictionary.h"
#ifdef OF_HAVE_FILES
# import "OFFile.h"
# import "OFFileManager.h"
#endif
#import "OFIRI.h"
#import "OFIRIHandler.h"
#import "OFStream.h"
#import "OFString.h"

#import "OFSystemInfo.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
#import "OFTruncatedDataException.h"
#import "OFUnsupportedProtocolException.h"








/* References for static linking */
void
_references_to_categories_of_OFData(void)
{
	_OFData_CryptographicHashing_reference = 1;
	_OFData_MessagePackParsing_reference = 1;
}








































































@implementation OFData





@synthesize itemSize = _itemSize;


















+ (instancetype)dataWithItems: (const void *)items count: (size_t)count
{
	return [[[self alloc] initWithItems: items count: count] autorelease];
}

+ (instancetype)dataWithItems: (const void *)items







>









>










>
>
>
>
>
>
>








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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

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

#import "OFData.h"
#import "OFBase64.h"
#import "OFConcreteData.h"
#import "OFDictionary.h"
#ifdef OF_HAVE_FILES
# import "OFFile.h"
# import "OFFileManager.h"
#endif
#import "OFIRI.h"
#import "OFIRIHandler.h"
#import "OFStream.h"
#import "OFString.h"
#import "OFSubdata.h"
#import "OFSystemInfo.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
#import "OFTruncatedDataException.h"
#import "OFUnsupportedProtocolException.h"

static struct {
	Class isa;
} placeholder;

@interface OFPlaceholderData: OFString
@end

/* References for static linking */
void
_references_to_categories_of_OFData(void)
{
	_OFData_CryptographicHashing_reference = 1;
	_OFData_MessagePackParsing_reference = 1;
}

@implementation OFPlaceholderData
- (instancetype)init
{
	return (id)[[OFConcreteData alloc] init];
}

- (instancetype)initWithItemSize: (size_t)itemSize
{
	return (id)[[OFConcreteData alloc] initWithItemSize: itemSize];
}

- (instancetype)initWithItems: (const void *)items count: (size_t)count
{
	return (id)[[OFConcreteData alloc] initWithItems: items count: count];
}

- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	return (id)[[OFConcreteData alloc] initWithItems: items
						   count: count
						itemSize: itemSize];
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	return (id)[[OFConcreteData alloc] initWithItemsNoCopy: items
							 count: count
						  freeWhenDone: freeWhenDone];
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	return (id)[[OFConcreteData alloc] initWithItemsNoCopy: items
							 count: count
						      itemSize: itemSize
						  freeWhenDone: freeWhenDone];
}

#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path
{
	return (id)[[OFConcreteData alloc] initWithContentsOfFile: path];
}
#endif

- (instancetype)initWithContentsOfIRI: (OFIRI *)IRI
{
	return (id)[[OFConcreteData alloc] initWithContentsOfIRI: IRI];
}

- (instancetype)initWithStringRepresentation: (OFString *)string
{
	return (id)[[OFConcreteData alloc]
	    initWithStringRepresentation: string];
}

- (instancetype)initWithBase64EncodedString: (OFString *)string
{
	return (id)[[OFConcreteData alloc] initWithBase64EncodedString: string];
}

OF_SINGLETON_METHODS
@end

@implementation OFData
+ (void)initialize
{
	if (self == [OFData class])
		object_setClass((id)&placeholder, [OFPlaceholderData class]);
}

+ (instancetype)alloc
{
	if (self == [OFData class])
		return (id)&placeholder;

	return [super alloc];
}

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

+ (instancetype)dataWithItemSize: (size_t)itemSize
{
	return [[[self alloc] initWithItemSize: itemSize] autorelease];
}

+ (instancetype)dataWithItems: (const void *)items count: (size_t)count
{
	return [[[self alloc] initWithItems: items count: count] autorelease];
}

+ (instancetype)dataWithItems: (const void *)items
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
	    initWithStringRepresentation: string] autorelease];
}

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























- (instancetype)initWithItems: (const void *)items count: (size_t)count
{
	return [self initWithItems: items count: count itemSize: 1];
}

- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	self = [super init];

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_items = OFAllocMemory(count, itemSize);
		_count = count;
		_itemSize = itemSize;
		_freeWhenDone = true;

		memcpy(_items, items, count * itemSize);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	return [self initWithItemsNoCopy: items
				   count: count
				itemSize: 1
			    freeWhenDone: freeWhenDone];
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	self = [super init];

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_items = (unsigned char *)items;
		_count = count;
		_itemSize = itemSize;
		_freeWhenDone = freeWhenDone;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path
{
	char *buffer = NULL;
	OFStreamOffset fileSize;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
	    initWithStringRepresentation: string] autorelease];
}

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

- (instancetype)init
{
	if ([self isMemberOfClass: [OFData class]] ||
	    [self isMemberOfClass: [OFMutableData class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
		} @catch (id e) {
			[self release];
			@throw e;
		}

		abort();
	}

	return [super init];
}

- (instancetype)initWithItemSize: (size_t)itemSize
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithItems: (const void *)items count: (size_t)count
{
	return [self initWithItems: items count: count itemSize: 1];
}

- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize
{

	OF_INVALID_INIT_METHOD
















}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	return [self initWithItemsNoCopy: items
				   count: count
				itemSize: 1
			    freeWhenDone: freeWhenDone];
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{

	OF_INVALID_INIT_METHOD














}

#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path
{
	char *buffer = NULL;
	OFStreamOffset fileSize;
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

	return self;
}
#endif

- (instancetype)initWithContentsOfIRI: (OFIRI *)IRI
{

	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFStream *stream = [OFIRIHandler openItemAtIRI: IRI mode: @"r"];
		size_t pageSize;
		unsigned char *buffer;

		_count = 0;
		_itemSize = 1;
		_freeWhenDone = true;

		pageSize = [OFSystemInfo pageSize];
		buffer = OFAllocMemory(1, pageSize);

		@try {
			while (!stream.atEndOfStream) {
				size_t length = [stream
				    readIntoBuffer: buffer
					    length: pageSize];

				if (SIZE_MAX - _count < length)
					@throw [OFOutOfRangeException
					    exception];

				_items = OFResizeMemory(_items,
				    _count + length, 1);
				memcpy(_items + _count, buffer, length);
				_count += length;
			}
		} @finally {
			OFFreeMemory(buffer);
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {


		[self release];










		@throw e;
	}

	return self;
}

- (instancetype)initWithStringRepresentation: (OFString *)string
{

	self = [super init];

	@try {


		size_t count = [string
		    cStringLengthWithEncoding: OFStringEncodingASCII];
		const char *cString;

		if (count % 2 != 0)
			@throw [OFInvalidFormatException exception];

		count /= 2;

		_items = OFAllocMemory(count, 1);
		_count = count;
		_itemSize = 1;
		_freeWhenDone = true;

		cString = [string cStringWithEncoding: OFStringEncodingASCII];

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







>
|





<

<
<
<
<



<
|
|
<
|

|
|
<

|
<
|
|
<
<
<




>
>

>
>
>
>
>
>
>
>
>
>








>
|


>
>
|

<





<
|
<
<
<







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

	return self;
}
#endif

- (instancetype)initWithContentsOfIRI: (OFIRI *)IRI
{
	char *items = NULL, *buffer = NULL;
	size_t count = 0;

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFStream *stream = [OFIRIHandler openItemAtIRI: IRI mode: @"r"];
		size_t pageSize;






		pageSize = [OFSystemInfo pageSize];
		buffer = OFAllocMemory(1, pageSize);


		while (!stream.atEndOfStream) {
			size_t length = [stream readIntoBuffer: buffer

							length: pageSize];

			if (SIZE_MAX - count < length)
				@throw [OFOutOfRangeException exception];


			items = OFResizeMemory(items, count + length, 1);

			memcpy(items + count, buffer, length);
			count += length;



		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		OFFreeMemory(buffer);
		OFFreeMemory(items);
		[self release];

		@throw e;
	}

	@try {
		self = [self initWithItemsNoCopy: items
					   count: count
				    freeWhenDone: true];
	} @catch (id e) {
		OFFreeMemory(items);
		@throw e;
	}

	return self;
}

- (instancetype)initWithStringRepresentation: (OFString *)string
{
	char *items = NULL;
	size_t count = 0;

	@try {
		const char *cString;

		count = [string
		    cStringLengthWithEncoding: OFStringEncodingASCII];


		if (count % 2 != 0)
			@throw [OFInvalidFormatException exception];

		count /= 2;

		items = OFAllocMemory(count, 1);




		cString = [string cStringWithEncoding: OFStringEncodingASCII];

		for (size_t i = 0; i < count; i++) {
			uint8_t c1 = cString[2 * i];
			uint8_t c2 = cString[2 * i + 1];
			uint8_t byte;
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
			else if (c2 >= 'a' && c2 <= 'f')
				byte |= c2 - 'a' + 10;
			else if (c2 >= 'A' && c2 <= 'F')
				byte |= c2 - 'A' + 10;
			else
				@throw [OFInvalidFormatException exception];

			_items[i] = byte;
		}
	} @catch (id e) {

		[self release];










		@throw e;
	}

	return self;
}

- (instancetype)initWithBase64EncodedString: (OFString *)string
{
	bool mutable = [self isKindOfClass: [OFMutableData class]];

	if (!mutable) {
		[self release];
		self = [OFMutableData alloc];
	}

	self = [(OFMutableData *)self initWithCapacity: string.length / 3];

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








	if (!mutable)





		[(OFMutableData *)self makeImmutable];









	return self;
}


- (void)dealloc

{
	if (_freeWhenDone)
		OFFreeMemory(_items);

	[_parentData release];


	[super dealloc];

}

- (size_t)count
{
	return _count;

}

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

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

	return _items + idx * _itemSize;
}

- (const void *)firstItem
{


	if (_items == NULL || _count == 0)
		return NULL;

	return _items;
}

- (const void *)lastItem
{



	if (_items == NULL || _count == 0)
		return NULL;

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

- (id)copy
{
	return [self retain];
}

- (id)mutableCopy
{
	return [[OFMutableData alloc] initWithItems: _items
					      count: _count
					   itemSize: _itemSize];
}

- (bool)isEqual: (id)object
{

	OFData *data;

	if (object == self)
		return true;

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



	data = object;

	if (data.count != _count || data.itemSize != _itemSize)
		return false;
	if (memcmp(data.items, _items, _count * _itemSize) != 0)
		return false;

	return true;
}

- (OFComparisonResult)compare: (OFData *)data
{
	int comparison;
	size_t count, minCount;

	if (![data isKindOfClass: [OFData class]])
		@throw [OFInvalidArgumentException exception];

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


	count = data.count;
	minCount = (_count > count ? count : _count);

	if ((comparison = memcmp(_items, data.items,
	    minCount * _itemSize)) == 0) {
		if (_count > count)
			return OFOrderedDescending;
		if (_count < count)
			return OFOrderedAscending;

		return OFOrderedSame;
	}

	if (comparison > 0)
		return OFOrderedDescending;
	else
		return OFOrderedAscending;
}

- (unsigned long)hash
{


	unsigned long hash;

	OFHashInit(&hash);

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

	OFHashFinalize(&hash);

	return hash;
}

- (OFData *)subdataWithRange: (OFRange)range
{
	OFData *ret;

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

	ret = [OFData dataWithItemsNoCopy: _items + (range.location * _itemSize)


				    count: range.length
				 itemSize: _itemSize
			     freeWhenDone: false];
	ret->_parentData = [(_parentData != nil ? _parentData : self) copy];

	return ret;



}

- (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
{
	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
{
	return OFBase64Encode(_items, _count * _itemSize);
}

- (OFRange)rangeOfData: (OFData *)data
	       options: (OFDataSearchOptions)options
		 range: (OFRange)range
{


	const char *search;
	size_t searchLength;

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

	if (data == nil || data.itemSize != _itemSize)
		@throw [OFInvalidArgumentException exception];

	if ((searchLength = data.count) == 0)
		return OFMakeRange(0, 0);

	if (searchLength > range.length)
		return OFMakeRange(OFNotFound, 0);

	search = data.items;

	if (options & OFDataSearchBackwards) {
		for (size_t i = range.length - searchLength;; i--) {
			if (memcmp(_items + i * _itemSize, search,
			    searchLength * _itemSize) == 0)
				return OFMakeRange(i, searchLength);

			/* No match and we're at the last item */
			if (i == 0)
				break;
		}
	} else {
		for (size_t i = range.location;
		    i <= range.length - searchLength; i++)
			if (memcmp(_items + i * _itemSize, search,
			    searchLength * _itemSize) == 0)
				return OFMakeRange(i, searchLength);
	}

	return OFMakeRange(OFNotFound, 0);
}

#ifdef OF_HAVE_FILES
- (void)writeToFile: (OFString *)path
{
	OFFile *file = [[OFFile alloc] initWithPath: path mode: @"w"];
	@try {
		[file writeBuffer: _items length: _count * _itemSize];

	} @finally {
		[file release];
	}
}
#endif

- (void)writeToIRI: (OFIRI *)IRI
{
	void *pool = objc_autoreleasePoolPush();

	[[OFIRIHandler openItemAtIRI: IRI mode: @"w"] writeData: self];

	objc_autoreleasePoolPop(pool);
}

- (OFData *)messagePackRepresentation
{
	OFMutableData *data;


	if (_itemSize != 1)
		@throw [OFNotImplementedException exceptionWithSelector: _cmd
								 object: self];



	if (_count <= UINT8_MAX) {
		uint8_t type = 0xC4;
		uint8_t tmp = (uint8_t)_count;

		data = [OFMutableData dataWithCapacity: _count + 2];
		[data addItem: &type];
		[data addItem: &tmp];
	} else if (_count <= UINT16_MAX) {
		uint8_t type = 0xC5;
		uint16_t tmp = OFToBigEndian16((uint16_t)_count);

		data = [OFMutableData dataWithCapacity: _count + 3];
		[data addItem: &type];
		[data addItems: &tmp count: sizeof(tmp)];
	} else if (_count <= UINT32_MAX) {
		uint8_t type = 0xC6;
		uint32_t tmp = OFToBigEndian32((uint32_t)_count);

		data = [OFMutableData dataWithCapacity: _count + 5];
		[data addItem: &type];
		[data addItems: &tmp count: sizeof(tmp)];
	} else
		@throw [OFOutOfRangeException exception];

	[data addItems: _items count: _count];
	[data makeImmutable];

	return data;
}
@end







|


>

>
>
>
>
>
>
>
>
>
>








<
|
<
<
|
|
|
|

<
|








>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
|
|

>
|
>
|
|
<
|
|
>
|
<
>


|

<
>




|




|


|




>
>
|


|




>
>
>
|


|









|
|
|




>








>
>


|

|








|




|


>
|
|

|
|
|

|













>
>




|
|








<
<

|


<
>
>
|
<
<
<

|
>
>
>





>
>

|



|
|











>
>

|
|
|







|






>
>




|


|












|
|









|
|











|
>


















>

|



>
>
|

|

|


|

|

|


|

|

|





|





386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416


417
418
419
420
421

422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461

462
463
464
465

466
467
468
469
470

471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591


592
593
594
595

596
597
598



599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
			else if (c2 >= 'a' && c2 <= 'f')
				byte |= c2 - 'a' + 10;
			else if (c2 >= 'A' && c2 <= 'F')
				byte |= c2 - 'A' + 10;
			else
				@throw [OFInvalidFormatException exception];

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

		@throw e;
	}

	@try {
		self = [self initWithItemsNoCopy: items
					   count: count
				    freeWhenDone: true];
	} @catch (id e) {
		OFFreeMemory(items);
		@throw e;
	}

	return self;
}

- (instancetype)initWithBase64EncodedString: (OFString *)string
{

	void *pool = objc_autoreleasePoolPush();


	OFMutableData *data;

	@try {
		data = [OFMutableData data];


		if (!OFBase64Decode(data,
		    [string cStringWithEncoding: OFStringEncodingASCII],
		    [string cStringLengthWithEncoding: OFStringEncodingASCII]))
			@throw [OFInvalidFormatException exception];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	/* Avoid copying if the class already matches. */
	if (data.class == self.class) {
		[self release];
		self = [data retain];
		objc_autoreleasePoolPop(pool);
		return self;
	}

	/*
	 * Make it immutable and avoid copying if the class already matches
	 * after that.
	 */
	@try {
		[data makeImmutable];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	if (data.class == self.class) {
		[self release];
		self = [data retain];
		objc_autoreleasePoolPop(pool);
		return self;
	}

	self = [self initWithItems: data.items count: data.count];

	objc_autoreleasePoolPop(pool);

	return self;

}

- (size_t)count
{

	OF_UNRECOGNIZED_SELECTOR
}

- (size_t)itemSize
{

	OF_UNRECOGNIZED_SELECTOR
}

- (const void *)items
{
	OF_UNRECOGNIZED_SELECTOR
}

- (const void *)itemAtIndex: (size_t)idx
{
	if (idx >= self.count)
		@throw [OFOutOfRangeException exception];

	return (const unsigned char *)self.items + idx * self.itemSize;
}

- (const void *)firstItem
{
	const void *items = self.items;

	if (items == NULL || self.count == 0)
		return NULL;

	return items;
}

- (const void *)lastItem
{
	const unsigned char *items = self.items;
	size_t count = self.count;

	if (items == NULL || count == 0)
		return NULL;

	return items + (count - 1) * self.itemSize;
}

- (id)copy
{
	return [self retain];
}

- (id)mutableCopy
{
	return [[OFMutableData alloc] initWithItems: self.items
					      count: self.count
					   itemSize: self.itemSize];
}

- (bool)isEqual: (id)object
{
	size_t count, itemSize;
	OFData *data;

	if (object == self)
		return true;

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

	count = self.count;
	itemSize = self.itemSize;
	data = object;

	if (data.count != count || data.itemSize != itemSize)
		return false;
	if (memcmp(data.items, self.items, count * itemSize) != 0)
		return false;

	return true;
}

- (OFComparisonResult)compare: (OFData *)data
{
	int comparison;
	size_t count, dataCount, minCount;

	if (![data isKindOfClass: [OFData class]])
		@throw [OFInvalidArgumentException exception];

	if (data.itemSize != self.itemSize)
		@throw [OFInvalidArgumentException exception];

	count = self.count;
	dataCount = data.count;
	minCount = (count > dataCount ? dataCount : count);

	if ((comparison = memcmp(self.items, data.items,
	    minCount * self.itemSize)) == 0) {
		if (count > dataCount)
			return OFOrderedDescending;
		if (count < dataCount)
			return OFOrderedAscending;

		return OFOrderedSame;
	}

	if (comparison > 0)
		return OFOrderedDescending;
	else
		return OFOrderedAscending;
}

- (unsigned long)hash
{
	const unsigned char *items = self.items;
	size_t count = self.count, itemSize = self.itemSize;
	unsigned long hash;

	OFHashInit(&hash);

	for (size_t i = 0; i < count * itemSize; i++)
		OFHashAddByte(&hash, items[i]);

	OFHashFinalize(&hash);

	return hash;
}

- (OFData *)subdataWithRange: (OFRange)range
{


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


	if (![self isKindOfClass: [OFMutableData class]])
		return [[[OFSubdata alloc] initWithData: self
						  range: range] autorelease];




	return [OFData dataWithItems: (const unsigned char *)self.items +
				      (range.location * self.itemSize)
			       count: self.count
			    itemSize: self.itemSize];
}

- (OFString *)description
{
	OFMutableString *ret = [OFMutableString stringWithString: @"<"];
	const unsigned char *items = self.items;
	size_t count = self.count, itemSize = self.itemSize;

	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
{
	OFMutableString *ret = [OFMutableString string];
	const unsigned char *items = self.items;
	size_t count = self.count, itemSize = self.itemSize;

	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
{
	return OFBase64Encode(self.items, self.count * self.itemSize);
}

- (OFRange)rangeOfData: (OFData *)data
	       options: (OFDataSearchOptions)options
		 range: (OFRange)range
{
	const unsigned char *items = self.items;
	size_t count = self.count, itemSize = self.itemSize;
	const char *search;
	size_t searchLength;

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

	if (data == nil || data.itemSize != itemSize)
		@throw [OFInvalidArgumentException exception];

	if ((searchLength = data.count) == 0)
		return OFMakeRange(0, 0);

	if (searchLength > range.length)
		return OFMakeRange(OFNotFound, 0);

	search = data.items;

	if (options & OFDataSearchBackwards) {
		for (size_t i = range.length - searchLength;; i--) {
			if (memcmp(items + i * itemSize, search,
			    searchLength * itemSize) == 0)
				return OFMakeRange(i, searchLength);

			/* No match and we're at the last item */
			if (i == 0)
				break;
		}
	} else {
		for (size_t i = range.location;
		    i <= range.length - searchLength; i++)
			if (memcmp(items + i * itemSize, search,
			    searchLength * itemSize) == 0)
				return OFMakeRange(i, searchLength);
	}

	return OFMakeRange(OFNotFound, 0);
}

#ifdef OF_HAVE_FILES
- (void)writeToFile: (OFString *)path
{
	OFFile *file = [[OFFile alloc] initWithPath: path mode: @"w"];
	@try {
		[file writeBuffer: self.items
			   length: self.count * self.itemSize];
	} @finally {
		[file release];
	}
}
#endif

- (void)writeToIRI: (OFIRI *)IRI
{
	void *pool = objc_autoreleasePoolPush();

	[[OFIRIHandler openItemAtIRI: IRI mode: @"w"] writeData: self];

	objc_autoreleasePoolPop(pool);
}

- (OFData *)messagePackRepresentation
{
	OFMutableData *data;
	size_t count;

	if (self.itemSize != 1)
		@throw [OFNotImplementedException exceptionWithSelector: _cmd
								 object: self];

	count = self.count;

	if (count <= UINT8_MAX) {
		uint8_t type = 0xC4;
		uint8_t tmp = (uint8_t)count;

		data = [OFMutableData dataWithCapacity: count + 2];
		[data addItem: &type];
		[data addItem: &tmp];
	} else if (count <= UINT16_MAX) {
		uint8_t type = 0xC5;
		uint16_t tmp = OFToBigEndian16((uint16_t)count);

		data = [OFMutableData dataWithCapacity: count + 3];
		[data addItem: &type];
		[data addItems: &tmp count: sizeof(tmp)];
	} else if (count <= UINT32_MAX) {
		uint8_t type = 0xC6;
		uint32_t tmp = OFToBigEndian32((uint32_t)count);

		data = [OFMutableData dataWithCapacity: count + 5];
		[data addItem: &type];
		[data addItems: &tmp count: sizeof(tmp)];
	} else
		@throw [OFOutOfRangeException exception];

	[data addItems: self.items count: count];
	[data makeImmutable];

	return data;
}
@end

Modified src/OFDatagramSocket.h from [c25f58addd] to [8628474603].

101
102
103
104
105
106
107



108
109
110
111
112
113
114
 *	    than one thread at the same time is not thread-safe, even if copy
 *	    was called to create one "instance" for every thread!
 */
@interface OFDatagramSocket: OFObject <OFCopying, OFReadyForReadingObserving,
    OFReadyForWritingObserving>
{
	OFSocketHandle _socket;



	bool _canBlock;
#ifdef OF_WII
	bool _canSendToBroadcastAddresses;
#endif
	id <OFDatagramSocketDelegate> _Nullable _delegate;
	OF_RESERVE_IVARS(OFDatagramSocket, 4)
}







>
>
>







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
 *	    than one thread at the same time is not thread-safe, even if copy
 *	    was called to create one "instance" for every thread!
 */
@interface OFDatagramSocket: OFObject <OFCopying, OFReadyForReadingObserving,
    OFReadyForWritingObserving>
{
	OFSocketHandle _socket;
#ifdef OF_AMIGAOS
	LONG _socketID;
#endif
	bool _canBlock;
#ifdef OF_WII
	bool _canSendToBroadcastAddresses;
#endif
	id <OFDatagramSocketDelegate> _Nullable _delegate;
	OF_RESERVE_IVARS(OFDatagramSocket, 4)
}
293
294
295
296
297
298
299
























300
301
302
303
304
305
306
 */
- (void)asyncSendData: (OFData *)data
	     receiver: (const OFSocketAddress *)receiver
	  runLoopMode: (OFRunLoopMode)runLoopMode
		block: (OFDatagramSocketAsyncSendDataBlock)block;
#endif

























/**
 * @brief Cancels all pending asynchronous requests on the socket.
 */
- (void)cancelAsyncRequests;

/**
 * @brief Closes the socket so that it can neither receive nor send any more







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
 */
- (void)asyncSendData: (OFData *)data
	     receiver: (const OFSocketAddress *)receiver
	  runLoopMode: (OFRunLoopMode)runLoopMode
		block: (OFDatagramSocketAsyncSendDataBlock)block;
#endif

/**
 * @brief Releases the socket from the current thread.
 *
 * This is necessary on some platforms in order to allow a different thread to
 * use the socket, e.g. on AmigaOS, but you should call it on all operating
 * systems before using the socket from a different thread.
 *
 * After calling this method, you must no longer use the socket until
 * @ref obtainSocketForCurrentThread has been called.
 */
- (void)releaseSocketFromCurrentThread;

/**
 * @brief Obtains the socket for the current thread.
 *
 * This is necessary on some platforms in order to allow a different thread to
 * use the socket, e.g. on AmigaOS, but you should call it on all operating
 * systems before using the socket from a different thread.
 *
 * You must only call this method after @ref releaseSocketFromCurrentThread has
 * been called from a different thread.
 */
- (void)obtainSocketForCurrentThread;

/**
 * @brief Cancels all pending asynchronous requests on the socket.
 */
- (void)cancelAsyncRequests;

/**
 * @brief Closes the socket so that it can neither receive nor send any more

Modified src/OFDatagramSocket.m from [0470d4f081] to [6000a37970].

29
30
31
32
33
34
35

36
37
38

39
40
41
42
43




44
45
46
47
48
49
50
#import "OFDatagramSocket.h"
#import "OFData.h"
#import "OFRunLoop.h"
#import "OFRunLoop+Private.h"
#import "OFSocket.h"
#import "OFSocket+Private.h"


#import "OFGetOptionFailedException.h"
#import "OFInitializationFailedException.h"
#import "OFNotOpenException.h"

#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFWriteFailedException.h"





@implementation OFDatagramSocket
@synthesize delegate = _delegate;

+ (void)initialize
{
	if (self != [OFDatagramSocket class])







>



>





>
>
>
>







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#import "OFDatagramSocket.h"
#import "OFData.h"
#import "OFRunLoop.h"
#import "OFRunLoop+Private.h"
#import "OFSocket.h"
#import "OFSocket+Private.h"

#import "OFAlreadyOpenException.h"
#import "OFGetOptionFailedException.h"
#import "OFInitializationFailedException.h"
#import "OFNotOpenException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFWriteFailedException.h"

#if defined(OF_AMIGAOS) && !defined(UNIQUE_ID)
# define UNIQUE_ID -1
#endif

@implementation OFDatagramSocket
@synthesize delegate = _delegate;

+ (void)initialize
{
	if (self != [OFDatagramSocket class])
67
68
69
70
71
72
73



74
75
76
77
78
79
80
	@try {
		if (self.class == [OFDatagramSocket class]) {
			[self doesNotRecognizeSelector: _cmd];
			abort();
		}

		_socket = OFInvalidSocketHandle;



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

	return self;







>
>
>







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
	@try {
		if (self.class == [OFDatagramSocket class]) {
			[self doesNotRecognizeSelector: _cmd];
			abort();
		}

		_socket = OFInvalidSocketHandle;
#ifdef OF_HAVE_AMIGAOS
		_socketID = -1;
#endif
		_canBlock = true;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
402
403
404
405
406
407
408













































409
410
411
412
413
414
415
416
417
418

	if (_socket > INT_MAX)
		@throw [OFOutOfRangeException exception];

	return (int)_socket;
#endif
}














































- (void)close
{
	if (_socket == OFInvalidSocketHandle)
		@throw [OFNotOpenException exceptionWithObject: self];

	closesocket(_socket);
	_socket = OFInvalidSocketHandle;
}
@end







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










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

	if (_socket > INT_MAX)
		@throw [OFOutOfRangeException exception];

	return (int)_socket;
#endif
}

- (void)releaseSocketFromCurrentThread
{
#ifdef OF_AMIGAOS
	if (_socket == OFInvalidSocketHandle)
		@throw [OFNotOpenException exceptionWithObject: self];

	if ((_socketID = ReleaseSocket(_socket, UNIQUE_ID)) == -1) {
		switch (Errno()) {
		case ENOMEM:
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: 0];
		case EBADF:
			@throw [OFNotOpenException exceptionWithObject: self];
		default:
			OFEnsure(0);
		}
	}

	_socket = OFInvalidSocketHandle;
#endif
}

- (void)obtainSocketForCurrentThread
{
#ifdef OF_AMIGAOS
	if (_socket != OFInvalidSocketHandle)
		@throw [OFAlreadyOpenException exceptionWithObject: self];

	if (_socketID == -1)
		@throw [OFNotOpenException exceptionWithObject: self];

	/*
	 * FIXME: We should store these, but that requires changing all
	 *	  subclasses. This only becomes a problem if IPv6 support ever
	 *	  gets added.
	 */
	_socket = ObtainSocket(_socketID, AF_INET, SOCK_DGRAM, 0);
	if (_socket == OFInvalidSocketHandle)
		@throw [OFInitializationFailedException
		    exceptionWithClass: self.class];

	_socketID = -1;
#endif
}

- (void)close
{
	if (_socket == OFInvalidSocketHandle)
		@throw [OFNotOpenException exceptionWithObject: self];

	closesocket(_socket);
	_socket = OFInvalidSocketHandle;
}
@end

Modified src/OFDate.h from [5d6447d0f7] to [0270f8788a].

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@class OFConstantString;

/**
 * @class OFDate OFDate.h ObjFW/OFDate.h
 *
 * @brief A class for storing, accessing and comparing dates.
 */
#ifndef OF_DATE_M
OF_SUBCLASSING_RESTRICTED
#endif
@interface OFDate: OFObject <OFCopying, OFComparing,
    OFMessagePackRepresentation>
{
	OFTimeInterval _seconds;
}

#ifdef OF_HAVE_CLASS_PROPERTIES
@property (class, readonly, nonatomic) OFDate *distantFuture;
@property (class, readonly, nonatomic) OFDate *distantPast;
#endif

/**
 * @brief The microsecond of the date.







<
<
<


<
<
<
<







22
23
24
25
26
27
28



29
30




31
32
33
34
35
36
37
@class OFConstantString;

/**
 * @class OFDate OFDate.h ObjFW/OFDate.h
 *
 * @brief A class for storing, accessing and comparing dates.
 */



@interface OFDate: OFObject <OFCopying, OFComparing,
    OFMessagePackRepresentation>




#ifdef OF_HAVE_CLASS_PROPERTIES
@property (class, readonly, nonatomic) OFDate *distantFuture;
@property (class, readonly, nonatomic) OFDate *distantPast;
#endif

/**
 * @brief The microsecond of the date.

Modified src/OFDate.m from [8b8a822187] to [468bf23684].

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



54
55
56
57
58
59
60
61
62
63
#import "OFOutOfRangeException.h"

#if defined(OF_AMIGAOS_M68K) || defined(OF_MINT)
/* amiga-gcc and freemint-gcc do not have trunc() */
# define trunc(x) ((int64_t)(x))
#endif

@interface OFDate ()
+ (instancetype)of_alloc;
@end

@interface OFDateSingleton: OFDate



@end

@interface OFDatePlaceholder: OFDateSingleton
@end

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
@interface OFTaggedPointerDate: OFDateSingleton
@end
#endif








|
<


|
>
>
>


|







42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#import "OFOutOfRangeException.h"

#if defined(OF_AMIGAOS_M68K) || defined(OF_MINT)
/* amiga-gcc and freemint-gcc do not have trunc() */
# define trunc(x) ((int64_t)(x))
#endif

@interface OFPlaceholderDate: OFDate

@end

@interface OFConcreteDate: OFDate
{
	OFTimeInterval _seconds;
}
@end

@interface OFDateSingleton: OFConcreteDate
@end

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
@interface OFTaggedPointerDate: OFDateSingleton
@end
#endif

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
	/* Time zone */
	seconds += -(double)tz * 60;

	return seconds;
}

@implementation OFDateSingleton
- (instancetype)autorelease
{
	return self;
}

- (instancetype)retain
{
	return self;
}

- (void)release
{
}

- (unsigned int)retainCount
{
	return OFMaxRetainCount;
}
@end

@implementation OFDatePlaceholder
#ifdef __clang__
/* We intentionally don't call into super, so silence the warning. */
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunknown-pragmas"
# pragma clang diagnostic ignored "-Wobjc-designated-initializers"
#endif
- (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<


|







258
259
260
261
262
263
264




265













266
267
268
269
270
271
272
273
274
275
	/* Time zone */
	seconds += -(double)tz * 60;

	return seconds;
}

@implementation OFDateSingleton




OF_SINGLETON_METHODS













@end

@implementation OFPlaceholderDate
#ifdef __clang__
/* We intentionally don't call into super, so silence the warning. */
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunknown-pragmas"
# pragma clang diagnostic ignored "-Wobjc-designated-initializers"
#endif
- (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds
309
310
311
312
313
314
315

316
317
318
319
320


















321
322
323
324
325
326
327
		    value & ~(UINT64_C(4) << 60));

		if (ret != nil)
			return ret;
	}
#endif


	return (id)[[OFDate of_alloc] initWithTimeIntervalSince1970: seconds];
}
#ifdef __clang__
# pragma clang diagnostic pop
#endif


















@end

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
@implementation OFTaggedPointerDate
- (OFTimeInterval)timeIntervalSince1970
{
	uint64_t value = (uint64_t)object_getTaggedPointerValue(self);







>
|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
		    value & ~(UINT64_C(4) << 60));

		if (ret != nil)
			return ret;
	}
#endif

	return (id)[[OFConcreteDate alloc]
	    initWithTimeIntervalSince1970: seconds];
}
#ifdef __clang__
# pragma clang diagnostic pop
#endif

OF_SINGLETON_METHODS
@end

@implementation OFConcreteDate
- (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds
{
	self = [super initWithTimeIntervalSince1970: seconds];

	_seconds = seconds;

	return self;
}

- (OFTimeInterval)timeIntervalSince1970
{
	return _seconds;
}
@end

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
@implementation OFTaggedPointerDate
- (OFTimeInterval)timeIntervalSince1970
{
	uint64_t value = (uint64_t)object_getTaggedPointerValue(self);
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
#ifdef OF_WINDOWS
	HMODULE module;
#endif

	if (self != [OFDate class])
		return;

	placeholder.isa = [OFDatePlaceholder class];

#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_HAVE_THREADS)
	mutex = [[OFMutex alloc] init];
	atexit(releaseMutex);
#endif

#ifdef OF_WINDOWS
	if ((module = LoadLibrary("msvcrt.dll")) != NULL)
		_mktime64FuncPtr = (__time64_t (*)(struct tm *))
		    GetProcAddress(module, "_mktime64");
#endif

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
	dateTag = objc_registerTaggedPointerClass([OFTaggedPointerDate class]);
#endif
}

+ (instancetype)of_alloc
{
	return [super alloc];
}

+ (instancetype)alloc
{
	if (self == [OFDate class])
		return (id)&placeholder;

	return [super alloc];
}







|


















<
<
<
<
<







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
#ifdef OF_WINDOWS
	HMODULE module;
#endif

	if (self != [OFDate class])
		return;

	object_setClass((id)&placeholder, [OFPlaceholderDate class]);

#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
    defined(OF_HAVE_THREADS)
	mutex = [[OFMutex alloc] init];
	atexit(releaseMutex);
#endif

#ifdef OF_WINDOWS
	if ((module = LoadLibrary("msvcrt.dll")) != NULL)
		_mktime64FuncPtr = (__time64_t (*)(struct tm *))
		    GetProcAddress(module, "_mktime64");
#endif

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
	dateTag = objc_registerTaggedPointerClass([OFTaggedPointerDate class]);
#endif
}






+ (instancetype)alloc
{
	if (self == [OFDate class])
		return (id)&placeholder;

	return [super alloc];
}
424
425
426
427
428
429
430




431

432
433

434

435
436
437
438
439
440
441
442
- (instancetype)init
{
	return [self initWithTimeIntervalSince1970: now()];
}

- (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds
{




	self = [super init];


	_seconds = seconds;



	return self;
}

- (instancetype)initWithTimeIntervalSinceNow: (OFTimeInterval)seconds
{
	return [self initWithTimeIntervalSince1970: now() + seconds];
}








>
>
>
>
|
>
|
|
>
|
>
|







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
- (instancetype)init
{
	return [self initWithTimeIntervalSince1970: now()];
}

- (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds
{
	if ([self isMemberOfClass: [OFDate class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
		} @catch (id e) {
			[self release];
			@throw e;
		}

		abort();
	}

	return [super init];
}

- (instancetype)initWithTimeIntervalSinceNow: (OFTimeInterval)seconds
{
	return [self initWithTimeIntervalSince1970: now() + seconds];
}

829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
		return otherDate;

	return self;
}

- (OFTimeInterval)timeIntervalSince1970
{
	return _seconds;
}

- (OFTimeInterval)timeIntervalSinceDate: (OFDate *)otherDate
{
	return self.timeIntervalSince1970 - otherDate.timeIntervalSince1970;
}








|







835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
		return otherDate;

	return self;
}

- (OFTimeInterval)timeIntervalSince1970
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFTimeInterval)timeIntervalSinceDate: (OFDate *)otherDate
{
	return self.timeIntervalSince1970 - otherDate.timeIntervalSince1970;
}

Modified src/OFDictionary.m from [34eb84dfb7] to [8b606ffec2].

16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
#include "config.h"

#include <stdlib.h>

#import "OFDictionary.h"
#import "OFArray.h"
#import "OFCharacterSet.h"

#import "OFData.h"
#import "OFEnumerator.h"
#import "OFMapTableDictionary.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"
#import "OFOutOfRangeException.h"
#import "OFUndefinedKeyException.h"

static struct {
	Class isa;
} placeholder;

@interface OFDictionary ()
- (OFString *)
    of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options
			       depth: (size_t)depth;
@end

@interface OFDictionaryPlaceholder: OFDictionary
@end

OF_DIRECT_MEMBERS
@interface OFDictionaryObjectEnumerator: OFEnumerator
{
	OFDictionary *_dictionary;
	OFEnumerator *_keyEnumerator;
}

- (instancetype)initWithDictionary: (OFDictionary *)dictionary;
@end

@implementation OFDictionaryPlaceholder
- (instancetype)init
{
	return (id)[[OFMapTableDictionary alloc] init];
}

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

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

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

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

- (instancetype)initWithKeysAndObjects: (id <OFCopying>)firstKey, ...
{
	id ret;
	va_list arguments;

	va_start(arguments, firstKey);
	ret = [[OFMapTableDictionary alloc] initWithKey: firstKey
					      arguments: arguments];
	va_end(arguments);

	return ret;
}

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

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end

@implementation OFDictionary
+ (void)initialize
{
	if (self == [OFDictionary class])
		placeholder.isa = [OFDictionaryPlaceholder class];

}

+ (instancetype)alloc
{
	if (self == [OFDictionary class])
		return (id)&placeholder;








>


<
















|












|


|




|





|





|







|










|









|



<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<






|
>







16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
#include "config.h"

#include <stdlib.h>

#import "OFDictionary.h"
#import "OFArray.h"
#import "OFCharacterSet.h"
#import "OFConcreteDictionary.h"
#import "OFData.h"
#import "OFEnumerator.h"

#import "OFString.h"

#import "OFInvalidArgumentException.h"
#import "OFOutOfRangeException.h"
#import "OFUndefinedKeyException.h"

static struct {
	Class isa;
} placeholder;

@interface OFDictionary ()
- (OFString *)
    of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options
			       depth: (size_t)depth;
@end

@interface OFPlaceholderDictionary: OFDictionary
@end

OF_DIRECT_MEMBERS
@interface OFDictionaryObjectEnumerator: OFEnumerator
{
	OFDictionary *_dictionary;
	OFEnumerator *_keyEnumerator;
}

- (instancetype)initWithDictionary: (OFDictionary *)dictionary;
@end

@implementation OFPlaceholderDictionary
- (instancetype)init
{
	return (id)[[OFConcreteDictionary alloc] init];
}

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

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

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

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

- (instancetype)initWithKeysAndObjects: (id <OFCopying>)firstKey, ...
{
	id ret;
	va_list arguments;

	va_start(arguments, firstKey);
	ret = [[OFConcreteDictionary alloc] initWithKey: firstKey
					      arguments: arguments];
	va_end(arguments);

	return ret;
}

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





OF_SINGLETON_METHODS













@end

@implementation OFDictionary
+ (void)initialize
{
	if (self == [OFDictionary class])
		object_setClass((id)&placeholder,
		    [OFPlaceholderDictionary class]);
}

+ (instancetype)alloc
{
	if (self == [OFDictionary class])
		return (id)&placeholder;

183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
	va_end(arguments);

	return ret;
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFDictionary class]]) {

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








|
>







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
	va_end(arguments);

	return ret;
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFDictionary class]] ||
	    [self isMemberOfClass: [OFMutableDictionary class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
		} @catch (id e) {
			[self release];
			@throw e;
		}

Modified src/OFFileManager.h from [eca60449c1] to [7ca03f8186].

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
#import "OFDictionary.h"

OF_ASSUME_NONNULL_BEGIN

/** @file */

#ifdef OF_HAVE_FILES
# if defined(OF_HAVE_CHMOD) && !defined(OF_AMIGAOS)
#  define OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
# endif
# if defined(OF_HAVE_CHOWN) && !defined(OF_AMIGAOS)
#  define OF_FILE_MANAGER_SUPPORTS_OWNER
# endif
# if (defined(OF_HAVE_LINK) && !defined(OF_AMIGAOS)) || defined(OF_WINDOWS)

#  define OF_FILE_MANAGER_SUPPORTS_LINKS
# endif
# if (defined(OF_HAVE_SYMLINK) && !defined(OF_AMIGAOS)) || defined(OF_WINDOWS)

#  define OF_FILE_MANAGER_SUPPORTS_SYMLINKS
# endif
# if defined(OF_LINUX) || defined(OF_MACOS)
#  define OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES
# endif
#endif

@class OFArray OF_GENERIC(ObjectType);
@class OFConstantString;
@class OFDate;







|


|


|
>


|
>


|







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
#import "OFDictionary.h"

OF_ASSUME_NONNULL_BEGIN

/** @file */

#ifdef OF_HAVE_FILES
# if (defined(OF_HAVE_CHMOD) && !defined(OF_AMIGAOS)) || defined(DOXYGEN)
#  define OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
# endif
# if (defined(OF_HAVE_CHOWN) && !defined(OF_AMIGAOS)) || defined(DOXYGEN)
#  define OF_FILE_MANAGER_SUPPORTS_OWNER
# endif
# if (defined(OF_HAVE_LINK) && !defined(OF_AMIGAOS)) || defined(OF_WINDOWS) || \
    defined(DOXYGEN)
#  define OF_FILE_MANAGER_SUPPORTS_LINKS
# endif
# if (defined(OF_HAVE_SYMLINK) && !defined(OF_AMIGAOS)) || \
    defined(OF_WINDOWS) || defined(DOXYGEN)
#  define OF_FILE_MANAGER_SUPPORTS_SYMLINKS
# endif
# if defined(OF_LINUX) || defined(OF_MACOS) || defined(DOXYGEN)
#  define OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES
# endif
#endif

@class OFArray OF_GENERIC(ObjectType);
@class OFConstantString;
@class OFDate;

Modified src/OFFileManager.m from [c425786752] to [34c9baec0c].

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
				 ofItemAtIRI: [OFIRI fileIRIWithPath: path]];
	objc_autoreleasePoolPop(pool);
}
#endif
@end

@implementation OFDefaultFileManager
- (instancetype)autorelease
{
	return self;
}

- (instancetype)retain
{
	return self;
}

- (void)release
{
}

- (unsigned int)retainCount
{
	return OFMaxRetainCount;
}
@end

@implementation OFDictionary (FileAttributes)
- (unsigned long long)fileSize
{
	return [attributeForKeyOrException(self, OFFileSize)
	    unsignedLongLongValue];







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<







992
993
994
995
996
997
998




999













1000
1001
1002
1003
1004
1005
1006
				 ofItemAtIRI: [OFIRI fileIRIWithPath: path]];
	objc_autoreleasePoolPop(pool);
}
#endif
@end

@implementation OFDefaultFileManager




OF_SINGLETON_METHODS













@end

@implementation OFDictionary (FileAttributes)
- (unsigned long long)fileSize
{
	return [attributeForKeyOrException(self, OFFileSize)
	    unsignedLongLongValue];

Modified src/OFHTTPClient.h from [67bbe697a1] to [0bca7b11fb].

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
/**
 * @protocol OFHTTPClientDelegate OFHTTPClient.h ObjFW/OFHTTPClient.h
 *
 * @brief A delegate for OFHTTPClient.
 */
@protocol OFHTTPClientDelegate <OFObject>
/**
 * @brief A callback which is called when an OFHTTPClient performed a request.

 *
 * @param client The OFHTTPClient which performed the request
 * @param request The request the OFHTTPClient performed
 * @param response The response to the request performed, or nil on error
 * @param exception An exception if the request failed, or nil on success
 */
-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (nullable OFHTTPResponse *)response
	  exception: (nullable id)exception;

@optional
/**
 * @brief A callback which is called when an OFHTTPClient creates a TCP socket.

 *
 * This can be used to tell the socket about a SOCKS5 proxy it should use for
 * this connection.
 *
 * @param client The OFHTTPClient that created a TCP socket
 * @param TCPSocket The socket created by the OFHTTPClient
 * @param request The request for which the TCP socket was created
 */
-	(void)client: (OFHTTPClient *)client
  didCreateTCPSocket: (OFTCPSocket *)TCPSocket
	     request: (OFHTTPRequest *)request;

/**
 * @brief A callback which is called when an OFHTTPClient creates a TLS stream.

 *
 * This can be used to tell the TLS stream about a client certificate it should
 * use before performing the TLS handshake.
 *
 * @param client The OFHTTPClient that created a TLS stream
 * @param TLSStream The TLS stream created by the OFHTTPClient
 * @param request The request for which the TLS stream was created
 */
-	(void)client: (OFHTTPClient *)client
  didCreateTLSStream: (OFTLSStream *)TLSStream
	     request: (OFHTTPRequest *)request;

/**
 * @brief A callback which is called when an OFHTTPClient wants to send the
 *	  body for a request.
 *
 * @param client The OFHTTPClient that wants to send the body
 * @param requestBody A stream into which the body of the request should be
 *		      written
 * @param request The request for which the OFHTTPClient wants to send the body
 */
-     (void)client: (OFHTTPClient *)client
  wantsRequestBody: (OFStream *)requestBody
	   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
	 statusCode: (short)statusCode
	    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,
 * this callback will not be called then and you have to look at the status code
 * to detect a redirect.
 *
 * This callback will only be called if the OFHTTPClient will follow a







|
>













|
>













|
>













|
|











|













|
|







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
/**
 * @protocol OFHTTPClientDelegate OFHTTPClient.h ObjFW/OFHTTPClient.h
 *
 * @brief A delegate for OFHTTPClient.
 */
@protocol OFHTTPClientDelegate <OFObject>
/**
 * @brief A callback which is called when an @ref OFHTTPClient performed a
 *	  request.
 *
 * @param client The OFHTTPClient which performed the request
 * @param request The request the OFHTTPClient performed
 * @param response The response to the request performed, or nil on error
 * @param exception An exception if the request failed, or nil on success
 */
-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (nullable OFHTTPResponse *)response
	  exception: (nullable id)exception;

@optional
/**
 * @brief A callback which is called when an @ref OFHTTPClient creates a TCP
 *	  socket.
 *
 * This can be used to tell the socket about a SOCKS5 proxy it should use for
 * this connection.
 *
 * @param client The OFHTTPClient that created a TCP socket
 * @param TCPSocket The socket created by the OFHTTPClient
 * @param request The request for which the TCP socket was created
 */
-	(void)client: (OFHTTPClient *)client
  didCreateTCPSocket: (OFTCPSocket *)TCPSocket
	     request: (OFHTTPRequest *)request;

/**
 * @brief A callback which is called when an @ref OFHTTPClient creates a TLS
 *	  stream.
 *
 * This can be used to tell the TLS stream about a client certificate it should
 * use before performing the TLS handshake.
 *
 * @param client The OFHTTPClient that created a TLS stream
 * @param TLSStream The TLS stream created by the OFHTTPClient
 * @param request The request for which the TLS stream was created
 */
-	(void)client: (OFHTTPClient *)client
  didCreateTLSStream: (OFTLSStream *)TLSStream
	     request: (OFHTTPRequest *)request;

/**
 * @brief A callback which is called when an @ref OFHTTPClient wants to send
 *	  the body for a request.
 *
 * @param client The OFHTTPClient that wants to send the body
 * @param requestBody A stream into which the body of the request should be
 *		      written
 * @param request The request for which the OFHTTPClient wants to send the body
 */
-     (void)client: (OFHTTPClient *)client
  wantsRequestBody: (OFStream *)requestBody
	   request: (OFHTTPRequest *)request;

/**
 * @brief A callback which is called when an @ref 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
	 statusCode: (short)statusCode
	    request: (OFHTTPRequest *)request;

/**
 * @brief A callback which is called when an @ref 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,
 * this callback will not be called then and you have to look at the status code
 * to detect a redirect.
 *
 * This callback will only be called if the OFHTTPClient will follow a

Modified src/OFIRI.m from [fdb5d156bf] to [bb77525714].

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
	if (character >= 0x100000 && character <= 0x10FFFD)
		return true;

	return false;
}

@implementation OFIRIAllowedCharacterSetBase
- (instancetype)autorelease
{
	return self;
}

- (instancetype)retain
{
	return self;
}

- (void)release
{
}

- (unsigned int)retainCount
{
	return OFMaxRetainCount;
}
@end

@implementation OFIRIAllowedCharacterSet
- (bool)characterIsMember: (OFUnichar)character
{
	if (character < CHAR_MAX && OFASCIIIsAlnum(character))
		return true;







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<







187
188
189
190
191
192
193




194













195
196
197
198
199
200
201
	if (character >= 0x100000 && character <= 0x10FFFD)
		return true;

	return false;
}

@implementation OFIRIAllowedCharacterSetBase




OF_SINGLETON_METHODS













@end

@implementation OFIRIAllowedCharacterSet
- (bool)characterIsMember: (OFUnichar)character
{
	if (character < CHAR_MAX && OFASCIIIsAlnum(character))
		return true;

Modified src/OFInflate64Stream.h from [95b4831491] to [f13138a788].

66
67
68
69
70
71
72








73
74
75
76
77
78
79
			int state;
			uint16_t value, length, distance, extraBits;
		} huffman;
	} _context;
	bool _inLastBlock, _atEndOfStream;
}









/**
 * @brief Creates a new OFInflate64Stream 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 OFInflate64Stream
 */







>
>
>
>
>
>
>
>







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
			int state;
			uint16_t value, length, distance, extraBits;
		} huffman;
	} _context;
	bool _inLastBlock, _atEndOfStream;
}

/**
 * @brief The underlying stream of the inflate stream.
 *
 * Setting this can be useful if the the data to be inflated is coming from
 * multiple streams, such as split across multiple files.
 */
@property (retain, nonatomic) OFStream *underlyingStream;

/**
 * @brief Creates a new OFInflate64Stream 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 OFInflate64Stream
 */

Modified src/OFInflateStream.h from [4379fb100c] to [1320fce7c5].

66
67
68
69
70
71
72








73
74
75
76
77
78
79
			int state;
			uint16_t value, length, distance, extraBits;
		} huffman;
	} _context;
	bool _inLastBlock, _atEndOfStream;
}









/**
 * @brief Creates a new OFInflateStream 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 OFInflateStream
 */







>
>
>
>
>
>
>
>







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
			int state;
			uint16_t value, length, distance, extraBits;
		} huffman;
	} _context;
	bool _inLastBlock, _atEndOfStream;
}

/**
 * @brief The underlying stream of the inflate stream.
 *
 * Setting this can be useful if the the data to be inflated is coming from
 * multiple streams, such as split across multiple files.
 */
@property (retain, nonatomic) OFStream *underlyingStream;

/**
 * @brief Creates a new OFInflateStream 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 OFInflateStream
 */

Modified src/OFInflateStream.m from [2767dcbcf2] to [7aafb9081b].

96
97
98
99
100
101
102


103
104
105
106
107
108
109
#endif
static const uint8_t codeLengthsOrder[19] = {
	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
};
static OFHuffmanTree fixedLitLenTree, fixedDistTree;

@implementation OFInflateStream


static OF_INLINE bool
tryReadBits(OFInflateStream *stream, uint16_t *bits, uint8_t count)
{
	uint16_t ret = stream->_savedBits;

	OFAssert(stream->_savedBitsLength < count);








>
>







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#endif
static const uint8_t codeLengthsOrder[19] = {
	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
};
static OFHuffmanTree fixedLitLenTree, fixedDistTree;

@implementation OFInflateStream
@synthesize underlyingStream = _stream;

static OF_INLINE bool
tryReadBits(OFInflateStream *stream, uint16_t *bits, uint8_t count)
{
	uint16_t ret = stream->_savedBits;

	OFAssert(stream->_savedBitsLength < count);

Modified src/OFKernelEventObserver.h from [3a6c883edd] to [c6ff38a2d3].

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/**
 * @brief This callback is called when an object did get ready for writing.
 *
 * @param object The object which did become ready for writing
 */
- (void)objectIsReadyForWriting: (id)object;

#ifdef OF_AMIGAOS
/**
 * @brief This callback is called when an Exec Signal was received.
 *
 * @note This is only available on AmigaOS!
 */
- (void)execSignalWasReceived: (ULONG)signalMask;
#endif







|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/**
 * @brief This callback is called when an object did get ready for writing.
 *
 * @param object The object which did become ready for writing
 */
- (void)objectIsReadyForWriting: (id)object;

#if defined(OF_AMIGAOS) || defined(DOXYGEN)
/**
 * @brief This callback is called when an Exec Signal was received.
 *
 * @note This is only available on AmigaOS!
 */
- (void)execSignalWasReceived: (ULONG)signalMask;
#endif
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
@interface OFKernelEventObserver: OFObject
{
	OFMutableArray OF_GENERIC(id <OFReadyForReadingObserving>)
	    *_readObjects;
	OFMutableArray OF_GENERIC(id <OFReadyForWritingObserving>)
	    *_writeObjects;
	id <OFKernelEventObserverDelegate> _Nullable _delegate;
#if defined(OF_AMIGAOS)
	struct Task *_waitingTask;
	ULONG _cancelSignal;
#elif defined(OF_HAVE_PIPE)
	int _cancelFD[2];
#else
	OFSocketHandle _cancelFD[2];
	struct sockaddr_in _cancelAddr;
#endif
#ifdef OF_AMIGAOS
	ULONG _execSignalMask;
#endif
	OF_RESERVE_IVARS(OFKernelEventObserver, 4)
}

/**
 * @brief The delegate for the OFKernelEventObserver.
 */
@property OF_NULLABLE_PROPERTY (assign, nonatomic)
    id <OFKernelEventObserverDelegate> delegate;

#ifdef OF_AMIGAOS
/**
 * @brief A mask of Exec Signals to wait for.
 *
 * @note This is only available on AmigaOS!
 */
@property (nonatomic) ULONG execSignalMask;
#endif

/**
 * @brief Creates a new OFKernelEventObserver.
 *
 * @return A new, autoreleased OFKernelEventObserver
 */
+ (instancetype)observer;







|


|

|


|
|

|









|






|







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
@interface OFKernelEventObserver: OFObject
{
	OFMutableArray OF_GENERIC(id <OFReadyForReadingObserving>)
	    *_readObjects;
	OFMutableArray OF_GENERIC(id <OFReadyForWritingObserving>)
	    *_writeObjects;
	id <OFKernelEventObserverDelegate> _Nullable _delegate;
# if defined(OF_AMIGAOS)
	struct Task *_waitingTask;
	ULONG _cancelSignal;
# elif defined(OF_HAVE_PIPE)
	int _cancelFD[2];
# else
	OFSocketHandle _cancelFD[2];
	struct sockaddr_in _cancelAddr;
# endif
# ifdef OF_AMIGAOS
	ULONG _execSignalMask;
# endif
	OF_RESERVE_IVARS(OFKernelEventObserver, 4)
}

/**
 * @brief The delegate for the OFKernelEventObserver.
 */
@property OF_NULLABLE_PROPERTY (assign, nonatomic)
    id <OFKernelEventObserverDelegate> delegate;

# if defined(OF_AMIGAOS) || defined(DOXYGEN)
/**
 * @brief A mask of Exec Signals to wait for.
 *
 * @note This is only available on AmigaOS!
 */
@property (nonatomic) ULONG execSignalMask;
# endif

/**
 * @brief Creates a new OFKernelEventObserver.
 *
 * @return A new, autoreleased OFKernelEventObserver
 */
+ (instancetype)observer;

Modified src/OFMutableArray.m from [0c37234313] to [6a1691417f].

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

#include "config.h"

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

#import "OFMutableArray.h"
#import "OFMutableAdjacentArray.h"

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

static struct {
	Class isa;
} placeholder;

@interface OFMutableArrayPlaceholder: OFMutableArray
@end

static void
quicksort(OFMutableArray *array, size_t left, size_t right,
    OFCompareFunction compare, void *context, OFArraySortOptions options)
{
	OFComparisonResult ascending, descending;







|









|







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

#include "config.h"

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

#import "OFMutableArray.h"
#import "OFConcreteMutableArray.h"

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

static struct {
	Class isa;
} placeholder;

@interface OFPlaceholderMutableArray: OFMutableArray
@end

static void
quicksort(OFMutableArray *array, size_t left, size_t right,
    OFCompareFunction compare, void *context, OFArraySortOptions options)
{
	OFComparisonResult ascending, descending;
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
			quicksort(array, left, i - 1, compare, context,
			    options);

		left = i + 1;
	}
}

@implementation OFMutableArrayPlaceholder
- (instancetype)init
{
	return (id)[[OFMutableAdjacentArray alloc] init];
}

- (instancetype)initWithCapacity: (size_t)capacity
{
	return (id)[[OFMutableAdjacentArray alloc] initWithCapacity: capacity];
}

- (instancetype)initWithObject: (id)object
{
	return (id)[[OFMutableAdjacentArray alloc] initWithObject: object];
}

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

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

	return ret;
}

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

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

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

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end

@implementation OFMutableArray
+ (void)initialize
{
	if (self == [OFMutableArray class])

		placeholder.isa = [OFMutableArrayPlaceholder class];
}

+ (instancetype)alloc
{
	if (self == [OFMutableArray class])
		return (id)&placeholder;

	return [super alloc];
}

+ (instancetype)arrayWithCapacity: (size_t)capacity
{
	return [[[self alloc] initWithCapacity: capacity] autorelease];
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFMutableArray class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
			abort();
		} @catch (id e) {
			[self release];
			@throw e;
		}
	}

	return [super init];
}

- (instancetype)initWithCapacity: (size_t)capacity
{
	OF_INVALID_INIT_METHOD
}

- (id)copy
{







|


|




|




|








|








|





|




|



<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<






>
|















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
			quicksort(array, left, i - 1, compare, context,
			    options);

		left = i + 1;
	}
}

@implementation OFPlaceholderMutableArray
- (instancetype)init
{
	return (id)[[OFConcreteMutableArray alloc] init];
}

- (instancetype)initWithCapacity: (size_t)capacity
{
	return (id)[[OFConcreteMutableArray alloc] initWithCapacity: capacity];
}

- (instancetype)initWithObject: (id)object
{
	return (id)[[OFConcreteMutableArray alloc] initWithObject: object];
}

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

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

	return ret;
}

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

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

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





OF_SINGLETON_METHODS













@end

@implementation OFMutableArray
+ (void)initialize
{
	if (self == [OFMutableArray class])
		object_setClass((id)&placeholder,
		    [OFPlaceholderMutableArray class]);
}

+ (instancetype)alloc
{
	if (self == [OFMutableArray class])
		return (id)&placeholder;

	return [super alloc];
}

+ (instancetype)arrayWithCapacity: (size_t)capacity
{
	return [[[self alloc] initWithCapacity: capacity] autorelease];
}
















- (instancetype)initWithCapacity: (size_t)capacity
{
	OF_INVALID_INIT_METHOD
}

- (id)copy
{

Modified src/OFMutableData.h from [6167546110] to [4756340133].

13
14
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
 * file.
 */

#import "OFData.h"

OF_ASSUME_NONNULL_BEGIN

@class OFString;

/**
 * @class OFMutableData OFMutableData.h ObjFW/OFMutableData.h
 *
 * @brief A class for storing and manipulating arbitrary data in an array.
 */
@interface OFMutableData: OFData
{
	size_t _capacity;
	OF_RESERVE_IVARS(OFMutableData, 4)
}

/**
 * @brief All items of the OFMutableData as a C array.
 *
 * @warning The pointer is only valid until the OFMutableData is changed!
 *
 * Modifying the returned array directly is allowed and will change the contents
 * of the data.







<
<






<
<
<
<
<







13
14
15
16
17
18
19


20
21
22
23
24
25





26
27
28
29
30
31
32
 * file.
 */

#import "OFData.h"

OF_ASSUME_NONNULL_BEGIN



/**
 * @class OFMutableData OFMutableData.h ObjFW/OFMutableData.h
 *
 * @brief A class for storing and manipulating arbitrary data in an array.
 */
@interface OFMutableData: OFData





/**
 * @brief All items of the OFMutableData as a C array.
 *
 * @warning The pointer is only valid until the OFMutableData is changed!
 *
 * Modifying the returned array directly is allowed and will change the contents
 * of the data.
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

/**
 * @brief The last item of the OFMutableData or `NULL`.
 */
@property OF_NULLABLE_PROPERTY (readonly, nonatomic) void *mutableLastItem
    OF_RETURNS_INNER_POINTER;

/**
 * @brief Creates a new OFMutableData with an item size of 1.
 *
 * @return A new autoreleased OFMutableData
 */
+ (instancetype)data;

/**
 * @brief Creates a new OFMutableData whose items all have the same specified
 *	  size.
 *
 * @param itemSize The size of a single element in the OFMutableData
 * @return A new autoreleased OFMutableData
 */
+ (instancetype)dataWithItemSize: (size_t)itemSize;

/**
 * @brief Creates a new OFMutableData with enough memory to hold the specified
 *	  number of items which all have an item size of 1.
 *
 * @param capacity The initial capacity for the OFMutableData
 * @return A new autoreleased OFMutableData
 */
+ (instancetype)dataWithCapacity: (size_t)capacity;

/**
 * @brief Creates a new OFMutableData with enough memory to hold the specified
 *	  number of items which all have the same specified size.
 *
 * @param itemSize The size of a single element in the OFMutableData
 * @param capacity The initial capacity for the OFMutableData
 * @return A new autoreleased OFMutableData
 */
+ (instancetype)dataWithItemSize: (size_t)itemSize capacity: (size_t)capacity;

/**
 * @brief Initializes an already allocated OFMutableData with an item size of 1.
 *
 * @return An initialized OFMutableData
 */
- (instancetype)init;

/**
 * @brief Initializes an already allocated OFMutableData whose items all have
 *	  the same size.
 *
 * @param itemSize The size of a single element in the OFMutableData
 * @return An initialized OFMutableData
 */
- (instancetype)initWithItemSize: (size_t)itemSize;

/**
 * @brief Initializes an already allocated OFMutableData with enough memory to
 *	  hold the the specified number of items which all have an item size of
 *	  1.
 *
 * @param capacity The initial capacity for the OFMutableData
 * @return An initialized OFMutableData







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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

/**
 * @brief The last item of the OFMutableData or `NULL`.
 */
@property OF_NULLABLE_PROPERTY (readonly, nonatomic) void *mutableLastItem
    OF_RETURNS_INNER_POINTER;

















/**
 * @brief Creates a new OFMutableData with enough memory to hold the specified
 *	  number of items which all have an item size of 1.
 *
 * @param capacity The initial capacity for the OFMutableData
 * @return A new autoreleased OFMutableData
 */
+ (instancetype)dataWithCapacity: (size_t)capacity;

/**
 * @brief Creates a new OFMutableData with enough memory to hold the specified
 *	  number of items which all have the same specified size.
 *
 * @param itemSize The size of a single element in the OFMutableData
 * @param capacity The initial capacity for the OFMutableData
 * @return A new autoreleased OFMutableData
 */
+ (instancetype)dataWithItemSize: (size_t)itemSize capacity: (size_t)capacity;

















/**
 * @brief Initializes an already allocated OFMutableData with enough memory to
 *	  hold the the specified number of items which all have an item size of
 *	  1.
 *
 * @param capacity The initial capacity for the OFMutableData
 * @return An initialized OFMutableData

Modified src/OFMutableData.m from [ab7e0d2674] to [eabfe1061f].

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





























































































29







30
31


32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
#include "config.h"

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

#import "OFMutableData.h"
#import "OFString.h"

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






























































































@implementation OFMutableData







+ (instancetype)data
{


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

}

+ (instancetype)dataWithItemSize: (size_t)itemSize
{
	return [[[self alloc] initWithItemSize: itemSize] autorelease];
}

+ (instancetype)dataWithCapacity: (size_t)capacity
{
	return [[[self alloc] initWithCapacity: capacity] autorelease];
}

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

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

	_itemSize = 1;
	_freeWhenDone = true;

	return self;
}

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

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_itemSize = itemSize;
		_freeWhenDone = true;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithCapacity: (size_t)capacity
{
	return [self initWithItemSize: 1
			     capacity: capacity];
}

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

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_items = OFAllocMemory(capacity, itemSize);
		_itemSize = itemSize;
		_capacity = capacity;
		_freeWhenDone = true;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	self = [super initWithItems: items count: count itemSize: itemSize];

	_capacity = _count;

	return self;
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	self = [self initWithItems: items count: count itemSize: itemSize];

	if (freeWhenDone)
		OFFreeMemory(items);

	return self;
}

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

	_capacity = _count;

	return self;
}

- (void *)mutableItems
{
	return _items;

}

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

	return _items + idx * _itemSize;
}

- (void *)mutableFirstItem
{

	if (_items == NULL || _count == 0)

		return NULL;

	return _items;
}

- (void *)mutableLastItem
{



	if (_items == NULL || _count == 0)
		return NULL;

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

- (OFData *)subdataWithRange: (OFRange)range
{


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


	return [OFData dataWithItems: _items + (range.location * _itemSize)

			       count: range.length
			    itemSize: _itemSize];
}

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

	if (_count + 1 > _capacity) {
		_items = OFResizeMemory(_items, _count + 1, _itemSize);
		_capacity = _count + 1;
	}

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

	_count++;
}

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

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

	if (_count + count > _capacity) {
		_items = OFResizeMemory(_items, _count + count, _itemSize);
		_capacity = _count + count;
	}

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

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

	if (_count + count > _capacity) {
		_items = OFResizeMemory(_items, _count + count, _itemSize);
		_capacity = _count + count;
	}

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

	_count += count;
}

- (void)increaseCountBy: (size_t)count
{
	if (count > SIZE_MAX - _count)
		@throw [OFOutOfRangeException exception];

	if (_count + count > _capacity) {
		_items = OFResizeMemory(_items, _count + count, _itemSize);
		_capacity = _count + count;
	}

	memset(_items + _count * _itemSize, '\0', count * _itemSize);
	_count += count;
}

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

- (void)removeItemsInRange: (OFRange)range
{
	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > _count)
		@throw [OFOutOfRangeException exception];

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

	_count -= range.length;
	@try {
		_items = OFResizeMemory(_items, _count, _itemSize);
		_capacity = _count;
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
	}
}

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

	_count--;
	@try {
		_items = OFResizeMemory(_items, _count, _itemSize);
		_capacity = _count;
	} @catch (OFOutOfMemoryException *e) {
		/* We don't care, as we only made it smaller */
	}

}

- (void)removeAllItems
{
	OFFreeMemory(_items);
	_items = NULL;
	_count = 0;
	_capacity = 0;
}

- (id)copy
{
	return [[OFData alloc] initWithItems: _items
				       count: _count
				    itemSize: _itemSize];
}

- (void)makeImmutable
{
	if (_capacity != _count) {
		@try {
			_items = OFResizeMemory(_items, _count, _itemSize);
			_capacity = _count;
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only made it smaller */
		}
	}

	object_setClass(self, [OFData class]);
}
@end







|

<
<


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
|

>
>
|
>


















<
<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
|




|
<




<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<















<
<
<
<
<
<
<
<
<


<
>




|


|




>
|
>


|




>
>
>
|


|




>
>

|


>
|
>

|




<
<
|
<
<
<
<
<
<
<
<









<
<
|
<
<
<
<
<
<
<






<
<
|
<
<
<
<
<
<
<
<
<
<




<
<
|
<
<
<
<
<
<
<









<
<
<
|
<
<
<
<
<
<
<
<
<
<
<




|
<

|
|
<
<
<
<
|
>




<
<
|
<




|
|
|




<
<
<
<
<
<
|
<
<
<
<

16
17
18
19
20
21
22
23
24


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
#include "config.h"

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

#import "OFMutableData.h"
#import "OFConcreteMutableData.h"



#import "OFOutOfRangeException.h"

static struct {
	Class isa;
} placeholder;

@interface OFPlaceholderMutableData: OFMutableData
@end

@implementation OFPlaceholderMutableData
- (instancetype)init
{
	return (id)[[OFConcreteMutableData alloc] init];
}

- (instancetype)initWithItemSize: (size_t)itemSize
{
	return (id)[[OFConcreteMutableData alloc] initWithItemSize: itemSize];
}

- (instancetype)initWithItems: (const void *)items count: (size_t)count
{
	return (id)[[OFConcreteMutableData alloc] initWithItems: items
							  count: count];
}

- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	return (id)[[OFConcreteMutableData alloc] initWithItems: items
							  count: count
						       itemSize: itemSize];
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	return (id)[[OFConcreteMutableData alloc]
	    initWithItemsNoCopy: items
			  count: count
		   freeWhenDone: freeWhenDone];
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	return (id)[[OFConcreteMutableData alloc]
	    initWithItemsNoCopy: items
			  count: count
		       itemSize: itemSize
		   freeWhenDone: freeWhenDone];
}

#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path
{
	return (id)[[OFConcreteMutableData alloc] initWithContentsOfFile: path];
}
#endif

- (instancetype)initWithContentsOfIRI: (OFIRI *)IRI
{
	return (id)[[OFConcreteMutableData alloc] initWithContentsOfIRI: IRI];
}

- (instancetype)initWithStringRepresentation: (OFString *)string
{
	return (id)[[OFConcreteMutableData alloc]
	    initWithStringRepresentation: string];
}

- (instancetype)initWithBase64EncodedString: (OFString *)string
{
	return (id)[[OFConcreteMutableData alloc]
	    initWithBase64EncodedString: string];
}

- (instancetype)initWithCapacity: (size_t)capacity
{
	return (id)[[OFConcreteMutableData alloc] initWithCapacity: capacity];
}

- (instancetype)initWithItemSize: (size_t)itemSize capacity: (size_t)capacity
{
	return (id)[[OFConcreteMutableData alloc] initWithItemSize: itemSize
							  capacity: capacity];
}

OF_SINGLETON_METHODS
@end

@implementation OFMutableData
+ (void)initialize
{
	if (self == [OFMutableData class])
		object_setClass((id)&placeholder,
		    [OFPlaceholderMutableData class]);
}

+ (instancetype)alloc
{
	if (self == [OFMutableData class])
		return (id)&placeholder;

	return [super alloc];
}

+ (instancetype)dataWithItemSize: (size_t)itemSize
{
	return [[[self alloc] initWithItemSize: itemSize] autorelease];
}

+ (instancetype)dataWithCapacity: (size_t)capacity
{
	return [[[self alloc] initWithCapacity: capacity] autorelease];
}

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











- (instancetype)initWithItemSize: (size_t)itemSize
{













	return [self initWithItemSize: 1 capacity: 0];
}

- (instancetype)initWithCapacity: (size_t)capacity
{
	return [self initWithItemSize: 1 capacity: capacity];

}

- (instancetype)initWithItemSize: (size_t)itemSize capacity: (size_t)capacity
{

	OF_INVALID_INIT_METHOD

























}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	self = [self initWithItems: items count: count itemSize: itemSize];

	if (freeWhenDone)
		OFFreeMemory(items);

	return self;
}










- (void *)mutableItems
{

	OF_UNRECOGNIZED_SELECTOR
}

- (void *)mutableItemAtIndex: (size_t)idx
{
	if (idx >= self.count)
		@throw [OFOutOfRangeException exception];

	return (unsigned char *)self.mutableItems + idx * self.itemSize;
}

- (void *)mutableFirstItem
{
	void *mutableItems = self.mutableItems;

	if (mutableItems == NULL || self.count == 0)
		return NULL;

	return mutableItems;
}

- (void *)mutableLastItem
{
	unsigned char *mutableItems = self.mutableItems;
	size_t count = self.count;

	if (mutableItems == NULL || count == 0)
		return NULL;

	return mutableItems + (count - 1) * self.itemSize;
}

- (OFData *)subdataWithRange: (OFRange)range
{
	size_t itemSize;

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

	itemSize = self.itemSize;
	return [OFData dataWithItems: (unsigned char *)self.mutableItems +
				      (range.location * itemSize)
			       count: range.length
			    itemSize: itemSize];
}

- (void)addItem: (const void *)item
{


	[self insertItems: item atIndex: self.count count: 1];








}

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

- (void)addItems: (const void *)items count: (size_t)count
{


	[self insertItems: items atIndex: self.count count: count];







}

- (void)insertItems: (const void *)items
	    atIndex: (size_t)idx
	      count: (size_t)count
{


	OF_UNRECOGNIZED_SELECTOR










}

- (void)increaseCountBy: (size_t)count
{


	OF_UNRECOGNIZED_SELECTOR







}

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

- (void)removeItemsInRange: (OFRange)range
{



	OF_UNRECOGNIZED_SELECTOR











}

- (void)removeLastItem
{
	size_t count = self.count;


	if (count == 0)
		return;





	[self removeItemsInRange: OFMakeRange(count - 1, 1)];
}

- (void)removeAllItems
{


	[self removeItemsInRange: OFMakeRange(0, self.count)];

}

- (id)copy
{
	return [[OFData alloc] initWithItems: self.mutableItems
				       count: self.count
				    itemSize: self.itemSize];
}

- (void)makeImmutable
{






}




@end

Modified src/OFMutableDictionary.m from [4bd030691a] to [c24bbf1afd].

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
 * file.
 */

#include "config.h"

#include <stdlib.h>

#import "OFMutableMapTableDictionary.h"
#import "OFArray.h"
#import "OFString.h"

static struct {
	Class isa;
} placeholder;

@interface OFMutableDictionaryPlaceholder: OFDictionary
@end

@implementation OFMutableDictionaryPlaceholder
- (instancetype)init
{
	return (id)[[OFMutableMapTableDictionary alloc] init];
}

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

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

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

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

- (instancetype)initWithKeysAndObjects: (id)firstKey, ...
{
	id ret;
	va_list arguments;

	va_start(arguments, firstKey);
	ret = (id)[[OFMutableMapTableDictionary alloc] initWithKey: firstKey
							 arguments: arguments];
	va_end(arguments);

	return ret;
}

- (instancetype)initWithKey: (id)firstKey arguments: (va_list)arguments
{
	return (id)[[OFMutableMapTableDictionary alloc] initWithKey: firstKey
							  arguments: arguments];
}

- (instancetype)initWithCapacity: (size_t)capacity
{
	return (id)[[OFMutableMapTableDictionary alloc]
	    initWithCapacity: capacity];
}

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end

@implementation OFMutableDictionary
+ (void)initialize
{
	if (self == [OFMutableDictionary class])

		placeholder.isa = [OFMutableDictionaryPlaceholder class];
}

+ (instancetype)alloc
{
	if (self == [OFMutableDictionary class])
		return (id)&placeholder;

	return [super alloc];
}

+ (instancetype)dictionaryWithCapacity: (size_t)capacity
{
	return [[[self alloc] initWithCapacity: capacity] autorelease];
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFMutableDictionary class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
		} @catch (id e) {
			[self release];
			@throw e;
		}

		abort();
	}

	return [super init];
}

- (instancetype)initWithCapacity: (size_t)capacity
{
	OF_INVALID_INIT_METHOD
}

- (void)setObject: (id)object forKey: (id)key
{







|







|


|


|




|





|





|







|










|








|





|



<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<






>
|















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88




89













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
 * file.
 */

#include "config.h"

#include <stdlib.h>

#import "OFConcreteMutableDictionary.h"
#import "OFArray.h"
#import "OFString.h"

static struct {
	Class isa;
} placeholder;

@interface OFPlaceholderMutableDictionary: OFDictionary
@end

@implementation OFPlaceholderMutableDictionary
- (instancetype)init
{
	return (id)[[OFConcreteMutableDictionary alloc] init];
}

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

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

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

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

- (instancetype)initWithKeysAndObjects: (id)firstKey, ...
{
	id ret;
	va_list arguments;

	va_start(arguments, firstKey);
	ret = (id)[[OFConcreteMutableDictionary alloc] initWithKey: firstKey
							 arguments: arguments];
	va_end(arguments);

	return ret;
}

- (instancetype)initWithKey: (id)firstKey arguments: (va_list)arguments
{
	return (id)[[OFConcreteMutableDictionary alloc] initWithKey: firstKey
							  arguments: arguments];
}

- (instancetype)initWithCapacity: (size_t)capacity
{
	return (id)[[OFConcreteMutableDictionary alloc]
	    initWithCapacity: capacity];
}





OF_SINGLETON_METHODS













@end

@implementation OFMutableDictionary
+ (void)initialize
{
	if (self == [OFMutableDictionary class])
		object_setClass((id)&placeholder,
		    [OFPlaceholderMutableDictionary class]);
}

+ (instancetype)alloc
{
	if (self == [OFMutableDictionary class])
		return (id)&placeholder;

	return [super alloc];
}

+ (instancetype)dictionaryWithCapacity: (size_t)capacity
{
	return [[[self alloc] initWithCapacity: capacity] autorelease];
}

















- (instancetype)initWithCapacity: (size_t)capacity
{
	OF_INVALID_INIT_METHOD
}

- (void)setObject: (id)object forKey: (id)key
{

Modified src/OFMutableSet.m from [f395937f21] to [c4dda1aa5f].

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
 */

#include "config.h"

#include <stdlib.h>

#import "OFMutableSet.h"
#import "OFMutableMapTableSet.h"
#import "OFString.h"

static struct {
	Class isa;
} placeholder;

@interface OFMutableSetPlaceholder: OFMutableSet
@end

@implementation OFMutableSetPlaceholder
- (instancetype)init
{
	return (id)[[OFMutableMapTableSet alloc] init];
}

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

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

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

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

	return ret;
}

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

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

- (instancetype)initWithCapacity: (size_t)capacity
{
	return (id)[[OFMutableMapTableSet alloc] initWithCapacity: capacity];
}

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end

@implementation OFMutableSet
+ (void)initialize
{
	if (self == [OFMutableSet class])
		placeholder.isa = [OFMutableSetPlaceholder class];

}

+ (instancetype)alloc
{
	if (self == [OFMutableSet class])
		return (id)&placeholder;

	return [super alloc];
}

+ (instancetype)setWithCapacity: (size_t)capacity
{
	return [[[self alloc] initWithCapacity: capacity] autorelease];
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFMutableSet class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
			abort();
		} @catch (id e) {
			[self release];
			@throw e;
		}
	}

	return [super init];
}

- (instancetype)initWithCapacity: (size_t)capacity
{
	OF_INVALID_INIT_METHOD
}

- (id)copy
{







|






|


|


|




|




|








|








|





|





|


<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<






|
>















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76




77













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















101
102
103
104
105
106
107
 */

#include "config.h"

#include <stdlib.h>

#import "OFMutableSet.h"
#import "OFConcreteMutableSet.h"
#import "OFString.h"

static struct {
	Class isa;
} placeholder;

@interface OFPlaceholderMutableSet: OFMutableSet
@end

@implementation OFPlaceholderMutableSet
- (instancetype)init
{
	return (id)[[OFConcreteMutableSet alloc] init];
}

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

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

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

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

	return ret;
}

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

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

- (instancetype)initWithCapacity: (size_t)capacity
{
	return (id)[[OFConcreteMutableSet alloc] initWithCapacity: capacity];
}





OF_SINGLETON_METHODS













@end

@implementation OFMutableSet
+ (void)initialize
{
	if (self == [OFMutableSet class])
		object_setClass((id)&placeholder,
		    [OFPlaceholderMutableSet class]);
}

+ (instancetype)alloc
{
	if (self == [OFMutableSet class])
		return (id)&placeholder;

	return [super alloc];
}

+ (instancetype)setWithCapacity: (size_t)capacity
{
	return [[[self alloc] initWithCapacity: capacity] autorelease];
}
















- (instancetype)initWithCapacity: (size_t)capacity
{
	OF_INVALID_INIT_METHOD
}

- (id)copy
{

Modified src/OFMutableString.h from [02fdd7e9ff] to [0f33d313e2].

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#ifndef OBJFW_OF_MUTABLE_STRING_H
#define OBJFW_OF_MUTABLE_STRING_H

#include "OFString.h"

OF_ASSUME_NONNULL_BEGIN

#ifdef __OBJC__
/**
 * @class OFMutableString OFString.h ObjFW/OFString.h
 *
 * @brief A class for storing and modifying strings.
 */
@interface OFMutableString: OFString
/**







<
<
<
|



<







9
10
11
12
13
14
15



16
17
18
19

20
21
22
23
24
25
26
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */




#import "OFString.h"

OF_ASSUME_NONNULL_BEGIN


/**
 * @class OFMutableString OFString.h ObjFW/OFString.h
 *
 * @brief A class for storing and modifying strings.
 */
@interface OFMutableString: OFString
/**
206
207
208
209
210
211
212
213
214
215
216
217
- (void)deleteEnclosingWhitespaces;

/**
 * @brief Converts the mutable string to an immutable string.
 */
- (void)makeImmutable;
@end
#endif

OF_ASSUME_NONNULL_END

#endif







<


<
<
202
203
204
205
206
207
208

209
210


- (void)deleteEnclosingWhitespaces;

/**
 * @brief Converts the mutable string to an immutable string.
 */
- (void)makeImmutable;
@end


OF_ASSUME_NONNULL_END


Modified src/OFMutableString.m from [6babdf726b] to [19236c79ee].

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

#import "unicode.h"

static struct {
	Class isa;
} placeholder;

@interface OFMutableStringPlaceholder: OFMutableString
@end

@implementation OFMutableStringPlaceholder
- (instancetype)init
{
	return (id)[[OFMutableUTF8String alloc] init];
}

- (instancetype)initWithUTF8String: (const char *)UTF8String
{







|


|







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

#import "unicode.h"

static struct {
	Class isa;
} placeholder;

@interface OFPlaceholderMutableString: OFMutableString
@end

@implementation OFPlaceholderMutableString
- (instancetype)init
{
	return (id)[[OFMutableUTF8String alloc] init];
}

- (instancetype)initWithUTF8String: (const char *)UTF8String
{
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
			     encoding: (OFStringEncoding)encoding
{
	return (id)[[OFMutableUTF8String alloc]
	    initWithContentsOfIRI: IRI
			 encoding: encoding];
}

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end

@implementation OFMutableString
+ (void)initialize
{
	if (self == [OFMutableString class])

		placeholder.isa = [OFMutableStringPlaceholder class];
}

+ (instancetype)alloc
{
	if (self == [OFMutableString class])
		return (id)&placeholder;








<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<






>
|







183
184
185
186
187
188
189




190













191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
			     encoding: (OFStringEncoding)encoding
{
	return (id)[[OFMutableUTF8String alloc]
	    initWithContentsOfIRI: IRI
			 encoding: encoding];
}





OF_SINGLETON_METHODS













@end

@implementation OFMutableString
+ (void)initialize
{
	if (self == [OFMutableString class])
		object_setClass((id)&placeholder,
		    [OFPlaceholderMutableString class]);
}

+ (instancetype)alloc
{
	if (self == [OFMutableString class])
		return (id)&placeholder;

Modified src/OFNotificationCenter.m from [bec84a1cd3] to [3787fafa30].

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

	objc_autoreleasePoolPop(pool);
}
@end

@implementation OFDefaultNotificationCenter
- (instancetype)autorelease
{
	return self;
}

- (instancetype)retain
{
	return self;
}

- (void)release
{
}

- (unsigned int)retainCount
{
	return OFMaxRetainCount;
}
@end







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<

379
380
381
382
383
384
385




386













387
					userInfo: userInfo]];

	objc_autoreleasePoolPop(pool);
}
@end

@implementation OFDefaultNotificationCenter




OF_SINGLETON_METHODS













@end

Modified src/OFNull.m from [820a727986] to [9a95c48990].

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

- (OFData *)messagePackRepresentation
{
	uint8_t type = 0xC0;
	return [OFData dataWithItems: &type count: 1];
}

- (instancetype)autorelease
{
	return self;
}

- (instancetype)retain
{
	return self;
}

- (void)release
{
}

- (unsigned int)retainCount
{
	return OFMaxRetainCount;
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

70
71
72
73
74
75
76




77


















78

- (OFData *)messagePackRepresentation
{
	uint8_t type = 0xC0;
	return [OFData dataWithItems: &type count: 1];
}





OF_SINGLETON_METHODS


















@end

Modified src/OFNumber.m from [b9b4334494] to [8fe1f42701].

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@interface OFNumber ()
+ (instancetype)of_alloc;
- (OFString *)
    of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options
			       depth: (size_t)depth;
@end

@interface OFNumberPlaceholder: OFNumber
@end

@interface OFNumberSingleton: OFNumber
@end

#ifdef OF_OBJFW_RUNTIME
enum Tag {







|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@interface OFNumber ()
+ (instancetype)of_alloc;
- (OFString *)
    of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options
			       depth: (size_t)depth;
@end

@interface OFPlaceholderNumber: OFNumber
@end

@interface OFNumberSingleton: OFNumber
@end

#ifdef OF_OBJFW_RUNTIME
enum Tag {
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
	case 'd':
		return true;
	default:
		return false;
	}
}

@implementation OFNumberPlaceholder
- (instancetype)initWithBool: (bool)value
{
	if (value) {
		static OFOnceControl onceControl = OFOnceControlInitValue;
		OFOnce(&onceControl, trueNumberInit);
		return (id)trueNumber;
	} else {







|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
	case 'd':
		return true;
	default:
		return false;
	}
}

@implementation OFPlaceholderNumber
- (instancetype)initWithBool: (bool)value
{
	if (value) {
		static OFOnceControl onceControl = OFOnceControlInitValue;
		OFOnce(&onceControl, trueNumberInit);
		return (id)trueNumber;
	} else {
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
	}

	return (id)[[OFNumber of_alloc] initWithDouble: value];
}
#ifdef __clang__
# pragma clang diagnostic pop
#endif


@end

@implementation OFNumberSingleton
- (instancetype)autorelease
{
	return self;
}

- (instancetype)retain
{
	return self;
}

- (void)release
{
}

- (unsigned int)retainCount
{
	return OFMaxRetainCount;
}
@end

#ifdef OF_OBJFW_RUNTIME
@implementation OFTaggedPointerNumber
- (const char *)objCType
{
	uintptr_t value = object_getTaggedPointerValue(self);







>
>



<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<







374
375
376
377
378
379
380
381
382
383
384
385




386













387
388
389
390
391
392
393
	}

	return (id)[[OFNumber of_alloc] initWithDouble: value];
}
#ifdef __clang__
# pragma clang diagnostic pop
#endif

OF_SINGLETON_METHODS
@end

@implementation OFNumberSingleton




OF_SINGLETON_METHODS













@end

#ifdef OF_OBJFW_RUNTIME
@implementation OFTaggedPointerNumber
- (const char *)objCType
{
	uintptr_t value = object_getTaggedPointerValue(self);
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

@implementation OFNumber
+ (void)initialize
{
	if (self != [OFNumber class])
		return;

	placeholder.isa = [OFNumberPlaceholder class];

#ifdef OF_OBJFW_RUNTIME
	numberTag =
	    objc_registerTaggedPointerClass([OFTaggedPointerNumber class]);
#endif
}








|







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

@implementation OFNumber
+ (void)initialize
{
	if (self != [OFNumber class])
		return;

	object_setClass((id)&placeholder, [OFPlaceholderNumber class]);

#ifdef OF_OBJFW_RUNTIME
	numberTag =
	    objc_registerTaggedPointerClass([OFTaggedPointerNumber class]);
#endif
}

Modified src/OFObject.h from [f176d35c0c] to [2c787e015d].

9
10
11
12
13
14
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
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#ifndef OBJFW_OF_OBJECT_H
#define OBJFW_OF_OBJECT_H

#include "objfw-defs.h"

#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS
#endif

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>

#include "macros.h"

#include "OFOnce.h"

/*
 * Some versions of MinGW require <winsock2.h> to be included before
 * <windows.h>. Do this here to make sure this is always done in the correct
 * order, even if another header includes just <windows.h>.
 */
#ifdef __MINGW32__







<
<
<
















|







9
10
11
12
13
14
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
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */




#include "objfw-defs.h"

#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS
#endif

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>

#include "macros.h"

#import "OFOnce.h"

/*
 * Some versions of MinGW require <winsock2.h> to be included before
 * <windows.h>. Do this here to make sure this is always done in the correct
 * order, even if another header includes just <windows.h>.
 */
#ifdef __MINGW32__
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
	tmp += tmp << 15;

	*hash = tmp;
}

static const size_t OFNotFound = SIZE_MAX;

#ifdef __OBJC__
@class OFMethodSignature;
@class OFString;
@class OFThread;

/**
 * @protocol OFObject OFObject.h ObjFW/OFObject.h
 *







<







450
451
452
453
454
455
456

457
458
459
460
461
462
463
	tmp += tmp << 15;

	*hash = tmp;
}

static const size_t OFNotFound = SIZE_MAX;


@class OFMethodSignature;
@class OFString;
@class OFThread;

/**
 * @protocol OFObject OFObject.h ObjFW/OFObject.h
 *
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
/**
 * @brief Retain a weak reference to this object.
 *
 * @return Whether a weak reference to this object has been retained
 */
- (bool)retainWeakReference;
@end
#endif

/**
 * @class OFObject OFObject.h ObjFW/OFObject.h
 *
 * @brief The root class for all other classes inside ObjFW.
 */
#ifdef __OBJC__
OF_ROOT_CLASS
@interface OFObject <OFObject>
{
@private
# ifndef __clang_analyzer__
	Class _isa;
# else
	Class _isa __attribute__((__unused__));
# endif
}

# ifdef OF_HAVE_CLASS_PROPERTIES
#  ifndef __cplusplus
@property (class, readonly, nonatomic) Class class;
#  else
@property (class, readonly, nonatomic, getter=class) Class class_;
#  endif
@property (class, readonly, nonatomic) OFString *className;
@property (class, readonly, nullable, nonatomic) Class superclass;
@property (class, readonly, nonatomic) OFString *description;
# endif

# ifndef __cplusplus
@property (readonly, nonatomic) Class class;
# else
@property (readonly, nonatomic, getter=class) Class class_;
#endif
@property OF_NULLABLE_PROPERTY (readonly, nonatomic) Class superclass;
@property (readonly, nonatomic) unsigned long hash;
@property (readonly, nonatomic) unsigned int retainCount;
@property (readonly, nonatomic) bool isProxy;
@property (readonly, nonatomic) bool allowsWeakReference;







<






<




|

|

|


|
|

|

|



|

|

|







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
/**
 * @brief Retain a weak reference to this object.
 *
 * @return Whether a weak reference to this object has been retained
 */
- (bool)retainWeakReference;
@end


/**
 * @class OFObject OFObject.h ObjFW/OFObject.h
 *
 * @brief The root class for all other classes inside ObjFW.
 */

OF_ROOT_CLASS
@interface OFObject <OFObject>
{
@private
#ifndef __clang_analyzer__
	Class _isa;
#else
	Class _isa __attribute__((__unused__));
#endif
}

#ifdef OF_HAVE_CLASS_PROPERTIES
# ifndef __cplusplus
@property (class, readonly, nonatomic) Class class;
# else
@property (class, readonly, nonatomic, getter=class) Class class_;
# endif
@property (class, readonly, nonatomic) OFString *className;
@property (class, readonly, nullable, nonatomic) Class superclass;
@property (class, readonly, nonatomic) OFString *description;
#endif

#ifndef __cplusplus
@property (readonly, nonatomic) Class class;
#else
@property (readonly, nonatomic, getter=class) Class class_;
#endif
@property OF_NULLABLE_PROPERTY (readonly, nonatomic) Class superclass;
@property (readonly, nonatomic) unsigned long hash;
@property (readonly, nonatomic) unsigned int retainCount;
@property (readonly, nonatomic) bool isProxy;
@property (readonly, nonatomic) bool allowsWeakReference;
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
- (void)performSelector: (SEL)selector
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     withObject: (nullable id)object4
	     afterDelay: (OFTimeInterval)delay;

# ifdef OF_HAVE_THREADS
/**
 * @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
 */







|







1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
- (void)performSelector: (SEL)selector
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     withObject: (nullable id)object4
	     afterDelay: (OFTimeInterval)delay;

#ifdef OF_HAVE_THREADS
/**
 * @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
 */
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     withObject: (nullable id)object4
	     afterDelay: (OFTimeInterval)delay;
# endif

/**
 * @brief This method is called when @ref resolveClassMethod: or
 *	  @ref resolveInstanceMethod: returned false. It should return a target
 *	  to which the message should be forwarded.
 *
 * @note When the message should not be forwarded, you should not return `nil`,







|







1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
- (void)performSelector: (SEL)selector
	       onThread: (OFThread *)thread
	     withObject: (nullable id)object1
	     withObject: (nullable id)object2
	     withObject: (nullable id)object3
	     withObject: (nullable id)object4
	     afterDelay: (OFTimeInterval)delay;
#endif

/**
 * @brief This method is called when @ref resolveClassMethod: or
 *	  @ref resolveInstanceMethod: returned false. It should return a target
 *	  to which the message should be forwarded.
 *
 * @note When the message should not be forwarded, you should not return `nil`,
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
 *	    returns!
 *
 * @param selector The selector not understood by the receiver
 * @throw OFNotImplementedException
 */
- (void)doesNotRecognizeSelector: (SEL)selector OF_NO_RETURN;
@end
#else
typedef void OFObject;
#endif

#ifdef __OBJC__
/**
 * @protocol OFCopying OFObject.h ObjFW/OFObject.h
 *
 * @brief A protocol for the creation of copies.
 */
@protocol OFCopying
/**







<
<
<

<







1332
1333
1334
1335
1336
1337
1338



1339

1340
1341
1342
1343
1344
1345
1346
 *	    returns!
 *
 * @param selector The selector not understood by the receiver
 * @throw OFNotImplementedException
 */
- (void)doesNotRecognizeSelector: (SEL)selector OF_NO_RETURN;
@end





/**
 * @protocol OFCopying OFObject.h ObjFW/OFObject.h
 *
 * @brief A protocol for the creation of copies.
 */
@protocol OFCopying
/**
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
 * @brief Compares the object to another object.
 *
 * @param object An object to compare the object to
 * @return The result of the comparison
 */
- (OFComparisonResult)compare: (id <OFComparing>)object;
@end
#endif

#ifdef __cplusplus
extern "C" {
#endif
/**
 * @brief Allocates memory for the specified number of items of the specified
 *	  size.







<







1384
1385
1386
1387
1388
1389
1390

1391
1392
1393
1394
1395
1396
1397
 * @brief Compares the object to another object.
 *
 * @param object An object to compare the object to
 * @return The result of the comparison
 */
- (OFComparisonResult)compare: (id <OFComparing>)object;
@end


#ifdef __cplusplus
extern "C" {
#endif
/**
 * @brief Allocates memory for the specified number of items of the specified
 *	  size.
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
extern uint64_t OFRandom64(void);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

#include "OFBlock.h"

#ifdef __OBJC__
# import "OFObject+KeyValueCoding.h"
#endif

#endif







|
<
<
|
<
<
<
1497
1498
1499
1500
1501
1502
1503
1504


1505



extern uint64_t OFRandom64(void);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

#import "OFBlock.h"


#import "OFObject+KeyValueCoding.h"



Modified src/OFObject.m from [e705635cfb] to [663f9433ab].

339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
		extraAlignment = ((instanceSize + extraAlignment - 1) &
		    ~(extraAlignment - 1)) - extraAlignment;

	instance = calloc(1, PRE_IVARS_ALIGN + instanceSize +
	    extraAlignment + extraSize);

	if OF_UNLIKELY (instance == nil) {

		allocFailedException.isa = [OFAllocFailedException class];
		@throw (id)&allocFailedException;
	}

	((struct PreIvars *)instance)->retainCount = 1;

#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
	if OF_UNLIKELY (OFSpinlockNew(







>
|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
		extraAlignment = ((instanceSize + extraAlignment - 1) &
		    ~(extraAlignment - 1)) - extraAlignment;

	instance = calloc(1, PRE_IVARS_ALIGN + instanceSize +
	    extraAlignment + extraSize);

	if OF_UNLIKELY (instance == nil) {
		object_setClass((id)&allocFailedException,
		    [OFAllocFailedException class]);
		@throw (id)&allocFailedException;
	}

	((struct PreIvars *)instance)->retainCount = 1;

#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
	if OF_UNLIKELY (OFSpinlockNew(

Modified src/OFPlainCondition.h from [f98542ce7c] to [d2cd398f52].

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
extern int OFPlainConditionNew(OFPlainCondition *condition);
extern int OFPlainConditionSignal(OFPlainCondition *condition);
extern int OFPlainConditionBroadcast(OFPlainCondition *condition);
extern int OFPlainConditionWait(OFPlainCondition *condition,
    OFPlainMutex *mutex);
extern int OFPlainConditionTimedWait(OFPlainCondition *condition,
    OFPlainMutex *mutex, OFTimeInterval timeout);
#ifdef OF_AMIGAOS
extern int OFPlainConditionWaitOrExecSignal(OFPlainCondition *condition,
    OFPlainMutex *mutex, ULONG *signalMask);
extern int OFPlainConditionTimedWaitOrExecSignal(OFPlainCondition *condition,
    OFPlainMutex *mutex, OFTimeInterval timeout, ULONG *signalMask);
#endif
extern int OFPlainConditionFree(OFPlainCondition *condition);
#ifdef __cplusplus
}
#endif







|









52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
extern int OFPlainConditionNew(OFPlainCondition *condition);
extern int OFPlainConditionSignal(OFPlainCondition *condition);
extern int OFPlainConditionBroadcast(OFPlainCondition *condition);
extern int OFPlainConditionWait(OFPlainCondition *condition,
    OFPlainMutex *mutex);
extern int OFPlainConditionTimedWait(OFPlainCondition *condition,
    OFPlainMutex *mutex, OFTimeInterval timeout);
#if defined(OF_AMIGAOS) || defined(DOXYGEN)
extern int OFPlainConditionWaitOrExecSignal(OFPlainCondition *condition,
    OFPlainMutex *mutex, ULONG *signalMask);
extern int OFPlainConditionTimedWaitOrExecSignal(OFPlainCondition *condition,
    OFPlainMutex *mutex, OFTimeInterval timeout, ULONG *signalMask);
#endif
extern int OFPlainConditionFree(OFPlainCondition *condition);
#ifdef __cplusplus
}
#endif

Modified src/OFRunLoop.h from [575aa234f6] to [7ce3da0557].

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
 * @brief Adds an OFTimer to the run loop for the specified mode.
 *
 * @param timer The timer to add
 * @param mode The run loop mode in which to run the timer
 */
- (void)addTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode;

#ifdef OF_AMIGAOS
/**
 * @brief Adds an Exec Signal to the run loop.
 *
 * If a signal is added multiple times, the specified methods will be performed
 * in the order added.
 *
 * @note This is only available on AmigaOS!







|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
 * @brief Adds an OFTimer to the run loop for the specified mode.
 *
 * @param timer The timer to add
 * @param mode The run loop mode in which to run the timer
 */
- (void)addTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode;

#if defined(OF_AMIGAOS) || defined(DOXYGEN)
/**
 * @brief Adds an Exec Signal to the run loop.
 *
 * If a signal is added multiple times, the specified methods will be performed
 * in the order added.
 *
 * @note This is only available on AmigaOS!

Modified src/OFRunLoop.m from [e289a6e931] to [74044bacbe].

1610
1611
1612
1613
1614
1615
1616

1617
1618
1619
1620
1621
1622
1623
#ifdef OF_HAVE_THREADS
			} @finally {
				[state->_timersQueueMutex unlock];
			}
#endif

			if (timer.valid) {

				[timer fire];
				return;
			}
		}

#ifdef OF_HAVE_THREADS
		[state->_timersQueueMutex lock];







>







1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
#ifdef OF_HAVE_THREADS
			} @finally {
				[state->_timersQueueMutex unlock];
			}
#endif

			if (timer.valid) {
				[timer of_reschedule];
				[timer fire];
				return;
			}
		}

#ifdef OF_HAVE_THREADS
		[state->_timersQueueMutex lock];

Modified src/OFSecureData.h from [5deb9cb9cd] to [37557f6a68].

28
29
30
31
32
33
34



35
36
37
38
39
40
41
42
43
 *	    deallocated. Check the @ref allowsSwappableMemory property to see
 *	    whether a particular OFSecureData might be allocated in swappable
 *	    memory.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFSecureData: OFData
{



	void *_page;
	bool _allowsSwappableMemory;
}

/**
 * @brief Whether the data may be stored in swappable memory.
 */
@property (readonly, nonatomic) bool allowsSwappableMemory;








>
>
>

<







28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
 *	    deallocated. Check the @ref allowsSwappableMemory property to see
 *	    whether a particular OFSecureData might be allocated in swappable
 *	    memory.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFSecureData: OFData
{
	unsigned char *_Nullable _items;
	size_t _count, _itemSize;
	bool _freeWhenDone, _allowsSwappableMemory;
	void *_page;

}

/**
 * @brief Whether the data may be stored in swappable memory.
 */
@property (readonly, nonatomic) bool allowsSwappableMemory;

131
132
133
134
135
136
137


138
139
140
141
142
143
144
 * @return An initialized OFSecureData
 */
- (instancetype)initWithCount: (size_t)count
		     itemSize: (size_t)itemSize
	allowsSwappableMemory: (bool)allowsSwappableMemory
    OF_DESIGNATED_INITIALIZER;



- (instancetype)initWithItems: (const void *)items
			count: (size_t)count OF_UNAVAILABLE;
- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize OF_UNAVAILABLE;
- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count







>
>







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
 * @return An initialized OFSecureData
 */
- (instancetype)initWithCount: (size_t)count
		     itemSize: (size_t)itemSize
	allowsSwappableMemory: (bool)allowsSwappableMemory
    OF_DESIGNATED_INITIALIZER;

- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithItemSize: (size_t)itemSize OF_UNAVAILABLE;
- (instancetype)initWithItems: (const void *)items
			count: (size_t)count OF_UNAVAILABLE;
- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize OF_UNAVAILABLE;
- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count

Modified src/OFSecureData.m from [47b9727f66] to [21abf2b09b].

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
{
	return [[[self alloc] initWithCount: count
				   itemSize: itemSize
		      allowsSwappableMemory: allowsSwappableMemory]
	    autorelease];
}

+ (instancetype)dataWithItems: (const void *)items
			count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)dataWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize







|
<







336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
{
	return [[[self alloc] initWithCount: count
				   itemSize: itemSize
		      allowsSwappableMemory: allowsSwappableMemory]
	    autorelease];
}

+ (instancetype)dataWithItems: (const void *)items count: (size_t)count

{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)dataWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)dataWithBase64EncodedString: (OFString *)string
{
	OF_UNRECOGNIZED_SELECTOR
}


- (instancetype)initWithCount: (size_t)count
	allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [self initWithCount: count
			  itemSize: 1
	     allowsSwappableMemory: allowsSwappableMemory];







<







384
385
386
387
388
389
390

391
392
393
394
395
396
397
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)dataWithBase64EncodedString: (OFString *)string
{
	OF_UNRECOGNIZED_SELECTOR
}


- (instancetype)initWithCount: (size_t)count
	allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [self initWithCount: count
			  itemSize: 1
	     allowsSwappableMemory: allowsSwappableMemory];
460
461
462
463
464
465
466










467
468
469
470
471
472
473
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}











- (instancetype)initWithItems: (const void *)items count: (size_t)count
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithItems: (const void *)items







>
>
>
>
>
>
>
>
>
>







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithItemSize: (size_t)itemSize
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithItems: (const void *)items count: (size_t)count
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithItems: (const void *)items
531
532
533
534
535
536
537



538
539















540
541
542
543
544
545
546
				freeMemory(_page, _items, _count * _itemSize);

			removePageIfEmpty(_page);
		}
	}
#endif




	[super dealloc];
}
















- (void *)mutableItems
{
	return _items;
}

- (void *)mutableItemAtIndex: (size_t)idx







>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
				freeMemory(_page, _items, _count * _itemSize);

			removePageIfEmpty(_page);
		}
	}
#endif

	if (_freeWhenDone)
		OFFreeMemory(_items);

	[super dealloc];
}

- (size_t)count
{
	return _count;
}

- (size_t)itemSize
{
	return _itemSize;
}

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

- (void *)mutableItems
{
	return _items;
}

- (void *)mutableItemAtIndex: (size_t)idx
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

	return copy;
}

- (bool)isEqual: (id)object
{
	OFData *otherData;

	unsigned char diff;

	if (object == self)
		return true;

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

	otherData = object;


	if (otherData->_count != _count || otherData->_itemSize != _itemSize)
		return false;

	diff = 0;

	for (size_t i = 0; i < _count * _itemSize; i++)
		diff |= otherData->_items[i] ^ _items[i];

	return (diff == 0);
}

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







>









>

|





|







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

	return copy;
}

- (bool)isEqual: (id)object
{
	OFData *otherData;
	const unsigned char *otherDataItems;
	unsigned char diff;

	if (object == self)
		return true;

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

	otherData = object;
	otherDataItems = otherData.items;

	if (otherData.count != _count || otherData.itemSize != _itemSize)
		return false;

	diff = 0;

	for (size_t i = 0; i < _count * _itemSize; i++)
		diff |= otherDataItems[i] ^ _items[i];

	return (diff == 0);
}

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

Modified src/OFSeekableStream.h from [68192be558] to [8647af4bcb].

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/** @file */

#if defined(OF_WINDOWS)
typedef __int64 OFStreamOffset;
#elif defined(OF_ANDROID)
typedef long long OFStreamOffset;
#elif defined(OF_MORPHOS)
typedef signed long long OFStreamOffset;
#elif defined(OF_HAVE_OFF64_T)
typedef off64_t OFStreamOffset;
#else
typedef off_t OFStreamOffset;
#endif

/**







|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/** @file */

#if defined(OF_WINDOWS)
typedef __int64 OFStreamOffset;
#elif defined(OF_ANDROID)
typedef long long OFStreamOffset;
#elif defined(OF_MORPHOS)
typedef long long OFStreamOffset;
#elif defined(OF_HAVE_OFF64_T)
typedef off64_t OFStreamOffset;
#else
typedef off_t OFStreamOffset;
#endif

/**

Modified src/OFSequencedPacketSocket.h from [2027150bf7] to [94c6897cee].

363
364
365
366
367
368
369
























370
371
372
373
374
375
376
377
378
379
#endif

/**
 * @brief Cancels all pending asynchronous requests on the socket.
 */
- (void)cancelAsyncRequests;

























/**
 * @brief Closes the socket so that it can neither receive nor send any more
 *	  datagrams.
 *
 * @throw OFNotOpenException The socket is not open
 */
- (void)close;
@end

OF_ASSUME_NONNULL_END







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










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

/**
 * @brief Cancels all pending asynchronous requests on the socket.
 */
- (void)cancelAsyncRequests;

/**
 * @brief Releases the socket from the current thread.
 *
 * This is necessary on some platforms in order to allow a different thread to
 * use the socket, e.g. on AmigaOS, but you should call it on all operating
 * systems before using the socket from a different thread.
 *
 * After calling this method, you must no longer use the socket until
 * @ref obtainSocketForCurrentThread has been called.
 */
- (void)releaseSocketFromCurrentThread;

/**
 * @brief Obtains the socket for the current thread.
 *
 * This is necessary on some platforms in order to allow a different thread to
 * use the socket, e.g. on AmigaOS, but you should call it on all operating
 * systems before using the socket from a different thread.
 *
 * You must only call this method after @ref releaseSocketFromCurrentThread has
 * been called from a different thread.
 */
- (void)obtainSocketForCurrentThread;

/**
 * @brief Closes the socket so that it can neither receive nor send any more
 *	  datagrams.
 *
 * @throw OFNotOpenException The socket is not open
 */
- (void)close;
@end

OF_ASSUME_NONNULL_END

Modified src/OFSequencedPacketSocket.m from [2cba19ddea] to [2aa9e7fdaf].

462
463
464
465
466
467
468
















469
470
471
472
473
474
475
476
477
478
479
480
481

	if (_socket > INT_MAX)
		@throw [OFOutOfRangeException exception];

	return (int)_socket;
#endif
}

















- (void)close
{
	if (_socket == OFInvalidSocketHandle)
		@throw [OFNotOpenException exceptionWithObject: self];

	_listening = false;
	memset(&_remoteAddress, 0, sizeof(_remoteAddress));

	closesocket(_socket);
	_socket = OFInvalidSocketHandle;
}
@end







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













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

	if (_socket > INT_MAX)
		@throw [OFOutOfRangeException exception];

	return (int)_socket;
#endif
}

- (void)releaseSocketFromCurrentThread
{
	/*
	 * Currently a nop, as all supported OSes that have SOCK_SEQPACKET do
	 * not need anything to move sockets between threads.
	 */
}

- (void)obtainSocketForCurrentThread
{
	/*
	 * Currently a nop, as all supported OSes that have SOCK_SEQPACKET do
	 * not need anything to move sockets between threads.
	 */
}

- (void)close
{
	if (_socket == OFInvalidSocketHandle)
		@throw [OFNotOpenException exceptionWithObject: self];

	_listening = false;
	memset(&_remoteAddress, 0, sizeof(_remoteAddress));

	closesocket(_socket);
	_socket = OFInvalidSocketHandle;
}
@end

Modified src/OFSet.m from [bebf07d610] to [cf7d351eda].

15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

#include "config.h"

#include <stdlib.h>

#import "OFSet.h"
#import "OFArray.h"

#import "OFMapTableSet.h"
#import "OFNull.h"
#import "OFString.h"

static struct {
	Class isa;
} placeholder;

@interface OFSetPlaceholder: OFSet
@end

@implementation OFSetPlaceholder
- (instancetype)init
{
	return (id)[[OFMapTableSet alloc] init];
}

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

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

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

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

	return ret;
}

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

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

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end

@implementation OFSet
+ (void)initialize
{
	if (self == [OFSet class])
		placeholder.isa = [OFSetPlaceholder class];
}

+ (instancetype)alloc
{
	if (self == [OFSet class])
		return (id)&placeholder;








>
|







|


|


|




|




|








|








|





|



<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<






|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74




75













76
77
78
79
80
81
82
83
84
85
86
87
88
89

#include "config.h"

#include <stdlib.h>

#import "OFSet.h"
#import "OFArray.h"
#import "OFConcreteSet.h"
#import "OFCountedSet.h"
#import "OFNull.h"
#import "OFString.h"

static struct {
	Class isa;
} placeholder;

@interface OFPlaceholderSet: OFSet
@end

@implementation OFPlaceholderSet
- (instancetype)init
{
	return (id)[[OFConcreteSet alloc] init];
}

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

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

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

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

	return ret;
}

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

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





OF_SINGLETON_METHODS













@end

@implementation OFSet
+ (void)initialize
{
	if (self == [OFSet class])
		object_setClass((id)&placeholder, [OFPlaceholderSet class]);
}

+ (instancetype)alloc
{
	if (self == [OFSet class])
		return (id)&placeholder;

138
139
140
141
142
143
144
145


146
147
148
149
150
151
152
{
	return [[[self alloc] initWithObjects: objects
					count: count] autorelease];
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFSet class]]) {


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








|
>
>







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
{
	return [[[self alloc] initWithObjects: objects
					count: count] autorelease];
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFSet class]] ||
	    [self isMemberOfClass: [OFMutableSet class]] ||
	    [self isMemberOfClass: [OFCountedSet class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
		} @catch (id e) {
			[self release];
			@throw e;
		}

Modified src/OFSocket+Private.h from [ba231b2658] to [05528469e5].

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif

#include "OFSocket.h"

#ifndef INADDR_NONE
# define INADDR_NONE ((in_addr_t)-1)
#endif

#ifndef SOMAXCONN
/*







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif

#import "OFSocket.h"

#ifndef INADDR_NONE
# define INADDR_NONE ((in_addr_t)-1)
#endif

#ifndef SOMAXCONN
/*

Modified src/OFSocket.m from [602607c474] to [0cd5c67cfd].

954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
	node = ((uint64_t)addrIPX->sipx_node[0] << 40) |
	    ((uint64_t)addrIPX->sipx_node[1] << 32) |
	    ((uint64_t)addrIPX->sipx_node[2] << 24) |
	    ((uint64_t)addrIPX->sipx_node[3] << 16) |
	    ((uint64_t)addrIPX->sipx_node[4] << 8) |
	    (uint64_t)addrIPX->sipx_node[5];

	return [OFString stringWithFormat: @"%X.%X",
	    OFFromBigEndian32(network), node];
}

static OFString *
appleTalkString(const OFSocketAddress *address)
{
	const struct sockaddr_at *addrAT = &address->sockaddr.at;







|







954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
	node = ((uint64_t)addrIPX->sipx_node[0] << 40) |
	    ((uint64_t)addrIPX->sipx_node[1] << 32) |
	    ((uint64_t)addrIPX->sipx_node[2] << 24) |
	    ((uint64_t)addrIPX->sipx_node[3] << 16) |
	    ((uint64_t)addrIPX->sipx_node[4] << 8) |
	    (uint64_t)addrIPX->sipx_node[5];

	return [OFString stringWithFormat: @"%" PRIX32 ".%" PRIX64,
	    OFFromBigEndian32(network), node];
}

static OFString *
appleTalkString(const OFSocketAddress *address)
{
	const struct sockaddr_at *addrAT = &address->sockaddr.at;

Modified src/OFStdIOStream.m from [3c1f5e2bd8] to [f8e458060e].

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

#import "OFStdIOStream.h"
#import "OFStdIOStream+Private.h"
#import "OFColor.h"
#import "OFDate.h"
#import "OFApplication.h"
#ifdef OF_WINDOWS
# include "OFWin32ConsoleStdIOStream.h"
#endif

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"







|







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

#import "OFStdIOStream.h"
#import "OFStdIOStream+Private.h"
#import "OFColor.h"
#import "OFDate.h"
#import "OFApplication.h"
#ifdef OF_WINDOWS
# import "OFWin32ConsoleStdIOStream.h"
#endif

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"

Modified src/OFStreamSocket.h from [09d6517bdb] to [06b86be919].

62
63
64
65
66
67
68



69
70
71
72
73
74
75
 *
 * @brief A class which provides methods to create and use stream sockets.
 */
@interface OFStreamSocket: OFStream <OFReadyForReadingObserving,
    OFReadyForWritingObserving>
{
	OFSocketHandle _socket;



	bool _atEndOfStream, _listening;
	OFSocketAddress _remoteAddress;
	OF_RESERVE_IVARS(OFStreamSocket, 4)
}

/**
 * @brief Whether the socket is a listening socket.







>
>
>







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 *
 * @brief A class which provides methods to create and use stream sockets.
 */
@interface OFStreamSocket: OFStream <OFReadyForReadingObserving,
    OFReadyForWritingObserving>
{
	OFSocketHandle _socket;
#ifdef OF_AMIGAOS
	LONG _socketID;
#endif
	bool _atEndOfStream, _listening;
	OFSocketAddress _remoteAddress;
	OF_RESERVE_IVARS(OFStreamSocket, 4)
}

/**
 * @brief Whether the socket is a listening socket.
157
158
159
160
161
162
163
























164
165
166
 * @param block The block to execute when a new connection has been accepted.
 *		Returns whether the next incoming connection should be accepted
 *		by the specified block as well.
 */
- (void)asyncAcceptWithRunLoopMode: (OFRunLoopMode)runLoopMode
			     block: (OFStreamSocketAsyncAcceptBlock)block;
#endif
























@end

OF_ASSUME_NONNULL_END







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



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
 * @param block The block to execute when a new connection has been accepted.
 *		Returns whether the next incoming connection should be accepted
 *		by the specified block as well.
 */
- (void)asyncAcceptWithRunLoopMode: (OFRunLoopMode)runLoopMode
			     block: (OFStreamSocketAsyncAcceptBlock)block;
#endif

/**
 * @brief Releases the socket from the current thread.
 *
 * This is necessary on some platforms in order to allow a different thread to
 * use the socket, e.g. on AmigaOS, but you should call it on all operating
 * systems before using the socket from a different thread.
 *
 * After calling this method, you must no longer use the socket until
 * @ref obtainSocketForCurrentThread has been called.
 */
- (void)releaseSocketFromCurrentThread;

/**
 * @brief Obtains the socket for the current thread.
 *
 * This is necessary on some platforms in order to allow a different thread to
 * use the socket, e.g. on AmigaOS, but you should call it on all operating
 * systems before using the socket from a different thread.
 *
 * You must only call this method after @ref releaseSocketFromCurrentThread has
 * been called from a different thread.
 */
- (void)obtainSocketForCurrentThread;
@end

OF_ASSUME_NONNULL_END

Modified src/OFStreamSocket.m from [0cffca82b0] to [cfdeffc17d].

27
28
29
30
31
32
33

34
35
36
37
38

39
40
41
42




43
44
45
46
47
48
49
#import "OFStreamSocket.h"
#import "OFStreamSocket+Private.h"
#import "OFRunLoop.h"
#import "OFRunLoop+Private.h"
#import "OFSocket+Private.h"

#import "OFAcceptSocketFailedException.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFListenOnSocketFailedException.h"
#import "OFNotImplementedException.h"
#import "OFNotOpenException.h"

#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFWriteFailedException.h"





@implementation OFStreamSocket
@dynamic delegate;
@synthesize listening = _listening;

+ (void)initialize
{







>





>




>
>
>
>







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 "OFStreamSocket.h"
#import "OFStreamSocket+Private.h"
#import "OFRunLoop.h"
#import "OFRunLoop+Private.h"
#import "OFSocket+Private.h"

#import "OFAcceptSocketFailedException.h"
#import "OFAlreadyOpenException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFListenOnSocketFailedException.h"
#import "OFNotImplementedException.h"
#import "OFNotOpenException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFSetOptionFailedException.h"
#import "OFWriteFailedException.h"

#if defined(OF_AMIGAOS) && !defined(UNIQUE_ID)
# define UNIQUE_ID -1
#endif

@implementation OFStreamSocket
@dynamic delegate;
@synthesize listening = _listening;

+ (void)initialize
{
67
68
69
70
71
72
73



74
75
76
77
78
79
80
	@try {
		if (self.class == [OFStreamSocket class]) {
			[self doesNotRecognizeSelector: _cmd];
			abort();
		}

		_socket = OFInvalidSocketHandle;



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

	return self;
}







>
>
>







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
	@try {
		if (self.class == [OFStreamSocket class]) {
			[self doesNotRecognizeSelector: _cmd];
			abort();
		}

		_socket = OFInvalidSocketHandle;
#ifdef OF_AMIGAOS
		_socketID = -1;
#endif
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
355
356
357
358
359
360
361













































362
363
364
365
366
367
368
		@throw [OFInvalidArgumentException exception];

	if (_remoteAddress.length > (socklen_t)sizeof(_remoteAddress.sockaddr))
		@throw [OFOutOfRangeException exception];

	return &_remoteAddress;
}














































- (void)close
{
	if (_socket == OFInvalidSocketHandle)
		@throw [OFNotOpenException exceptionWithObject: self];

	_listening = false;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
		@throw [OFInvalidArgumentException exception];

	if (_remoteAddress.length > (socklen_t)sizeof(_remoteAddress.sockaddr))
		@throw [OFOutOfRangeException exception];

	return &_remoteAddress;
}

- (void)releaseSocketFromCurrentThread
{
#ifdef OF_AMIGAOS
	if (_socket == OFInvalidSocketHandle)
		@throw [OFNotOpenException exceptionWithObject: self];

	if ((_socketID = ReleaseSocket(_socket, UNIQUE_ID)) == -1) {
		switch (Errno()) {
		case ENOMEM:
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: 0];
		case EBADF:
			@throw [OFNotOpenException exceptionWithObject: self];
		default:
			OFEnsure(0);
		}
	}

	_socket = OFInvalidSocketHandle;
#endif
}

- (void)obtainSocketForCurrentThread
{
#ifdef OF_AMIGAOS
	if (_socket != OFInvalidSocketHandle)
		@throw [OFAlreadyOpenException exceptionWithObject: self];

	if (_socketID == -1)
		@throw [OFNotOpenException exceptionWithObject: self];

	/*
	 * FIXME: We should store these, but that requires changing all
	 *	  subclasses. This only becomes a problem if IPv6 support ever
	 *	  gets added.
	 */
	_socket = ObtainSocket(_socketID, AF_INET, SOCK_STREAM, 0);
	if (_socket == OFInvalidSocketHandle)
		@throw [OFInitializationFailedException
		    exceptionWithClass: self.class];

	_socketID = -1;
#endif
}

- (void)close
{
	if (_socket == OFInvalidSocketHandle)
		@throw [OFNotOpenException exceptionWithObject: self];

	_listening = false;

Modified src/OFString.h from [55ba0a041b] to [9fa7a96c12].

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#ifndef OBJFW_OF_STRING_H
#define OBJFW_OF_STRING_H

#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS
#endif

#include "objfw-defs.h"

#ifdef OF_HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#include <stdarg.h>
#include <stdint.h>
#ifdef OF_HAVE_INTTYPES_H
# include <inttypes.h>
#endif

#include "OFObject.h"
#ifdef __OBJC__
# import "OFJSONRepresentation.h"
# import "OFMessagePackRepresentation.h"
#endif

OF_ASSUME_NONNULL_BEGIN

/** @file */

#ifdef __OBJC__

@class OFConstantString;
@class OFString;
#else
typedef void OFString;
#endif

#if defined(__cplusplus) && __cplusplus >= 201103L
typedef char16_t OFChar16;
typedef char32_t OFChar32;
#else
typedef uint_least16_t OFChar16;
typedef uint_least32_t OFChar32;







<
<
<



















|
<
|
|
<





|
>

|
<
|
<







9
10
11
12
13
14
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
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */




#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS
#endif

#include "objfw-defs.h"

#ifdef OF_HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#include <stdarg.h>
#include <stdint.h>
#ifdef OF_HAVE_INTTYPES_H
# include <inttypes.h>
#endif

#import "OFObject.h"

#import "OFJSONRepresentation.h"
#import "OFMessagePackRepresentation.h"


OF_ASSUME_NONNULL_BEGIN

/** @file */

@class OFArray OF_GENERIC(ObjectType);
@class OFCharacterSet;
@class OFConstantString;
@class OFIRI;

@class OFString;


#if defined(__cplusplus) && __cplusplus >= 201103L
typedef char16_t OFChar16;
typedef char32_t OFChar32;
#else
typedef uint_least16_t OFChar16;
typedef uint_least32_t OFChar32;
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
 * @param line The current line
 * @param stop A pointer to a variable that can be set to true to stop the
 *	       enumeration
 */
typedef void (^OFStringLineEnumerationBlock)(OFString *line, bool *stop);
#endif

#ifdef __OBJC__
@class OFArray OF_GENERIC(ObjectType);
@class OFCharacterSet;
@class OFIRI;

/**
 * @class OFString OFString.h ObjFW/OFString.h
 *
 * @brief A class for handling strings.
 */
@interface OFString: OFObject <OFCopying, OFMutableCopying, OFComparing,
    OFJSONRepresentation, OFMessagePackRepresentation>







<
<
<
<
<







122
123
124
125
126
127
128





129
130
131
132
133
134
135
 * @param line The current line
 * @param stop A pointer to a variable that can be set to true to stop the
 *	       enumeration
 */
typedef void (^OFStringLineEnumerationBlock)(OFString *line, bool *stop);
#endif






/**
 * @class OFString OFString.h ObjFW/OFString.h
 *
 * @brief A class for handling strings.
 */
@interface OFString: OFObject <OFCopying, OFMutableCopying, OFComparing,
    OFJSONRepresentation, OFMessagePackRepresentation>
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
@property (readonly, nonatomic) OFString *stringByDeletingTrailingWhitespaces;

/**
 * @brief The string with leading and trailing whitespaces deleted.
 */
@property (readonly, nonatomic) OFString *stringByDeletingEnclosingWhitespaces;

# ifdef OF_HAVE_UNICODE_TABLES
/**
 * @brief The string in Unicode Normalization Form D (NFD).
 */
@property (readonly, nonatomic) OFString *decomposedStringWithCanonicalMapping;

/**
 * @brief The string in Unicode Normalization Form KD (NFKD).
 */
@property (readonly, nonatomic)
    OFString *decomposedStringWithCompatibilityMapping;
# endif

# ifdef OF_WINDOWS
/**
 * @brief The string with the Windows Environment Strings expanded.
 */
@property (readonly, nonatomic)
    OFString *stringByExpandingWindowsEnvironmentStrings;
# endif

/**
 * @brief Creates a new OFString.
 *
 * @return A new, autoreleased OFString
 */
+ (instancetype)string;







|










|

|





|







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
@property (readonly, nonatomic) OFString *stringByDeletingTrailingWhitespaces;

/**
 * @brief The string with leading and trailing whitespaces deleted.
 */
@property (readonly, nonatomic) OFString *stringByDeletingEnclosingWhitespaces;

#ifdef OF_HAVE_UNICODE_TABLES
/**
 * @brief The string in Unicode Normalization Form D (NFD).
 */
@property (readonly, nonatomic) OFString *decomposedStringWithCanonicalMapping;

/**
 * @brief The string in Unicode Normalization Form KD (NFKD).
 */
@property (readonly, nonatomic)
    OFString *decomposedStringWithCompatibilityMapping;
#endif

#if defined(OF_WINDOWS) || defined(DOXYGEN)
/**
 * @brief The string with the Windows Environment Strings expanded.
 */
@property (readonly, nonatomic)
    OFString *stringByExpandingWindowsEnvironmentStrings;
#endif

/**
 * @brief Creates a new OFString.
 *
 * @return A new, autoreleased OFString
 */
+ (instancetype)string;
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
 * @return A new autoreleased OFString
 * @throw OFInvalidFormatException The specified format is invalid
 * @throw OFInvalidEncodingException The resulting string is not in not in UTF-8
 *				     encoding
 */
+ (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
 * @throw OFInvalidEncodingException The string is not properly UTF-8-encoded







|







511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
 * @return A new autoreleased OFString
 * @throw OFInvalidFormatException The specified format is invalid
 * @throw OFInvalidEncodingException The resulting string is not in not in UTF-8
 *				     encoding
 */
+ (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
 * @throw OFInvalidEncodingException The string is not properly UTF-8-encoded
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
 * @param path The path to the file
 * @param encoding The encoding of the file
 * @return A new autoreleased OFString
 * @throw OFInvalidEncodingException The string is not in the specified encoding
 */
+ (instancetype)stringWithContentsOfFile: (OFString *)path
				encoding: (OFStringEncoding)encoding;
# endif

/**
 * @brief Creates a new OFString with the contents of the specified IRI.
 *
 * If the IRI's scheme is file, it tries UTF-8 encoding.
 *
 * If the IRI's scheme is http(s), it tries to detect the encoding from the HTTP







|







533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
 * @param path The path to the file
 * @param encoding The encoding of the file
 * @return A new autoreleased OFString
 * @throw OFInvalidEncodingException The string is not in the specified encoding
 */
+ (instancetype)stringWithContentsOfFile: (OFString *)path
				encoding: (OFStringEncoding)encoding;
#endif

/**
 * @brief Creates a new OFString with the contents of the specified IRI.
 *
 * If the IRI's scheme is file, it tries UTF-8 encoding.
 *
 * If the IRI's scheme is http(s), it tries to detect the encoding from the HTTP
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
 * @throw OFInvalidFormatException The specified format is invalid
 * @throw OFInvalidEncodingException The resulting string is not in not in UTF-8
 *				     encoding
 */
- (instancetype)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
 * @throw OFInvalidEncodingException The string is not properly UTF-8-encoded







|







804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
 * @throw OFInvalidFormatException The specified format is invalid
 * @throw OFInvalidEncodingException The resulting string is not in not in UTF-8
 *				     encoding
 */
- (instancetype)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
 * @throw OFInvalidEncodingException The string is not properly UTF-8-encoded
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
 * @param path The path to the file
 * @param encoding The encoding of the file
 * @return An initialized OFString
 * @throw OFInvalidEncodingException The string is not in the specified encoding
 */
- (instancetype)initWithContentsOfFile: (OFString *)path
			      encoding: (OFStringEncoding)encoding;
# endif

/**
 * @brief Initializes an already allocated OFString with the contents of the
 *	  specified IRI.
 *
 * If the IRI's scheme is file, it tries UTF-8 encoding.
 *







|







826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
 * @param path The path to the file
 * @param encoding The encoding of the file
 * @return An initialized OFString
 * @throw OFInvalidEncodingException The string is not in the specified encoding
 */
- (instancetype)initWithContentsOfFile: (OFString *)path
			      encoding: (OFStringEncoding)encoding;
#endif

/**
 * @brief Initializes an already allocated OFString with the contents of the
 *	  specified IRI.
 *
 * If the IRI's scheme is file, it tries UTF-8 encoding.
 *
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
 * @param encoding The encoding to use for the returned OFData
 * @return The string as OFData with the specified encoding
 * @throw OFInvalidEncodingException The string cannot be represented in the
 *				     specified encoding
 */
- (OFData *)dataWithEncoding: (OFStringEncoding)encoding;

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

/**
 * @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
 * @throw OFInvalidEncodingException The string cannot be represented in the
 *				     specified encoding
 */
- (void)writeToFile: (OFString *)path encoding: (OFStringEncoding)encoding;
# endif

/**
 * @brief Writes the string to the specified IRI using UTF-8 encoding.
 *
 * @param IRI The IRI to write to
 */
- (void)writeToIRI: (OFIRI *)IRI;

/**
 * @brief Writes the string to the specified IRI using the specified encoding.
 *
 * @param IRI The IRI to write to
 * @param encoding The encoding to use to write the string to the IRI
 * @throw OFInvalidEncodingException The string cannot be represented in the
 *				     specified encoding
 */
- (void)writeToIRI: (OFIRI *)IRI encoding: (OFStringEncoding)encoding;

# 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: (OFStringLineEnumerationBlock)block;
# endif
@end
#endif

#ifdef __cplusplus
extern "C" {
#endif
/**
 * @brief Parses the specified string encoding name and returns the
 *	  OFStringEncoding for it.







|

















|


















|






|

<







1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315

1316
1317
1318
1319
1320
1321
1322
 * @param encoding The encoding to use for the returned OFData
 * @return The string as OFData with the specified encoding
 * @throw OFInvalidEncodingException The string cannot be represented in the
 *				     specified encoding
 */
- (OFData *)dataWithEncoding: (OFStringEncoding)encoding;

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

/**
 * @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
 * @throw OFInvalidEncodingException The string cannot be represented in the
 *				     specified encoding
 */
- (void)writeToFile: (OFString *)path encoding: (OFStringEncoding)encoding;
#endif

/**
 * @brief Writes the string to the specified IRI using UTF-8 encoding.
 *
 * @param IRI The IRI to write to
 */
- (void)writeToIRI: (OFIRI *)IRI;

/**
 * @brief Writes the string to the specified IRI using the specified encoding.
 *
 * @param IRI The IRI to write to
 * @param encoding The encoding to use to write the string to the IRI
 * @throw OFInvalidEncodingException The string cannot be represented in the
 *				     specified encoding
 */
- (void)writeToIRI: (OFIRI *)IRI encoding: (OFStringEncoding)encoding;

#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: (OFStringLineEnumerationBlock)block;
#endif
@end


#ifdef __cplusplus
extern "C" {
#endif
/**
 * @brief Parses the specified string encoding name and returns the
 *	  OFStringEncoding for it.
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
extern size_t OFUTF32StringLength(const OFChar32 *);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

#include "OFConstantString.h"
#include "OFMutableString.h"
#ifdef __OBJC__
# import "OFString+CryptographicHashing.h"
# import "OFString+JSONParsing.h"
# ifdef OF_HAVE_FILES
#  import "OFString+PathAdditions.h"
# endif
# import "OFString+PercentEncoding.h"
# import "OFString+PropertyListParsing.h"
# import "OFString+XMLEscaping.h"
# import "OFString+XMLUnescaping.h"
#endif

#if defined(__OBJC__) && !defined(NSINTEGER_DEFINED) && !__has_feature(modules)
/*
 * Very *ugly* hack required for string boxing literals to work.
 *
 * This hack is needed in order to work with `@class NSString` from Apple's
 * objc/NSString.h - which is included when using modules - as
 * @compatibility_alias does not work if @class has been used before.
 * For some reason, this makes Clang refer to OFString for string box literals
 * and not to NSString (which would result in a linker error, but would be the
 * correct behavior).
 *
 * TODO: Submit a patch for Clang that makes the boxing classes configurable!
 */
@interface NSString: OFString
@end
#endif

#endif







|
|
<
|
|
|
|
|
|
|
|
|
<

|















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


extern size_t OFUTF32StringLength(const OFChar32 *);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

#import "OFConstantString.h"
#import "OFMutableString.h"

#import "OFString+CryptographicHashing.h"
#import "OFString+JSONParsing.h"
#ifdef OF_HAVE_FILES
# import "OFString+PathAdditions.h"
#endif
#import "OFString+PercentEncoding.h"
#import "OFString+PropertyListParsing.h"
#import "OFString+XMLEscaping.h"
#import "OFString+XMLUnescaping.h"


#if !defined(NSINTEGER_DEFINED) && !__has_feature(modules)
/*
 * Very *ugly* hack required for string boxing literals to work.
 *
 * This hack is needed in order to work with `@class NSString` from Apple's
 * objc/NSString.h - which is included when using modules - as
 * @compatibility_alias does not work if @class has been used before.
 * For some reason, this makes Clang refer to OFString for string box literals
 * and not to NSString (which would result in a linker error, but would be the
 * correct behavior).
 *
 * TODO: Submit a patch for Clang that makes the boxing classes configurable!
 */
@interface NSString: OFString
@end
#endif


Modified src/OFString.m from [a697442a34] to [e84d292643].

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
- (const char *)of_cStringWithEncoding: (OFStringEncoding)encoding
				 lossy: (bool)lossy OF_DIRECT;
- (OFString *)
    of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options
			       depth: (size_t)depth;
@end

@interface OFStringPlaceholder: OFString
@end

extern bool OFUnicodeToISO8859_2(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool OFUnicodeToISO8859_3(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool OFUnicodeToISO8859_15(const OFUnichar *, unsigned char *,







|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
- (const char *)of_cStringWithEncoding: (OFStringEncoding)encoding
				 lossy: (bool)lossy OF_DIRECT;
- (OFString *)
    of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options
			       depth: (size_t)depth;
@end

@interface OFPlaceholderString: OFString
@end

extern bool OFUnicodeToISO8859_2(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool OFUnicodeToISO8859_3(const OFUnichar *, unsigned char *,
    size_t, bool);
extern bool OFUnicodeToISO8859_15(const OFUnichar *, unsigned char *,
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387

	objc_autoreleasePoolPop(pool);

	return ret;
}
#endif

@implementation OFStringPlaceholder
- (instancetype)init
{
	return (id)[[OFUTF8String alloc] init];
}

- (instancetype)initWithUTF8String: (const char *)UTF8String
{







|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387

	objc_autoreleasePoolPop(pool);

	return ret;
}
#endif

@implementation OFPlaceholderString
- (instancetype)init
{
	return (id)[[OFUTF8String alloc] init];
}

- (instancetype)initWithUTF8String: (const char *)UTF8String
{
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
- (instancetype)initWithContentsOfIRI: (OFIRI *)IRI
			     encoding: (OFStringEncoding)encoding
{
	return (id)[[OFUTF8String alloc] initWithContentsOfIRI: IRI
						      encoding: encoding];
}

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}
@end

@implementation OFString
+ (void)initialize
{
	if (self != [OFString class])
		return;

	placeholder.isa = [OFStringPlaceholder class];

#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L) || defined(HAVE_USELOCALE)
	if ((cLocale = newlocale(LC_ALL_MASK, "C", NULL)) == NULL)
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
#endif
}







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<








|







588
589
590
591
592
593
594




595













596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
- (instancetype)initWithContentsOfIRI: (OFIRI *)IRI
			     encoding: (OFStringEncoding)encoding
{
	return (id)[[OFUTF8String alloc] initWithContentsOfIRI: IRI
						      encoding: encoding];
}





OF_SINGLETON_METHODS













@end

@implementation OFString
+ (void)initialize
{
	if (self != [OFString class])
		return;

	object_setClass((id)&placeholder, [OFPlaceholderString class]);

#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L) || defined(HAVE_USELOCALE)
	if ((cLocale = newlocale(LC_ALL_MASK, "C", NULL)) == NULL)
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
#endif
}
799
800
801
802
803
804
805
806

807
808
809
810
811
812
813
{
	return [[[self alloc] initWithContentsOfIRI: IRI
					   encoding: encoding] autorelease];
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFString class]]) {

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








|
>







782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
{
	return [[[self alloc] initWithContentsOfIRI: IRI
					   encoding: encoding] autorelease];
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OFString class]] ||
	    [self isMemberOfClass: [OFMutableString class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
		} @catch (id e) {
			[self release];
			@throw e;
		}

Modified src/OFSubarray.h from [6cc244c93d] to [e3a4736adc].

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

@interface OFSubarray: OFArray
{
	OFArray *_array;
	OFRange _range;
}

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

OF_ASSUME_NONNULL_END







<




19
20
21
22
23
24
25

26
27
28
29

@interface OFSubarray: OFArray
{
	OFArray *_array;
	OFRange _range;
}


- (instancetype)initWithArray: (OFArray *)array range: (OFRange)range;
@end

OF_ASSUME_NONNULL_END

Added src/OFSubdata.h version [125a37157e].



























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
26
27
28
29
/*
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFData.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFSubdata: OFData
{
	OFData *_data;
	OFRange _range;
}

- (instancetype)initWithData: (OFData *)data range: (OFRange)range;
@end

OF_ASSUME_NONNULL_END

Added src/OFSubdata.m version [3275105cae].























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
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
/*
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFSubdata.h"

@implementation OFSubdata
- (instancetype)initWithData: (OFData *)data range: (OFRange)range
{
	self = [super init];

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

	return self;
}

- (void)dealloc
{
	[_data release];

	[super dealloc];
}

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

- (size_t)itemSize
{
	return _data.itemSize;
}

- (const void *)items
{
	return (const unsigned char *)_data.items +
	    (_range.location * _data.itemSize);
}
@end

Modified src/OFSystemInfo.h from [1f526bb329] to [bd80cd4ad3].

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
@property (class, readonly, nonatomic) bool supportsAVX2;
@property (class, readonly, nonatomic) bool supportsAESNI;
@property (class, readonly, nonatomic) bool supportsSHAExtensions;
# endif
# if defined(OF_POWERPC) || defined(OF_POWERPC64) || defined(DOXYGEN)
@property (class, readonly, nonatomic) bool supportsAltiVec;
# endif
# ifdef OF_WINDOWS
@property (class, readonly, nonatomic, getter=isWindowsNT) bool windowsNT;
# endif
#endif

/**
 * @brief Returns the size of a page.
 *







|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
@property (class, readonly, nonatomic) bool supportsAVX2;
@property (class, readonly, nonatomic) bool supportsAESNI;
@property (class, readonly, nonatomic) bool supportsSHAExtensions;
# endif
# if defined(OF_POWERPC) || defined(OF_POWERPC64) || defined(DOXYGEN)
@property (class, readonly, nonatomic) bool supportsAltiVec;
# endif
# if defined(OF_WINDOWS) || defined(DOXYGEN)
@property (class, readonly, nonatomic, getter=isWindowsNT) bool windowsNT;
# endif
#endif

/**
 * @brief Returns the size of a page.
 *
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
 * @note This method is only available on AMD64 and x86.
 *
 * @return Whether the CPU supports Intel SHA Extensions
 */
+ (bool)supportsSHAExtensions;
#endif

#if defined(OF_POWERPC) || defined(OF_POWERPC64)
/**
 * @brief Returns whether the CPU and OS support AltiVec.
 *
 * @note This method is only available on PowerPC and PowerPC 64.
 *
 * @return Whether the CPU and OS support AltiVec
 */
+ (bool)supportsAltiVec;
#endif

#ifdef OF_WINDOWS
/**
 * @brief Returns whether the application is running on Windows NT.
 *
 * @note This method is only available on Windows.
 *
 * @return Whether the application is running on Windows NT
 */







|










|







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
 * @note This method is only available on AMD64 and x86.
 *
 * @return Whether the CPU supports Intel SHA Extensions
 */
+ (bool)supportsSHAExtensions;
#endif

#if defined(OF_POWERPC) || defined(OF_POWERPC64) || defined(DOXYGEN)
/**
 * @brief Returns whether the CPU and OS support AltiVec.
 *
 * @note This method is only available on PowerPC and PowerPC 64.
 *
 * @return Whether the CPU and OS support AltiVec
 */
+ (bool)supportsAltiVec;
#endif

#if defined(OF_WINDOWS) || defined(DOXYGEN)
/**
 * @brief Returns whether the application is running on Windows NT.
 *
 * @note This method is only available on Windows.
 *
 * @return Whether the application is running on Windows NT
 */

Added src/OFTaggedPointerColor.h version [ee19a5ec0d].

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
26
27
28
/*
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFColor.h"

OF_ASSUME_NONNULL_BEGIN

#ifdef OF_OBJFW_RUNTIME
@interface OFTaggedPointerColor: OFColor
+ (instancetype)colorWithRed: (uint8_t)red
		       green: (uint8_t)green
			blue: (uint8_t)blue;
@end
#endif

OF_ASSUME_NONNULL_END

Added src/OFTaggedPointerColor.m version [c4dd78fccc].















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
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
/*
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFTaggedPointerColor.h"

#ifdef OF_OBJFW_RUNTIME
static int colorTag;

@implementation OFTaggedPointerColor
+ (void)initialize
{
	if (self == [OFTaggedPointerColor class])
		colorTag = objc_registerTaggedPointerClass(self);
}

+ (instancetype)colorWithRed: (uint8_t)red
		       green: (uint8_t)green
			blue: (uint8_t)blue
{
	return objc_createTaggedPointer(colorTag,
	    (uintptr_t)red << 16 | (uintptr_t)green << 8 | (uintptr_t)blue);
}

- (void)getRed: (float *)red
	 green: (float *)green
	  blue: (float *)blue
	 alpha: (float *)alpha
{
	uintptr_t value = object_getTaggedPointerValue(self);

	*red = (float)(value >> 16) / 255;
	*green = (float)((value >> 8) & 0xFF) / 255;
	*blue = (float)(value & 0xFF) / 255;

	if (alpha != NULL)
		*alpha = 1;
}

OF_SINGLETON_METHODS
@end
#endif

Modified src/OFTimer+Private.h from [0f4b8327b6] to [387c4c02eb].

17
18
19
20
21
22
23

24
25
26

OF_ASSUME_NONNULL_BEGIN

OF_DIRECT_MEMBERS
@interface OFTimer ()
- (void)of_setInRunLoop: (nullable OFRunLoop *)runLoop
		   mode: (nullable OFRunLoopMode)mode;

@end

OF_ASSUME_NONNULL_END







>



17
18
19
20
21
22
23
24
25
26
27

OF_ASSUME_NONNULL_BEGIN

OF_DIRECT_MEMBERS
@interface OFTimer ()
- (void)of_setInRunLoop: (nullable OFRunLoop *)runLoop
		   mode: (nullable OFRunLoopMode)mode;
- (void)of_reschedule;
@end

OF_ASSUME_NONNULL_END

Modified src/OFTimer.h from [e91495b8af] to [12e510d1ae].

458
459
460
461
462
463
464
465
466


467
468
469
470
471
472
473
 *
 * @param timer The timer to compare the string to
 * @return The result of the comparison
 */
- (OFComparisonResult)compare: (OFTimer *)timer;

/**
 * @brief Fires the timer, meaning it will execute the specified selector on the
 *	  target.


 */
- (void)fire;

/**
 * @brief Invalidates the timer, preventing it from firing.
 */
- (void)invalidate;







|
<
>
>







458
459
460
461
462
463
464
465

466
467
468
469
470
471
472
473
474
 *
 * @param timer The timer to compare the string to
 * @return The result of the comparison
 */
- (OFComparisonResult)compare: (OFTimer *)timer;

/**
 * @brief Fires the timer without changing its regular schedule.

 *
 * A non-repeating timer will be invalidated after firing.
 */
- (void)fire;

/**
 * @brief Invalidates the timer, preventing it from firing.
 */
- (void)invalidate;

Modified src/OFTimer.m from [f074999bf7] to [1f910610bc].

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

	_inRunLoop = [runLoop retain];
	[oldInRunLoop release];

	_inRunLoopMode = [mode copy];
	[oldInRunLoopMode release];
}

- (void)fire
{
	void *pool = objc_autoreleasePoolPush();
	id target = [[_target retain] autorelease];
	id object1 = [[_object1 retain] autorelease];
	id object2 = [[_object2 retain] autorelease];
	id object3 = [[_object3 retain] autorelease];
	id object4 = [[_object4 retain] autorelease];

	OFEnsure(_arguments <= 4);


	if (_repeats && _valid) {
		int64_t missedIntervals =
		    -_fireDate.timeIntervalSinceNow / _interval;
		OFTimeInterval newFireDate;
		OFRunLoop *runLoop;

		/* In case the clock was changed backwards */
		if (missedIntervals < 0)
			missedIntervals = 0;

		newFireDate = _fireDate.timeIntervalSince1970 +
		    (missedIntervals + 1) * _interval;

		[_fireDate release];

		_fireDate = [[OFDate alloc]
		    initWithTimeIntervalSince1970: newFireDate];

		runLoop = [OFRunLoop currentRunLoop];
		[runLoop addTimer: self forMode: runLoop.currentMode];

	} else



		[self invalidate];



#ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(self);
	else {
#endif
		switch (_arguments) {
		case 0:
			[target performSelector: _selector];
			break;
		case 1:
			[target performSelector: _selector withObject: object1];

			break;
		case 2:
			[target performSelector: _selector
				     withObject: object1
				     withObject: object2];
			break;
		case 3:
			[target performSelector: _selector
				     withObject: object1
				     withObject: object2
				     withObject: object3];
			break;
		case 4:
			[target performSelector: _selector
				     withObject: object1
				     withObject: object2
				     withObject: object3
				     withObject: object4];
			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif




#ifdef OF_HAVE_THREADS
	[_condition lock];
	@try {
		_done = true;
		[_condition signal];
	} @finally {
		[_condition unlock];
	}
#endif

	objc_autoreleasePoolPop(pool);
}

- (OFDate *)fireDate
{
	return _fireDate;
}









|

|
|
|
<
<
<

|
>

<
<
|
<
<

|
|
|

|
|

|
>
|
|

|
|
>
|
>
>
>
|
>
>








|


|
>


|
|
|


|
|
|
|


|
|
|
|
|






>
>
>









<
<







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

	_inRunLoop = [runLoop retain];
	[oldInRunLoop release];

	_inRunLoopMode = [mode copy];
	[oldInRunLoopMode release];
}

- (void)of_reschedule
{
	long long missedIntervals;
	OFTimeInterval newFireDate;
	OFRunLoop *runLoop;




	if (!_repeats || !_valid)
		return;



	missedIntervals = -_fireDate.timeIntervalSinceNow / _interval;



	/* In case the clock was changed backwards */
	if (missedIntervals < 0)
		missedIntervals = 0;

	newFireDate = _fireDate.timeIntervalSince1970 +
	    (missedIntervals + 1) * _interval;

	[_fireDate release];
	_fireDate = nil;
	_fireDate = [[OFDate alloc]
	    initWithTimeIntervalSince1970: newFireDate];

	runLoop = [OFRunLoop currentRunLoop];
	[runLoop addTimer: self forMode: runLoop.currentMode];
}

- (void)fire
{
	OFEnsure(_arguments <= 4);

	if (!_valid)
		return;

#ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(self);
	else {
#endif
		switch (_arguments) {
		case 0:
			[_target performSelector: _selector];
			break;
		case 1:
			[_target performSelector: _selector
				      withObject: _object1];
			break;
		case 2:
			[_target performSelector: _selector
				      withObject: _object1
				      withObject: _object2];
			break;
		case 3:
			[_target performSelector: _selector
				      withObject: _object1
				      withObject: _object2
				      withObject: _object3];
			break;
		case 4:
			[_target performSelector: _selector
				      withObject: _object1
				      withObject: _object2
				      withObject: _object3
				      withObject: _object4];
			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif

	if  (!_repeats)
		[self invalidate];

#ifdef OF_HAVE_THREADS
	[_condition lock];
	@try {
		_done = true;
		[_condition signal];
	} @finally {
		[_condition unlock];
	}
#endif


}

- (OFDate *)fireDate
{
	return _fireDate;
}

631
632
633
634
635
636
637



638
639
640
641
642
643
644
	}
}

- (void)invalidate
{
	_valid = false;




	[_target release];
	[_object1 release];
	[_object2 release];
	[_object3 release];
	[_object4 release];

	_target = nil;







>
>
>







634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
	}
}

- (void)invalidate
{
	_valid = false;

#ifdef OF_HAVE_BLOCKS
	[_block release];
#endif
	[_target release];
	[_object1 release];
	[_object2 release];
	[_object3 release];
	[_object4 release];

	_target = nil;

Modified src/OFZIPArchive.h from [82b11667ec] to [a8992114f0].

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

OF_ASSUME_NONNULL_BEGIN

@class OFArray OF_GENERIC(ObjectType);
@class OFMutableArray OF_GENERIC(ObjectType);
@class OFMutableDictionary OF_GENERIC(KeyType, ObjectType);

@class OFStream;























/**
 * @class OFZIPArchive OFZIPArchive.h ObjFW/OFZIPArchive.h
 *
 * @brief A class for accessing and manipulating ZIP files.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFZIPArchive: OFObject
{
	OF_KINDOF(OFStream *) _stream;
#ifdef OF_ZIP_ARCHIVE_M
@public
#endif


	int64_t _offset;
@protected
	uint_least8_t _mode;
	uint32_t _diskNumber, _centralDirectoryDisk;


	uint64_t _centralDirectoryEntriesInDisk, _centralDirectoryEntries;
	uint64_t _centralDirectorySize;
	int64_t _centralDirectoryOffset;
	OFString *_Nullable _archiveComment;
#ifdef OF_ZIP_ARCHIVE_M
@public
#endif
	OFMutableArray OF_GENERIC(OFZIPArchiveEntry *) *_entries;
	OFMutableDictionary OF_GENERIC(OFString *, OFZIPArchiveEntry *)
	    *_pathToEntryMap;
	OFStream *_Nullable _lastReturnedStream;
}







/**
 * @brief The archive comment.
 */
@property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *archiveComment;

/**
 * @brief The entries in the central directory of the archive as an array of







>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









<



>
>

<

|
>
>













>
>
>
>
>
>







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
#import "OFZIPArchiveEntry.h"

OF_ASSUME_NONNULL_BEGIN

@class OFArray OF_GENERIC(ObjectType);
@class OFMutableArray OF_GENERIC(ObjectType);
@class OFMutableDictionary OF_GENERIC(KeyType, ObjectType);
@class OFSeekableStream;
@class OFStream;
@class OFZIPArchive;

/**
 * @protocol OFZIPArchiveDelegate OFZIPArchive.h ObjFW/OFZIPArchive.h
 *
 * @brief A delegate for OFZIPArchive.
 */
@protocol OFZIPArchiveDelegate <OFObject>
@optional
/**
 * @brief A callback that is called when an @ref OFZIPArchive wants to read a
 *	  different archive part.
 *
 * @param archive The archive that wants to read another part
 * @param partNumber The number of the part the archive wants to read
 * @param lastPartNumber The number of the last archive part
 * @return The stream to read the needed part, or `nil` if no such part exists
 */
- (nullable OFSeekableStream *)archive: (OFZIPArchive *)archive
		     wantsPartNumbered: (unsigned int)partNumber
			lastPartNumber: (unsigned int)lastPartNumber;
@end

/**
 * @class OFZIPArchive OFZIPArchive.h ObjFW/OFZIPArchive.h
 *
 * @brief A class for accessing and manipulating ZIP files.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFZIPArchive: OFObject
{

#ifdef OF_ZIP_ARCHIVE_M
@public
#endif
	OFObject <OFZIPArchiveDelegate> *_Nullable _delegate;
	OF_KINDOF(OFStream *) _stream;
	int64_t _offset;

	uint_least8_t _mode;
	uint32_t _diskNumber, _lastDiskNumber;
@protected
	uint32_t _centralDirectoryDisk;
	uint64_t _centralDirectoryEntriesInDisk, _centralDirectoryEntries;
	uint64_t _centralDirectorySize;
	int64_t _centralDirectoryOffset;
	OFString *_Nullable _archiveComment;
#ifdef OF_ZIP_ARCHIVE_M
@public
#endif
	OFMutableArray OF_GENERIC(OFZIPArchiveEntry *) *_entries;
	OFMutableDictionary OF_GENERIC(OFString *, OFZIPArchiveEntry *)
	    *_pathToEntryMap;
	OFStream *_Nullable _lastReturnedStream;
}

/**
 * @brief The delegate of the ZIP archive.
 */
@property OF_NULLABLE_PROPERTY (assign, nonatomic)
    OFObject <OFZIPArchiveDelegate> *delegate;

/**
 * @brief The archive comment.
 */
@property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *archiveComment;

/**
 * @brief The entries in the central directory of the archive as an array of

Modified src/OFZIPArchive.m from [1186bd8318] to [03f366c882].

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#import "OFOutOfRangeException.h"
#import "OFSeekFailedException.h"
#import "OFTruncatedDataException.h"
#import "OFUnsupportedVersionException.h"
#import "OFWriteFailedException.h"

/*
 * FIXME: Current limitations:
 *  - Split archives are not supported.
 *  - Encrypted files cannot be read.
 */

enum {
	modeRead,
	modeWrite,
	modeAppend







|
<







43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
#import "OFOutOfRangeException.h"
#import "OFSeekFailedException.h"
#import "OFTruncatedDataException.h"
#import "OFUnsupportedVersionException.h"
#import "OFWriteFailedException.h"

/*
 * TODO: Current limitations:

 *  - Encrypted files cannot be read.
 */

enum {
	modeRead,
	modeWrite,
	modeAppend
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
- (bool)matchesEntry: (OFZIPArchiveEntry *)entry;
@end

OF_DIRECT_MEMBERS
@interface OFZIPArchiveFileReadStream: OFStream
{
	OFZIPArchive *_archive;

	OFStream *_stream, *_decompressedStream;
	OFZIPArchiveEntry *_entry;
	unsigned long long _toRead;
	uint32_t _CRC32;
	bool _atEndOfStream;
}

- (instancetype)of_initWithArchive: (OFZIPArchive *)archive







>
|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
- (bool)matchesEntry: (OFZIPArchiveEntry *)entry;
@end

OF_DIRECT_MEMBERS
@interface OFZIPArchiveFileReadStream: OFStream
{
	OFZIPArchive *_archive;
	OFZIPArchiveEntryCompressionMethod _compressionMethod;
	OF_KINDOF(OFStream *) _decompressedStream;
	OFZIPArchiveEntry *_entry;
	unsigned long long _toRead;
	uint32_t _CRC32;
	bool _atEndOfStream;
}

- (instancetype)of_initWithArchive: (OFZIPArchive *)archive
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

	*data += 8;
	*size -= 8;

	return field;
}




static void
seekOrThrowInvalidFormat(OFSeekableStream *stream,
    OFStreamOffset offset, OFSeekWhence whence)
{




















	@try {
		[stream seekToOffset: offset whence: whence];
	} @catch (OFSeekFailedException *e) {
		if (e.errNo == EINVAL)
			@throw [OFInvalidFormatException exception];

		@throw e;
	}
}

@implementation OFZIPArchive
@synthesize archiveComment = _archiveComment;

+ (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode
{
	return [[[self alloc] initWithStream: stream mode: mode] autorelease];
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI mode: (OFString *)mode
{







>
>
>

|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|








<
<
<







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

	*data += 8;
	*size -= 8;

	return field;
}

@implementation OFZIPArchive
@synthesize delegate = _delegate, archiveComment = _archiveComment;

static void
seekOrThrowInvalidFormat(OFZIPArchive *archive, const uint32_t *diskNumber,
    OFStreamOffset offset, OFSeekWhence whence)
{
	if (diskNumber != NULL && *diskNumber != archive->_diskNumber) {
		OFStream *oldStream = archive->_stream;
		OFSeekableStream *stream;

		if (archive->_mode != modeRead ||
		    *diskNumber > archive->_lastDiskNumber)
			@throw [OFInvalidFormatException exception];

		stream = [archive->_delegate archive: archive
				   wantsPartNumbered: *diskNumber
				      lastPartNumber: archive->_lastDiskNumber];

		if (stream == nil)
			@throw [OFInvalidFormatException exception];

		archive->_diskNumber = *diskNumber;
		archive->_stream = [stream retain];
		[oldStream release];
	}

	@try {
		[archive->_stream seekToOffset: offset whence: whence];
	} @catch (OFSeekFailedException *e) {
		if (e.errNo == EINVAL)
			@throw [OFInvalidFormatException exception];

		@throw e;
	}
}




+ (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode
{
	return [[[self alloc] initWithStream: stream mode: mode] autorelease];
}

+ (instancetype)archiveWithIRI: (OFIRI *)IRI mode: (OFString *)mode
{
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

			[self of_readZIPInfo];
			[self of_readEntries];
		}

		if (_mode == modeAppend) {
			_offset = _centralDirectoryOffset;
			seekOrThrowInvalidFormat(_stream,
			    (OFStreamOffset)_offset, OFSeekSet);
		}
	} @catch (id e) {
		/*
		 * If we are in write or append mode, we do not want -[close]
		 * to write anything to it on error - after all, it might not
		 * be a ZIP file which we would destroy otherwise.







|







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

			[self of_readZIPInfo];
			[self of_readEntries];
		}

		if (_mode == modeAppend) {
			_offset = _centralDirectoryOffset;
			seekOrThrowInvalidFormat(self, NULL,
			    (OFStreamOffset)_offset, OFSeekSet);
		}
	} @catch (id e) {
		/*
		 * If we are in write or append mode, we do not want -[close]
		 * to write anything to it on error - after all, it might not
		 * be a ZIP file which we would destroy otherwise.
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
{
	void *pool = objc_autoreleasePoolPush();
	uint16_t commentLength;
	OFStreamOffset offset = -22;
	bool valid = false;

	do {
		seekOrThrowInvalidFormat(_stream, offset, OFSeekEnd);

		if ([_stream readLittleEndianInt32] == 0x06054B50) {
			valid = true;
			break;
		}
	} while (--offset >= -65557);

	if (!valid)
		@throw [OFInvalidFormatException exception];

	_diskNumber = [_stream readLittleEndianInt16];
	_centralDirectoryDisk = [_stream readLittleEndianInt16];
	_centralDirectoryEntriesInDisk = [_stream readLittleEndianInt16];
	_centralDirectoryEntries = [_stream readLittleEndianInt16];
	_centralDirectorySize = [_stream readLittleEndianInt32];
	_centralDirectoryOffset = [_stream readLittleEndianInt32];

	commentLength = [_stream readLittleEndianInt16];
	_archiveComment = [[_stream
	    readStringWithLength: commentLength
			encoding: OFStringEncodingCodepage437] copy];

	if (_diskNumber == 0xFFFF ||
	    _centralDirectoryDisk == 0xFFFF ||
	    _centralDirectoryEntriesInDisk == 0xFFFF ||
	    _centralDirectoryEntries == 0xFFFF ||
	    _centralDirectorySize == 0xFFFFFFFF ||
	    _centralDirectoryOffset == 0xFFFFFFFF) {

		int64_t offset64;
		uint64_t size;

		seekOrThrowInvalidFormat(_stream, offset - 20, OFSeekEnd);

		if ([_stream readLittleEndianInt32] != 0x07064B50) {
			objc_autoreleasePoolPop(pool);
			return;
		}

		/*
		 * FIXME: Handle number of the disk containing ZIP64 end of
		 * central directory record.
		 */
		[_stream readLittleEndianInt32];
		offset64 = [_stream readLittleEndianInt64];





		if (offset64 < 0 || (OFStreamOffset)offset64 != offset64)
			@throw [OFOutOfRangeException exception];

		seekOrThrowInvalidFormat(_stream,
		    (OFStreamOffset)offset64, OFSeekSet);

		if ([_stream readLittleEndianInt32] != 0x06064B50)
			@throw [OFInvalidFormatException exception];

		size = [_stream readLittleEndianInt64];
		if (size < 44)
			@throw [OFInvalidFormatException exception];

		/* version made by */
		[_stream readLittleEndianInt16];
		/* version needed to extract */
		[_stream readLittleEndianInt16];

		_diskNumber = [_stream readLittleEndianInt32];


		_centralDirectoryDisk = [_stream readLittleEndianInt32];
		_centralDirectoryEntriesInDisk =
		    [_stream readLittleEndianInt64];
		_centralDirectoryEntries = [_stream readLittleEndianInt64];
		_centralDirectorySize = [_stream readLittleEndianInt64];
		_centralDirectoryOffset = [_stream readLittleEndianInt64];








|










|











|





>



|










|

>
>
>
>




|














|
>
>







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
{
	void *pool = objc_autoreleasePoolPush();
	uint16_t commentLength;
	OFStreamOffset offset = -22;
	bool valid = false;

	do {
		seekOrThrowInvalidFormat(self, NULL, offset, OFSeekEnd);

		if ([_stream readLittleEndianInt32] == 0x06054B50) {
			valid = true;
			break;
		}
	} while (--offset >= -65557);

	if (!valid)
		@throw [OFInvalidFormatException exception];

	_diskNumber = _lastDiskNumber = [_stream readLittleEndianInt16];
	_centralDirectoryDisk = [_stream readLittleEndianInt16];
	_centralDirectoryEntriesInDisk = [_stream readLittleEndianInt16];
	_centralDirectoryEntries = [_stream readLittleEndianInt16];
	_centralDirectorySize = [_stream readLittleEndianInt32];
	_centralDirectoryOffset = [_stream readLittleEndianInt32];

	commentLength = [_stream readLittleEndianInt16];
	_archiveComment = [[_stream
	    readStringWithLength: commentLength
			encoding: OFStringEncodingCodepage437] copy];

	if (_lastDiskNumber == 0xFFFF ||
	    _centralDirectoryDisk == 0xFFFF ||
	    _centralDirectoryEntriesInDisk == 0xFFFF ||
	    _centralDirectoryEntries == 0xFFFF ||
	    _centralDirectorySize == 0xFFFFFFFF ||
	    _centralDirectoryOffset == 0xFFFFFFFF) {
		uint32_t diskNumber;
		int64_t offset64;
		uint64_t size;

		seekOrThrowInvalidFormat(self, NULL, offset - 20, OFSeekEnd);

		if ([_stream readLittleEndianInt32] != 0x07064B50) {
			objc_autoreleasePoolPop(pool);
			return;
		}

		/*
		 * FIXME: Handle number of the disk containing ZIP64 end of
		 * central directory record.
		 */
		diskNumber = [_stream readLittleEndianInt32];
		offset64 = [_stream readLittleEndianInt64];
		_lastDiskNumber = [_stream readLittleEndianInt32];
		if (_lastDiskNumber == 0)
			@throw [OFInvalidFormatException exception];
		_lastDiskNumber--;

		if (offset64 < 0 || (OFStreamOffset)offset64 != offset64)
			@throw [OFOutOfRangeException exception];

		seekOrThrowInvalidFormat(self, &diskNumber,
		    (OFStreamOffset)offset64, OFSeekSet);

		if ([_stream readLittleEndianInt32] != 0x06064B50)
			@throw [OFInvalidFormatException exception];

		size = [_stream readLittleEndianInt64];
		if (size < 44)
			@throw [OFInvalidFormatException exception];

		/* version made by */
		[_stream readLittleEndianInt16];
		/* version needed to extract */
		[_stream readLittleEndianInt16];

		if ([_stream readLittleEndianInt32] != _diskNumber)
			@throw [OFInvalidFormatException exception];

		_centralDirectoryDisk = [_stream readLittleEndianInt32];
		_centralDirectoryEntriesInDisk =
		    [_stream readLittleEndianInt64];
		_centralDirectoryEntries = [_stream readLittleEndianInt64];
		_centralDirectorySize = [_stream readLittleEndianInt64];
		_centralDirectoryOffset = [_stream readLittleEndianInt64];

362
363
364
365
366
367
368
369
370
371
372
373

































374
375
376
377
378
379
380
{
	void *pool = objc_autoreleasePoolPush();

	if (_centralDirectoryOffset < 0 ||
	    (OFStreamOffset)_centralDirectoryOffset != _centralDirectoryOffset)
		@throw [OFOutOfRangeException exception];

	seekOrThrowInvalidFormat(_stream,
	    (OFStreamOffset)_centralDirectoryOffset, OFSeekSet);

	for (size_t i = 0; i < _centralDirectoryEntries; i++) {
		OFZIPArchiveEntry *entry = [[[OFZIPArchiveEntry alloc]

































		    of_initWithStream: _stream] autorelease];

		if ([_pathToEntryMap objectForKey: entry.fileName] != nil)
			@throw [OFInvalidFormatException exception];

		[_entries addObject: entry];
		[_pathToEntryMap setObject: entry forKey: entry.fileName];







|



|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
{
	void *pool = objc_autoreleasePoolPush();

	if (_centralDirectoryOffset < 0 ||
	    (OFStreamOffset)_centralDirectoryOffset != _centralDirectoryOffset)
		@throw [OFOutOfRangeException exception];

	seekOrThrowInvalidFormat(self, &_centralDirectoryDisk,
	    (OFStreamOffset)_centralDirectoryOffset, OFSeekSet);

	for (size_t i = 0; i < _centralDirectoryEntries; i++) {
		OFZIPArchiveEntry *entry;
		char buffer;

		/*
		 * The stream might have 0 bytes left to read, but might not
		 * realize that before a read is attempted, where it will then
		 * return a length of 0. But OFZIPArchiveEntry expects to be
		 * able to read the entire entry and will then throw an
		 * OFTruncatedDataException. Therefore, try to peek one byte to
		 * make sure the stream realizes that it's at the end.
		 */
		if ([_stream readIntoBuffer: &buffer length: 1] == 1)
			[_stream unreadFromBuffer: &buffer length: 1];

		if ([_stream isAtEndOfStream]) {
			OFStream *oldStream = _stream;
			OFSeekableStream *stream;

			if (_diskNumber >= _lastDiskNumber)
				@throw [OFTruncatedDataException exception];

			stream = [_delegate archive: self
				  wantsPartNumbered: _diskNumber + 1
				     lastPartNumber: _lastDiskNumber];

			if (stream == nil)
				@throw [OFInvalidFormatException exception];

			_diskNumber++;
			_stream = [stream retain];
			[oldStream release];
		}

		entry = [[[OFZIPArchiveEntry alloc]
		    of_initWithStream: _stream] autorelease];

		if ([_pathToEntryMap objectForKey: entry.fileName] != nil)
			@throw [OFInvalidFormatException exception];

		[_entries addObject: entry];
		[_pathToEntryMap setObject: entry forKey: entry.fileName];
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
}

- (OFStream *)streamForReadingFile: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFZIPArchiveEntry *entry;
	OFZIPArchiveLocalFileHeader *localFileHeader;

	int64_t offset64;

	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_mode != modeRead)
		@throw [OFInvalidArgumentException exception];

	if ((entry = [_pathToEntryMap objectForKey: path]) == nil)
		@throw [OFOpenItemFailedException exceptionWithPath: path
							       mode: @"r"
							      errNo: ENOENT];

	@try {
		[_lastReturnedStream close];
	} @catch (OFNotOpenException *e) {
		/* Might have already been closed by the user - that's fine. */
	}
	_lastReturnedStream = nil;


	offset64 = entry.of_localFileHeaderOffset;
	if (offset64 < 0 || (OFStreamOffset)offset64 != offset64)
		@throw [OFOutOfRangeException exception];


	seekOrThrowInvalidFormat(_stream, (OFStreamOffset)offset64, OFSeekSet);
	localFileHeader = [[[OFZIPArchiveLocalFileHeader alloc]
	    initWithStream: _stream] autorelease];

	if (![localFileHeader matchesEntry: entry])
		@throw [OFInvalidFormatException exception];

	if ((localFileHeader->_minVersionNeeded & 0xFF) > 45) {







>




















>




>
|







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
}

- (OFStream *)streamForReadingFile: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFZIPArchiveEntry *entry;
	OFZIPArchiveLocalFileHeader *localFileHeader;
	uint32_t startDiskNumber;
	int64_t offset64;

	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_mode != modeRead)
		@throw [OFInvalidArgumentException exception];

	if ((entry = [_pathToEntryMap objectForKey: path]) == nil)
		@throw [OFOpenItemFailedException exceptionWithPath: path
							       mode: @"r"
							      errNo: ENOENT];

	@try {
		[_lastReturnedStream close];
	} @catch (OFNotOpenException *e) {
		/* Might have already been closed by the user - that's fine. */
	}
	_lastReturnedStream = nil;

	startDiskNumber = entry.of_startDiskNumber;
	offset64 = entry.of_localFileHeaderOffset;
	if (offset64 < 0 || (OFStreamOffset)offset64 != offset64)
		@throw [OFOutOfRangeException exception];

	seekOrThrowInvalidFormat(self, &startDiskNumber,
	    (OFStreamOffset)offset64, OFSeekSet);
	localFileHeader = [[[OFZIPArchiveLocalFileHeader alloc]
	    initWithStream: _stream] autorelease];

	if (![localFileHeader matchesEntry: entry])
		@throw [OFInvalidFormatException exception];

	if ((localFileHeader->_minVersionNeeded & 0xFF) > 45) {
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
			    stream: (OFStream *)stream
			     entry: (OFZIPArchiveEntry *)entry
{
	self = [super init];

	@try {
		_archive = [archive retain];
		_stream = [stream retain];

		switch (entry.compressionMethod) {
		case OFZIPArchiveEntryCompressionMethodNone:
			_decompressedStream = [stream retain];
			break;
		case OFZIPArchiveEntryCompressionMethodDeflate:
			_decompressedStream = [[OFInflateStream alloc]
			    initWithStream: stream];
			break;
		case OFZIPArchiveEntryCompressionMethodDeflate64:
			_decompressedStream = [[OFInflate64Stream alloc]
			    initWithStream: stream];
			break;
		default:
			@throw [OFNotImplementedException
			    exceptionWithSelector: _cmd
					   object: nil];
		}

		_entry = [entry copy];
		_toRead = entry.uncompressedSize;
		_CRC32 = ~0;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	if (_stream != nil || _decompressedStream != nil)
		[self close];

	[_entry release];

	if (_archive->_lastReturnedStream == self)
		_archive->_lastReturnedStream = nil;

	[_archive release];

	[super dealloc];
}

- (bool)lowlevelIsAtEndOfStream
{
	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	return _atEndOfStream;
}

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

	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_atEndOfStream)
		return 0;


	if (_stream.atEndOfStream && !_decompressedStream.hasDataInReadBuffer)




		@throw [OFTruncatedDataException exception];































#if SIZE_MAX >= UINT64_MAX
	if (length > UINT64_MAX)
		@throw [OFOutOfRangeException exception];
#endif

	if (length > _toRead)







|

|

|



|



|




















|














|









|





>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
			    stream: (OFStream *)stream
			     entry: (OFZIPArchiveEntry *)entry
{
	self = [super init];

	@try {
		_archive = [archive retain];
		_compressionMethod = entry.compressionMethod;

		switch (_compressionMethod) {
		case OFZIPArchiveEntryCompressionMethodNone:
			_decompressedStream = [_archive->_stream retain];
			break;
		case OFZIPArchiveEntryCompressionMethodDeflate:
			_decompressedStream = [[OFInflateStream alloc]
			    initWithStream: _archive->_stream];
			break;
		case OFZIPArchiveEntryCompressionMethodDeflate64:
			_decompressedStream = [[OFInflate64Stream alloc]
			    initWithStream: _archive->_stream];
			break;
		default:
			@throw [OFNotImplementedException
			    exceptionWithSelector: _cmd
					   object: nil];
		}

		_entry = [entry copy];
		_toRead = entry.uncompressedSize;
		_CRC32 = ~0;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	if (_decompressedStream != nil)
		[self close];

	[_entry release];

	if (_archive->_lastReturnedStream == self)
		_archive->_lastReturnedStream = nil;

	[_archive release];

	[super dealloc];
}

- (bool)lowlevelIsAtEndOfStream
{
	if (_decompressedStream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	return _atEndOfStream;
}

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

	if (_decompressedStream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_atEndOfStream)
		return 0;

	if ([_archive->_stream isAtEndOfStream] &&
	    ![_decompressedStream hasDataInReadBuffer]) {
		OFStream *oldStream = _archive->_stream, *oldDecompressedStream;
		OFSeekableStream *stream;

		if (_archive->_diskNumber >= _archive->_lastDiskNumber)
			@throw [OFTruncatedDataException exception];

		stream = [_archive->_delegate
			      archive: _archive
		    wantsPartNumbered: _archive->_diskNumber + 1
		       lastPartNumber: _archive->_lastDiskNumber];

		if (stream == nil)
			@throw [OFInvalidFormatException exception];

		_archive->_diskNumber++;
		_archive->_stream = [stream retain];
		[oldStream release];

		switch (_compressionMethod) {
		case OFZIPArchiveEntryCompressionMethodNone:
			oldDecompressedStream = _decompressedStream;
			_decompressedStream = [_archive->_stream retain];
			[oldDecompressedStream release];
			break;
		case OFZIPArchiveEntryCompressionMethodDeflate:
		case OFZIPArchiveEntryCompressionMethodDeflate64:
			[_decompressedStream
			    setUnderlyingStream: _archive->_stream];
			break;
		default:
			@throw [OFNotImplementedException
			    exceptionWithSelector: _cmd
					   object: nil];
		}
	}

#if SIZE_MAX >= UINT64_MAX
	if (length > UINT64_MAX)
		@throw [OFOutOfRangeException exception];
#endif

	if (length > _toRead)
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

	return ret;
}

- (bool)hasDataInReadBuffer
{
	return (super.hasDataInReadBuffer ||
	    _decompressedStream.hasDataInReadBuffer);
}

- (int)fileDescriptorForReading
{
	return ((id <OFReadyForReadingObserving>)_decompressedStream)
	    .fileDescriptorForReading;
}

- (void)close
{
	if (_stream == nil || _decompressedStream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	[_stream release];
	_stream = nil;

	[_decompressedStream release];
	_decompressedStream = nil;

	[super close];
}
@end








|










|


<
<
<







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

	return ret;
}

- (bool)hasDataInReadBuffer
{
	return (super.hasDataInReadBuffer ||
	    [_decompressedStream hasDataInReadBuffer]);
}

- (int)fileDescriptorForReading
{
	return ((id <OFReadyForReadingObserving>)_decompressedStream)
	    .fileDescriptorForReading;
}

- (void)close
{
	if (_decompressedStream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];




	[_decompressedStream release];
	_decompressedStream = nil;

	[super close];
}
@end

Modified src/OFZIPArchiveEntry+Private.h from [086f6aeb71] to [cd5774f862].

16
17
18
19
20
21
22

23
24
25
26
27
28
29
#import "OFZIPArchive.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFZIPArchiveEntry ()
@property (readonly, nonatomic)
    uint16_t of_lastModifiedFileTime, of_lastModifiedFileDate;

@property (readonly, nonatomic) int64_t of_localFileHeaderOffset;

- (instancetype)of_init OF_METHOD_FAMILY(init);
- (instancetype)of_initWithStream: (OFStream *)stream
    OF_METHOD_FAMILY(init) OF_DIRECT;
- (uint64_t)of_writeToStream: (OFStream *)stream OF_DIRECT;
@end







>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#import "OFZIPArchive.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFZIPArchiveEntry ()
@property (readonly, nonatomic)
    uint16_t of_lastModifiedFileTime, of_lastModifiedFileDate;
@property (readonly, nonatomic) uint32_t of_startDiskNumber;
@property (readonly, nonatomic) int64_t of_localFileHeaderOffset;

- (instancetype)of_init OF_METHOD_FAMILY(init);
- (instancetype)of_initWithStream: (OFStream *)stream
    OF_METHOD_FAMILY(init) OF_DIRECT;
- (uint64_t)of_writeToStream: (OFStream *)stream OF_DIRECT;
@end

Modified src/OFZIPArchiveEntry.m from [b03fc597d2] to [f349333dfe].

403
404
405
406
407
408
409





410
411
412
413
414
415
416
	return _lastModifiedFileTime;
}

- (uint16_t)of_lastModifiedFileDate
{
	return _lastModifiedFileDate;
}






- (int64_t)of_localFileHeaderOffset
{
	return _localFileHeaderOffset;
}

- (OFString *)description







>
>
>
>
>







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
	return _lastModifiedFileTime;
}

- (uint16_t)of_lastModifiedFileDate
{
	return _lastModifiedFileDate;
}

- (uint32_t)of_startDiskNumber
{
	return _startDiskNumber;
}

- (int64_t)of_localFileHeaderOffset
{
	return _localFileHeaderOffset;
}

- (OFString *)description

Modified src/exceptions/OFAllocFailedException.m from [35f3b6d4b6] to [8de5460cac].

30
31
32
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
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
	return self;
}

- (unsigned int)retainCount
{
	return OFMaxRetainCount;
}

- (void)release
{
}

- (void)dealloc
{
	OF_DEALLOC_UNSUPPORTED
}

- (OFString *)description
{
	return @"Allocating an object failed!";
}
@end







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






30
31
32
33
34
35
36




37


















38
39
40
41
42
43
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}





OF_SINGLETON_METHODS



















- (OFString *)description
{
	return @"Allocating an object failed!";
}
@end

Modified src/macros.h from [4191bc0c4c] to [50c6f2e2c4].

405
406
407
408
409
410
411
























412
413
414
415
416
417
418
# define OF_DEALLOC_UNSUPPORTED						\
	[self doesNotRecognizeSelector: _cmd];				\
									\
	abort();							\
									\
	[super dealloc];	/* Get rid of a stupid warning */
#endif

























#define OF_CONSTRUCTOR(prio)					\
	static void __attribute__((__constructor__(prio)))	\
	OF_PREPROCESSOR_CONCAT(constructor, __LINE__)(void)
#define OF_DESTRUCTOR(prio)					\
	static void __attribute__((__destructor__(prio)))	\
	OF_PREPROCESSOR_CONCAT(destructor, __LINE__)(void)







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
# define OF_DEALLOC_UNSUPPORTED						\
	[self doesNotRecognizeSelector: _cmd];				\
									\
	abort();							\
									\
	[super dealloc];	/* Get rid of a stupid warning */
#endif
#define OF_SINGLETON_METHODS			\
	- (instancetype)autorelease		\
	{					\
		return self;			\
	}					\
						\
	- (instancetype)retain			\
	{					\
		return self;			\
	}					\
						\
	- (void)release				\
	{					\
	}					\
						\
	- (unsigned int)retainCount		\
	{					\
		return OFMaxRetainCount;	\
	}					\
						\
	- (void)dealloc				\
	{					\
		OF_DEALLOC_UNSUPPORTED		\
	}

#define OF_CONSTRUCTOR(prio)					\
	static void __attribute__((__constructor__(prio)))	\
	OF_PREPROCESSOR_CONCAT(constructor, __LINE__)(void)
#define OF_DESTRUCTOR(prio)					\
	static void __attribute__((__destructor__(prio)))	\
	OF_PREPROCESSOR_CONCAT(destructor, __LINE__)(void)

Modified src/platform/POSIX/OFSystemInfo+NetworkInterfaces.m from [5833caf501] to [7433d01bcf].

17
18
19
20
21
22
23



24
25
26
27
28
29
30

#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef OF_HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif



#ifdef HAVE_NET_IF_H
# include <net/if.h>
#endif
#ifdef HAVE_NET_IF_ARP_H
# include <net/if_arp.h>
#endif
#ifdef HAVE_NET_IF_DL_H







>
>
>







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

#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef OF_HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SOCKIO_H
# include <sys/sockio.h>
#endif
#ifdef HAVE_NET_IF_H
# include <net/if.h>
#endif
#ifdef HAVE_NET_IF_ARP_H
# include <net/if_arp.h>
#endif
#ifdef HAVE_NET_IF_DL_H
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108




109



110
































































111
112
113
114
115
116
117
static bool
queryNetworkInterfaceAddresses(OFMutableDictionary *ret,
    OFNetworkInterfaceKey key, OFSocketAddressFamily addressFamily, int family,
    size_t sockaddrSize)
{
	OFStringEncoding encoding = [OFLocale encoding];
	int sock = socket(family, SOCK_DGRAM, 0);
	struct ifconf ifc;
	struct ifreq *ifrs;
	OFMutableDictionary *interface;
	OFEnumerator *enumerator;

	if (sock < 0)
		return false;





	ifrs = malloc(128 * sizeof(struct ifreq));



	if (ifrs == NULL) {
































































		closesocket(sock);
		return false;
	}

	@try {
		char *buffer;








<
<






>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
static bool
queryNetworkInterfaceAddresses(OFMutableDictionary *ret,
    OFNetworkInterfaceKey key, OFSocketAddressFamily addressFamily, int family,
    size_t sockaddrSize)
{
	OFStringEncoding encoding = [OFLocale encoding];
	int sock = socket(family, SOCK_DGRAM, 0);


	OFMutableDictionary *interface;
	OFEnumerator *enumerator;

	if (sock < 0)
		return false;

# if defined(HAVE_STRUCT_LIFCONF) && defined(SIOCGLIFCONF)
	struct lifconf lifc;
	struct lifreq *lifrs;

	if ((lifrs = malloc(128 * sizeof(struct lifreq))) == NULL) {
		closesocket(sock);
		return false;
	}

	@try {
		char *buffer;

		memset(&lifc, 0, sizeof(lifc));
		lifc.lifc_buf = (void *)lifrs;
		lifc.lifc_len = 128 * sizeof(struct lifreq);
		if (ioctl(sock, SIOCGLIFCONF, &lifc) < 0)
			return false;

		for (buffer = lifc.lifc_buf;
		    buffer < (char *)lifc.lifc_buf + lifc.lifc_len;
		    buffer += sizeof(struct lifreq)) {
			struct lifreq *current =
			    (struct lifreq *)(void *)buffer;
			OFString *name;
			OFMutableData *addresses;
			OFSocketAddress address;

			if (current->lifr_addr.ss_family != family)
				continue;

			name = [OFString stringWithCString: current->lifr_name
						  encoding: encoding];
			if ((interface = [ret objectForKey: name]) == nil) {
				interface = [OFMutableDictionary dictionary];
				[ret setObject: interface forKey: name];
			}

			addresses = [interface objectForKey: key];
			if (addresses == nil) {
				addresses = [OFMutableData
				    dataWithItemSize: sizeof(OFSocketAddress)];
				[interface setObject: addresses forKey: key];
			}

			memset(&address, 0, sizeof(address));
			address.family = addressFamily;
			memcpy(&address.sockaddr.in, &current->lifr_addr,
			    sockaddrSize);

#  if defined(OF_HAVE_IPV6) && defined(HAVE_IF_NAMETOINDEX)
			if (address.sockaddr.in6.sin6_family == AF_INET6 &&
			    address.sockaddr.in6.sin6_addr.s6_addr[0] == 0xFE &&
			    (address.sockaddr.in6.sin6_addr.s6_addr[1] & 0xC0)
			    == 0x80)
				address.sockaddr.in6.sin6_scope_id =
				    if_nametoindex(
				    [name cStringWithEncoding: encoding]);
#  endif

			[addresses addItem: &address];
		}
	} @finally {
		free(lifrs);
		closesocket(sock);
	}
# else
	struct ifconf ifc;
	struct ifreq *ifrs;

	if (sock < 0)
		return false;

	if ((ifrs = malloc(128 * sizeof(struct ifreq))) == NULL) {
		closesocket(sock);
		return false;
	}

	@try {
		char *buffer;

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
				[interface setObject: addresses forKey: key];
			}

			memset(&address, 0, sizeof(address));
			address.family = addressFamily;
			memcpy(&address.sockaddr.in, &current->ifr_addr,
			    sockaddrSize);











			[addresses addItem: &address];

next:
# ifdef _SIZEOF_ADDR_IFREQ
			buffer += _SIZEOF_ADDR_IFREQ(*current);
# else
			buffer += sizeof(struct ifreq);
# endif
		}
	} @finally {
		free(ifrs);
		closesocket(sock);
	}


	enumerator = [ret objectEnumerator];
	while ((interface = [enumerator nextObject]) != nil)
		[[interface objectForKey: key] makeImmutable];

	return true;
}







>
>
>
>
>
>
>
>
>
>














>







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
				[interface setObject: addresses forKey: key];
			}

			memset(&address, 0, sizeof(address));
			address.family = addressFamily;
			memcpy(&address.sockaddr.in, &current->ifr_addr,
			    sockaddrSize);

#  if defined(OF_HAVE_IPV6) && defined(HAVE_IF_NAMETOINDEX)
			if (address.sockaddr.in6.sin6_family == AF_INET6 &&
			    address.sockaddr.in6.sin6_addr.s6_addr[0] == 0xFE &&
			    (address.sockaddr.in6.sin6_addr.s6_addr[1] & 0xC0)
			    == 0x80)
				address.sockaddr.in6.sin6_scope_id =
				    if_nametoindex(
				    [name cStringWithEncoding: encoding]);
#  endif

			[addresses addItem: &address];

next:
# ifdef _SIZEOF_ADDR_IFREQ
			buffer += _SIZEOF_ADDR_IFREQ(*current);
# else
			buffer += sizeof(struct ifreq);
# endif
		}
	} @finally {
		free(ifrs);
		closesocket(sock);
	}
# endif

	enumerator = [ret objectEnumerator];
	while ((interface = [enumerator nextObject]) != nil)
		[[interface objectForKey: key] makeImmutable];

	return true;
}
185
186
187
188
189
190
191



192
193
194
195
196
197
198
}

#ifdef OF_HAVE_IPV6
static bool
queryNetworkInterfaceIPv6Addresses(OFMutableDictionary *ret)
{
# if defined(OF_LINUX) && defined(OF_HAVE_FILES)



	OFFile *file;
	OFString *line;
	OFMutableDictionary *interface;
	OFEnumerator *enumerator;

	@try {
		file = [OFFile fileWithPath: @"/proc/net/if_inet6" mode: @"r"];







>
>
>







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

#ifdef OF_HAVE_IPV6
static bool
queryNetworkInterfaceIPv6Addresses(OFMutableDictionary *ret)
{
# if defined(OF_LINUX) && defined(OF_HAVE_FILES)
#  ifdef HAVE_IF_NAMETOINDEX
	OFStringEncoding encoding = [OFLocale encoding];
#  endif
	OFFile *file;
	OFString *line;
	OFMutableDictionary *interface;
	OFEnumerator *enumerator;

	@try {
		file = [OFFile fileWithPath: @"/proc/net/if_inet6" mode: @"r"];
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
		if ((interface = [ret objectForKey: name]) == nil) {
			interface = [OFMutableDictionary dictionary];
			[ret setObject: interface forKey: name];
		}

		memset(&address, 0, sizeof(address));
		address.family = OFSocketAddressFamilyIPv6;


		for (size_t i = 0; i < 32; i += 2) {
			unsigned long long byte;

			@try {
				byte = [[addressString
				    substringWithRange: OFMakeRange(i, 2)]
				    unsignedLongLongValueWithBase: 16];
			} @catch (OFInvalidFormatException *e) {
				goto next_line;
			}

			if (byte > 0xFF)
				goto next_line;

			address.sockaddr.in6.sin6_addr.s6_addr[i / 2] =
			    (unsigned char)byte;
		}








		if ((addresses = [interface
		    objectForKey: OFNetworkInterfaceIPv6Addresses]) == nil) {
			addresses = [OFMutableData
			    dataWithItemSize: sizeof(OFSocketAddress)];
			[interface setObject: addresses
				      forKey: OFNetworkInterfaceIPv6Addresses];







>


















>
>
>
>
>
>
>







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
		if ((interface = [ret objectForKey: name]) == nil) {
			interface = [OFMutableDictionary dictionary];
			[ret setObject: interface forKey: name];
		}

		memset(&address, 0, sizeof(address));
		address.family = OFSocketAddressFamilyIPv6;
		address.sockaddr.in6.sin6_family = AF_INET6;

		for (size_t i = 0; i < 32; i += 2) {
			unsigned long long byte;

			@try {
				byte = [[addressString
				    substringWithRange: OFMakeRange(i, 2)]
				    unsignedLongLongValueWithBase: 16];
			} @catch (OFInvalidFormatException *e) {
				goto next_line;
			}

			if (byte > 0xFF)
				goto next_line;

			address.sockaddr.in6.sin6_addr.s6_addr[i / 2] =
			    (unsigned char)byte;
		}

#  ifdef HAVE_IF_NAMETOINDEX
		if (address.sockaddr.in6.sin6_addr.s6_addr[0] == 0xFE &&
		    (address.sockaddr.in6.sin6_addr.s6_addr[1] & 0xC0) == 0x80)
			address.sockaddr.in6.sin6_scope_id = if_nametoindex(
			    [name cStringWithEncoding: encoding]);
#  endif

		if ((addresses = [interface
		    objectForKey: OFNetworkInterfaceIPv6Addresses]) == nil) {
			addresses = [OFMutableData
			    dataWithItemSize: sizeof(OFSocketAddress)];
			[interface setObject: addresses
				      forKey: OFNetworkInterfaceIPv6Addresses];
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
}
#endif

#ifdef OF_HAVE_IPX
static bool
queryNetworkInterfaceIPXAddresses(OFMutableDictionary *ret)
{











































































# if defined(HAVE_IOCTL) && defined(HAVE_NET_IF_H)
	return queryNetworkInterfaceAddresses(ret,
	    OFNetworkInterfaceIPXAddresses, OFSocketAddressFamilyIPX,
	    AF_IPX, sizeof(struct sockaddr_ipx));
# else
	return false;
# endif
}
#endif

#ifdef OF_HAVE_APPLETALK
static bool
queryNetworkInterfaceAppleTalkAddresses(OFMutableDictionary *ret)
{












































































# if defined(HAVE_IOCTL) && defined(HAVE_NET_IF_H)
	return queryNetworkInterfaceAddresses(ret,
	    OFNetworkInterfaceAppleTalkAddresses,
	    OFSocketAddressFamilyAppleTalk, AF_APPLETALK,
	    sizeof(struct sockaddr_at));
# else
	return false;
# endif
}
#endif

static bool
queryNetworkInterfaceHardwareAddress(OFMutableDictionary *ret)
{
#if defined(HAVE_IOCTL) && defined(HAVE_NET_IF_H) && defined(SIOCGIFHWADDR)




































	OFStringEncoding encoding = [OFLocale encoding];
	int sock = socket(AF_INET, SOCK_DGRAM, 0);

	if (sock < 0)
		return false;

	for (OFString *name in ret) {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|













|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
}
#endif

#ifdef OF_HAVE_IPX
static bool
queryNetworkInterfaceIPXAddresses(OFMutableDictionary *ret)
{
# if defined(OF_LINUX) && defined(OF_HAVE_FILES)
	OFFile *file;
	OFString *line;
	OFMutableDictionary *interface;
	OFEnumerator *enumerator;

	@try {
		file = [OFFile fileWithPath: @"/proc/net/ipx/interface"
				       mode: @"r"];
	} @catch (OFOpenItemFailedException *e) {
		return false;
	}

	/* First line is "Network Node_Address Primary Device Frame_Type" */
	if (![[file readLine] hasPrefix: @"Network "])
		return false;

	while ((line = [file readLine]) != nil) {
		OFArray *components = [line
		    componentsSeparatedByString: @" "
					options: OFStringSkipEmptyComponents];
		OFString *name;
		unsigned long long network, nodeLong;
		unsigned char node[IPX_NODE_LEN];
		OFSocketAddress address;
		OFMutableData *addresses;

		if (components.count < 5)
			continue;

		name = [components objectAtIndex: 3];

		if ((interface = [ret objectForKey: name]) == nil) {
			interface = [OFMutableDictionary dictionary];
			[ret setObject: interface forKey: name];
		}

		@try {
			network = [[components objectAtIndex: 0]
			    unsignedLongLongValueWithBase: 16];
			nodeLong = [[components objectAtIndex: 1]
			    unsignedLongLongValueWithBase: 16];
		} @catch (OFInvalidFormatException *e) {
			continue;
		}

		if (network > 0xFFFFFFFF || nodeLong > 0xFFFFFFFFFFFF)
			continue;

		node[0] = (nodeLong >> 40) & 0xFF;
		node[1] = (nodeLong >> 32) & 0xFF;
		node[2] = (nodeLong >> 24) & 0xFF;
		node[3] = (nodeLong >> 16) & 0xFF;
		node[4] = (nodeLong >> 8) & 0xFF;
		node[5] = nodeLong & 0xFF;

		address = OFSocketAddressMakeIPX((uint32_t)network, node, 0);

		if ((addresses = [interface objectForKey:
		    OFNetworkInterfaceIPXAddresses]) == nil) {
			addresses = [OFMutableData
			    dataWithItemSize: sizeof(OFSocketAddress)];
			[interface setObject: addresses
				      forKey: OFNetworkInterfaceIPXAddresses];
		}

		[addresses addItem: &address];
	}

	enumerator = [ret objectEnumerator];
	while ((interface = [enumerator nextObject]) != nil)
		[[interface objectForKey: OFNetworkInterfaceIPXAddresses]
		    makeImmutable];

	return false;
# elif defined(HAVE_IOCTL) && defined(HAVE_NET_IF_H)
	return queryNetworkInterfaceAddresses(ret,
	    OFNetworkInterfaceIPXAddresses, OFSocketAddressFamilyIPX,
	    AF_IPX, sizeof(struct sockaddr_ipx));
# else
	return false;
# endif
}
#endif

#ifdef OF_HAVE_APPLETALK
static bool
queryNetworkInterfaceAppleTalkAddresses(OFMutableDictionary *ret)
{
# if defined(OF_LINUX) && defined(OF_HAVE_FILES)
	OFFile *file;
	OFString *line;
	OFMutableDictionary *interface;
	OFEnumerator *enumerator;

	@try {
		file = [OFFile fileWithPath: @"/proc/net/atalk/interface"
				       mode: @"r"];
	} @catch (OFOpenItemFailedException *e) {
		return false;
	}

	/* First line is "Interface Address Networks Status" */
	if (![[file readLine] hasPrefix: @"Interface "])
		return false;

	while ((line = [file readLine]) != nil) {
		OFArray *components = [line
		    componentsSeparatedByString: @" "
					options: OFStringSkipEmptyComponents];
		OFString *addressString, *name;
		unsigned long long network, node;
		OFSocketAddress address;
		OFMutableData *addresses;

		if (components.count < 4)
			continue;

		name = [components objectAtIndex: 0];
		addressString = [components objectAtIndex: 1];

		if (addressString.length != 7 ||
		    [addressString characterAtIndex: 4] != ':')
			continue;

		if ((interface = [ret objectForKey: name]) == nil) {
			interface = [OFMutableDictionary dictionary];
			[ret setObject: interface forKey: name];
		}

		@try {
			network = [[addressString
			    substringWithRange: OFMakeRange(0, 4)]
			    unsignedLongLongValueWithBase: 16];
			node = [[addressString
			    substringWithRange: OFMakeRange(5, 2)]
			    unsignedLongLongValueWithBase: 16];
		} @catch (OFInvalidFormatException *e) {
			continue;
		}

		if (network > 0xFFFF || node > 0xFF)
			continue;

		address = OFSocketAddressMakeAppleTalk(
		    (uint16_t)network, (uint8_t)node, 0);

		if ((addresses = [interface objectForKey:
		    OFNetworkInterfaceAppleTalkAddresses]) == nil) {
			addresses = [OFMutableData
			    dataWithItemSize: sizeof(OFSocketAddress)];
			[interface
			    setObject: addresses
			       forKey: OFNetworkInterfaceAppleTalkAddresses];
		}

		[addresses addItem: &address];
	}

	enumerator = [ret objectEnumerator];
	while ((interface = [enumerator nextObject]) != nil)
		[[interface objectForKey: OFNetworkInterfaceAppleTalkAddresses]
		    makeImmutable];

	return false;
# elif defined(HAVE_IOCTL) && defined(HAVE_NET_IF_H)
	return queryNetworkInterfaceAddresses(ret,
	    OFNetworkInterfaceAppleTalkAddresses,
	    OFSocketAddressFamilyAppleTalk, AF_APPLETALK,
	    sizeof(struct sockaddr_at));
# else
	return false;
# endif
}
#endif

static bool
queryNetworkInterfaceHardwareAddress(OFMutableDictionary *ret)
{
#if defined(HAVE_IOCTL) && defined(HAVE_NET_IF_H) && defined(SIOCGLIFHWADDR)
	OFStringEncoding encoding = [OFLocale encoding];
	int sock = socket(AF_INET, SOCK_DGRAM, 0);

	if (sock < 0)
		return false;

	for (OFString *name in ret) {
		size_t nameLength = [name cStringLengthWithEncoding: encoding];
		struct lifreq lifr;
		struct sockaddr_dl *sdl;
		OFData *hardwareAddress;

		if (nameLength > IFNAMSIZ)
			continue;

		memset(&lifr, 0, sizeof(lifr));
		memcpy(&lifr.lifr_name, [name cStringWithEncoding: encoding],
		    nameLength);

		if (ioctl(sock, SIOCGLIFHWADDR, &lifr) < 0)
			continue;

		if (lifr.lifr_addr.ss_family != AF_LINK)
			continue;

		sdl = (struct sockaddr_dl *)(void *)&lifr.lifr_addr;
		hardwareAddress = [OFData dataWithItems: LLADDR(sdl)
						  count: sdl->sdl_alen];
		[[ret objectForKey: name]
		    setObject: hardwareAddress
		       forKey: OFNetworkInterfaceHardwareAddress];
	}

	return true;
#elif defined(HAVE_IOCTL) && defined(HAVE_NET_IF_H) && \
    defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_HWADDR)
	OFStringEncoding encoding = [OFLocale encoding];
	int sock = socket(AF_INET, SOCK_DGRAM, 0);

	if (sock < 0)
		return false;

	for (OFString *name in ret) {

Modified src/runtime/exception.m from [aa18b3eafc] to [0555413ebe].

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <string.h>

#import "ObjFWRT.h"
#import "private.h"

#import "macros.h"
#ifdef OF_HAVE_THREADS
# include "OFPlainMutex.h"
#endif

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

#if defined(HAVE_DWARF_EXCEPTIONS)







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <string.h>

#import "ObjFWRT.h"
#import "private.h"

#import "macros.h"
#ifdef OF_HAVE_THREADS
# import "OFPlainMutex.h"
#endif

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

#if defined(HAVE_DWARF_EXCEPTIONS)

Modified tests/OFSetTests.m from [bc79bd72ed] to [c815f9bb11].

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 */

#include "config.h"

#import "TestsAppDelegate.h"

#import "OFSet.h"
#import "OFMapTableSet.h"
#import "OFMutableMapTableSet.h"

static OFString *module;

@interface SimpleSet: OFSet
{
	OFMutableSet *_set;
}







|
|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 */

#include "config.h"

#import "TestsAppDelegate.h"

#import "OFSet.h"
#import "OFConcreteSet.h"
#import "OFConcreteMutableSet.h"

static OFString *module;

@interface SimpleSet: OFSet
{
	OFMutableSet *_set;
}
284
285
286
287
288
289
290
291
292
293
294
295

- (void)setTests
{
	module = @"OFSet";
	[self setTestsWithClass: [SimpleSet class]
		   mutableClass: [SimpleMutableSet class]];

	module = @"OFMapTableSet";
	[self setTestsWithClass: [OFMapTableSet class]
		   mutableClass: [OFMutableMapTableSet class]];
}
@end







|
|
|


284
285
286
287
288
289
290
291
292
293
294
295

- (void)setTests
{
	module = @"OFSet";
	[self setTestsWithClass: [SimpleSet class]
		   mutableClass: [SimpleMutableSet class]];

	module = @"OFConcreteSet";
	[self setTestsWithClass: [OFConcreteSet class]
		   mutableClass: [OFConcreteMutableSet class]];
}
@end

Modified utils/ofarc/Archive.h from [5ec6829033] to [41439c3fd1].

12
13
14
15
16
17
18
19


20

21
22
23

24
25
26
27
28
29
30
31
32


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

#import "OFObject.h"
#import "OFFile.h"
#import "OFArray.h"



@protocol Archive <OFObject>

+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream
			     mode: (OFString *)mode
			 encoding: (OFStringEncoding)encoding;

- (instancetype)initWithStream: (OF_KINDOF(OFStream *))stream
			  mode: (OFString *)mode
		      encoding: (OFStringEncoding)encoding;
- (void)listFiles;
- (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files;
- (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files;
@optional
- (void)addFiles: (OFArray OF_GENERIC(OFString *) *)files;
@end










>
>

>
|
|
|
>
|
|
|






>
>
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFObject.h"
#import "OFFile.h"
#import "OFArray.h"

OF_ASSUME_NONNULL_BEGIN

@protocol Archive <OFObject>
+ (instancetype)archiveWithPath: (OFString *)path
			 stream: (OF_KINDOF(OFStream *))stream
			   mode: (OFString *)mode
		       encoding: (OFStringEncoding)encoding;
- (instancetype)initWithPath: (OFString *)path
		      stream: (OF_KINDOF(OFStream *))stream
			mode: (OFString *)mode
		    encoding: (OFStringEncoding)encoding;
- (void)listFiles;
- (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files;
- (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files;
@optional
- (void)addFiles: (OFArray OF_GENERIC(OFString *) *)files;
@end

OF_ASSUME_NONNULL_END

Modified utils/ofarc/GZIPArchive.m from [f819d2f5e4] to [f5cd966d15].

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
@implementation GZIPArchive
+ (void)initialize
{
	if (self == [GZIPArchive class])
		app = (OFArc *)[OFApplication sharedApplication].delegate;
}


+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream
			     mode: (OFString *)mode
			 encoding: (OFStringEncoding)encoding
{
	return [[[self alloc] initWithStream: stream

					mode: mode
				    encoding: encoding] autorelease];
}


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

	@try {
		_stream = [[OFGZIPStream alloc] initWithStream: stream
							  mode: mode];
	} @catch (id e) {







>
|
|
|

|
>
|
|


>
|
|
|







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
@implementation GZIPArchive
+ (void)initialize
{
	if (self == [GZIPArchive class])
		app = (OFArc *)[OFApplication sharedApplication].delegate;
}

+ (instancetype)archiveWithPath: (OFString *)path
			 stream: (OF_KINDOF(OFStream *))stream
			   mode: (OFString *)mode
		       encoding: (OFStringEncoding)encoding
{
	return [[[self alloc] initWithPath: path
				    stream: stream
				      mode: mode
				  encoding: encoding] autorelease];
}

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

	@try {
		_stream = [[OFGZIPStream alloc] initWithStream: stream
							  mode: mode];
	} @catch (id e) {

Modified utils/ofarc/LHAArchive.m from [f59c7fc9d2] to [e1794bea79].

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
@implementation LHAArchive
+ (void)initialize
{
	if (self == [LHAArchive class])
		app = (OFArc *)[OFApplication sharedApplication].delegate;
}


+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream
			     mode: (OFString *)mode
			 encoding: (OFStringEncoding)encoding
{
	return [[[self alloc] initWithStream: stream

					mode: mode
				    encoding: encoding] autorelease];
}


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

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








>
|
|
|

|
>
|
|


>
|
|
|







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
@implementation LHAArchive
+ (void)initialize
{
	if (self == [LHAArchive class])
		app = (OFArc *)[OFApplication sharedApplication].delegate;
}

+ (instancetype)archiveWithPath: (OFString *)path
			 stream: (OF_KINDOF(OFStream *))stream
			   mode: (OFString *)mode
		       encoding: (OFStringEncoding)encoding
{
	return [[[self alloc] initWithPath: path
				    stream: stream
				      mode: mode
				  encoding: encoding] autorelease];
}

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

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

Modified utils/ofarc/OFArc.m from [eb89655310] to [5c5bcb3795].

530
531
532
533
534
535
536


537
538
539
540
541
542
543
		case 'p':
		case 'x':
			file = OFStdIn;
			break;
		default:
			@throw [OFInvalidArgumentException exception];
		}


	} else {
		@try {
			file = [OFFile fileWithPath: path mode: fileModeString];
		} @catch (OFOpenItemFailedException *e) {
			OFString *error = [OFString
			    stringWithCString: strerror(e.errNo)
				     encoding: [OFLocale encoding]];







>
>







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
		case 'p':
		case 'x':
			file = OFStdIn;
			break;
		default:
			@throw [OFInvalidArgumentException exception];
		}

		path = nil;
	} else {
		@try {
			file = [OFFile fileWithPath: path mode: fileModeString];
		} @catch (OFOpenItemFailedException *e) {
			OFString *error = [OFString
			    stringWithCString: strerror(e.errNo)
				     encoding: [OFLocale encoding]];
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
			type = @"tar";
		else
			type = @"zip";
	}

	@try {
		if ([type isEqual: @"gz"])
			archive = [GZIPArchive archiveWithStream: file

							    mode: modeString
							encoding: encoding];
		else if ([type isEqual: @"lha"])
			archive = [LHAArchive archiveWithStream: file

							   mode: modeString
						       encoding: encoding];
		else if ([type isEqual: @"tar"])
			archive = [TarArchive archiveWithStream: file

							   mode: modeString
						       encoding: encoding];
		else if ([type isEqual: @"tgz"]) {
			OFStream *GZIPStream = [OFGZIPStream
			    streamWithStream: file
					mode: modeString];
			archive = [TarArchive archiveWithStream: GZIPStream

							   mode: modeString
						       encoding: encoding];
		} else if ([type isEqual: @"zip"])
			archive = [ZIPArchive archiveWithStream: file

							   mode: modeString
						       encoding: encoding];
		else {
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"unknown_archive_type",
			    @"Unknown archive type: %[type]",
			    @"type", type)];
			goto error;
		}







|
>
|
|

|
>
|
|

|
>
|
|




|
>
|
|

|
>
|
|







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
			type = @"tar";
		else
			type = @"zip";
	}

	@try {
		if ([type isEqual: @"gz"])
			archive = [GZIPArchive archiveWithPath: path
							stream: file
							  mode: modeString
						      encoding: encoding];
		else if ([type isEqual: @"lha"])
			 archive = [LHAArchive archiveWithPath: path
							stream: file
							  mode: modeString
						      encoding: encoding];
		else if ([type isEqual: @"tar"])
			archive = [TarArchive archiveWithPath: path
						       stream: file
							 mode: modeString
						     encoding: encoding];
		else if ([type isEqual: @"tgz"]) {
			OFStream *GZIPStream = [OFGZIPStream
			    streamWithStream: file
					mode: modeString];
			archive = [TarArchive archiveWithPath: path
						       stream: GZIPStream
							 mode: modeString
						     encoding: encoding];
		} else if ([type isEqual: @"zip"])
			archive = [ZIPArchive archiveWithPath: path
						       stream: file
							 mode: modeString
						     encoding: encoding];
		else {
			[OFStdErr writeLine: OF_LOCALIZED(
			    @"unknown_archive_type",
			    @"Unknown archive type: %[type]",
			    @"type", type)];
			goto error;
		}

Modified utils/ofarc/TarArchive.m from [9bead949cb] to [67f5b716a2].

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
@implementation TarArchive
+ (void)initialize
{
	if (self == [TarArchive class])
		app = (OFArc *)[OFApplication sharedApplication].delegate;
}


+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream
			     mode: (OFString *)mode
			 encoding: (OFStringEncoding)encoding
{
	return [[[self alloc] initWithStream: stream

					mode: mode
				    encoding: encoding] autorelease];
}


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

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








>
|
|
|

|
>
|
|


>
|
|
|







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
@implementation TarArchive
+ (void)initialize
{
	if (self == [TarArchive class])
		app = (OFArc *)[OFApplication sharedApplication].delegate;
}

+ (instancetype)archiveWithPath: (OFString *)path
			 stream: (OF_KINDOF(OFStream *))stream
			   mode: (OFString *)mode
		       encoding: (OFStringEncoding)encoding
{
	return [[[self alloc] initWithPath: path
				    stream: stream
				      mode: mode
				  encoding: encoding] autorelease];
}

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

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

Modified utils/ofarc/ZIPArchive.h from [1c079ef618] to [00d8052406].

13
14
15
16
17
18
19
20
21

22
23
24
 * file.
 */

#import "OFZIPArchive.h"

#import "Archive.h"

@interface ZIPArchive: OFObject <Archive>
{

	OFZIPArchive *_archive;
}
@end







|

>



13
14
15
16
17
18
19
20
21
22
23
24
25
 * file.
 */

#import "OFZIPArchive.h"

#import "Archive.h"

@interface ZIPArchive: OFObject <OFZIPArchiveDelegate, Archive>
{
	OFString *_path;
	OFZIPArchive *_archive;
}
@end

Modified utils/ofarc/ZIPArchive.m from [110299511c] to [5f0ed89edf].

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
@implementation ZIPArchive
+ (void)initialize
{
	if (self == [ZIPArchive class])
		app = (OFArc *)[OFApplication sharedApplication].delegate;
}


+ (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream
			     mode: (OFString *)mode
			 encoding: (OFStringEncoding)encoding
{
	return [[[self alloc] initWithStream: stream

					mode: mode
				    encoding: encoding] autorelease];
}


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

	@try {

		_archive = [[OFZIPArchive alloc] initWithStream: stream
							   mode: mode];

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

	return self;
}

- (void)dealloc
{

	[_archive release];

	[super dealloc];
}






























- (void)listFiles
{
	for (OFZIPArchiveEntry *entry in _archive.entries) {
		void *pool = objc_autoreleasePoolPush();

		[OFStdOut writeLine: entry.fileName];







>
|
|
|

|
>
|
|


>
|
|
|




>


>










>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
@implementation ZIPArchive
+ (void)initialize
{
	if (self == [ZIPArchive class])
		app = (OFArc *)[OFApplication sharedApplication].delegate;
}

+ (instancetype)archiveWithPath: (OFString *)path
			 stream: (OF_KINDOF(OFStream *))stream
			   mode: (OFString *)mode
		       encoding: (OFStringEncoding)encoding
{
	return [[[self alloc] initWithPath: path
				    stream: stream
				      mode: mode
				  encoding: encoding] autorelease];
}

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

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

	return self;
}

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

	[super dealloc];
}

- (OFSeekableStream *)archive: (OFZIPArchive *)archive
	    wantsPartNumbered: (unsigned int)partNumber
	       lastPartNumber: (unsigned int)lastPartNumber
{
	OFString *path;

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

	if (partNumber > 98)
		return nil;

	if (partNumber == lastPartNumber)
		path = _path;
	else
		path = [_path.stringByDeletingPathExtension
		    stringByAppendingFormat: @".z%02u", partNumber + 1];

	@try {
		return [OFFile fileWithPath: path mode: @"r"];
	} @catch (OFOpenItemFailedException *e) {
		if (e.errNo != ENOENT)
			@throw e;

		return nil;
	}
}

- (void)listFiles
{
	for (OFZIPArchiveEntry *entry in _archive.entries) {
		void *pool = objc_autoreleasePoolPush();

		[OFStdOut writeLine: entry.fileName];

Modified utils/ofhttp/Makefile from [a53c9301a9] to [66e80fe2b3].

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2}

CPPFLAGS += -I../../src							\
	    -I../../src/runtime						\
	    -I../../src/exceptions					\
	    -I../../src/tls						\
	    -I../..							\
	    -DLOCALIZATION_DIR='"${datadir}/ofhttp/localization"'	\
	    -DLIB_PREFIX='"${LIB_PREFIX}"'				\
	    -DLIB_SUFFIX='"${LIB_SUFFIX}"'
LIBS := -L../../src -L../../src/tls ${OFHTTP_LIBS} -lobjfw		\
	-L../../src/runtime -L../../src/runtime/linklib ${RUNTIME_LIBS}	\
	${LIBS}
LD = ${OBJC}
LDFLAGS += ${LDFLAGS_RPATH}







|
<
<





13
14
15
16
17
18
19
20


21
22
23
24
25
${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2}

CPPFLAGS += -I../../src							\
	    -I../../src/runtime						\
	    -I../../src/exceptions					\
	    -I../../src/tls						\
	    -I../..							\
	    -DLOCALIZATION_DIR='"${datadir}/ofhttp/localization"'


LIBS := -L../../src -L../../src/tls ${OFHTTP_LIBS} -lobjfw		\
	-L../../src/runtime -L../../src/runtime/linklib ${RUNTIME_LIBS}	\
	${LIBS}
LD = ${OBJC}
LDFLAGS += ${LDFLAGS_RPATH}