ObjFW  Check-in [ff6eb7b6c3]

Overview
Comment:Merge trunk into branch "tagged-pointers"
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tagged-pointers
Files: files | file ages | folders
SHA3-256: ff6eb7b6c3ea22ad9f8a70a36255734607022e934d6f26f909f35e891f52716e
User & Date: js on 2020-08-30 15:40:33
Other Links: branch diff | manifest | tags
Context
2020-08-30
16:22
OFNumber: Never access ivars after init check-in: bc9998913a user: js tags: tagged-pointers
15:40
Merge trunk into branch "tagged-pointers" check-in: ff6eb7b6c3 user: js tags: tagged-pointers
2020-08-29
23:17
ofhttp: Translate "Error!" message check-in: f79f04f882 user: js tags: trunk
2020-07-26
21:09
lookup-asm-x86_64-macho.S: Fix missing @GOTPCREL check-in: 4cf6858694 user: js tags: tagged-pointers
Changes

Modified .fossil-settings/clean-glob from [bcab2de1f3] to [8cc139c114].

23
24
25
26
27
28
29

30
31
32
33
34
35
36
configure
docs
extra.mk
generators/gen_tables
src/Info.plist
src/bridge/Info.plist
src/objfw-defs.h

src/runtime/amiga-library-functable.inc
src/runtime/inline.h
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/objc_sync/objc_sync







>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
configure
docs
extra.mk
generators/gen_tables
src/Info.plist
src/bridge/Info.plist
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/amiga-library-functable.inc
src/runtime/inline.h
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/objc_sync/objc_sync

Modified .fossil-settings/ignore-glob from [01fa00e105] to [9af6ddf1c8].

25
26
27
28
29
30
31

32
33
34
35
36
37
38
configure
docs
extra.mk
generators/gen_tables
src/Info.plist
src/bridge/Info.plist
src/objfw-defs.h

src/runtime/amiga-library-functable.inc
src/runtime/inline.h
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/iOS.xcodeproj/*.pbxuser







>







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
configure
docs
extra.mk
generators/gen_tables
src/Info.plist
src/bridge/Info.plist
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/amiga-library-functable.inc
src/runtime/inline.h
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/iOS.xcodeproj/*.pbxuser

Modified .gitignore from [65d8f91504] to [1a9a1a32ef].

25
26
27
28
29
30
31

32
33
34
35
36
37
38
configure
docs
extra.mk
generators/gen_tables
src/Info.plist
src/bridge/Info.plist
src/objfw-defs.h

src/runtime/amiga-library-functable.inc
src/runtime/inline.h
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/iOS.xcodeproj/*.pbxuser







>







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
configure
docs
extra.mk
generators/gen_tables
src/Info.plist
src/bridge/Info.plist
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/amiga-library-functable.inc
src/runtime/inline.h
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/iOS.xcodeproj/*.pbxuser

Modified README.md from [c7f0f5d8b7] to [08dca7b831].

117
118
119
120
121
122
123





124
125
126
127
128
129


130
131
132
133
134
135
136

    $ fossil ui

  It's also possible to open the same local repository multiple times, so that
  you have multiple working directories all backed by the same local
  repository.






<h2 id="cloning-git">Git</h2>

  To clone the Git repository, use the following:

    $ git clone https://github.com/ObjFW/ObjFW




<h1 id="installation">Installation</h1>

  To install ObjFW, just run the following commands:

    $ ./configure
    $ make







>
>
>
>
>






>
>







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

    $ fossil ui

  It's also possible to open the same local repository multiple times, so that
  you have multiple working directories all backed by the same local
  repository.

  In order to verify the signature of the currently checked out checkin, you
  can use:

    $ fossil artifact current | gpg --verify

<h2 id="cloning-git">Git</h2>

  To clone the Git repository, use the following:

    $ git clone https://github.com/ObjFW/ObjFW

  Git commits are not signed, so if you want to check the signature of an
  individual commit, branch head or tag, please use Fossil.

<h1 id="installation">Installation</h1>

  To install ObjFW, just run the following commands:

    $ ./configure
    $ make

Modified configure.ac from [69c688a7b0] to [64037d8825].

410
411
412
413
414
415
416

417
418
419
420
421
422
423
])

AC_DEFINE_UNQUOTED(PLUGIN_SUFFIX, "$PLUGIN_SUFFIX", [Suffix for plugins])
AS_IF([test x"$enable_files" != x"no" -a x"$PLUGIN_SUFFIX" != x""], [
	AC_SUBST(USE_SRCS_PLUGINS, '${SRCS_PLUGINS}')
	AC_SUBST(TESTPLUGIN, "plugin")
	AC_DEFINE(OF_HAVE_PLUGINS, 1, [Whether we have plugin support])


	AS_IF([test x"$build_framework" = x"yes"], [
		TESTPLUGIN_LIBS="-F../../src -F../../src/runtime"
		TESTPLUGIN_LIBS="$TESTPLUGIN_LIBS -framework ObjFW"
		TESTPLUGIN_LIBS="$TESTPLUGIN_LIBS \${RUNTIME_FRAMEWORK_LIBS}"
	], [
		TESTPLUGIN_LIBS="-L../../src -L../../src/runtime"







>







410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
])

AC_DEFINE_UNQUOTED(PLUGIN_SUFFIX, "$PLUGIN_SUFFIX", [Suffix for plugins])
AS_IF([test x"$enable_files" != x"no" -a x"$PLUGIN_SUFFIX" != x""], [
	AC_SUBST(USE_SRCS_PLUGINS, '${SRCS_PLUGINS}')
	AC_SUBST(TESTPLUGIN, "plugin")
	AC_DEFINE(OF_HAVE_PLUGINS, 1, [Whether we have plugin support])
	AC_CONFIG_FILES(tests/plugin/Info.plist)

	AS_IF([test x"$build_framework" = x"yes"], [
		TESTPLUGIN_LIBS="-F../../src -F../../src/runtime"
		TESTPLUGIN_LIBS="$TESTPLUGIN_LIBS -framework ObjFW"
		TESTPLUGIN_LIBS="$TESTPLUGIN_LIBS \${RUNTIME_FRAMEWORK_LIBS}"
	], [
		TESTPLUGIN_LIBS="-L../../src -L../../src/runtime"
520
521
522
523
524
525
526

527
528
529
530
531
532
533
			OBJCFLAGS="$old_OBJCFLAGS $flag"
			OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flag"
			AC_MSG_RESULT(no)
			old_compiler="yes"
		])

		AC_SUBST(RUNTIME, "runtime")


		AS_IF([test x"$enable_shared" != x"no"], [
			AC_SUBST(OBJFWRT_SHARED_LIB,
				"${LIB_PREFIX}objfwrt${LIB_SUFFIX}")
		])

		AS_IF([test x"$enable_static" = x"yes"], [







>







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
			OBJCFLAGS="$old_OBJCFLAGS $flag"
			OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flag"
			AC_MSG_RESULT(no)
			old_compiler="yes"
		])

		AC_SUBST(RUNTIME, "runtime")
		AC_CONFIG_FILES(src/runtime/Info.plist)

		AS_IF([test x"$enable_shared" != x"no"], [
			AC_SUBST(OBJFWRT_SHARED_LIB,
				"${LIB_PREFIX}objfwrt${LIB_SUFFIX}")
		])

		AS_IF([test x"$enable_static" = x"yes"], [
1570
1571
1572
1573
1574
1575
1576

1577
1578
1579
1580
1581
1582
1583
AC_CHECK_FUNC(pledge, [
	AC_DEFINE(OF_HAVE_PLEDGE, 1, [Whether we have pledge()])
])

AS_IF([test x"$objc_runtime" = x"Apple runtime"], [
	AC_CHECK_HEADER(Foundation/NSObject.h, [
		AC_SUBST(BRIDGE, "bridge")


		AS_IF([test x"$enable_shared" != x"no"], [
			AC_SUBST(OBJFWBRIDGE_SHARED_LIB,
				"${LIB_PREFIX}objfwbridge${LIB_SUFFIX}")
		])
		AS_IF([test x"$enable_static" = x"yes" \
		    -o x"$enable_shared" = x"no"], [







>







1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
AC_CHECK_FUNC(pledge, [
	AC_DEFINE(OF_HAVE_PLEDGE, 1, [Whether we have pledge()])
])

AS_IF([test x"$objc_runtime" = x"Apple runtime"], [
	AC_CHECK_HEADER(Foundation/NSObject.h, [
		AC_SUBST(BRIDGE, "bridge")
		AC_CONFIG_FILES(src/bridge/Info.plist)

		AS_IF([test x"$enable_shared" != x"no"], [
			AC_SUBST(OBJFWBRIDGE_SHARED_LIB,
				"${LIB_PREFIX}objfwbridge${LIB_SUFFIX}")
		])
		AS_IF([test x"$enable_static" = x"yes" \
		    -o x"$enable_shared" = x"no"], [
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921

AC_SUBST(TESTS_LIBS)

AC_CONFIG_FILES([
	buildsys.mk
	extra.mk
	src/Info.plist
	src/bridge/Info.plist
	tests/Info.plist
	tests/plugin/Info.plist
	utils/objfw-config
])
AC_CONFIG_HEADERS([config.h src/objfw-defs.h])
AC_OUTPUT

AS_IF([test x"$old_compiler" = x"yes"], [
	echo







<

<







1908
1909
1910
1911
1912
1913
1914

1915

1916
1917
1918
1919
1920
1921
1922

AC_SUBST(TESTS_LIBS)

AC_CONFIG_FILES([
	buildsys.mk
	extra.mk
	src/Info.plist

	tests/Info.plist

	utils/objfw-config
])
AC_CONFIG_HEADERS([config.h src/objfw-defs.h])
AC_OUTPUT

AS_IF([test x"$old_compiler" = x"yes"], [
	echo

Modified generators/TableGenerator.m from [8fbc15917b] to [ce006846a1].

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

		components = [line componentsSeparatedByString: @";"];
		if (components.count != 15) {
			of_log(@"Invalid line: %@\n", line);
			[OFApplication terminateWithStatus: 1];
		}

		codePoint = (of_unichar_t)
		    [[components objectAtIndex: 0] hexadecimalValue];

		if (codePoint > 0x10FFFF)
			@throw [OFOutOfRangeException exception];

		_uppercaseTable[codePoint] = (of_unichar_t)
		    [[components objectAtIndex: 12] hexadecimalValue];
		_lowercaseTable[codePoint] = (of_unichar_t)
		    [[components objectAtIndex: 13] hexadecimalValue];
		_titlecaseTable[codePoint] = (of_unichar_t)
		    [[components objectAtIndex: 14] hexadecimalValue];

		if ([[components objectAtIndex: 5] length] > 0) {
			OFArray *decomposed = [[components objectAtIndex: 5]
			    componentsSeparatedByString: @" "];
			bool compat = false;
			OFMutableString *string;

			if ([decomposed.firstObject hasPrefix: @"<"]) {
				decomposed = [decomposed objectsInRange:
				    of_range(1, decomposed.count - 1)];
				compat = true;
			}

			string = [OFMutableString string];

			for (OFString *character in decomposed) {
				of_unichar_t unichar =
				    (of_unichar_t)character.hexadecimalValue;

				[string appendCharacters: &unichar
						  length: 1];
			}

			[string makeImmutable];








|
|




|
|
|
|
|
|
















|
|







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

		components = [line componentsSeparatedByString: @";"];
		if (components.count != 15) {
			of_log(@"Invalid line: %@\n", line);
			[OFApplication terminateWithStatus: 1];
		}

		codePoint = (of_unichar_t)[[components objectAtIndex: 0]
		    unsignedLongLongValueWithBase: 16];

		if (codePoint > 0x10FFFF)
			@throw [OFOutOfRangeException exception];

		_uppercaseTable[codePoint] = (of_unichar_t)[[components
		    objectAtIndex: 12] unsignedLongLongValueWithBase: 16];
		_lowercaseTable[codePoint] = (of_unichar_t)[[components
		    objectAtIndex: 13] unsignedLongLongValueWithBase: 16];
		_titlecaseTable[codePoint] = (of_unichar_t)[[components
		    objectAtIndex: 14] unsignedLongLongValueWithBase: 16];

		if ([[components objectAtIndex: 5] length] > 0) {
			OFArray *decomposed = [[components objectAtIndex: 5]
			    componentsSeparatedByString: @" "];
			bool compat = false;
			OFMutableString *string;

			if ([decomposed.firstObject hasPrefix: @"<"]) {
				decomposed = [decomposed objectsInRange:
				    of_range(1, decomposed.count - 1)];
				compat = true;
			}

			string = [OFMutableString string];

			for (OFString *character in decomposed) {
				of_unichar_t unichar = (of_unichar_t)[character
				    unsignedLongLongValueWithBase: 16];

				[string appendCharacters: &unichar
						  length: 1];
			}

			[string makeImmutable];

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
			[OFApplication terminateWithStatus: 1];
		}

		if (![[components objectAtIndex: 1] isEqual: @"S"] &&
		    ![[components objectAtIndex: 1] isEqual: @"C"])
			continue;

		codePoint = (of_unichar_t)
		    [[components objectAtIndex: 0] hexadecimalValue];

		if (codePoint > 0x10FFFF)
			@throw [OFOutOfRangeException exception];

		_casefoldingTable[codePoint] = (of_unichar_t)
		    [[components objectAtIndex: 2] hexadecimalValue];

		objc_autoreleasePoolPop(pool2);
	}

	[of_stdout writeLine: @" done"];

	[self writeFiles];







|
|




|
|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
			[OFApplication terminateWithStatus: 1];
		}

		if (![[components objectAtIndex: 1] isEqual: @"S"] &&
		    ![[components objectAtIndex: 1] isEqual: @"C"])
			continue;

		codePoint = (of_unichar_t)[[components objectAtIndex: 0]
		    unsignedLongLongValueWithBase: 16];

		if (codePoint > 0x10FFFF)
			@throw [OFOutOfRangeException exception];

		_casefoldingTable[codePoint] = (of_unichar_t)[[components
		    objectAtIndex: 2] unsignedLongLongValueWithBase: 16];

		objc_autoreleasePoolPop(pool2);
	}

	[of_stdout writeLine: @" done"];

	[self writeFiles];
263
264
265
266
267
268
269


270
271
272
273
274
275
276

			if (changed) {
				[table[i] release];
				table[i] = [replacement copy];

				done = false;
			}


		}
	} while (!done);
}

- (void)writeFiles
{
	OFURL *URL;







>
>







263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

			if (changed) {
				[table[i] release];
				table[i] = [replacement copy];

				done = false;
			}

			objc_autoreleasePoolPop(pool);
		}
	} while (!done);
}

- (void)writeFiles
{
	OFURL *URL;

Modified src/Info.plist.in from [125685d722] to [4f293d51f7].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>ObjFW</string>
	<key>CFBundleName</key>
	<string>ObjFW</string>
	<key>CFBundleIdentifier</key>
	<string>zone.heap.objfw</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>FMWK</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>MinimumOSVersion</key>
	<string>9.0</string>
</dict>
</plist>









|












1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>ObjFW</string>
	<key>CFBundleName</key>
	<string>ObjFW</string>
	<key>CFBundleIdentifier</key>
	<string>im.nil.objfw</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>FMWK</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>MinimumOSVersion</key>
	<string>9.0</string>
</dict>
</plist>

Modified src/Makefile from [34c348d2c8] to [02fc344718].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
       OFArray.m			\
       OFBlock.m			\
       OFCharacterSet.m			\
       OFColor.m			\
       OFConstantString.m		\
       OFCountedSet.m			\
       OFData.m				\
       OFData+ASN1DERValue.m		\
       OFData+CryptoHashing.m		\
       OFData+MessagePackValue.m	\
       OFDate.m				\
       OFDictionary.m			\
       OFEnumerator.m			\
       OFFileManager.m			\
       OFGZIPStream.m			\
       OFHMAC.m				\
       OFInflate64Stream.m		\







|

|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
       OFArray.m			\
       OFBlock.m			\
       OFCharacterSet.m			\
       OFColor.m			\
       OFConstantString.m		\
       OFCountedSet.m			\
       OFData.m				\
       OFData+ASN1DERParsing.m		\
       OFData+CryptoHashing.m		\
       OFData+MessagePackParsing.m	\
       OFDate.m				\
       OFDictionary.m			\
       OFEnumerator.m			\
       OFFileManager.m			\
       OFGZIPStream.m			\
       OFHMAC.m				\
       OFInflate64Stream.m		\
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
       OFSHA384Or512Hash.m		\
       OFSHA512Hash.m			\
       OFSortedList.m			\
       OFStdIOStream.m			\
       OFStream.m			\
       OFString.m			\
       OFString+CryptoHashing.m		\
       OFString+JSONValue.m		\
       OFString+PropertyListValue.m	\
       OFString+Serialization.m		\
       OFString+URLEncoding.m		\
       OFString+XMLEscaping.m		\
       OFString+XMLUnescaping.m		\
       OFSystemInfo.m			\
       OFTarArchive.m			\
       OFTarArchiveEntry.m		\







|
|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
       OFSHA384Or512Hash.m		\
       OFSHA512Hash.m			\
       OFSortedList.m			\
       OFStdIOStream.m			\
       OFStream.m			\
       OFString.m			\
       OFString+CryptoHashing.m		\
       OFString+JSONParsing.m		\
       OFString+PropertyListParsing.m	\
       OFString+Serialization.m		\
       OFString+URLEncoding.m		\
       OFString+XMLEscaping.m		\
       OFString+XMLUnescaping.m		\
       OFSystemInfo.m			\
       OFTarArchive.m			\
       OFTarArchiveEntry.m		\

Modified src/OFASN1Enumerated.h from [8d58cfdd70] to [b9ec14a4c3].

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

/*!
 * @brief An ASN.1 Enumerated.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFASN1Enumerated: OFObject
{
	intmax_t _integerValue;
}

/*!
 * @brief The integer value.
 */
@property (readonly, nonatomic) intmax_t integerValue;

/*!
 * @brief Creates an ASN.1 Enumerated with the specified integer value.
 *
 * @param integerValue The integer value of the Enumerated
 * @return A new, autoreleased OFASN1Enumerated
 */
+ (instancetype)enumeratedWithIntegerValue: (intmax_t)integerValue;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @brief Initializes an already allocated ASN.1 Enumerated with the specified
 *	  integer value.
 *
 * @param integerValue The integer value of the Enumerated
 * @return An initialized OFASN1Enumerated
 */
- (instancetype)initWithIntegerValue: (intmax_t)integerValue
    OF_DESIGNATED_INITIALIZER;

/*!
 * @brief Initializes an already allocated ASN.1 Enumerated with the specified
 *	  arguments.
 *
 * @param tagClass The tag class of the value's type
 * @param tagNumber The tag number of the value's type







|





|




|


|







|


<
|







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

/*!
 * @brief An ASN.1 Enumerated.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFASN1Enumerated: OFObject
{
	long long _longLongValue;
}

/*!
 * @brief The integer value.
 */
@property (readonly, nonatomic) long long longLongValue;

/*!
 * @brief Creates an ASN.1 Enumerated with the specified integer value.
 *
 * @param value The `long long` value of the Enumerated
 * @return A new, autoreleased OFASN1Enumerated
 */
+ (instancetype)enumeratedWithLongLong: (long long)value;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @brief Initializes an already allocated ASN.1 Enumerated with the specified
 *	  integer value.
 *
 * @param value The `long long` value of the Enumerated
 * @return An initialized OFASN1Enumerated
 */

- (instancetype)initWithLongLong: (long long)value OF_DESIGNATED_INITIALIZER;

/*!
 * @brief Initializes an already allocated ASN.1 Enumerated with the specified
 *	  arguments.
 *
 * @param tagClass The tag class of the value's type
 * @param tagNumber The tag number of the value's type

Modified src/OFASN1Enumerated.m from [1b0ff0da1e] to [78253ff0bd].

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

#import "OFASN1Enumerated.h"
#import "OFData.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"

extern intmax_t of_asn1_der_integer_parse(const unsigned char *buffer,
    size_t length);

@implementation OFASN1Enumerated
@synthesize integerValue = _integerValue;

+ (instancetype)enumeratedWithIntegerValue: (intmax_t)integerValue
{
	return [[[self alloc] initWithIntegerValue: integerValue] autorelease];
}

- (instancetype)initWithIntegerValue: (intmax_t)integerValue
{
	self = [super init];

	_integerValue = integerValue;

	return self;
}

- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass
		       tagNumber: (of_asn1_tag_number_t)tagNumber
		     constructed: (bool)constructed
	      DEREncodedContents: (OFData *)DEREncodedContents
{
	intmax_t integerValue;

	@try {
		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_ENUMERATED || constructed)
			@throw [OFInvalidArgumentException exception];

		if (DEREncodedContents.itemSize != 1)
			@throw [OFInvalidArgumentException exception];

		integerValue = of_asn1_der_integer_parse(
		    DEREncodedContents.items, DEREncodedContents.count);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return [self initWithIntegerValue: integerValue];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (bool)isEqual: (id)object
{
	OFASN1Enumerated *enumerated;

	if (object == self)
		return true;

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

	enumerated = object;

	if (enumerated->_integerValue != _integerValue)
		return false;

	return true;
}

- (uint32_t)hash
{
	return (uint32_t)_integerValue;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1Enumerated: %jd>",
					   _integerValue];
}
@end







|



|

|

|


|



|









|









|






|



















|







|




|
|


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

#import "OFASN1Enumerated.h"
#import "OFData.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"

extern long long of_asn1_der_integer_parse(const unsigned char *buffer,
    size_t length);

@implementation OFASN1Enumerated
@synthesize longLongValue = _longLongValue;

+ (instancetype)enumeratedWithLongLong: (long long)value
{
	return [[[self alloc] initWithLongLong: value] autorelease];
}

- (instancetype)initWithLongLong: (long long)value
{
	self = [super init];

	_longLongValue = value;

	return self;
}

- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass
		       tagNumber: (of_asn1_tag_number_t)tagNumber
		     constructed: (bool)constructed
	      DEREncodedContents: (OFData *)DEREncodedContents
{
	long long value;

	@try {
		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_ENUMERATED || constructed)
			@throw [OFInvalidArgumentException exception];

		if (DEREncodedContents.itemSize != 1)
			@throw [OFInvalidArgumentException exception];

		value = of_asn1_der_integer_parse(
		    DEREncodedContents.items, DEREncodedContents.count);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return [self initWithLongLong: value];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (bool)isEqual: (id)object
{
	OFASN1Enumerated *enumerated;

	if (object == self)
		return true;

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

	enumerated = object;

	if (enumerated->_longLongValue != _longLongValue)
		return false;

	return true;
}

- (uint32_t)hash
{
	return (uint32_t)_longLongValue;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1Enumerated: %lld>",
					   _longLongValue];
}
@end

Modified src/OFASN1Integer.h from [c737c6710d] to [ce3a4d009e].

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

/*!
 * @brief An ASN.1 Integer.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFASN1Integer: OFObject
{
	intmax_t _integerValue;
}

/*!
 * @brief The Integer value.
 */
@property (readonly, nonatomic) intmax_t integerValue;

/*!
 * @brief Creates an ASN.1 Integer with the specified integer value.
 *
 * @param integerValue The integer value of the Integer
 * @return A new, autoreleased OFASN1Integer
 */
+ (instancetype)integerWithIntegerValue: (intmax_t)integerValue;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @brief Initializes an already allocated ASN.1 Integer with the specified
 *	  integer value.
 *
 * @param integerValue The integer value of the Integer
 * @return An initialized OFASN1Integer
 */
- (instancetype)initWithIntegerValue: (intmax_t)integerValue
    OF_DESIGNATED_INITIALIZER;

/*!
 * @brief Initializes an already allocated ASN.1 Integer with the specified
 *	  arguments.
 *
 * @param tagClass The tag class of the value's type
 * @param tagNumber The tag number of the value's type







|





|




|


|







|


<
|







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

/*!
 * @brief An ASN.1 Integer.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFASN1Integer: OFObject
{
	long long _longLongValue;
}

/*!
 * @brief The Integer value.
 */
@property (readonly, nonatomic) long long longLongValue;

/*!
 * @brief Creates an ASN.1 Integer with the specified integer value.
 *
 * @param value The `long long` value of the Integer
 * @return A new, autoreleased OFASN1Integer
 */
+ (instancetype)integerWithLongLong: (long long)value;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @brief Initializes an already allocated ASN.1 Integer with the specified
 *	  integer value.
 *
 * @param value The `long long` value of the Integer
 * @return An initialized OFASN1Integer
 */

- (instancetype)initWithLongLong: (long long)value OF_DESIGNATED_INITIALIZER;

/*!
 * @brief Initializes an already allocated ASN.1 Integer with the specified
 *	  arguments.
 *
 * @param tagClass The tag class of the value's type
 * @param tagNumber The tag number of the value's type

Modified src/OFASN1Integer.m from [d8bb9bcba6] to [39a371a7d5].

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
#import "OFData.h"
#import "OFString.h"

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

intmax_t
of_asn1_der_integer_parse(const unsigned char *buffer, size_t length)
{
	uintmax_t value = 0;

	/* TODO: Support for big numbers */
	if (length > sizeof(uintmax_t) &&
	    (length != sizeof(uintmax_t) + 1 || buffer[0] != 0))
		@throw [OFOutOfRangeException exception];

	if (length >= 2 && ((buffer[0] == 0 && !(buffer[1] & 0x80)) ||
	    (buffer[0] == 0xFF && buffer[1] & 0x80)))
		@throw [OFInvalidFormatException exception];

	if (length >= 1 && buffer[0] & 0x80)
		value = ~(uintmax_t)0;

	while (length--)
		value = (value << 8) | *buffer++;

	return value;
}

@implementation OFASN1Integer
@synthesize integerValue = _integerValue;

+ (instancetype)integerWithIntegerValue: (intmax_t)integerValue
{
	return [[[self alloc] initWithIntegerValue: integerValue] autorelease];
}

- (instancetype)initWithIntegerValue: (intmax_t)integerValue
{
	self = [super init];

	_integerValue = integerValue;

	return self;
}

- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass
		       tagNumber: (of_asn1_tag_number_t)tagNumber
		     constructed: (bool)constructed
	      DEREncodedContents: (OFData *)DEREncodedContents
{
	intmax_t integerValue;

	@try {
		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_INTEGER || constructed)
			@throw [OFInvalidArgumentException exception];

		if (DEREncodedContents.itemSize != 1)
			@throw [OFInvalidArgumentException exception];

		integerValue = of_asn1_der_integer_parse(
		    DEREncodedContents.items, DEREncodedContents.count);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return [self initWithIntegerValue: integerValue];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (bool)isEqual: (id)object
{
	OFASN1Integer *integer;

	if (object == self)
		return true;

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

	integer = object;

	if (integer->_integerValue != _integerValue)
		return false;

	return true;
}

- (uint32_t)hash
{
	return (uint32_t)_integerValue;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1Integer: %jd>",
					   _integerValue];
}
@end







|


|


|
|







|








|

|

|


|



|









|









|






|



















|







|




|
|


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
#import "OFData.h"
#import "OFString.h"

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

long long
of_asn1_der_integer_parse(const unsigned char *buffer, size_t length)
{
	unsigned long long value = 0;

	/* TODO: Support for big numbers */
	if (length > sizeof(unsigned long long) &&
	    (length != sizeof(unsigned long long) + 1 || buffer[0] != 0))
		@throw [OFOutOfRangeException exception];

	if (length >= 2 && ((buffer[0] == 0 && !(buffer[1] & 0x80)) ||
	    (buffer[0] == 0xFF && buffer[1] & 0x80)))
		@throw [OFInvalidFormatException exception];

	if (length >= 1 && buffer[0] & 0x80)
		value = ~0ull;

	while (length--)
		value = (value << 8) | *buffer++;

	return value;
}

@implementation OFASN1Integer
@synthesize longLongValue = _longLongValue;

+ (instancetype)integerWithLongLong: (long long)value
{
	return [[[self alloc] initWithLongLong: value] autorelease];
}

- (instancetype)initWithLongLong: (long long)value
{
	self = [super init];

	_longLongValue = value;

	return self;
}

- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass
		       tagNumber: (of_asn1_tag_number_t)tagNumber
		     constructed: (bool)constructed
	      DEREncodedContents: (OFData *)DEREncodedContents
{
	long long value;

	@try {
		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_INTEGER || constructed)
			@throw [OFInvalidArgumentException exception];

		if (DEREncodedContents.itemSize != 1)
			@throw [OFInvalidArgumentException exception];

		value = of_asn1_der_integer_parse(
		    DEREncodedContents.items, DEREncodedContents.count);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return [self initWithLongLong: value];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (bool)isEqual: (id)object
{
	OFASN1Integer *integer;

	if (object == self)
		return true;

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

	integer = object;

	if (integer->_longLongValue != _longLongValue)
		return false;

	return true;
}

- (uint32_t)hash
{
	return (uint32_t)_longLongValue;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1Integer: %lld>",
					   _longLongValue];
}
@end

Modified src/OFASN1ObjectIdentifier.m from [64757d3fa2] to [13ae15fdce].

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
{
	self = [super init];

	@try {
		if (subidentifiers.count < 1)
			@throw [OFInvalidFormatException exception];

		switch ([[subidentifiers objectAtIndex: 0] intMaxValue]) {
		case 0:
		case 1:
		case 2:
			break;
		default:
			@throw [OFInvalidFormatException exception];
		}







|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
{
	self = [super init];

	@try {
		if (subidentifiers.count < 1)
			@throw [OFInvalidFormatException exception];

		switch ([[subidentifiers objectAtIndex: 0] longLongValue]) {
		case 0:
		case 1:
		case 2:
			break;
		default:
			@throw [OFInvalidFormatException exception];
		}
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
{
	void *pool = objc_autoreleasePoolPush();
	OFMutableArray OF_GENERIC(OFNumber *) *subidentifiers;

	@try {
		const unsigned char *items = DEREncodedContents.items;
		size_t count = DEREncodedContents.count;
		uintmax_t value = 0;
		uint_fast8_t bits = 0;

		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER ||
		    constructed)
			@throw [OFInvalidArgumentException exception];

		if (DEREncodedContents.itemSize != 1 || count == 0)
			@throw [OFInvalidArgumentException exception];

		subidentifiers = [OFMutableArray array];

		for (size_t i = 0; i < count; i++) {
			if (bits == 0 && items[i] == 0x80)
				@throw [OFInvalidFormatException exception];

			value = (value << 7) | (items[i] & 0x7F);
			bits += 7;

			if (bits > sizeof(uintmax_t) * 8)
				@throw [OFOutOfRangeException exception];

			if (items[i] & 0x80)
				continue;

			if (subidentifiers.count == 0) {
				if (value < 40)
					[subidentifiers addObject:
					    [OFNumber numberWithUIntMax: 0]];
				else if (value < 80) {
					[subidentifiers addObject:
					    [OFNumber numberWithUIntMax: 1]];
					value -= 40;
				} else {
					[subidentifiers addObject:
					    [OFNumber numberWithUIntMax: 2]];
					value -= 80;
				}
			}

			[subidentifiers addObject:
			    [OFNumber numberWithUIntMax: value]];

			value = 0;
			bits = 0;
		}

		if (items[count - 1] & 0x80)
			@throw [OFInvalidFormatException exception];







|



















|








|


|



|





|







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
{
	void *pool = objc_autoreleasePoolPush();
	OFMutableArray OF_GENERIC(OFNumber *) *subidentifiers;

	@try {
		const unsigned char *items = DEREncodedContents.items;
		size_t count = DEREncodedContents.count;
		unsigned long long value = 0;
		uint_fast8_t bits = 0;

		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER ||
		    constructed)
			@throw [OFInvalidArgumentException exception];

		if (DEREncodedContents.itemSize != 1 || count == 0)
			@throw [OFInvalidArgumentException exception];

		subidentifiers = [OFMutableArray array];

		for (size_t i = 0; i < count; i++) {
			if (bits == 0 && items[i] == 0x80)
				@throw [OFInvalidFormatException exception];

			value = (value << 7) | (items[i] & 0x7F);
			bits += 7;

			if (bits > sizeof(unsigned long long) * 8)
				@throw [OFOutOfRangeException exception];

			if (items[i] & 0x80)
				continue;

			if (subidentifiers.count == 0) {
				if (value < 40)
					[subidentifiers addObject:
					    [OFNumber numberWithInt: 0]];
				else if (value < 80) {
					[subidentifiers addObject:
					    [OFNumber numberWithInt: 1]];
					value -= 40;
				} else {
					[subidentifiers addObject:
					    [OFNumber numberWithInt: 2]];
					value -= 80;
				}
			}

			[subidentifiers addObject:
			    [OFNumber numberWithUnsignedLongLong: value]];

			value = 0;
			bits = 0;
		}

		if (items[count - 1] & 0x80)
			@throw [OFInvalidFormatException exception];

Modified src/OFConstantString.m from [1a9a1e4686] to [0761b10d3a].

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
- (OFString *)stringByDeletingLastPathComponent
{
	[self finishInitialization];

	return self.stringByDeletingLastPathComponent;
}




- (intmax_t)decimalValue











{
	[self finishInitialization];

	return self.decimalValue;
}

- (uintmax_t)hexadecimalValue
{
	[self finishInitialization];

	return self.hexadecimalValue;
}

- (uintmax_t)octalValue
{
	[self finishInitialization];

	return self.octalValue;
}

- (float)floatValue
{
	[self finishInitialization];

	return self.floatValue;







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



|


|



<
<
|
<
<
<
<
<







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
- (OFString *)stringByDeletingLastPathComponent
{
	[self finishInitialization];

	return self.stringByDeletingLastPathComponent;
}

- (long long)longLongValue
{
	[self finishInitialization];

	return self.longLongValue;
}

- (long long)longLongValueWithBase: (int)base
{
	[self finishInitialization];

	return [self longLongValueWithBase: base];
}

- (unsigned long long)unsignedLongLongValue
{
	[self finishInitialization];

	return self.unsignedLongLongValue;
}

- (unsigned long long)unsignedLongLongValueWithBase: (int)base
{
	[self finishInitialization];



	return [self unsignedLongLongValueWithBase: base];





}

- (float)floatValue
{
	[self finishInitialization];

	return self.floatValue;

Modified src/OFCountedMapTableSet.m from [5ffa3e62ea] to [72e0c09af3].

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

		for (OFXMLElement *objectElement in
		    [element elementsForName: @"object"
				   namespace: OF_SERIALIZATION_NS]) {
			void *pool2 = objc_autoreleasePoolPush();
			OFXMLElement *object;
			OFXMLAttribute *countAttribute;
			intmax_t signedCount;
			uintmax_t count;

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

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

			signedCount = countAttribute.decimalValue;
			if (signedCount < 0)
			       @throw [OFOutOfRangeException exception];

			count = signedCount;
			if (count > SIZE_MAX || count > UINTPTR_MAX)
				@throw [OFOutOfRangeException exception];

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

			objc_autoreleasePoolPop(pool2);







<
|









|
<
<
<
<







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

		for (OFXMLElement *objectElement in
		    [element elementsForName: @"object"
				   namespace: OF_SERIALIZATION_NS]) {
			void *pool2 = objc_autoreleasePoolPush();
			OFXMLElement *object;
			OFXMLAttribute *countAttribute;

			unsigned long long count;

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

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

			count = countAttribute.unsignedLongLongValue;




			if (count > SIZE_MAX || count > UINTPTR_MAX)
				@throw [OFOutOfRangeException exception];

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

			objc_autoreleasePoolPop(pool2);

Modified src/OFDNSResolver.m from [6319b8ebc8] to [abd3a40827].

489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
		_settings = [settings copy];
		_delegate = [delegate retain];

		queryData = [OFMutableData dataWithCapacity: 512];

		/* Header */

		tmp = OF_BSWAP16_IF_LE(_ID.uInt16Value);
		[queryData addItems: &tmp
			      count: 2];

		/* RD */
		tmp = OF_BSWAP16_IF_LE(1u << 8);
		[queryData addItems: &tmp
			      count: 2];







|







489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
		_settings = [settings copy];
		_delegate = [delegate retain];

		queryData = [OFMutableData dataWithCapacity: 512];

		/* Header */

		tmp = OF_BSWAP16_IF_LE(_ID.unsignedShortValue);
		[queryData addItems: &tmp
			      count: 2];

		/* RD */
		tmp = OF_BSWAP16_IF_LE(1u << 8);
		[queryData addItems: &tmp
			      count: 2];
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
{
	void *pool = objc_autoreleasePoolPush();
	OFNumber *ID;
	OFDNSResolverContext *context;

	/* Random, unused ID */
	do {
		ID = [OFNumber numberWithUInt16: of_random16()];
	} while ([_queries objectForKey: ID] != nil);

	if (query.domainName.UTF8StringLength > 253)
		@throw [OFOutOfRangeException exception];

	if (_settings->_nameServers.count == 0) {
		id exception = [OFDNSQueryFailedException







|







810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
{
	void *pool = objc_autoreleasePoolPush();
	OFNumber *ID;
	OFDNSResolverContext *context;

	/* Random, unused ID */
	do {
		ID = [OFNumber numberWithUnsignedShort: of_random16()];
	} while ([_queries objectForKey: ID] != nil);

	if (query.domainName.UTF8StringLength > 253)
		@throw [OFOutOfRangeException exception];

	if (_settings->_nameServers.count == 0) {
		id exception = [OFDNSQueryFailedException
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
	OFNumber *ID;
	OFDNSResolverContext *context;

	if (length < 2)
		/* We can't get the ID to get the context. Ignore packet. */
		return true;

	ID = [OFNumber numberWithUInt16: (buffer[0] << 8) | buffer[1]];
	context = [[[_queries objectForKey: ID] retain] autorelease];

	if (context == nil)
		return true;

	if (context->_TCPSocket != nil) {
		if ([_TCPQueries objectForKey: context->_TCPSocket] != context)







|







909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
	OFNumber *ID;
	OFDNSResolverContext *context;

	if (length < 2)
		/* We can't get the ID to get the context. Ignore packet. */
		return true;

	ID = [OFNumber numberWithUnsignedShort: (buffer[0] << 8) | buffer[1]];
	context = [[[_queries objectForKey: ID] retain] autorelease];

	if (context == nil)
		return true;

	if (context->_TCPSocket != nil) {
		if ([_TCPQueries objectForKey: context->_TCPSocket] != context)

Modified src/OFDNSResolverSettings.m from [995314850c] to [aa15389045].

30
31
32
33
34
35
36

37
38
39
40
41
42
43
#ifdef OF_WINDOWS
# import "OFWindowsRegistryKey.h"
#endif

#import "OFInvalidFormatException.h"
#import "OFOpenItemFailedException.h"
#import "OFOutOfMemoryException.h"


#ifdef OF_WINDOWS
# define interface struct
# include <iphlpapi.h>
# undef interface
#endif








>







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#ifdef OF_WINDOWS
# import "OFWindowsRegistryKey.h"
#endif

#import "OFInvalidFormatException.h"
#import "OFOpenItemFailedException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

#ifdef OF_WINDOWS
# define interface struct
# include <iphlpapi.h>
# undef interface
#endif

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
}

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


			option = [option substringWithRange:
			    of_range(6, option.length - 6)];





			_minNumberOfDotsInAbsoluteName =
			    (unsigned int)option.decimalValue;
		} else if ([option hasPrefix: @"timeout:"]) {
			option = [option substringWithRange:
			    of_range(8, option.length - 8)];

			_timeout = option.decimalValue;
		} else if ([option hasPrefix: @"attempts:"]) {


			option = [option substringWithRange:
			    of_range(9, option.length - 9)];





			_maxAttempts = (unsigned int)option.decimalValue;
		} else if ([option hasPrefix: @"reload-period:"]) {
			option = [option substringWithRange:
			    of_range(14, option.length - 14)];

			_configReloadInterval = option.decimalValue;
		} else if ([option isEqual: @"tcp"])
			_usesTCP = true;
	} @catch (OFInvalidFormatException *e) {
	}
}

- (void)parseResolvConf: (OFString *)path







>
>


>

>
>
>
|
<




|

>
>


>

>
>
>
|




|







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
}

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

			option = [option substringWithRange:
			    of_range(6, option.length - 6)];
			number = option.unsignedLongLongValue;

			if (number > UINT_MAX)
				@throw [OFOutOfRangeException exception];

			_minNumberOfDotsInAbsoluteName = (unsigned int)number;

		} else if ([option hasPrefix: @"timeout:"]) {
			option = [option substringWithRange:
			    of_range(8, option.length - 8)];

			_timeout = option.unsignedLongLongValue;
		} else if ([option hasPrefix: @"attempts:"]) {
			unsigned long long number;

			option = [option substringWithRange:
			    of_range(9, option.length - 9)];
			number = option.unsignedLongLongValue;

			if (number > UINT_MAX)
				@throw [OFOutOfRangeException exception];

			_maxAttempts = (unsigned int)number;
		} else if ([option hasPrefix: @"reload-period:"]) {
			option = [option substringWithRange:
			    of_range(14, option.length - 14)];

			_configReloadInterval = option.unsignedLongLongValue;
		} else if ([option isEqual: @"tcp"])
			_usesTCP = true;
	} @catch (OFInvalidFormatException *e) {
	}
}

- (void)parseResolvConf: (OFString *)path

Modified src/OFDNSResourceRecord.m from [054747ac72] to [08b68e10ee].

77
78
79
80
81
82
83
84

85
86
87
88
89
90
91

	string = string.uppercaseString;

	if ([string isEqual: @"IN"])
		DNSClass = OF_DNS_CLASS_IN;
	else {
		@try {
			DNSClass = (of_dns_class_t)string.decimalValue;

		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidArgumentException exception];
		}
	}

	objc_autoreleasePoolPop(pool);








|
>







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

	string = string.uppercaseString;

	if ([string isEqual: @"IN"])
		DNSClass = OF_DNS_CLASS_IN;
	else {
		@try {
			DNSClass = (of_dns_class_t)
			    [string unsignedLongLongValueWithBase: 0];
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidArgumentException exception];
		}
	}

	objc_autoreleasePoolPop(pool);

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
		recordType = OF_DNS_RECORD_TYPE_AAAA;
	else if ([string isEqual: @"SRV"])
		recordType = OF_DNS_RECORD_TYPE_SRV;
	else if ([string isEqual: @"ALL"])
		recordType = OF_DNS_RECORD_TYPE_ALL;
	else {
		@try {
			recordType =
			    (of_dns_record_type_t)string.decimalValue;
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidArgumentException exception];
		}
	}

	objc_autoreleasePoolPop(pool);








|
|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
		recordType = OF_DNS_RECORD_TYPE_AAAA;
	else if ([string isEqual: @"SRV"])
		recordType = OF_DNS_RECORD_TYPE_SRV;
	else if ([string isEqual: @"ALL"])
		recordType = OF_DNS_RECORD_TYPE_ALL;
	else {
		@try {
			recordType = (of_dns_record_type_t)
			    [string unsignedLongLongValueWithBase: 0];
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidArgumentException exception];
		}
	}

	objc_autoreleasePoolPop(pool);

Renamed and modified src/OFData+ASN1DERValue.h [f3069736d2] to src/OFData+ASN1DERParsing.h [edd796e7d5].

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

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFData_ASN1DERValue_reference;
#ifdef __cplusplus
}
#endif

@interface OFData (ASN1DERValue)
/*!
 * @brief The data interpreted as ASN.1 in DER representation and parsed as an
 *	  object.
 *
 * This is either an OFArray (for a sequence), an OFSet (for a set) or an
 * OFASN1Value.
 */
@property (readonly, nonatomic) id ASN1DERValue;

/*!
 * @brief Parses the ASN.1 DER representation and returns it as an object.
 *
 * This is either an OFArray (for a sequence), an OFSet (for a set) or an
 * OFASN1Value.
 *
 * @param depthLimit The maximum depth the parser should accept (defaults to 32
 *		     if not specified, 0 means no limit (insecure!))
 * @return The ASN.1 DER representation as an object
 */
- (id)ASN1DERValueWithDepthLimit: (size_t)depthLimit;
@end

OF_ASSUME_NONNULL_END







|




|







|











|



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

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFData_ASN1DERParsing_reference;
#ifdef __cplusplus
}
#endif

@interface OFData (ASN1DERParsing)
/*!
 * @brief The data interpreted as ASN.1 in DER representation and parsed as an
 *	  object.
 *
 * This is either an OFArray (for a sequence), an OFSet (for a set) or an
 * OFASN1Value.
 */
@property (readonly, nonatomic) id objectByParsingASN1DER;

/*!
 * @brief Parses the ASN.1 DER representation and returns it as an object.
 *
 * This is either an OFArray (for a sequence), an OFSet (for a set) or an
 * OFASN1Value.
 *
 * @param depthLimit The maximum depth the parser should accept (defaults to 32
 *		     if not specified, 0 means no limit (insecure!))
 * @return The ASN.1 DER representation as an object
 */
- (id)objectByParsingASN1DERWithDepthLimit: (size_t)depthLimit;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFData+ASN1DERValue.m [e3b3051875] to src/OFData+ASN1DERParsing.m [31638813f3].

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * 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 "OFData+ASN1DERValue.h"
#import "OFASN1BitString.h"
#import "OFASN1Boolean.h"
#import "OFASN1Enumerated.h"
#import "OFASN1IA5String.h"
#import "OFASN1Integer.h"
#import "OFASN1NumericString.h"
#import "OFASN1ObjectIdentifier.h"







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * 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 "OFData+ASN1DERParsing.h"
#import "OFASN1BitString.h"
#import "OFASN1Boolean.h"
#import "OFASN1Enumerated.h"
#import "OFASN1IA5String.h"
#import "OFASN1Integer.h"
#import "OFASN1NumericString.h"
#import "OFASN1ObjectIdentifier.h"
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#import "OFOutOfRangeException.h"
#import "OFTruncatedDataException.h"

enum {
	ASN1_TAG_CONSTRUCTED_MASK = 0x20
};

int _OFData_ASN1DERValue_reference;

static size_t parseObject(OFData *self, id *object, size_t depthLimit);

static OFArray *
parseSequence(OFData *contents, size_t depthLimit)
{
	OFMutableArray *ret = [OFMutableArray array];







|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#import "OFOutOfRangeException.h"
#import "OFTruncatedDataException.h"

enum {
	ASN1_TAG_CONSTRUCTED_MASK = 0x20
};

int _OFData_ASN1DERParsing_reference;

static size_t parseObject(OFData *self, id *object, size_t depthLimit);

static OFArray *
parseSequence(OFData *contents, size_t depthLimit)
{
	OFMutableArray *ret = [OFMutableArray array];
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
	      initWithTagClass: tag >> 6
		     tagNumber: tag & 0x1F
		   constructed: tag & ASN1_TAG_CONSTRUCTED_MASK
	    DEREncodedContents: contents] autorelease];
	return bytesConsumed;
}

@implementation OFData (ASN1DERValue)
- (id)ASN1DERValue
{
	return [self ASN1DERValueWithDepthLimit: 32];
}

- (id)ASN1DERValueWithDepthLimit: (size_t)depthLimit
{
	void *pool = objc_autoreleasePoolPush();
	id object;

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








|
|

|


|







221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
	      initWithTagClass: tag >> 6
		     tagNumber: tag & 0x1F
		   constructed: tag & ASN1_TAG_CONSTRUCTED_MASK
	    DEREncodedContents: contents] autorelease];
	return bytesConsumed;
}

@implementation OFData (ASN1DERParsing)
- (id)objectByParsingASN1DER
{
	return [self objectByParsingASN1DERWithDepthLimit: 32];
}

- (id)objectByParsingASN1DERWithDepthLimit: (size_t)depthLimit
{
	void *pool = objc_autoreleasePoolPush();
	id object;

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

Renamed and modified src/OFData+MessagePackValue.h [2409c49524] to src/OFData+MessagePackParsing.h [6f2988f9a2].

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

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFData_MessagePackValue_reference;
#ifdef __cplusplus
}
#endif

@interface OFData (MessagePackValue)
/*!
 * @brief The data interpreted as MessagePack representation and parsed as an
 *	  object.
 */
@property (readonly, nonatomic) id messagePackValue;

/*!
 * @brief Parses the MessagePack representation and returns it as an object.
 *
 * @param depthLimit The maximum depth the parser should accept (defaults to 32
 *		     if not specified, 0 means no limit (insecure!))
 * @return The MessagePack representation as an object
 */
- (id)messagePackValueWithDepthLimit: (size_t)depthLimit;
@end

OF_ASSUME_NONNULL_END







|




|




|








|



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

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFData_MessagePackParsing_reference;
#ifdef __cplusplus
}
#endif

@interface OFData (MessagePackParsing)
/*!
 * @brief The data interpreted as MessagePack representation and parsed as an
 *	  object.
 */
@property (readonly, nonatomic) id objectByParsingMessagePack;

/*!
 * @brief Parses the MessagePack representation and returns it as an object.
 *
 * @param depthLimit The maximum depth the parser should accept (defaults to 32
 *		     if not specified, 0 means no limit (insecure!))
 * @return The MessagePack representation as an object
 */
- (id)objectByParsingMessagePackWithDepthLimit: (size_t)depthLimit;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFData+MessagePackValue.m [caaaf51219] to src/OFData+MessagePackParsing.m [464ca7dfaa].

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

#include "config.h"

#include <string.h>

#import "OFData+MessagePackValue.h"
#import "OFArray.h"
#import "OFDate.h"
#import "OFDictionary.h"
#import "OFMessagePackExtension.h"
#import "OFNull.h"
#import "OFNumber.h"
#import "OFString.h"

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

int _OFData_MessagePackValue_reference;

static size_t parseObject(const unsigned char *buffer, size_t length,
    id *object, size_t depthLimit);

static uint16_t
readUInt16(const unsigned char *buffer)
{







|













|







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

#include "config.h"

#include <string.h>

#import "OFData+MessagePackParsing.h"
#import "OFArray.h"
#import "OFDate.h"
#import "OFDictionary.h"
#import "OFMessagePackExtension.h"
#import "OFNull.h"
#import "OFNumber.h"
#import "OFString.h"

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

int _OFData_MessagePackParsing_reference;

static size_t parseObject(const unsigned char *buffer, size_t length,
    id *object, size_t depthLimit);

static uint16_t
readUInt16(const unsigned char *buffer)
{
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
	OFData *data;

	if (length < 1)
		@throw [OFTruncatedDataException exception];

	/* positive fixint */
	if ((buffer[0] & 0x80) == 0) {
		*object = [OFNumber numberWithUInt8: buffer[0] & 0x7F];
		return 1;
	}
	/* negative fixint */
	if ((buffer[0] & 0xE0) == 0xE0) {
		*object = [OFNumber numberWithInt8:
		    ((int8_t)(buffer[0] & 0x1F)) - 32];
		return 1;
	}

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







|




|







189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
	OFData *data;

	if (length < 1)
		@throw [OFTruncatedDataException exception];

	/* positive fixint */
	if ((buffer[0] & 0x80) == 0) {
		*object = [OFNumber numberWithUnsignedChar: buffer[0] & 0x7F];
		return 1;
	}
	/* negative fixint */
	if ((buffer[0] & 0xE0) == 0xE0) {
		*object = [OFNumber numberWithChar:
		    ((int8_t)(buffer[0] & 0x1F)) - 32];
		return 1;
	}

	/* fixstr */
	if ((buffer[0] & 0xE0) == 0xA0) {
		count = buffer[0] & 0x1F;
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
	/* Prefix byte */
	switch (buffer[0]) {
	/* Unsigned integers */
	case 0xCC: /* uint8 */
		if (length < 2)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUInt8: buffer[1]];
		return 2;
	case 0xCD: /* uint 16 */
		if (length < 3)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUInt16: readUInt16(buffer + 1)];

		return 3;
	case 0xCE: /* uint 32 */
		if (length < 5)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUInt32: readUInt32(buffer + 1)];

		return 5;
	case 0xCF: /* uint 64 */
		if (length < 9)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUInt64: readUInt64(buffer + 1)];

		return 9;
	/* Signed integers */
	case 0xD0: /* int 8 */
		if (length < 2)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithInt8: buffer[1]];
		return 2;
	case 0xD1: /* int 16 */
		if (length < 3)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithInt16: readUInt16(buffer + 1)];
		return 3;
	case 0xD2: /* int 32 */
		if (length < 5)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithInt32: readUInt32(buffer + 1)];
		return 5;
	case 0xD3: /* int 64 */
		if (length < 9)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithInt64: readUInt64(buffer + 1)];
		return 9;
	/* Floating point */
	case 0xCA:; /* float 32 */
		float f;

		if (length < 5)
			@throw [OFTruncatedDataException exception];







|





|
>





|
>





|
>






|





|





|





|







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
	/* Prefix byte */
	switch (buffer[0]) {
	/* Unsigned integers */
	case 0xCC: /* uint8 */
		if (length < 2)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUnsignedChar: buffer[1]];
		return 2;
	case 0xCD: /* uint 16 */
		if (length < 3)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUnsignedShort:
		    readUInt16(buffer + 1)];
		return 3;
	case 0xCE: /* uint 32 */
		if (length < 5)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUnsignedLong:
		    readUInt32(buffer + 1)];
		return 5;
	case 0xCF: /* uint 64 */
		if (length < 9)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUnsignedLongLong:
		    readUInt64(buffer + 1)];
		return 9;
	/* Signed integers */
	case 0xD0: /* int 8 */
		if (length < 2)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithChar: buffer[1]];
		return 2;
	case 0xD1: /* int 16 */
		if (length < 3)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithShort: readUInt16(buffer + 1)];
		return 3;
	case 0xD2: /* int 32 */
		if (length < 5)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithLong: readUInt32(buffer + 1)];
		return 5;
	case 0xD3: /* int 64 */
		if (length < 9)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithLongLong: readUInt64(buffer + 1)];
		return 9;
	/* Floating point */
	case 0xCA:; /* float 32 */
		float f;

		if (length < 5)
			@throw [OFTruncatedDataException exception];
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
		return parseTable(buffer + 5, length - 5, object,
		    readUInt32(buffer + 1), depthLimit) + 5;
	default:
		@throw [OFInvalidFormatException exception];
	}
}

@implementation OFData (MessagePackValue)
- (id)messagePackValue
{
	return [self messagePackValueWithDepthLimit: 32];
}

- (id)messagePackValueWithDepthLimit: (size_t)depthLimit
{
	void *pool = objc_autoreleasePoolPush();
	size_t count = self.count;
	id object;

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







|
|

|


|







541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
		return parseTable(buffer + 5, length - 5, object,
		    readUInt32(buffer + 1), depthLimit) + 5;
	default:
		@throw [OFInvalidFormatException exception];
	}
}

@implementation OFData (MessagePackParsing)
- (id)objectByParsingMessagePack
{
	return [self objectByParsingMessagePackWithDepthLimit: 32];
}

- (id)objectByParsingMessagePackWithDepthLimit: (size_t)depthLimit
{
	void *pool = objc_autoreleasePoolPush();
	size_t count = self.count;
	id object;

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

Modified src/OFData.h from [28777ad7ed] to [71ad4a3460].

323
324
325
326
327
328
329
330
331
332
 */
- (void)writeToURL: (OFURL *)URL;
@end

OF_ASSUME_NONNULL_END

#import "OFMutableData.h"
#import "OFData+ASN1DERValue.h"
#import "OFData+CryptoHashing.h"
#import "OFData+MessagePackValue.h"







|

|
323
324
325
326
327
328
329
330
331
332
 */
- (void)writeToURL: (OFURL *)URL;
@end

OF_ASSUME_NONNULL_END

#import "OFMutableData.h"
#import "OFData+ASN1DERParsing.h"
#import "OFData+CryptoHashing.h"
#import "OFData+MessagePackParsing.h"

Modified src/OFData.m from [9637aa54ff] to [63de509839].

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

#import "base64.h"

/* References for static linking */
void
_references_to_categories_of_OFData(void)
{
	_OFData_ASN1DERValue_reference = 1;
	_OFData_CryptoHashing_reference = 1;
	_OFData_MessagePackValue_reference = 1;
}

@implementation OFData
@synthesize itemSize = _itemSize;

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







|

|







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

#import "base64.h"

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

@implementation OFData
@synthesize itemSize = _itemSize;

+ (instancetype)dataWithItems: (const void *)items
			count: (size_t)count
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
	return self;
}

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

	@try {
		OFFile *file;

		size = [[OFFileManager defaultManager]
		    attributesOfItemAtPath: path].fileSize;

# if UINTMAX_MAX > SIZE_MAX
		if (size > SIZE_MAX)
			@throw [OFOutOfRangeException exception];
# endif

		if ((buffer = malloc((size_t)size)) == NULL)
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: (size_t)size];







|







|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
	return self;
}

#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path
{
	char *buffer = NULL;
	unsigned long long size;

	@try {
		OFFile *file;

		size = [[OFFileManager defaultManager]
		    attributesOfItemAtPath: path].fileSize;

# if ULLONG_MAX > SIZE_MAX
		if (size > SIZE_MAX)
			@throw [OFOutOfRangeException exception];
# endif

		if ((buffer = malloc((size_t)size)) == NULL)
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: (size_t)size];

Modified src/OFDate.m from [8d4b356936] to [4f38b261b8].

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
		seconds = tmAndTzToTime(&tm, &tz);

	return [self initWithTimeIntervalSince1970: seconds];
}

- (instancetype)initWithSerialization: (OFXMLElement *)element
{



	void *pool = objc_autoreleasePoolPush();
	of_time_interval_t seconds;

	if (![element.name isEqual: @"OFDate"] ||
	    ![element.namespace isEqual: OF_SERIALIZATION_NS])
		@throw [OFInvalidArgumentException exception];






	seconds = OF_BSWAP_DOUBLE_IF_LE(OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE(
	    element.hexadecimalValue)));

	objc_autoreleasePoolPop(pool);





	return [self initWithTimeIntervalSince1970: seconds];
}

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







>
>
>
|
|

|
|
|

>
>
>
>
>
|
|

|
>
>
>
>







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
		seconds = tmAndTzToTime(&tm, &tz);

	return [self initWithTimeIntervalSince1970: seconds];
}

- (instancetype)initWithSerialization: (OFXMLElement *)element
{
	of_time_interval_t seconds;

	@try {
		void *pool = objc_autoreleasePoolPush();
		unsigned long long value;

		if (![element.name isEqual: @"OFDate"] ||
		    ![element.namespace isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException exception];

		value = [element unsignedLongLongValueWithBase: 16];

		if (value > UINT64_MAX)
			@throw [OFOutOfRangeException exception];

		seconds = OF_BSWAP_DOUBLE_IF_LE(OF_INT_TO_DOUBLE_RAW(
		    OF_BSWAP64_IF_LE(value)));

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

	return [self initWithTimeIntervalSince1970: seconds];
}

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

Modified src/OFFileManager.h from [832085a76a] to [2be4d0719f].

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

@interface OFDictionary (FileAttributes)
/*!
 * @brief The @ref of_file_attribute_key_size key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) uintmax_t fileSize;

/*!
 * @brief The @ref of_file_attribute_key_type key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) of_file_type_t fileType;

/*!
 * @brief The @ref of_file_attribute_key_posix_permissions key from the
 *	  dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) uint16_t filePOSIXPermissions;

/*!
 * @brief The @ref of_file_attribute_key_posix_uid key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) uint32_t filePOSIXUID;

/*!
 * @brief The @ref of_file_attribute_key_posix_gid key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) uint32_t filePOSIXGID;

/*!
 * @brief The @ref of_file_attribute_key_owner key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) OFString *fileOwner;







|














|






|






|







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

@interface OFDictionary (FileAttributes)
/*!
 * @brief The @ref of_file_attribute_key_size key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) unsigned long long fileSize;

/*!
 * @brief The @ref of_file_attribute_key_type key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) of_file_type_t fileType;

/*!
 * @brief The @ref of_file_attribute_key_posix_permissions key from the
 *	  dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) unsigned long filePOSIXPermissions;

/*!
 * @brief The @ref of_file_attribute_key_posix_uid key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) unsigned long filePOSIXUID;

/*!
 * @brief The @ref of_file_attribute_key_posix_gid key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) unsigned long filePOSIXGID;

/*!
 * @brief The @ref of_file_attribute_key_owner key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) OFString *fileOwner;

Modified src/OFFileManager.m from [c5306f3b5d] to [d64d08867d].

934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
- (unsigned int)retainCount
{
	return OF_RETAIN_COUNT_MAX;
}
@end

@implementation OFDictionary (FileAttributes)
- (uintmax_t)fileSize
{
	return [attributeForKeyOrException(self, of_file_attribute_key_size)
	    uIntMaxValue];
}

- (of_file_type_t)fileType
{
	return attributeForKeyOrException(self, of_file_attribute_key_type);
}

- (uint16_t)filePOSIXPermissions
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_permissions) uInt16Value];
}

- (uint32_t)filePOSIXUID
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_uid) uInt32Value];
}

- (uint32_t)filePOSIXGID
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_gid) uInt32Value];
}

- (OFString *)fileOwner
{
	return attributeForKeyOrException(self, of_file_attribute_key_owner);
}








|


|







|


|


|


|


|


|







934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
- (unsigned int)retainCount
{
	return OF_RETAIN_COUNT_MAX;
}
@end

@implementation OFDictionary (FileAttributes)
- (unsigned long long)fileSize
{
	return [attributeForKeyOrException(self, of_file_attribute_key_size)
	    unsignedLongLongValue];
}

- (of_file_type_t)fileType
{
	return attributeForKeyOrException(self, of_file_attribute_key_type);
}

- (unsigned long)filePOSIXPermissions
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_permissions) unsignedLongValue];
}

- (unsigned long)filePOSIXUID
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_uid) unsignedLongValue];
}

- (unsigned long)filePOSIXGID
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_gid) unsignedLongValue];
}

- (OFString *)fileOwner
{
	return attributeForKeyOrException(self, of_file_attribute_key_owner);
}

Modified src/OFFileURLHandler.m from [b404d9c716] to [987947edfd].

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

static void
setOwnerAndGroupAttributes(of_mutable_file_attributes_t attributes,
    of_stat_t *s)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
	[attributes setObject: [NSNumber numberWithUInt16: s->st_uid]
		       forKey: of_file_attribute_key_posix_uid];
	[attributes setObject: [NSNumber numberWithUInt16: s->st_gid]
		       forKey: of_file_attribute_key_posix_gid];

# ifdef OF_HAVE_THREADS
	[passwdMutex lock];
	@try {
# endif
		of_string_encoding_t encoding = [OFLocale encoding];







|

|







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

static void
setOwnerAndGroupAttributes(of_mutable_file_attributes_t attributes,
    of_stat_t *s)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
	[attributes setObject: [NSNumber numberWithUnsignedLong: s->st_uid]
		       forKey: of_file_attribute_key_posix_uid];
	[attributes setObject: [NSNumber numberWithUnsignedLong: s->st_gid]
		       forKey: of_file_attribute_key_posix_gid];

# ifdef OF_HAVE_THREADS
	[passwdMutex lock];
	@try {
# endif
		of_string_encoding_t encoding = [OFLocale encoding];
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
		@throw [OFRetrieveItemAttributesFailedException
		    exceptionWithURL: URL
			       errNo: errno];

	if (s.st_size < 0)
		@throw [OFOutOfRangeException exception];

	[ret setObject: [NSNumber numberWithUIntMax: s.st_size]
		forKey: of_file_attribute_key_size];

	setTypeAttribute(ret, &s);

	[ret setObject: [NSNumber numberWithUInt16: s.st_mode & 07777]
		forKey: of_file_attribute_key_posix_permissions];

	setOwnerAndGroupAttributes(ret, &s);
	setDateAttributes(ret, &s);

#ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS
	if (S_ISLNK(s.st_mode))







|




|







616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
		@throw [OFRetrieveItemAttributesFailedException
		    exceptionWithURL: URL
			       errNo: errno];

	if (s.st_size < 0)
		@throw [OFOutOfRangeException exception];

	[ret setObject: [NSNumber numberWithUnsignedLongLong: s.st_size]
		forKey: of_file_attribute_key_size];

	setTypeAttribute(ret, &s);

	[ret setObject: [NSNumber numberWithUnsignedLong: s.st_mode]
		forKey: of_file_attribute_key_posix_permissions];

	setOwnerAndGroupAttributes(ret, &s);
	setDateAttributes(ret, &s);

#ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS
	if (S_ISLNK(s.st_mode))
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
}

- (void)of_setPOSIXPermissions: (OFNumber *)permissions
		   ofItemAtURL: (OFURL *)URL
		    attributes: (of_file_attributes_t)attributes OF_DIRECT
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	uint16_t mode = permissions.uInt16Value & 0777;
	OFString *path = URL.fileSystemRepresentation;
	int status;

# ifdef OF_WINDOWS
	if ([OFSystemInfo isWindowsNT])
		status = _wchmod(path.UTF16String, mode);
	else







|







756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
}

- (void)of_setPOSIXPermissions: (OFNumber *)permissions
		   ofItemAtURL: (OFURL *)URL
		    attributes: (of_file_attributes_t)attributes OF_DIRECT
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	mode_t mode = (mode_t)permissions.unsignedLongValue;
	OFString *path = URL.fileSystemRepresentation;
	int status;

# ifdef OF_WINDOWS
	if ([OFSystemInfo isWindowsNT])
		status = _wchmod(path.UTF16String, mode);
	else

Modified src/OFHTTPClient.m from [8dda35db24] to [561ec71175].

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

OF_DIRECT_MEMBERS
@interface OFHTTPClientRequestBodyStream: OFStream <OFReadyForWritingObserving>
{
	OFHTTPClientRequestHandler *_handler;
	OFTCPSocket *_socket;
	bool _chunked;
	uintmax_t _toWrite;
	bool _atEndOfStream;
}

- (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler
			 socket: (OFTCPSocket *)sock;
@end

OF_DIRECT_MEMBERS
@interface OFHTTPClientResponse: OFHTTPResponse <OFReadyForReadingObserving>
{
	OFTCPSocket *_socket;
	bool _hasContentLength, _chunked, _keepAlive;
	bool _atEndOfStream, _setAtEndOfStream;
	intmax_t _toRead;
}

@property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive;

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








|













|







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

OF_DIRECT_MEMBERS
@interface OFHTTPClientRequestBodyStream: OFStream <OFReadyForWritingObserving>
{
	OFHTTPClientRequestHandler *_handler;
	OFTCPSocket *_socket;
	bool _chunked;
	unsigned long long _toWrite;
	bool _atEndOfStream;
}

- (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler
			 socket: (OFTCPSocket *)sock;
@end

OF_DIRECT_MEMBERS
@interface OFHTTPClientResponse: OFHTTPResponse <OFReadyForReadingObserving>
{
	OFTCPSocket *_socket;
	bool _hasContentLength, _chunked, _keepAlive;
	bool _atEndOfStream, _setAtEndOfStream;
	long long _toRead;
}

@property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive;

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

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
	} @catch (id e) {
		[self raiseException: e];
	}
}

- (bool)handleFirstLine: (OFString *)line
{


	/*
	 * It's possible that the write succeeds on a connection that is
	 * keep-alive, but the connection has already been closed by the remote
	 * end due to a timeout. In this case, we need to reconnect.
	 */
	if (line == nil) {
		[self closeAndReconnect];
		return false;
	}

	if (![line hasPrefix: @"HTTP/"] || line.length < 9 ||
	    [line characterAtIndex: 8] != ' ')
		@throw [OFInvalidServerReplyException exception];

	_version = [[line substringWithRange: of_range(5, 3)] copy];
	if (![_version isEqual: @"1.0"] && ![_version isEqual: @"1.1"])
		@throw [OFUnsupportedVersionException
		    exceptionWithVersion: _version];

	_status = (int)[line substringWithRange: of_range(9, 3)].decimalValue;






	return true;
}

- (bool)handleServerHeader: (OFString *)line
		    socket: (OFTCPSocket *)sock
{







>
>



















|
>
>
>
>
>







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
	} @catch (id e) {
		[self raiseException: e];
	}
}

- (bool)handleFirstLine: (OFString *)line
{
	long long status;

	/*
	 * It's possible that the write succeeds on a connection that is
	 * keep-alive, but the connection has already been closed by the remote
	 * end due to a timeout. In this case, we need to reconnect.
	 */
	if (line == nil) {
		[self closeAndReconnect];
		return false;
	}

	if (![line hasPrefix: @"HTTP/"] || line.length < 9 ||
	    [line characterAtIndex: 8] != ' ')
		@throw [OFInvalidServerReplyException exception];

	_version = [[line substringWithRange: of_range(5, 3)] copy];
	if (![_version isEqual: @"1.0"] && ![_version isEqual: @"1.1"])
		@throw [OFUnsupportedVersionException
		    exceptionWithVersion: _version];

	status = [line substringWithRange: of_range(9, 3)].longLongValue;

	if (status < 0 || status > 599)
		@throw [OFInvalidServerReplyException exception];

	_status = (int)status;

	return true;
}

- (bool)handleServerHeader: (OFString *)line
		    socket: (OFTCPSocket *)sock
{
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
		} else {
			sock = [OFTCPSocket socket];
			port = 80;
		}

		URLPort = URL.port;
		if (URLPort != nil)
			port = URLPort.uInt16Value;

		sock.delegate = self;
		[sock asyncConnectToHost: URL.host
				    port: port];
	} @catch (id e) {
		[self raiseException: e];
	}
}
@end

@implementation OFHTTPClientRequestBodyStream
- (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler
			 socket: (OFTCPSocket *)sock
{
	self = [super init];

	@try {
		OFDictionary OF_GENERIC(OFString *, OFString *) *headers;
		intmax_t contentLength;
		OFString *transferEncoding, *contentLengthString;

		_handler = [handler retain];
		_socket = [sock retain];

		headers = _handler->_request.headers;

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

		contentLengthString = [headers objectForKey: @"Content-Length"];
		if (contentLengthString != nil) {
			if (_chunked || contentLengthString.length == 0)
				@throw [OFInvalidArgumentException
				    exception];

			contentLength = contentLengthString.decimalValue;
			if (contentLength < 0)
				@throw [OFOutOfRangeException exception];

			_toWrite = contentLength;
		} else if (!_chunked)
			@throw [OFInvalidArgumentException exception];
	} @catch (id e) {
		[self release];
		@throw e;
	}








|


















<
















<
<
<
<
|







716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741

742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757




758
759
760
761
762
763
764
765
		} else {
			sock = [OFTCPSocket socket];
			port = 80;
		}

		URLPort = URL.port;
		if (URLPort != nil)
			port = URLPort.unsignedShortValue;

		sock.delegate = self;
		[sock asyncConnectToHost: URL.host
				    port: port];
	} @catch (id e) {
		[self raiseException: e];
	}
}
@end

@implementation OFHTTPClientRequestBodyStream
- (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler
			 socket: (OFTCPSocket *)sock
{
	self = [super init];

	@try {
		OFDictionary OF_GENERIC(OFString *, OFString *) *headers;

		OFString *transferEncoding, *contentLengthString;

		_handler = [handler retain];
		_socket = [sock retain];

		headers = _handler->_request.headers;

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

		contentLengthString = [headers objectForKey: @"Content-Length"];
		if (contentLengthString != nil) {
			if (_chunked || contentLengthString.length == 0)
				@throw [OFInvalidArgumentException
				    exception];





			_toWrite = contentLengthString.unsignedLongLongValue;
		} else if (!_chunked)
			@throw [OFInvalidArgumentException exception];
	} @catch (id e) {
		[self release];
		@throw e;
	}

891
892
893
894
895
896
897

898
899
900
901
902

903
904
905
906
907
908
909
	if (contentLength != nil) {
		if (_chunked || contentLength.length == 0)
			@throw [OFInvalidServerReplyException exception];

		_hasContentLength = true;

		@try {

			_toRead = contentLength.decimalValue;

			if (_toRead < 0)
				@throw [OFInvalidServerReplyException
				    exception];

		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidServerReplyException exception];
		}
	}
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer







>
|

|
|
|
>







893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
	if (contentLength != nil) {
		if (_chunked || contentLength.length == 0)
			@throw [OFInvalidServerReplyException exception];

		_hasContentLength = true;

		@try {
			unsigned long long toRead =
			    contentLength.unsignedLongLongValue;

			if (toRead > LLONG_MAX)
				@throw [OFOutOfRangeException exception];

			_toRead = (long long)toRead;
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidServerReplyException exception];
		}
	}
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
	if (_socket.atEndOfStream)
		@throw [OFTruncatedDataException exception];

	/* Content-Length */
	if (!_chunked) {
		size_t ret;

		if (length > (uintmax_t)_toRead)
			length = (size_t)_toRead;

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

		if (ret > length)
			@throw [OFOutOfRangeException exception];







|







926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
	if (_socket.atEndOfStream)
		@throw [OFTruncatedDataException exception];

	/* Content-Length */
	if (!_chunked) {
		size_t ret;

		if (length > (unsigned long long)_toRead)
			length = (size_t)_toRead;

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

		if (ret > length)
			@throw [OFOutOfRangeException exception];
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
		}

		if (_setAtEndOfStream && _toRead == 0)
			_atEndOfStream = true;

		return 0;
	} else if (_toRead > 0) {
		if (length > (uintmax_t)_toRead)
			length = (size_t)_toRead;

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

		_toRead -= length;








|







981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
		}

		if (_setAtEndOfStream && _toRead == 0)
			_atEndOfStream = true;

		return 0;
	} else if (_toRead > 0) {
		if (length > (unsigned long long)_toRead)
			length = (size_t)_toRead;

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

		_toRead -= length;

1022
1023
1024
1025
1026
1027
1028


1029

1030


1031
1032
1033
1034
1035
1036
1037
				@throw [OFTruncatedDataException exception];
			else
				@throw [OFInvalidServerReplyException
				    exception];
		}

		@try {


			if ((_toRead = line.hexadecimalValue) < 0)

				@throw [OFOutOfRangeException exception];


		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidServerReplyException exception];
		}

		if (_toRead == 0) {
			_setAtEndOfStream = true;
			_toRead = -2;







>
>
|
>

>
>







1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
				@throw [OFTruncatedDataException exception];
			else
				@throw [OFInvalidServerReplyException
				    exception];
		}

		@try {
			unsigned long long toRead =
			    [line unsignedLongLongValueWithBase: 16];

			if (toRead > LLONG_MAX)
				@throw [OFOutOfRangeException exception];

			_toRead = (long long)toRead;
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidServerReplyException exception];
		}

		if (_toRead == 0) {
			_setAtEndOfStream = true;
			_toRead = -2;

Modified src/OFHTTPCookie.m from [1c4b9e560d] to [1fa52c5268].

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
		if ([lowercaseName isEqual: @"expires"]) {
			OFDate *date = [OFDate
			    dateWithDateString: value
					format: @"%a, %d %b %Y %H:%M:%S %z"];
			cookie.expires = date;
		} else if ([lowercaseName isEqual: @"max-age"]) {
			OFDate *date = [OFDate dateWithTimeIntervalSinceNow:
			    value.decimalValue];
			cookie.expires = date;
		} else if ([lowercaseName isEqual: @"domain"])
			cookie.domain = value;
		else if ([lowercaseName isEqual: @"path"])
			cookie.path = value;
		else
			[cookie.extensions addObject:







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
		if ([lowercaseName isEqual: @"expires"]) {
			OFDate *date = [OFDate
			    dateWithDateString: value
					format: @"%a, %d %b %Y %H:%M:%S %z"];
			cookie.expires = date;
		} else if ([lowercaseName isEqual: @"max-age"]) {
			OFDate *date = [OFDate dateWithTimeIntervalSinceNow:
			    value.unsignedLongLongValue];
			cookie.expires = date;
		} else if ([lowercaseName isEqual: @"domain"])
			cookie.domain = value;
		else if ([lowercaseName isEqual: @"path"])
			cookie.path = value;
		else
			[cookie.extensions addObject:

Modified src/OFHTTPRequest.m from [2d1b69a80f] to [a65b94e9ae].

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
	return _protocolVersion;
}

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

	if (components.count != 2)
		@throw [OFInvalidFormatException exception];

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

	if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX)
		@throw [OFOutOfRangeException exception];

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

	self.protocolVersion = protocolVersion;








|





|
|

|







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
	return _protocolVersion;
}

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

	if (components.count != 2)
		@throw [OFInvalidFormatException exception];

	major = [components.firstObject unsignedLongLongValue];
	minor = [components.lastObject unsignedLongLongValue];

	if (major > UINT8_MAX || minor > UINT8_MAX)
		@throw [OFOutOfRangeException exception];

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

	self.protocolVersion = protocolVersion;

Modified src/OFHTTPResponse.m from [1abecd6ce8] to [b38122cc28].

267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
	return _protocolVersion;
}

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

	if (components.count != 2)
		@throw [OFInvalidFormatException exception];

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

	if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX)
		@throw [OFOutOfRangeException exception];

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

	self.protocolVersion = protocolVersion;








|





|
|

|







267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
	return _protocolVersion;
}

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

	if (components.count != 2)
		@throw [OFInvalidFormatException exception];

	major = [components.firstObject unsignedLongLongValue];
	minor = [components.lastObject unsignedLongLongValue];

	if (major > UINT8_MAX || minor > UINT8_MAX)
		@throw [OFOutOfRangeException exception];

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

	self.protocolVersion = protocolVersion;

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
{
	return [self stringWithEncoding: OF_STRING_ENCODING_AUTODETECT];
}

- (OFString *)stringWithEncoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFString *contentType, *contentLength, *ret;
	OFData *data;

	if (encoding == OF_STRING_ENCODING_AUTODETECT &&
	    (contentType = [_headers objectForKey: @"Content-Type"]) != nil)
		encoding = encodingForContentType(contentType);

	if (encoding == OF_STRING_ENCODING_AUTODETECT)
		encoding = OF_STRING_ENCODING_UTF_8;

	data = [self readDataUntilEndOfStream];

	if ((contentLength = [_headers objectForKey: @"Content-Length"]) != nil)







		if (data.count != (size_t)contentLength.decimalValue)
			@throw [OFTruncatedDataException exception];


	ret = [[OFString alloc] initWithCString: (char *)data.items
				       encoding: encoding
					 length: data.count];

	objc_autoreleasePoolPop(pool);








|











|
>
>
>
>
>
>
>
|

>







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
{
	return [self stringWithEncoding: OF_STRING_ENCODING_AUTODETECT];
}

- (OFString *)stringWithEncoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFString *contentType, *contentLengthString, *ret;
	OFData *data;

	if (encoding == OF_STRING_ENCODING_AUTODETECT &&
	    (contentType = [_headers objectForKey: @"Content-Type"]) != nil)
		encoding = encodingForContentType(contentType);

	if (encoding == OF_STRING_ENCODING_AUTODETECT)
		encoding = OF_STRING_ENCODING_UTF_8;

	data = [self readDataUntilEndOfStream];

	contentLengthString = [_headers objectForKey: @"Content-Length"];
	if (contentLengthString != nil) {
		unsigned long long contentLength =
		    contentLengthString.unsignedLongLongValue;

		if (contentLength > SIZE_MAX)
			@throw [OFOutOfRangeException exception];

		if (data.count != (size_t)contentLength)
			@throw [OFTruncatedDataException exception];
	}

	ret = [[OFString alloc] initWithCString: (char *)data.items
				       encoding: encoding
					 length: data.count];

	objc_autoreleasePoolPop(pool);

Modified src/OFHTTPServer.m from [868929166e] to [abf9a790cd].

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
@end

OF_DIRECT_MEMBERS
@interface OFHTTPServerRequestBodyStream: OFStream <OFReadyForReadingObserving>
{
	OFStreamSocket *_socket;
	bool _chunked;
	intmax_t _toRead;
	bool _atEndOfStream, _setAtEndOfStream;
}

- (instancetype)initWithSocket: (OFStreamSocket *)sock
		       chunked: (bool)chunked
		 contentLength: (uintmax_t)contentLength;
@end

#ifdef OF_HAVE_THREADS
OF_DIRECT_MEMBERS
@interface OFHTTPServerThread: OFThread
- (void)stop;
@end







|





|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
@end

OF_DIRECT_MEMBERS
@interface OFHTTPServerRequestBodyStream: OFStream <OFReadyForReadingObserving>
{
	OFStreamSocket *_socket;
	bool _chunked;
	long long _toRead;
	bool _atEndOfStream, _setAtEndOfStream;
}

- (instancetype)initWithSocket: (OFStreamSocket *)sock
		       chunked: (bool)chunked
		 contentLength: (unsigned long long)contentLength;
@end

#ifdef OF_HAVE_THREADS
OF_DIRECT_MEMBERS
@interface OFHTTPServerThread: OFThread
- (void)stop;
@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
	size_t pos;

	if (line.length == 0) {
		bool chunked = [[_headers objectForKey: @"Transfer-Encoding"]
		    isEqual: @"chunked"];
		OFString *contentLengthString =
		    [_headers objectForKey: @"Content-Length"];
		intmax_t contentLength = 0;

		if (contentLengthString != nil) {
			if (chunked || contentLengthString.length == 0)
				return [self sendErrorAndClose: 400];

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

			if (contentLength < 0)
				return [self sendErrorAndClose: 400];
		}

		if (chunked || contentLengthString != nil) {
			[_requestBody release];
			_requestBody = nil;
			_requestBody = [[OFHTTPServerRequestBodyStream alloc]
			    initWithSocket: _socket







|







|



<
<
<







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
	size_t pos;

	if (line.length == 0) {
		bool chunked = [[_headers objectForKey: @"Transfer-Encoding"]
		    isEqual: @"chunked"];
		OFString *contentLengthString =
		    [_headers objectForKey: @"Content-Length"];
		unsigned long long contentLength = 0;

		if (contentLengthString != nil) {
			if (chunked || contentLengthString.length == 0)
				return [self sendErrorAndClose: 400];

			@try {
				contentLength =
				    contentLengthString.unsignedLongLongValue;
			} @catch (OFInvalidFormatException *e) {
				return [self sendErrorAndClose: 400];
			}



		}

		if (chunked || contentLengthString != nil) {
			[_requestBody release];
			_requestBody = nil;
			_requestBody = [[OFHTTPServerRequestBodyStream alloc]
			    initWithSocket: _socket
478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
			[_host release];
			_host = [[value substringWithRange:
			    of_range(0, pos)] retain];

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


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

				_port = (uint16_t)portTmp;
			} @catch (OFInvalidFormatException *e) {
				return [self sendErrorAndClose: 400];







|
|
>







475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
			[_host release];
			_host = [[value substringWithRange:
			    of_range(0, pos)] retain];

			@try {
				of_range_t range =
				    of_range(pos + 1, value.length - pos - 1);
				unsigned long long portTmp =
				    [value substringWithRange: range]
				    .unsignedLongLongValue;

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

				_port = (uint16_t)portTmp;
			} @catch (OFInvalidFormatException *e) {
				return [self sendErrorAndClose: 400];
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
		_port = [_server port];
	}

	URL = [OFMutableURL URL];
	URL.scheme = @"http";
	URL.host = _host;
	if (_port != 80)
		URL.port = [OFNumber numberWithUInt16: _port];

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

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







|







539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
		_port = [_server port];
	}

	URL = [OFMutableURL URL];
	URL.scheme = @"http";
	URL.host = _host;
	if (_port != 80)
		URL.port = [OFNumber numberWithUnsignedShort: _port];

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

		path = [_path substringWithRange: of_range(0, pos)];
		query = [_path substringWithRange:
		    of_range(pos + 1, _path.length - pos - 1)];
581
582
583
584
585
586
587
588
589
590
591
592



593
594
595
596
597
598
599
600
601
602
	objc_autoreleasePoolPop(pool);
}
@end

@implementation OFHTTPServerRequestBodyStream
- (instancetype)initWithSocket: (OFStreamSocket *)sock
		       chunked: (bool)chunked
		 contentLength: (uintmax_t)contentLength
{
	self = [super init];

	@try {



		_socket = [sock retain];
		_chunked = chunked;
		_toRead = contentLength;

		if (_chunked && _toRead > 0)
			@throw [OFInvalidArgumentException exception];
	} @catch (id e) {
		[self release];
		@throw e;
	}







|




>
>
>


|







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

@implementation OFHTTPServerRequestBodyStream
- (instancetype)initWithSocket: (OFStreamSocket *)sock
		       chunked: (bool)chunked
		 contentLength: (unsigned long long)contentLength
{
	self = [super init];

	@try {
		if (contentLength > LLONG_MAX)
			@throw [OFOutOfRangeException exception];

		_socket = [sock retain];
		_chunked = chunked;
		_toRead = (long long)contentLength;

		if (_chunked && _toRead > 0)
			@throw [OFInvalidArgumentException exception];
	} @catch (id e) {
		[self release];
		@throw e;
	}
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
	if (_socket.atEndOfStream)
		@throw [OFTruncatedDataException exception];

	/* Content-Length */
	if (!_chunked) {
		size_t ret;

		if (length > (uintmax_t)_toRead)
			length = (size_t)_toRead;

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

		_toRead -= ret;








|







630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
	if (_socket.atEndOfStream)
		@throw [OFTruncatedDataException exception];

	/* Content-Length */
	if (!_chunked) {
		size_t ret;

		if (length > (unsigned long long)_toRead)
			length = (size_t)_toRead;

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

		_toRead -= ret;

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
		}

		if (_setAtEndOfStream && _toRead == 0)
			_atEndOfStream = true;

		return 0;
	} else if (_toRead > 0) {
		if (length > (uintmax_t)_toRead)
			length = (size_t)_toRead;

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

		_toRead -= length;

		if (_toRead == 0)
			_toRead = -2;

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


		@try {
			line = [_socket tryReadLine];
		} @catch (OFInvalidEncodingException *e) {
			@throw [OFInvalidFormatException exception];
		}








|















>







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
		}

		if (_setAtEndOfStream && _toRead == 0)
			_atEndOfStream = true;

		return 0;
	} else if (_toRead > 0) {
		if (length > (unsigned long long)_toRead)
			length = (size_t)_toRead;

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

		_toRead -= length;

		if (_toRead == 0)
			_toRead = -2;

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

		@try {
			line = [_socket tryReadLine];
		} @catch (OFInvalidEncodingException *e) {
			@throw [OFInvalidFormatException exception];
		}

721
722
723
724
725
726
727

728
729

730
731
732
733
734
735
736
			if (_socket.atEndOfStream &&
			    range.location == OF_NOT_FOUND)
				@throw [OFTruncatedDataException exception];
			else
				@throw [OFInvalidFormatException exception];
		}


		if ((_toRead = line.hexadecimalValue) < 0)
			@throw [OFOutOfRangeException exception];


		if (_toRead == 0) {
			_setAtEndOfStream = true;
			_toRead = -2;
		}

		objc_autoreleasePoolPop(pool);







>
|

>







723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
			if (_socket.atEndOfStream &&
			    range.location == OF_NOT_FOUND)
				@throw [OFTruncatedDataException exception];
			else
				@throw [OFInvalidFormatException exception];
		}

		toRead = [line unsignedLongLongValueWithBase: 16];
		if (toRead > LLONG_MAX)
			@throw [OFOutOfRangeException exception];
		_toRead = (long long)toRead;

		if (_toRead == 0) {
			_setAtEndOfStream = true;
			_toRead = -2;
		}

		objc_autoreleasePoolPop(pool);

Modified src/OFINICategory.h from [fee5b6cdbd] to [b224331a40].

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
 * the first key/value pair found is returned.
 *
 * @param key The key for which the integer value should be returned
 * @param defaultValue The value to return if the key does not exist
 * @return The integer value for the specified key or the specified default
 *	   value if it does not exist
 */
- (intmax_t)integerForKey: (OFString *)key
	     defaultValue: (intmax_t)defaultValue;

/*!
 * @brief Returns the bool value for the specified key or the specified default
 *	  value if it does not exist.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is returned.







|
|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
 * the first key/value pair found is returned.
 *
 * @param key The key for which the integer value should be returned
 * @param defaultValue The value to return if the key does not exist
 * @return The integer value for the specified key or the specified default
 *	   value if it does not exist
 */
- (long long)integerForKey: (OFString *)key
	      defaultValue: (long long)defaultValue;

/*!
 * @brief Returns the bool value for the specified key or the specified default
 *	  value if it does not exist.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is returned.
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is changed.
 *
 * @param integer The integer to which the value of the key should be set
 * @param key The key for which the new value should be set
 */
- (void)setInteger: (intmax_t)integer
	    forKey: (OFString *)key;

/*!
 * @brief Sets the value of the specified key to the specified bool.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is changed.







|







159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is changed.
 *
 * @param integer The integer to which the value of the key should be set
 * @param key The key for which the new value should be set
 */
- (void)setInteger: (long long)integer
	    forKey: (OFString *)key;

/*!
 * @brief Sets the value of the specified key to the specified bool.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is changed.

Modified src/OFINICategory.m from [6f7f003a8d] to [4145f33ae0].

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
		if ([pair->_key isEqual: key])
			return [[pair->_value copy] autorelease];
	}

	return defaultValue;
}

- (intmax_t)integerForKey: (OFString *)key
	     defaultValue: (intmax_t)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *value = [self stringForKey: key
				defaultValue: nil];
	intmax_t ret;

	if (value != nil) {
		if ([value hasPrefix: @"0x"] || [value hasPrefix: @"$"])
			ret = value.hexadecimalValue;
		else
			ret = value.decimalValue;
	} else
		ret = defaultValue;

	objc_autoreleasePoolPop(pool);

	return ret;
}








|
|




|

|
<
|
|
<
<







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

221
222


223
224
225
226
227
228
229
		if ([pair->_key isEqual: key])
			return [[pair->_value copy] autorelease];
	}

	return defaultValue;
}

- (long long)integerForKey: (OFString *)key
	      defaultValue: (long long)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *value = [self stringForKey: key
				defaultValue: nil];
	long long ret;

	if (value != nil)

		ret = [value longLongValueWithBase: 0];
	else


		ret = defaultValue;

	objc_autoreleasePoolPop(pool);

	return ret;
}

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

		@throw e;
	}

	objc_autoreleasePoolPop(pool);
}

- (void)setInteger: (intmax_t)integer
	    forKey: (OFString *)key
{
	void *pool = objc_autoreleasePoolPush();

	[self setString: [OFString stringWithFormat: @"%jd", integer]
		 forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setBool: (bool)bool_
	 forKey: (OFString *)key







|




|







347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366

		@throw e;
	}

	objc_autoreleasePoolPop(pool);
}

- (void)setInteger: (long long)integer
	    forKey: (OFString *)key
{
	void *pool = objc_autoreleasePoolPush();

	[self setString: [OFString stringWithFormat: @"%lld", integer]
		 forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setBool: (bool)bool_
	 forKey: (OFString *)key

Modified src/OFINIFileSettings.m from [9d965e74da] to [c8fa651c4c].

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

	[[_INIFile categoryForName: category] setString: string
						 forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setInteger: (intmax_t)integer
	   forPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;

	[self of_getCategory: &category
		      andKey: &key







|







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

	[[_INIFile categoryForName: category] setString: string
						 forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setInteger: (long long)integer
	   forPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;

	[self of_getCategory: &category
		      andKey: &key
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
						    defaultValue: defaultValue];

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

- (intmax_t)integerForPath: (OFString *)path
	      defaultValue: (intmax_t)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;
	intmax_t ret;

	[self of_getCategory: &category
		      andKey: &key
		     forPath: path];

	ret = [[_INIFile categoryForName: category]
	    integerForKey: key







|
|



|







182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
						    defaultValue: defaultValue];

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

- (long long)integerForPath: (OFString *)path
	       defaultValue: (long long)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;
	long long ret;

	[self of_getCategory: &category
		      andKey: &key
		     forPath: path];

	ret = [[_INIFile categoryForName: category]
	    integerForKey: key

Modified src/OFLHAArchiveEntry.m from [9cc455c13c] to [61acef2124].

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

	memcpy(&mode, (char *)extension.items + 1, 2);
	mode = OF_BSWAP16_IF_BE(mode);

	[entry->_mode release];
	entry->_mode = nil;

	entry->_mode = [[OFNumber alloc] initWithUInt16: mode];
}

static void
parseGIDUIDExtension(OFLHAArchiveEntry *entry, OFData *extension,
    of_string_encoding_t encoding)
{
	uint16_t UID, GID;







|







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

	memcpy(&mode, (char *)extension.items + 1, 2);
	mode = OF_BSWAP16_IF_BE(mode);

	[entry->_mode release];
	entry->_mode = nil;

	entry->_mode = [[OFNumber alloc] initWithUnsignedShort: mode];
}

static void
parseGIDUIDExtension(OFLHAArchiveEntry *entry, OFData *extension,
    of_string_encoding_t encoding)
{
	uint16_t UID, GID;
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

	[entry->_GID release];
	entry->_GID = nil;

	[entry->_UID release];
	entry->_UID = nil;

	entry->_GID = [[OFNumber alloc] initWithUInt16: GID];
	entry->_UID = [[OFNumber alloc] initWithUInt16: UID];
}

static void
parseGroupExtension(OFLHAArchiveEntry *entry, OFData *extension,
    of_string_encoding_t encoding)
{
	[entry->_group release];







|
|







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

	[entry->_GID release];
	entry->_GID = nil;

	[entry->_UID release];
	entry->_UID = nil;

	entry->_GID = [[OFNumber alloc] initWithUnsignedShort: GID];
	entry->_UID = [[OFNumber alloc] initWithUnsignedShort: UID];
}

static void
parseGroupExtension(OFLHAArchiveEntry *entry, OFData *extension,
    of_string_encoding_t encoding)
{
	[entry->_group release];
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

	if (_mode != nil) {
		tmp16 = OF_BSWAP16_IF_BE(5);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
		[data addItem: "\x50"];

		tmp16 = OF_BSWAP16_IF_BE(_mode.uInt16Value);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
	}

	if (_UID != nil || _GID != nil) {
		if (_UID == nil || _GID == nil)
			@throw [OFInvalidArgumentException exception];

		tmp16 = OF_BSWAP16_IF_BE(7);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
		[data addItem: "\x51"];

		tmp16 = OF_BSWAP16_IF_BE(_GID.uInt16Value);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];

		tmp16 = OF_BSWAP16_IF_BE(_UID.uInt16Value);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
	}

	if (_group != nil) {
		size_t groupLength =
		    [_group cStringLengthWithEncoding: encoding];







|













|



|







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

	if (_mode != nil) {
		tmp16 = OF_BSWAP16_IF_BE(5);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
		[data addItem: "\x50"];

		tmp16 = OF_BSWAP16_IF_BE(_mode.unsignedShortValue);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
	}

	if (_UID != nil || _GID != nil) {
		if (_UID == nil || _GID == nil)
			@throw [OFInvalidArgumentException exception];

		tmp16 = OF_BSWAP16_IF_BE(7);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
		[data addItem: "\x51"];

		tmp16 = OF_BSWAP16_IF_BE(_GID.unsignedShortValue);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];

		tmp16 = OF_BSWAP16_IF_BE(_UID.unsignedShortValue);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
	}

	if (_group != nil) {
		size_t groupLength =
		    [_group cStringLengthWithEncoding: encoding];
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
	objc_autoreleasePoolPop(pool);
}

- (OFString *)description
{
	void *pool = objc_autoreleasePoolPush();
	OFString *mode = (_mode == nil ? nil
	    : [OFString stringWithFormat: @"%" PRIo16, _mode.uInt16Value]);
	OFString *extensions = [_extensions.description
	    stringByReplacingOccurrencesOfString: @"\n"
				      withString: @"\n\t"];
	OFString *ret = [OFString stringWithFormat:
	    @"<%@:\n"
	    @"\tFile name = %@\n"
	    @"\tCompression method = %@\n"







|







757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
	objc_autoreleasePoolPop(pool);
}

- (OFString *)description
{
	void *pool = objc_autoreleasePoolPush();
	OFString *mode = (_mode == nil ? nil
	    : [OFString stringWithFormat: @"%ho", _mode.unsignedShortValue]);
	OFString *extensions = [_extensions.description
	    stringByReplacingOccurrencesOfString: @"\n"
				      withString: @"\n\t"];
	OFString *ret = [OFString stringWithFormat:
	    @"<%@:\n"
	    @"\tFile name = %@\n"
	    @"\tCompression method = %@\n"

Modified src/OFLocale.m from [2f0ab9defe] to [b6b16348ac].

211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
			else if ([token isEqual: @">="])
				var = [OFNumber numberWithBool: [first
				    compare: second] != OF_ORDERED_ASCENDING];
			else if ([token isEqual: @"+"])
				var = [OFNumber numberWithDouble:
				    [first doubleValue] + [second doubleValue]];
			else if ([token isEqual: @"%"])
				var = [OFNumber numberWithIntMax:

				    [first intMaxValue] % [second intMaxValue]];
			else if ([token isEqual: @"&&"])
				var = [OFNumber numberWithBool:
				    [first boolValue] && [second boolValue]];
			else if ([token isEqual: @"||"])
				var = [OFNumber numberWithBool:
				    [first boolValue] || [second boolValue]];
			else







|
>
|







211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
			else if ([token isEqual: @">="])
				var = [OFNumber numberWithBool: [first
				    compare: second] != OF_ORDERED_ASCENDING];
			else if ([token isEqual: @"+"])
				var = [OFNumber numberWithDouble:
				    [first doubleValue] + [second doubleValue]];
			else if ([token isEqual: @"%"])
				var = [OFNumber numberWithLongLong:
				    [first longLongValue] %
				    [second longLongValue]];
			else if ([token isEqual: @"&&"])
				var = [OFNumber numberWithBool:
				    [first boolValue] && [second boolValue]];
			else if ([token isEqual: @"||"])
				var = [OFNumber numberWithBool:
				    [first boolValue] || [second boolValue]];
			else
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
			first = stack.lastObject;

			if ([token isEqual: @"!"])
				var = [OFNumber numberWithBool:
				    ![first boolValue]];
			else if ([token isEqual: @"is_real"])
				var = [OFNumber numberWithBool:
				    [first doubleValue] != [first intMaxValue]];

			else
				OF_ENSURE(0);

			[stack replaceObjectAtIndex: stackSize - 1
					 withObject: var];
		} else
			[stack addObject: token];







|
>







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
			first = stack.lastObject;

			if ([token isEqual: @"!"])
				var = [OFNumber numberWithBool:
				    ![first boolValue]];
			else if ([token isEqual: @"is_real"])
				var = [OFNumber numberWithBool:
				    ([first doubleValue] !=
				    [first longLongValue])];
			else
				OF_ENSURE(0);

			[stack replaceObjectAtIndex: stackSize - 1
					 withObject: var];
		} else
			[stack addObject: token];
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
	if (_language == nil)
		return;

	pool = objc_autoreleasePoolPush();

	mapPath = [path stringByAppendingPathComponent: @"languages.json"];
	@try {
		map = [[OFString stringWithContentsOfFile: mapPath] JSONValue];

	} @catch (OFOpenItemFailedException *e) {
		objc_autoreleasePoolPop(pool);
		return;
	}

	language = _language.lowercaseString;
	territory = _territory.lowercaseString;







|
>







508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
	if (_language == nil)
		return;

	pool = objc_autoreleasePoolPush();

	mapPath = [path stringByAppendingPathComponent: @"languages.json"];
	@try {
		map = [[OFString stringWithContentsOfFile: mapPath]
		     objectByParsingJSON];
	} @catch (OFOpenItemFailedException *e) {
		objc_autoreleasePoolPop(pool);
		return;
	}

	language = _language.lowercaseString;
	territory = _territory.lowercaseString;
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
		objc_autoreleasePoolPop(pool);
		return;
	}

	languageFile = [path stringByAppendingPathComponent:
	    [languageFile stringByAppendingString: @".json"]];

	[_localizedStrings addObject:
	    [[OFString stringWithContentsOfFile: languageFile] JSONValue]];

	objc_autoreleasePoolPop(pool);
}
#endif

- (OFString *)localizedStringForID: (OFConstantString *)ID
			  fallback: (id)fallback, ...







|
|







533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
		objc_autoreleasePoolPop(pool);
		return;
	}

	languageFile = [path stringByAppendingPathComponent:
	    [languageFile stringByAppendingString: @".json"]];

	[_localizedStrings addObject: [[OFString stringWithContentsOfFile:
	    languageFile] objectByParsingJSON]];

	objc_autoreleasePoolPop(pool);
}
#endif

- (OFString *)localizedStringForID: (OFConstantString *)ID
			  fallback: (id)fallback, ...

Modified src/OFMutableTarArchiveEntry.h from [3fa49654d2] to [2a04d96f47].

34
35
36
37
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
 * @brief The file name of the entry.
 */
@property (readwrite, copy, nonatomic) OFString *fileName;

/*!
 * @brief The mode of the entry.
 */
@property (readwrite, nonatomic) uint32_t mode;

/*!
 * @brief The UID of the owner.
 */
@property (readwrite, nonatomic) uint32_t UID;

/*!
 * @brief The GID of the group.
 */
@property (readwrite, nonatomic) uint32_t GID;

/*!
 * @brief The size of the file.
 */
@property (readwrite, nonatomic) uint64_t size;

/*!
 * @brief The date of the last modification of the file.
 */
@property (readwrite, retain, nonatomic) OFDate *modificationDate;

/*!







|




|




|




|







34
35
36
37
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
 * @brief The file name of the entry.
 */
@property (readwrite, copy, nonatomic) OFString *fileName;

/*!
 * @brief The mode of the entry.
 */
@property (readwrite, nonatomic) unsigned long mode;

/*!
 * @brief The UID of the owner.
 */
@property (readwrite, nonatomic) unsigned long UID;

/*!
 * @brief The GID of the group.
 */
@property (readwrite, nonatomic) unsigned long GID;

/*!
 * @brief The size of the file.
 */
@property (readwrite, nonatomic) unsigned long long size;

/*!
 * @brief The date of the last modification of the file.
 */
@property (readwrite, retain, nonatomic) OFDate *modificationDate;

/*!
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
 * @brief The group of the file.
 */
@property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *group;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readwrite, nonatomic) uint32_t deviceMajor;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readwrite, nonatomic) uint32_t deviceMinor;

/*!
 * @brief Converts the OFMutableTarArchiveEntry to an immutable
 *	  OFTarArchiveEntry.
 */
- (void)makeImmutable;
@end

OF_ASSUME_NONNULL_END







|




|









82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
 * @brief The group of the file.
 */
@property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *group;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readwrite, nonatomic) unsigned long deviceMajor;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readwrite, nonatomic) unsigned long deviceMinor;

/*!
 * @brief Converts the OFMutableTarArchiveEntry to an immutable
 *	  OFTarArchiveEntry.
 */
- (void)makeImmutable;
@end

OF_ASSUME_NONNULL_END

Modified src/OFMutableTarArchiveEntry.m from [11e44c30db] to [1fdec748d1].

37
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
- (void)setFileName: (OFString *)fileName
{
	OFString *old = _fileName;
	_fileName = [fileName copy];
	[old release];
}

- (void)setMode: (uint32_t)mode
{
	_mode = mode;
}

- (void)setUID: (uint32_t)UID
{
	_UID = UID;
}

- (void)setGID: (uint32_t)GID
{
	_GID = GID;
}

- (void)setSize: (uint64_t)size
{
	_size = size;
}

- (void)setModificationDate: (OFDate *)modificationDate
{
	OFDate *old = _modificationDate;







|




|




|




|







37
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
- (void)setFileName: (OFString *)fileName
{
	OFString *old = _fileName;
	_fileName = [fileName copy];
	[old release];
}

- (void)setMode: (unsigned long)mode
{
	_mode = mode;
}

- (void)setUID: (unsigned long)UID
{
	_UID = UID;
}

- (void)setGID: (unsigned long)GID
{
	_GID = GID;
}

- (void)setSize: (unsigned long long)size
{
	_size = size;
}

- (void)setModificationDate: (OFDate *)modificationDate
{
	OFDate *old = _modificationDate;
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
- (void)setGroup: (OFString *)group
{
	OFString *old = _group;
	_group = [group copy];
	[old release];
}

- (void)setDeviceMajor: (uint32_t)deviceMajor
{
	_deviceMajor = deviceMajor;
}

- (void)setDeviceMinor: (uint32_t)deviceMinor
{
	_deviceMinor = deviceMinor;
}

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







|




|









90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
- (void)setGroup: (OFString *)group
{
	OFString *old = _group;
	_group = [group copy];
	[old release];
}

- (void)setDeviceMajor: (unsigned long)deviceMajor
{
	_deviceMajor = deviceMajor;
}

- (void)setDeviceMinor: (unsigned long)deviceMinor
{
	_deviceMinor = deviceMinor;
}

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

Modified src/OFNumber.h from [8668a7987f] to [5740ff4672].

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#ifndef OF_NUMBER_M
OF_SUBCLASSING_RESTRICTED
#endif
@interface OFNumber: OFValue <OFComparing, OFSerialization,
    OFJSONRepresentation, OFMessagePackRepresentation>
{
	union of_number_value {
		double    float_;
		intmax_t  signed_;
		uintmax_t unsigned_;
	} _value;
	enum of_number_type {
		OF_NUMBER_TYPE_FLOAT = 1,
		OF_NUMBER_TYPE_SIGNED,
		OF_NUMBER_TYPE_UNSIGNED
	} _type;
	const char *_typeEncoding;







|
|
|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#ifndef OF_NUMBER_M
OF_SUBCLASSING_RESTRICTED
#endif
@interface OFNumber: OFValue <OFComparing, OFSerialization,
    OFJSONRepresentation, OFMessagePackRepresentation>
{
	union of_number_value {
		double float_;
		long long signed_;
		unsigned long long unsigned_;
	} _value;
	enum of_number_type {
		OF_NUMBER_TYPE_FLOAT = 1,
		OF_NUMBER_TYPE_SIGNED,
		OF_NUMBER_TYPE_UNSIGNED
	} _type;
	const char *_typeEncoding;
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
@property (readonly, nonatomic) unsigned long unsignedLongValue;

/*!
 * @brief The OFNumber as an `unsigned long long`.
 */
@property (readonly, nonatomic) unsigned long long unsignedLongLongValue;

/*!
 * @brief The OFNumber as an `int8_t`.
 */
@property (readonly, nonatomic) int8_t int8Value;

/*!
 * @brief The OFNumber as an `int16_t`.
 */
@property (readonly, nonatomic) int16_t int16Value;

/*!
 * @brief The OFNumber as an `int32_t`.
 */
@property (readonly, nonatomic) int32_t int32Value;

/*!
 * @brief The OFNumber as an `int64_t`.
 */
@property (readonly, nonatomic) int64_t int64Value;

/*!
 * @brief The OFNumber as a `uint8_t`.
 */
@property (readonly, nonatomic) uint8_t uInt8Value;

/*!
 * @brief The OFNumber as a `uint16_t`.
 */
@property (readonly, nonatomic) uint16_t uInt16Value;

/*!
 * @brief The OFNumber as a `uint32_t`.
 */
@property (readonly, nonatomic) uint32_t uInt32Value;

/*!
 * @brief The OFNumber as a `uint64_t`.
 */
@property (readonly, nonatomic) uint64_t uInt64Value;

/*!
 * @brief The OFNumber as a `size_t`.
 */
@property (readonly, nonatomic) size_t sizeValue;

/*!
 * @brief The OFNumber as an `ssize_t`.
 */
@property (readonly, nonatomic) ssize_t sSizeValue;

/*!
 * @brief The OFNumber as an `intmax_t`.
 */
@property (readonly, nonatomic) intmax_t intMaxValue;

/*!
 * @brief The OFNumber as a `uintmax_t`.
 */
@property (readonly, nonatomic) uintmax_t uIntMaxValue;

/*!
 * @brief The OFNumber as a `ptrdiff_t`.
 */
@property (readonly, nonatomic) ptrdiff_t ptrDiffValue;

/*!
 * @brief The OFNumber as an `intptr_t`.
 */
@property (readonly, nonatomic) intptr_t intPtrValue;

/*!
 * @brief The OFNumber as a `uintptr_t`.
 */
@property (readonly, nonatomic) uintptr_t uIntPtrValue;

/*!
 * @brief The OFNumber as a `float`.
 */
@property (readonly, nonatomic) float floatValue;

/*!
 * @brief The OFNumber as a `double`.







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







112
113
114
115
116
117
118











































































119
120
121
122
123
124
125
@property (readonly, nonatomic) unsigned long unsignedLongValue;

/*!
 * @brief The OFNumber as an `unsigned long long`.
 */
@property (readonly, nonatomic) unsigned long long unsignedLongLongValue;












































































/*!
 * @brief The OFNumber as a `float`.
 */
@property (readonly, nonatomic) float floatValue;

/*!
 * @brief The OFNumber as a `double`.
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
+ (instancetype)valueWithDimension: (of_dimension_t)dimension OF_UNAVAILABLE;
+ (instancetype)valueWithRectangle: (of_rectangle_t)rectangle OF_UNAVAILABLE;
#endif

/*!
 * @brief Creates a new OFNumber with the specified `bool`.
 *
 * @param bool_ A `bool` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithBool: (bool)bool_;

/*!
 * @brief Creates a new OFNumber with the specified `signed char`.
 *
 * @param sChar A `signed char` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithChar: (signed char)sChar;

/*!
 * @brief Creates a new OFNumber with the specified `short`.
 *
 * @param sShort A `short` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithShort: (short)sShort;

/*!
 * @brief Creates a new OFNumber with the specified `int`.
 *
 * @param sInt An `int` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt: (int)sInt;

/*!
 * @brief Creates a new OFNumber with the specified `long`.
 *
 * @param sLong A `long` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithLong: (long)sLong;

/*!
 * @brief Creates a new OFNumber with the specified `long long`.
 *
 * @param sLongLong A `long long` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithLongLong: (long long)sLongLong;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned char`.
 *
 * @param uChar An `unsigned char` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedChar: (unsigned char)uChar;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned short`.
 *
 * @param uShort An `unsigned short` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedShort: (unsigned short)uShort;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned int`.
 *
 * @param uInt An `unsigned int` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedInt: (unsigned int)uInt;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned long`.
 *
 * @param uLong An `unsigned long` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedLong: (unsigned long)uLong;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned long long`.
 *
 * @param uLongLong An `unsigned long long` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedLongLong: (unsigned long long)uLongLong;

/*!
 * @brief Creates a new OFNumber with the specified `int8_t`.
 *
 * @param int8 An `int8_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt8: (int8_t)int8;

/*!
 * @brief Creates a new OFNumber with the specified `int16_t`.
 *
 * @param int16 An `int16_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt16: (int16_t)int16;

/*!
 * @brief Creates a new OFNumber with the specified `int32_t`.
 *
 * @param int32 An `int32_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt32: (int32_t)int32;

/*!
 * @brief Creates a new OFNumber with the specified `int64_t`.
 *
 * @param int64 An `int64_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt64: (int64_t)int64;

/*!
 * @brief Creates a new OFNumber with the specified `uint8_t`.
 *
 * @param uInt8 A `uint8_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUInt8: (uint8_t)uInt8;

/*!
 * @brief Creates a new OFNumber with the specified `uint16_t`.
 *
 * @param uInt16 A `uint16_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUInt16: (uint16_t)uInt16;

/*!
 * @brief Creates a new OFNumber with the specified `uint32_t`.
 *
 * @param uInt32 A `uint32_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUInt32: (uint32_t)uInt32;

/*!
 * @brief Creates a new OFNumber with the specified `uint64_t`.
 *
 * @param uInt64 A `uint64_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUInt64: (uint64_t)uInt64;

/*!
 * @brief Creates a new OFNumber with the specified `size_t`.
 *
 * @param size A `size_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithSize: (size_t)size;

/*!
 * @brief Creates a new OFNumber with the specified `ssize_t`.
 *
 * @param sSize An `ssize_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithSSize: (ssize_t)sSize;

/*!
 * @brief Creates a new OFNumber with the specified `intmax_t`.
 *
 * @param intMax An `intmax_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithIntMax: (intmax_t)intMax;

/*!
 * @brief Creates a new OFNumber with the specified `uintmax_t`.
 *
 * @param uIntMax A `uintmax_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUIntMax: (uintmax_t)uIntMax;

/*!
 * @brief Creates a new OFNumber with the specified `ptrdiff_t`.
 *
 * @param ptrDiff A `ptrdiff_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithPtrDiff: (ptrdiff_t)ptrDiff;

/*!
 * @brief Creates a new OFNumber with the specified `intptr_t`.
 *
 * @param intPtr An `intptr_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithIntPtr: (intptr_t)intPtr;

/*!
 * @brief Creates a new OFNumber with the specified `uintptr_t`.
 *
 * @param uIntPtr A `uintptr_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUIntPtr: (uintptr_t)uIntPtr;

/*!
 * @brief Creates a new OFNumber with the specified `float`.
 *
 * @param float_ A `float` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithFloat: (float)float_;

/*!
 * @brief Creates a new OFNumber with the specified `double`.
 *
 * @param double_ A `double` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithDouble: (double)double_;

- (instancetype)init OF_UNAVAILABLE;
#ifdef OF_HAVE_UNAVAILABLE
- (instancetype)initWithBytes: (const void *)bytes
		     objCType: (const char *)objCType OF_UNAVAILABLE;
- (instancetype)initWithPointer: (const void *)pointer OF_UNAVAILABLE;
- (instancetype)initWithNonretainedObject: (id)object OF_UNAVAILABLE;
- (instancetype)initWithRange: (of_range_t)range OF_UNAVAILABLE;
- (instancetype)initWithPoint: (of_point_t)point OF_UNAVAILABLE;
- (instancetype)initWithDimension: (of_dimension_t)dimension OF_UNAVAILABLE;
- (instancetype)initWithRectangle: (of_rectangle_t)rectangle OF_UNAVAILABLE;
#endif

/*!
 * @brief Initializes an already allocated OFNumber with the specified `bool`.
 *
 * @param bool_ A `bool` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithBool: (bool)bool_;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `signed char`.
 *
 * @param sChar A `signed char` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithChar: (signed char)sChar;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `short`.
 *
 * @param sShort A `short` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithShort: (short)sShort;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `int`.
 *
 * @param sInt An `int` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithInt: (int)sInt;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `long`.
 *
 * @param sLong A `long` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithLong: (long)sLong;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `long long`.
 *
 * @param sLongLong A `long long` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithLongLong: (long long)sLongLong;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned char`.
 *
 * @param uChar An `unsigned char` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedChar: (unsigned char)uChar;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned short`.
 *
 * @param uShort An `unsigned short` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedShort: (unsigned short)uShort;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned int`.
 *
 * @param uInt An `unsigned int` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedInt: (unsigned int)uInt;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned long`.
 *
 * @param uLong An `unsigned long` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedLong: (unsigned long)uLong;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned long long`.
 *
 * @param uLongLong An `unsigned long long` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedLongLong: (unsigned long long)uLongLong;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `int8_t`.
 *
 * @param int8 An `int8_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithInt8: (int8_t)int8;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `int16_t`.
 *
 * @param int16 An `int16_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithInt16: (int16_t)int16;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `int32_t`.
 *
 * @param int32 An `int32_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithInt32: (int32_t)int32;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `int64_t`.
 *
 * @param int64 An `int64_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithInt64: (int64_t)int64;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uint8_t`.
 *
 * @param uInt8 A `uint8_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUInt8: (uint8_t)uInt8;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uint16_t`.
 *
 * @param uInt16 A `uint16_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUInt16: (uint16_t)uInt16;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uint32_t`.
 *
 * @param uInt32 A `uint32_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUInt32: (uint32_t)uInt32;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uint64_t`.
 *
 * @param uInt64 A `uint64_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUInt64: (uint64_t)uInt64;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `size_t`.
 *
 * @param size A `size_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithSize: (size_t)size;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `ssize_t`.
 *
 * @param sSize An `ssize_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithSSize: (ssize_t)sSize;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `intmax_t`.
 *
 * @param intMax An `intmax_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithIntMax: (intmax_t)intMax;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uintmax_t`.
 *
 * @param uIntMax A `uintmax_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUIntMax: (uintmax_t)uIntMax;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `ptrdiff_t`.
 *
 * @param ptrDiff A `ptrdiff_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithPtrDiff: (ptrdiff_t)ptrDiff;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `intptr_t`.
 *
 * @param intPtr An `intptr_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithIntPtr: (intptr_t)intPtr;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uintptr_t`.
 *
 * @param uIntPtr A `uintptr_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUIntPtr: (uintptr_t)uIntPtr;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `float`.
 *
 * @param float_ A `float` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithFloat: (float)float_;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `double`.
 *
 * @param double_ A `double` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithDouble: (double)double_;
@end

OF_ASSUME_NONNULL_END

#if !defined(NSINTEGER_DEFINED) && !__has_feature(modules)
/* Required for number literals to work */
@compatibility_alias NSNumber OFNumber;
#endif







|


|




|


|




|


|




|


|




|


|




|


|




|


|




|


|




|


|




|


|




|


|


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


|


|




|


|
















|


|





|


|




|


|




|


|




|


|





|


|





|


|





|


|





|


|





|


|





|


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




|


|




|


|








141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
























































































































234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354





































































































































355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
+ (instancetype)valueWithDimension: (of_dimension_t)dimension OF_UNAVAILABLE;
+ (instancetype)valueWithRectangle: (of_rectangle_t)rectangle OF_UNAVAILABLE;
#endif

/*!
 * @brief Creates a new OFNumber with the specified `bool`.
 *
 * @param value The `bool` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithBool: (bool)value;

/*!
 * @brief Creates a new OFNumber with the specified `signed char`.
 *
 * @param value The `signed char` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithChar: (signed char)value;

/*!
 * @brief Creates a new OFNumber with the specified `short`.
 *
 * @param value The `short` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithShort: (short)value;

/*!
 * @brief Creates a new OFNumber with the specified `int`.
 *
 * @param value The `int` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt: (int)value;

/*!
 * @brief Creates a new OFNumber with the specified `long`.
 *
 * @param value The `long` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithLong: (long)value;

/*!
 * @brief Creates a new OFNumber with the specified `long long`.
 *
 * @param value The `long long` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithLongLong: (long long)value;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned char`.
 *
 * @param value The `unsigned char` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedChar: (unsigned char)value;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned short`.
 *
 * @param value The `unsigned short` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedShort: (unsigned short)value;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned int`.
 *
 * @param value The `unsigned int` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedInt: (unsigned int)value;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned long`.
 *
 * @param value The `unsigned long` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedLong: (unsigned long)value;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned long long`.
 *
 * @param value The `unsigned long long` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedLongLong: (unsigned long long)value;

/*!
























































































































 * @brief Creates a new OFNumber with the specified `float`.
 *
 * @param value The `float` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithFloat: (float)value;

/*!
 * @brief Creates a new OFNumber with the specified `double`.
 *
 * @param value The `double` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithDouble: (double)value;

- (instancetype)init OF_UNAVAILABLE;
#ifdef OF_HAVE_UNAVAILABLE
- (instancetype)initWithBytes: (const void *)bytes
		     objCType: (const char *)objCType OF_UNAVAILABLE;
- (instancetype)initWithPointer: (const void *)pointer OF_UNAVAILABLE;
- (instancetype)initWithNonretainedObject: (id)object OF_UNAVAILABLE;
- (instancetype)initWithRange: (of_range_t)range OF_UNAVAILABLE;
- (instancetype)initWithPoint: (of_point_t)point OF_UNAVAILABLE;
- (instancetype)initWithDimension: (of_dimension_t)dimension OF_UNAVAILABLE;
- (instancetype)initWithRectangle: (of_rectangle_t)rectangle OF_UNAVAILABLE;
#endif

/*!
 * @brief Initializes an already allocated OFNumber with the specified `bool`.
 *
 * @param value The `bool` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithBool: (bool)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `signed char`.
 *
 * @param value The `signed char` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithChar: (signed char)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `short`.
 *
 * @param value The `short` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithShort: (short)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `int`.
 *
 * @param value The `int` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithInt: (int)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `long`.
 *
 * @param value The `long` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithLong: (long)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `long long`.
 *
 * @param value The `long long` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithLongLong: (long long)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned char`.
 *
 * @param value The `unsigned char` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedChar: (unsigned char)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned short`.
 *
 * @param value The `unsigned short` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedShort: (unsigned short)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned int`.
 *
 * @param value The `unsigned int` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedInt: (unsigned int)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned long`.
 *
 * @param value The `unsigned long` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedLong: (unsigned long)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned long long`.
 *
 * @param value The `unsigned long long` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedLongLong: (unsigned long long)value;






































































































































/*!
 * @brief Initializes an already allocated OFNumber with the specified `float`.
 *
 * @param value The `float` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithFloat: (float)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `double`.
 *
 * @param value The `double` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithDouble: (double)value;
@end

OF_ASSUME_NONNULL_END

#if !defined(NSINTEGER_DEFINED) && !__has_feature(modules)
/* Required for number literals to work */
@compatibility_alias NSNumber OFNumber;
#endif

Modified src/OFNumber.m from [57186c2c7a] to [17a849254e].

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


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

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
255
256
257
258
259
260
261


262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

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


301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
@interface OFNumberSingleton: OFNumber
@end

static struct {
	Class isa;
} placeholder;

static OFNumberSingleton *zeroNumber, *oneNumber, *twoNumber;
static OFNumberSingleton *trueNumber, *falseNumber;

static void
initZeroNumber(void)
{
	zeroNumber = [[OFNumberSingleton alloc] initWithUnsignedChar: 0];
}

static void
initOneNumber(void)
{
	oneNumber = [[OFNumberSingleton alloc] initWithUnsignedChar: 1];
}

static void
initTwoNumber(void)
{


	twoNumber = [[OFNumberSingleton alloc] initWithUnsignedChar: 2];
}

static void
initTrueNumber(void)
{
	trueNumber = [[OFNumberSingleton alloc] initWithBool: true];
}

static void
initFalseNumber(void)
{
	falseNumber = [[OFNumberSingleton alloc] initWithBool: false];

}

@implementation OFNumberPlaceholder
- (instancetype)initWithBool: (bool)bool_
{
	if (bool_) {
		static of_once_t once;
		of_once(&once, initTrueNumber);
		return (id)trueNumber;
	} else {
		static of_once_t once;
		of_once(&once, initFalseNumber);
		return (id)falseNumber;
	}
}

- (instancetype)initWithChar: (signed char)sChar
{
	if (sChar >= 0)
		return [self initWithUnsignedChar: sChar];

	return (id)[[OFNumber of_alloc] initWithChar: sChar];
}

- (instancetype)initWithShort: (short)sShort
{
	if (sShort >= 0)
		return [self initWithUnsignedShort: sShort];
	if (sShort >= SCHAR_MIN)
		return [self initWithChar: (signed char)sShort];

	return (id)[[OFNumber of_alloc] initWithShort: sShort];
}

- (instancetype)initWithInt: (int)sInt
{
	if (sInt >= 0)
		return [self initWithUnsignedInt: sInt];
	if (sInt >= SHRT_MIN)
		return [self initWithShort: (short)sInt];

	return (id)[[OFNumber of_alloc] initWithInt: sInt];
}

- (instancetype)initWithLong: (long)sLong
{
	if (sLong >= 0)
		return [self initWithUnsignedLong: sLong];
	if (sLong >= INT_MIN)
		return [self initWithShort: (int)sLong];




	return (id)[[OFNumber of_alloc] initWithLong: sLong];
}

- (instancetype)initWithLongLong: (long long)sLongLong
{
	if (sLongLong >= 0)
		return [self initWithUnsignedLongLong: sLongLong];
	if (sLongLong >= LONG_MIN)
		return [self initWithLong: (long)sLongLong];

	return (id)[[OFNumber of_alloc] initWithLongLong: sLongLong];
}

- (instancetype)initWithUnsignedChar: (unsigned char)uChar
{
	switch (uChar) {
	case 0: {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, initZeroNumber);
		return (id)zeroNumber;
	}
	case 1: {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, initOneNumber);
		return (id)oneNumber;
	}
	case 2: {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, initTwoNumber);
		return (id)twoNumber;
	}
	}

	return (id)[[OFNumber of_alloc] initWithUnsignedChar: uChar];
}

- (instancetype)initWithUnsignedShort: (unsigned short)uShort
{
	if (uShort <= UCHAR_MAX)
		return [self initWithUnsignedChar: (unsigned char)uShort];


	return (id)[[OFNumber of_alloc] initWithUnsignedShort: uShort];
}

- (instancetype)initWithUnsignedInt: (unsigned int)uInt
{
	if (uInt <= USHRT_MAX)
		return [self initWithUnsignedShort: (unsigned short)uInt];

	return (id)[[OFNumber of_alloc] initWithUnsignedInt: uInt];
}

- (instancetype)initWithUnsignedLong: (unsigned long)uLong
{
	if (uLong <= UINT_MAX)
		return [self initWithUnsignedInt: (unsigned int)uLong];

	return (id)[[OFNumber of_alloc] initWithUnsignedLong: uLong];
}

- (instancetype)initWithUnsignedLongLong: (unsigned long long)uLongLong
{
	if (uLongLong <= ULONG_MAX)
		return [self initWithUnsignedLong: (unsigned long)uLongLong];

	return (id)[[OFNumber of_alloc] initWithUnsignedLongLong: uLongLong];
}

- (instancetype)initWithInt8: (int8_t)int8
{
	if (int8 >= 0)
		return [self initWithUInt8: int8];

	return (id)[[OFNumber of_alloc] initWithInt8: int8];
}

- (instancetype)initWithInt16: (int16_t)int16
{
	if (int16 >= 0)
		return [self initWithUInt16: int16];
	if (int16 >= INT8_MIN)
		return [self initWithInt8: (int8_t)int16];


	return (id)[[OFNumber of_alloc] initWithInt16: int16];
}

- (instancetype)initWithInt32: (int32_t)int32
{
	if (int32 >= 0)
		return [self initWithUInt32: int32];
	if (int32 >= INT16_MIN)
		return [self initWithInt16: (int16_t)int32];

	return (id)[[OFNumber of_alloc] initWithInt32: int32];
}

- (instancetype)initWithInt64: (int64_t)int64
{
	if (int64 >= 0)
		return [self initWithUInt64: int64];
	if (int64 >= INT32_MIN)
		return [self initWithInt32: (int32_t)int64];

	return (id)[[OFNumber of_alloc] initWithInt64: int64];
}

- (instancetype)initWithUInt8: (uint8_t)uInt8
{
	return (id)[[OFNumber of_alloc] initWithUInt8: uInt8];
}

- (instancetype)initWithUInt16: (uint16_t)uInt16
{
	if (uInt16 <= UINT8_MAX)
		return [self initWithUInt8: (uint8_t)uInt16];


	return (id)[[OFNumber of_alloc] initWithUInt16: uInt16];
}

- (instancetype)initWithUInt32: (uint32_t)uInt32
{
	if (uInt32 <= UINT16_MAX)
		return [self initWithUInt16: (uint16_t)uInt32];

	return (id)[[OFNumber of_alloc] initWithUInt32: uInt32];
}

- (instancetype)initWithUInt64: (uint64_t)uInt64
{
	if (uInt64 <= UINT32_MAX)


		return [self initWithUInt32: (uint32_t)uInt64];

	return (id)[[OFNumber of_alloc] initWithUInt64: uInt64];
}

- (instancetype)initWithSize: (size_t)size
{
	if (size <= ULONG_MAX)
		return [self initWithUnsignedLong: (unsigned long)size];

	return (id)[[OFNumber of_alloc] initWithSize: size];
}

- (instancetype)initWithSSize: (ssize_t)sSize
{
	if (sSize >= 0)
		return [self initWithSize: sSize];
	if (sSize <= LONG_MIN)
		return [self initWithLong: (long)sSize];


	return (id)[[OFNumber of_alloc] initWithSSize: sSize];
}

- (instancetype)initWithIntMax: (intmax_t)intMax
{
	if (intMax >= 0)
		return [self initWithUIntMax: intMax];
	if (intMax <= LLONG_MIN)
		return [self initWithLongLong: (long long)intMax];

	return (id)[[OFNumber of_alloc] initWithIntMax: intMax];
}

- (instancetype)initWithUIntMax: (uintmax_t)uIntMax
{
	if (uIntMax <= ULLONG_MAX)
		return [self initWithUnsignedLongLong:
		    (unsigned long long)uIntMax];



	return (id)[[OFNumber of_alloc] initWithUIntMax: uIntMax];
}

#ifdef __clang__
/*
 * This warning should probably not exist at all, as it prevents checking
 * whether one type fits into another in a portable way.
 */
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
#endif

- (instancetype)initWithPtrDiff: (ptrdiff_t)ptrDiff
{
	if (ptrDiff >= LLONG_MIN && ptrDiff <= LLONG_MAX)
		return [self initWithLongLong: (long long)ptrDiff];

	return (id)[[OFNumber of_alloc] initWithPtrDiff: ptrDiff];
}

- (instancetype)initWithIntPtr: (intptr_t)intPtr
{
	if (intPtr >= 0)
		return [self initWithUIntPtr: intPtr];
	if (intPtr >= LLONG_MIN)
		return [self initWithLongLong: (long long)intPtr];


	return (id)[[OFNumber of_alloc] initWithIntPtr: intPtr];
}

- (instancetype)initWithUIntPtr: (uintptr_t)uIntPtr
{
	if (uIntPtr <= ULLONG_MAX)
		return [self initWithUnsignedLongLong:
		    (unsigned long long)uIntPtr];

	return (id)[[OFNumber of_alloc] initWithUIntPtr: uIntPtr];
}

#ifdef __clang__
# pragma clang diagnostic pop
#endif

- (instancetype)initWithFloat: (float)float_
{
	if (float_ == (uintmax_t)float_)
		return [self initWithUIntMax: (uintmax_t)float_];
	if (float_ == (intmax_t)float_)
		return [self initWithIntMax: (intmax_t)float_];


	return (id)[[OFNumber of_alloc] initWithFloat: float_];
}

- (instancetype)initWithDouble: (double)double_
{
	if (double_ == (uintmax_t)double_)
		return [self initWithUIntMax: (uintmax_t)double_];
	if (double_ == (intmax_t)double_)
		return [self initWithIntMax: (intmax_t)double_];
	if (double_ == (float)double_)
		return [self initWithFloat: (float)double_];

	return (id)[[OFNumber of_alloc] initWithDouble: double_];
}

- (instancetype)initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFNumber of_alloc] initWithSerialization: element];
}
@end







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

|

|
|
|


|
|




|

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

<
<
<
<
<
<
<
|


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

<
<
<
<
<
<
<
|


|

<
|

|
|

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

|
<
|
>
|
|

<
<
<
<
<
|


|

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


|

|
<
<
<
|
>
|
|

<
<
<
<
<
<
<
|

<
<
<
<
<
<
<

<
<
<
|

<
<
|
<
<
<
<
|
>
|
|

<
<
<
<
<
|


|

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


|

|
<
<
<
|
>
|
|

<
<
<
<
<
<
<
|

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


|

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


<
<
<
<
|

|
<
<
<
|
>
|
|

<
<
<
<
<
<
<
<
<
|







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
@interface OFNumberSingleton: OFNumber
@end

static struct {
	Class isa;
} placeholder;

#define SINGLETON(var, sel, val)				\
	static OFNumberSingleton *var;				\
								\
	static void						\
	var##Init(void)						\
	{							\
		var = [[OFNumberSingleton alloc] sel val];	\
	}
SINGLETON(falseNumber, initWithBool:, false)

SINGLETON(trueNumber, initWithBool:, true)

SINGLETON(charZeroNumber, initWithChar:, 0)

SINGLETON(shortZeroNumber, initWithShort:, 0)

SINGLETON(intZeroNumber, initWithInt:, 0)

SINGLETON(longZeroNumber, initWithLong:, 0)
SINGLETON(longLongZeroNumber, initWithLongLong:, 0)
SINGLETON(unsignedCharZeroNumber, initWithUnsignedChar:, 0)

SINGLETON(unsignedShortZeroNumber, initWithUnsignedShort:, 0)

SINGLETON(unsignedIntZeroNumber, initWithUnsignedInt:, 0)

SINGLETON(unsignedLongZeroNumber, initWithUnsignedLong:, 0)

SINGLETON(unsignedLongLongZeroNumber, initWithUnsignedLongLong:, 0)

SINGLETON(floatZeroNumber, initWithFloat:, 0)

SINGLETON(doubleZeroNumber, initWithDouble:, 0)
#undef SINGLETON


@implementation OFNumberPlaceholder
- (instancetype)initWithBool: (bool)value
{
	if (value) {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, trueNumberInit);
		return (id)trueNumber;
	} else {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, falseNumberInit);
		return (id)falseNumber;
	}
}

- (instancetype)initWithChar: (signed char)value
{


	if (value == 0) {


		static of_once_t once = OF_ONCE_INIT;






		of_once(&once, charZeroNumberInit);
		return (id)charZeroNumber;
	}








	return (id)[[OFNumber of_alloc] initWithChar: value];
}






- (instancetype)initWithShort: (short)value
{
	if (value == 0) {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, shortZeroNumberInit);
		return (id)shortZeroNumber;
	}








	return (id)[[OFNumber of_alloc] initWithShort: value];
}

- (instancetype)initWithInt: (int)value
{

	if (value == 0) {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, intZeroNumberInit);
		return (id)intZeroNumber;
	}








	return (id)[[OFNumber of_alloc] initWithInt: value];
}





- (instancetype)initWithLong: (long)value
{
	if (value == 0) {

		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, longZeroNumberInit);
		return (id)longZeroNumber;
	}






	return (id)[[OFNumber of_alloc] initWithLong: value];
}

- (instancetype)initWithLongLong: (long long)value
{
	if (value == 0) {

		static of_once_t once = OF_ONCE_INIT;


		of_once(&once, longLongZeroNumberInit);


		return (id)longLongZeroNumber;

	}








	return (id)[[OFNumber of_alloc] initWithLongLong: value];
}

- (instancetype)initWithUnsignedChar: (unsigned char)value
{
	if (value == 0) {



		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, unsignedCharZeroNumberInit);
		return (id)unsignedCharZeroNumber;
	}








	return (id)[[OFNumber of_alloc] initWithUnsignedChar: value];
}











- (instancetype)initWithUnsignedShort: (unsigned short)value
{


	if (value == 0) {




		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, unsignedShortZeroNumberInit);
		return (id)unsignedShortZeroNumber;
	}






	return (id)[[OFNumber of_alloc] initWithUnsignedShort: value];
}

- (instancetype)initWithUnsignedInt: (unsigned int)value
{
	if (value == 0) {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, unsignedIntZeroNumberInit);
		return (id)unsignedIntZeroNumber;
	}








	return (id)[[OFNumber of_alloc] initWithUnsignedInt: value];
}

- (instancetype)initWithUnsignedLong: (unsigned long)value
{
	if (value == 0) {



		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, unsignedLongZeroNumberInit);
		return (id)unsignedLongZeroNumber;
	}








	return (id)[[OFNumber of_alloc] initWithUnsignedLong: value];
}




- (instancetype)initWithUnsignedLongLong: (unsigned long long)value

{
	if (value == 0) {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, unsignedLongLongZeroNumberInit);

		return (id)unsignedLongLongZeroNumber;








	}





	return (id)[[OFNumber of_alloc] initWithUnsignedLongLong: value];
}

- (instancetype)initWithFloat: (float)value
{
	if (value == 0) {



		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, floatZeroNumberInit);
		return (id)floatZeroNumber;

	}






	return (id)[[OFNumber of_alloc] initWithFloat: value];
}





- (instancetype)initWithDouble: (double)value
{
	if (value == 0) {



		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, doubleZeroNumberInit);
		return (id)doubleZeroNumber;
	}










	return (id)[[OFNumber of_alloc] initWithDouble: value];
}

- (instancetype)initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFNumber of_alloc] initWithSerialization: element];
}
@end
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
{
	if (self == [OFNumber class])
		return (id)&placeholder;

	return [super alloc];
}

+ (instancetype)numberWithBool: (bool)bool_
{
	return [[[self alloc] initWithBool: bool_] autorelease];
}

+ (instancetype)numberWithChar: (signed char)sChar
{
	return [[[self alloc] initWithChar: sChar] autorelease];
}

+ (instancetype)numberWithShort: (short)sShort
{
	return [[[self alloc] initWithShort: sShort] autorelease];
}

+ (instancetype)numberWithInt: (int)sInt
{
	return [[[self alloc] initWithInt: sInt] autorelease];
}

+ (instancetype)numberWithLong: (long)sLong
{
	return [[[self alloc] initWithLong: sLong] autorelease];
}

+ (instancetype)numberWithLongLong: (long long)sLongLong
{
	return [[[self alloc] initWithLongLong: sLongLong] autorelease];
}

+ (instancetype)numberWithUnsignedChar: (unsigned char)uChar
{
	return [[[self alloc] initWithUnsignedChar: uChar] autorelease];
}

+ (instancetype)numberWithUnsignedShort: (unsigned short)uShort
{
	return [[[self alloc] initWithUnsignedShort: uShort] autorelease];
}

+ (instancetype)numberWithUnsignedInt: (unsigned int)uInt
{
	return [[[self alloc] initWithUnsignedInt: uInt] autorelease];
}

+ (instancetype)numberWithUnsignedLong: (unsigned long)uLong
{
	return [[[self alloc] initWithUnsignedLong: uLong] autorelease];
}

+ (instancetype)numberWithUnsignedLongLong: (unsigned long long)uLongLong
{
	return [[[self alloc] initWithUnsignedLongLong: uLongLong] autorelease];
}

+ (instancetype)numberWithInt8: (int8_t)int8
{
	return [[[self alloc] initWithInt8: int8] autorelease];
}

+ (instancetype)numberWithInt16: (int16_t)int16
{
	return [[[self alloc] initWithInt16: int16] autorelease];
}

+ (instancetype)numberWithInt32: (int32_t)int32
{
	return [[[self alloc] initWithInt32: int32] autorelease];
}

+ (instancetype)numberWithInt64: (int64_t)int64
{
	return [[[self alloc] initWithInt64: int64] autorelease];
}

+ (instancetype)numberWithUInt8: (uint8_t)uInt8
{
	return [[[self alloc] initWithUInt8: uInt8] autorelease];
}

+ (instancetype)numberWithUInt16: (uint16_t)uInt16
{
	return [[[self alloc] initWithUInt16: uInt16] autorelease];
}

+ (instancetype)numberWithUInt32: (uint32_t)uInt32
{
	return [[[self alloc] initWithUInt32: uInt32] autorelease];
}

+ (instancetype)numberWithUInt64: (uint64_t)uInt64
{
	return [[[self alloc] initWithUInt64: uInt64] autorelease];
}

+ (instancetype)numberWithSize: (size_t)size
{
	return [[[self alloc] initWithSize: size] autorelease];
}

+ (instancetype)numberWithSSize: (ssize_t)sSize
{
	return [[[self alloc] initWithSSize: sSize] autorelease];
}

+ (instancetype)numberWithIntMax: (intmax_t)intMax
{
	return [[[self alloc] initWithIntMax: intMax] autorelease];
}

+ (instancetype)numberWithUIntMax: (uintmax_t)uIntMax
{
	return [[[self alloc] initWithUIntMax: uIntMax] autorelease];
}

+ (instancetype)numberWithPtrDiff: (ptrdiff_t)ptrDiff
{
	return [[[self alloc] initWithPtrDiff: ptrDiff] autorelease];
}

+ (instancetype)numberWithIntPtr: (intptr_t)intPtr
{
	return [[[self alloc] initWithIntPtr: intPtr] autorelease];
}

+ (instancetype)numberWithUIntPtr: (uintptr_t)uIntPtr
{
	return [[[self alloc] initWithUIntPtr: uIntPtr] autorelease];
}

+ (instancetype)numberWithFloat: (float)float_
{
	return [[[self alloc] initWithFloat: float_] autorelease];
}

+ (instancetype)numberWithDouble: (double)double_
{
	return [[[self alloc] initWithDouble: double_] autorelease];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithBool: (bool)bool_
{
	self = [super init];

	_value.unsigned_ = bool_;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(bool);

	return self;
}

- (instancetype)initWithChar: (signed char)sChar
{
	self = [super init];

	_value.signed_ = sChar;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(signed char);

	return self;
}

- (instancetype)initWithShort: (short)sShort
{
	self = [super init];

	_value.signed_ = sShort;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(short);

	return self;
}

- (instancetype)initWithInt: (int)sInt
{
	self = [super init];

	_value.signed_ = sInt;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(int);

	return self;
}

- (instancetype)initWithLong: (long)sLong
{
	self = [super init];

	_value.signed_ = sLong;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(long);

	return self;
}

- (instancetype)initWithLongLong: (long long)sLongLong
{
	self = [super init];

	_value.signed_ = sLongLong;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(long long);

	return self;
}

- (instancetype)initWithUnsignedChar: (unsigned char)uChar
{
	self = [super init];

	_value.unsigned_ = uChar;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned long);

	return self;
}

- (instancetype)initWithUnsignedShort: (unsigned short)uShort
{
	self = [super init];

	_value.unsigned_ = uShort;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned short);

	return self;
}

- (instancetype)initWithUnsignedInt: (unsigned int)uInt
{
	self = [super init];

	_value.unsigned_ = uInt;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned int);

	return self;
}

- (instancetype)initWithUnsignedLong: (unsigned long)uLong
{
	self = [super init];

	_value.unsigned_ = uLong;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned long);

	return self;
}

- (instancetype)initWithUnsignedLongLong: (unsigned long long)uLongLong
{
	self = [super init];

	_value.unsigned_ = uLongLong;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned long long);

	return self;
}

- (instancetype)initWithInt8: (int8_t)int8
{
	self = [super init];

	_value.signed_ = int8;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(int8_t);

	return self;
}

- (instancetype)initWithInt16: (int16_t)int16
{
	self = [super init];

	_value.signed_ = int16;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(int16_t);

	return self;
}

- (instancetype)initWithInt32: (int32_t)int32
{
	self = [super init];

	_value.signed_ = int32;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(int32_t);

	return self;
}

- (instancetype)initWithInt64: (int64_t)int64
{
	self = [super init];

	_value.signed_ = int64;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(int64_t);

	return self;
}

- (instancetype)initWithUInt8: (uint8_t)uInt8
{
	self = [super init];

	_value.unsigned_ = uInt8;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uint8_t);

	return self;
}

- (instancetype)initWithUInt16: (uint16_t)uInt16
{
	self = [super init];

	_value.unsigned_ = uInt16;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uint16_t);

	return self;
}

- (instancetype)initWithUInt32: (uint32_t)uInt32
{
	self = [super init];

	_value.unsigned_ = uInt32;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uint32_t);

	return self;
}

- (instancetype)initWithUInt64: (uint64_t)uInt64
{
	self = [super init];

	_value.unsigned_ = uInt64;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uint64_t);

	return self;
}

- (instancetype)initWithSize: (size_t)size
{
	self = [super init];

	_value.unsigned_ = size;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(size_t);

	return self;
}

- (instancetype)initWithSSize: (ssize_t)sSize
{
	self = [super init];

	_value.signed_ = sSize;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(ssize_t);

	return self;
}

- (instancetype)initWithIntMax: (intmax_t)intMax
{
	self = [super init];

	_value.signed_ = intMax;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(intmax_t);

	return self;
}

- (instancetype)initWithUIntMax: (uintmax_t)uIntMax
{
	self = [super init];

	_value.unsigned_ = uIntMax;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uintmax_t);

	return self;
}

- (instancetype)initWithPtrDiff: (ptrdiff_t)ptrDiff
{
	self = [super init];

	_value.signed_ = ptrDiff;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(ptrdiff_t);

	return self;
}

- (instancetype)initWithIntPtr: (intptr_t)intPtr
{
	self = [super init];

	_value.signed_ = intPtr;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(intptr_t);

	return self;
}

- (instancetype)initWithUIntPtr: (uintptr_t)uIntPtr
{
	self = [super init];

	_value.unsigned_ = uIntPtr;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uintptr_t);

	return self;
}

- (instancetype)initWithFloat: (float)float_
{
	self = [super init];

	_value.float_ = float_;
	_type = OF_NUMBER_TYPE_FLOAT;
	_typeEncoding = @encode(float);

	return self;
}

- (instancetype)initWithDouble: (double)double_
{
	self = [super init];

	_value.float_ = double_;
	_type = OF_NUMBER_TYPE_FLOAT;
	_typeEncoding = @encode(double);

	return self;
}

- (instancetype)initWithSerialization: (OFXMLElement *)element







|

|


|

|


|

|

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

<
<
<
<
<
|

|


<
<
<
<
<
<
<
<
<
<
|

|


|

|


|
<
<
<
|
<
<
|


|

|


|

|


<
<
<
<
<
<
<
<
<
<
|

|
<
<
<
<
<


|

<
<
<
<
<
|


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

|


|

|







|



|






|



|






|



|






|



|






|



|






|



|






|



|






|



|






|



|






|



|






|



|






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



|






|



|






|



|






|



|






|



|







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280




















281





282
283
284
285
286










287
288
289
290
291
292
293
294
295
296
297



298


299
300
301
302
303
304
305
306
307
308
309
310
311










312
313
314





315
316
317
318





319
320
321















322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457




































































































































458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
{
	if (self == [OFNumber class])
		return (id)&placeholder;

	return [super alloc];
}

+ (instancetype)numberWithBool: (bool)value
{
	return [[[self alloc] initWithBool: value] autorelease];
}

+ (instancetype)numberWithChar: (signed char)value
{
	return [[[self alloc] initWithChar: value] autorelease];
}

+ (instancetype)numberWithShort: (short)value
{
	return [[[self alloc] initWithShort: value] autorelease];
}


























+ (instancetype)numberWithInt: (int)value
{
	return [[[self alloc] initWithInt: value] autorelease];
}











+ (instancetype)numberWithLong: (long)value
{
	return [[[self alloc] initWithLong: value] autorelease];
}

+ (instancetype)numberWithLongLong: (long long)value
{
	return [[[self alloc] initWithLongLong: value] autorelease];
}

+ (instancetype)numberWithUnsignedChar: (unsigned char)value



{


	return [[[self alloc] initWithUnsignedChar: value] autorelease];
}

+ (instancetype)numberWithUnsignedShort: (unsigned short)value
{
	return [[[self alloc] initWithUnsignedShort: value] autorelease];
}

+ (instancetype)numberWithUnsignedInt: (unsigned int)value
{
	return [[[self alloc] initWithUnsignedInt: value] autorelease];
}











+ (instancetype)numberWithUnsignedLong: (unsigned long)value
{
	return [[[self alloc] initWithUnsignedLong: value] autorelease];





}

+ (instancetype)numberWithUnsignedLongLong: (unsigned long long)value
{





	return [[[self alloc] initWithUnsignedLongLong: value] autorelease];
}
















+ (instancetype)numberWithFloat: (float)value
{
	return [[[self alloc] initWithFloat: value] autorelease];
}

+ (instancetype)numberWithDouble: (double)value
{
	return [[[self alloc] initWithDouble: value] autorelease];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithBool: (bool)value
{
	self = [super init];

	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(bool);

	return self;
}

- (instancetype)initWithChar: (signed char)value
{
	self = [super init];

	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(signed char);

	return self;
}

- (instancetype)initWithShort: (short)value
{
	self = [super init];

	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(short);

	return self;
}

- (instancetype)initWithInt: (int)value
{
	self = [super init];

	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(int);

	return self;
}

- (instancetype)initWithLong: (long)value
{
	self = [super init];

	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(long);

	return self;
}

- (instancetype)initWithLongLong: (long long)value
{
	self = [super init];

	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(long long);

	return self;
}

- (instancetype)initWithUnsignedChar: (unsigned char)value
{
	self = [super init];

	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned long);

	return self;
}

- (instancetype)initWithUnsignedShort: (unsigned short)value
{
	self = [super init];

	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned short);

	return self;
}

- (instancetype)initWithUnsignedInt: (unsigned int)value
{
	self = [super init];

	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned int);

	return self;
}

- (instancetype)initWithUnsignedLong: (unsigned long)value
{
	self = [super init];

	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned long);

	return self;
}

- (instancetype)initWithUnsignedLongLong: (unsigned long long)value
{
	self = [super init];

	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned long long);

	return self;
}





































































































































- (instancetype)initWithPtrDiff: (ptrdiff_t)value
{
	self = [super init];

	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(ptrdiff_t);

	return self;
}

- (instancetype)initWithIntPtr: (intptr_t)value
{
	self = [super init];

	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(intptr_t);

	return self;
}

- (instancetype)initWithUIntPtr: (uintptr_t)value
{
	self = [super init];

	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uintptr_t);

	return self;
}

- (instancetype)initWithFloat: (float)value
{
	self = [super init];

	_value.float_ = value;
	_type = OF_NUMBER_TYPE_FLOAT;
	_typeEncoding = @encode(float);

	return self;
}

- (instancetype)initWithDouble: (double)value
{
	self = [super init];

	_value.float_ = value;
	_type = OF_NUMBER_TYPE_FLOAT;
	_typeEncoding = @encode(double);

	return self;
}

- (instancetype)initWithSerialization: (OFXMLElement *)element
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
			OFString *stringValue = element.stringValue;
			if ([stringValue isEqual: @"true"])
				self = [self initWithBool: true];
			else if ([stringValue isEqual: @"false"])
				self = [self initWithBool: false];
			else
				@throw [OFInvalidArgumentException exception];
		} else if ([typeString isEqual: @"float"])






			self = [self initWithDouble: OF_BSWAP_DOUBLE_IF_LE(
			    OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE(
			    (uint64_t)element.hexadecimalValue)))];
		else if ([typeString isEqual: @"signed"])
			self = [self initWithIntMax: element.doubleValue];
		else if ([typeString isEqual: @"unsigned"])
			/*
			 * FIXME: This will fail if the value is bigger than
			 *	  INTMAX_MAX!
			 */
			self = [self initWithUIntMax: element.decimalValue];

		else
			@throw [OFInvalidArgumentException exception];

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







|
>
>
>
>
>
>

|
<
|
|

<
<
<
<
|
>







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
			OFString *stringValue = element.stringValue;
			if ([stringValue isEqual: @"true"])
				self = [self initWithBool: true];
			else if ([stringValue isEqual: @"false"])
				self = [self initWithBool: false];
			else
				@throw [OFInvalidArgumentException exception];
		} else if ([typeString isEqual: @"float"]) {
			unsigned long long value =
			    [element unsignedLongLongValueWithBase: 16];

			if (value > UINT64_MAX)
				@throw [OFOutOfRangeException exception];

			self = [self initWithDouble: OF_BSWAP_DOUBLE_IF_LE(
			    OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE(value)))];

		} else if ([typeString isEqual: @"signed"])
			self = [self initWithLongLong: element.longLongValue];
		else if ([typeString isEqual: @"unsigned"])




			self = [self initWithUnsignedLongLong:
			    element.unsignedLongLongValue];
		else
			@throw [OFInvalidArgumentException exception];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
}

- (unsigned long long)unsignedLongLongValue
{
	RETURN_AS(unsigned long long)
}

- (int8_t)int8Value
{
	RETURN_AS(int8_t)
}

- (int16_t)int16Value
{
	RETURN_AS(int16_t)
}

- (int32_t)int32Value
{
	RETURN_AS(int32_t)
}

- (int64_t)int64Value
{
	RETURN_AS(int64_t)
}

- (uint8_t)uInt8Value
{
	RETURN_AS(uint8_t)
}

- (uint16_t)uInt16Value
{
	RETURN_AS(uint16_t)
}

- (uint32_t)uInt32Value
{
	RETURN_AS(uint32_t)
}

- (uint64_t)uInt64Value
{
	RETURN_AS(uint64_t)
}

- (size_t)sizeValue
{
	RETURN_AS(size_t)
}

- (ssize_t)sSizeValue
{
	RETURN_AS(ssize_t)
}

- (intmax_t)intMaxValue
{
	RETURN_AS(intmax_t)
}

- (uintmax_t)uIntMaxValue
{
	RETURN_AS(uintmax_t)
}

- (ptrdiff_t)ptrDiffValue
{
	RETURN_AS(ptrdiff_t)
}

- (intptr_t)intPtrValue
{
	RETURN_AS(intptr_t)
}

- (uintptr_t)uIntPtrValue
{
	RETURN_AS(uintptr_t)
}

- (float)floatValue
{
	RETURN_AS(float)
}

- (double)doubleValue
{







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







658
659
660
661
662
663
664











































































665
666
667
668
669
670
671
}

- (unsigned long long)unsignedLongLongValue
{
	RETURN_AS(unsigned long long)
}












































































- (float)floatValue
{
	RETURN_AS(float)
}

- (double)doubleValue
{
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
			return false;

		return (value1 == value2);
	}

	if (_type == OF_NUMBER_TYPE_SIGNED ||
	    number->_type == OF_NUMBER_TYPE_SIGNED)
		return (number.intMaxValue == self.intMaxValue);

	return (number.uIntMaxValue == self.uIntMaxValue);
}

- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	OFNumber *number;

	if (![(id)object isKindOfClass: [OFNumber class]])







|

|







696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
			return false;

		return (value1 == value2);
	}

	if (_type == OF_NUMBER_TYPE_SIGNED ||
	    number->_type == OF_NUMBER_TYPE_SIGNED)
		return (number.longLongValue == self.longLongValue);

	return (number.unsignedLongLongValue == self.unsignedLongLongValue);
}

- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	OFNumber *number;

	if (![(id)object isKindOfClass: [OFNumber class]])
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
			return OF_ORDERED_DESCENDING;
		if (double1 < double2)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
	} else if (_type == OF_NUMBER_TYPE_SIGNED ||
	    number->_type == OF_NUMBER_TYPE_SIGNED) {
		intmax_t int1 = self.intMaxValue;
		intmax_t int2 = number.intMaxValue;

		if (int1 > int2)
			return OF_ORDERED_DESCENDING;
		if (int1 < int2)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
	} else {
		uintmax_t uint1 = self.uIntMaxValue;
		uintmax_t uint2 = number.uIntMaxValue;

		if (uint1 > uint2)
			return OF_ORDERED_DESCENDING;
		if (uint1 < uint2)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;







|
|








|
|







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
			return OF_ORDERED_DESCENDING;
		if (double1 < double2)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
	} else if (_type == OF_NUMBER_TYPE_SIGNED ||
	    number->_type == OF_NUMBER_TYPE_SIGNED) {
		long long int1 = self.longLongValue;
		long long int2 = number.longLongValue;

		if (int1 > int2)
			return OF_ORDERED_DESCENDING;
		if (int1 < int2)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
	} else {
		unsigned long long uint1 = self.unsignedLongLongValue;
		unsigned long long uint2 = number.unsignedLongLongValue;

		if (uint1 > uint2)
			return OF_ORDERED_DESCENDING;
		if (uint1 < uint2)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
		if (isnan(self.doubleValue))
			return 0;

		d = OF_BSWAP_DOUBLE_IF_BE(self.doubleValue);

		for (uint_fast8_t i = 0; i < sizeof(double); i++)
			OF_HASH_ADD(hash, ((char *)&d)[i]);
	} else if (type == OF_NUMBER_TYPE_SIGNED) {
		intmax_t v = self.intMaxValue * -1;

		while (v != 0) {
			OF_HASH_ADD(hash, v & 0xFF);
			v >>= 8;
		}

		OF_HASH_ADD(hash, 1);
	} else if (type == OF_NUMBER_TYPE_UNSIGNED) {
		uintmax_t v = self.uIntMaxValue;

		while (v != 0) {
			OF_HASH_ADD(hash, v & 0xFF);
			v >>= 8;
		}
	} else
		@throw [OFInvalidFormatException exception];

	OF_HASH_FINALIZE(hash);

	return hash;







|
<
<
<
<
<
<
<
<
|
|

|
|
|







762
763
764
765
766
767
768
769








770
771
772
773
774
775
776
777
778
779
780
781
782
		if (isnan(self.doubleValue))
			return 0;

		d = OF_BSWAP_DOUBLE_IF_BE(self.doubleValue);

		for (uint_fast8_t i = 0; i < sizeof(double); i++)
			OF_HASH_ADD(hash, ((char *)&d)[i]);
	} else if (type == OF_NUMBER_TYPE_SIGNED ||








	    type == OF_NUMBER_TYPE_UNSIGNED) {
		unsigned long long value = self.unsignedLongLongValue;

		while (value != 0) {
			OF_HASH_ADD(hash, value & 0xFF);
			value >>= 8;
		}
	} else
		@throw [OFInvalidFormatException exception];

	OF_HASH_FINALIZE(hash);

	return hash;
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
- (OFString *)stringValue
{
	if (*_typeEncoding == 'B')
		return (_value.unsigned_ ? @"true" : @"false");
	if (_type == OF_NUMBER_TYPE_FLOAT)
		return [OFString stringWithFormat: @"%g", _value.float_];
	if (_type == OF_NUMBER_TYPE_SIGNED)
		return [OFString stringWithFormat: @"%jd", _value.signed_];
	if (_type == OF_NUMBER_TYPE_UNSIGNED)
		return [OFString stringWithFormat: @"%ju", _value.unsigned_];

	@throw [OFInvalidFormatException exception];
}

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







|

|







795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
- (OFString *)stringValue
{
	if (*_typeEncoding == 'B')
		return (_value.unsigned_ ? @"true" : @"false");
	if (_type == OF_NUMBER_TYPE_FLOAT)
		return [OFString stringWithFormat: @"%g", _value.float_];
	if (_type == OF_NUMBER_TYPE_SIGNED)
		return [OFString stringWithFormat: @"%lld", _value.signed_];
	if (_type == OF_NUMBER_TYPE_UNSIGNED)
		return [OFString stringWithFormat: @"%llu", _value.unsigned_];

	@throw [OFInvalidFormatException exception];
}

- (OFXMLElement *)XMLElementBySerializing
{
	void *pool = objc_autoreleasePoolPush();
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
		data = [OFMutableData dataWithItemSize: 1
					      capacity: 9];

		[data addItem: &type];
		[data addItems: &tmp
			 count: sizeof(tmp)];
	} else if (_type == OF_NUMBER_TYPE_SIGNED) {
		intmax_t value = self.intMaxValue;

		if (value >= -32 && value < 0) {
			uint8_t tmp = 0xE0 | ((uint8_t)(value - 32) & 0x1F);

			data = [OFMutableData dataWithItems: &tmp
						      count: 1];
		} else if (value >= INT8_MIN && value <= INT8_MAX) {







|







901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
		data = [OFMutableData dataWithItemSize: 1
					      capacity: 9];

		[data addItem: &type];
		[data addItems: &tmp
			 count: sizeof(tmp)];
	} else if (_type == OF_NUMBER_TYPE_SIGNED) {
		long long value = self.longLongValue;

		if (value >= -32 && value < 0) {
			uint8_t tmp = 0xE0 | ((uint8_t)(value - 32) & 0x1F);

			data = [OFMutableData dataWithItems: &tmp
						      count: 1];
		} else if (value >= INT8_MIN && value <= INT8_MAX) {
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398

			[data addItem: &type];
			[data addItems: &tmp
				 count: sizeof(tmp)];
		} else
			@throw [OFOutOfRangeException exception];
	} else if (_type == OF_NUMBER_TYPE_UNSIGNED) {
		uintmax_t value = self.uIntMaxValue;

		if (value <= 127) {
			uint8_t tmp = ((uint8_t)value & 0x7F);

			data = [OFMutableData dataWithItems: &tmp
						      count: 1];
		} else if (value <= UINT8_MAX) {







|







950
951
952
953
954
955
956
957
958
959
960
961
962
963
964

			[data addItem: &type];
			[data addItems: &tmp
				 count: sizeof(tmp)];
		} else
			@throw [OFOutOfRangeException exception];
	} else if (_type == OF_NUMBER_TYPE_UNSIGNED) {
		unsigned long long value = self.unsignedLongLongValue;

		if (value <= 127) {
			uint8_t tmp = ((uint8_t)value & 0x7F);

			data = [OFMutableData dataWithItems: &tmp
						      count: 1];
		} else if (value <= UINT8_MAX) {

Modified src/OFSettings.h from [2c70a1f69b] to [a4eaab9bfc].

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

/*!
 * @brief Sets the specified path to the specified integer.
 *
 * @param integer The integer to set
 * @param path The path to store the integer at
 */
- (void)setInteger: (intmax_t)integer
	   forPath: (OFString *)path;

/*!
 * @brief Sets the specified path to the specified bool.
 *
 * @param bool_ The bool to set
 * @param path The path to store the bool at







|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

/*!
 * @brief Sets the specified path to the specified integer.
 *
 * @param integer The integer to set
 * @param path The path to store the integer at
 */
- (void)setInteger: (long long)integer
	   forPath: (OFString *)path;

/*!
 * @brief Sets the specified path to the specified bool.
 *
 * @param bool_ The bool to set
 * @param path The path to store the bool at
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
 * @brief Returns the integer for the specified path, or the default value if
 *	  the path does not exist.
 *
 * @param path The path for which the integer value should be returned
 * @param defaultValue The default value to return if the path does not exist
 * @return The integer value of the specified path
 */
- (intmax_t)integerForPath: (OFString *)path
	      defaultValue: (intmax_t)defaultValue;

/*!
 * @brief Returns the bool for the specified path, or the default value if the
 *	  path does not exist.
 *
 * @param path The path for which the bool value should be returned
 * @param defaultValue The default value to return if the path does not exist







|
|







146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
 * @brief Returns the integer for the specified path, or the default value if
 *	  the path does not exist.
 *
 * @param path The path for which the integer value should be returned
 * @param defaultValue The default value to return if the path does not exist
 * @return The integer value of the specified path
 */
- (long long)integerForPath: (OFString *)path
	       defaultValue: (long long)defaultValue;

/*!
 * @brief Returns the bool for the specified path, or the default value if the
 *	  path does not exist.
 *
 * @param path The path for which the bool value should be returned
 * @param defaultValue The default value to return if the path does not exist

Modified src/OFSettings.m from [760331490f] to [5da0b0a891].

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

- (void)setString: (OFString *)string
	  forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setInteger: (intmax_t)integer
	   forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setBool: (bool)bool_
	forPath: (OFString *)path







|







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

- (void)setString: (OFString *)string
	  forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setInteger: (long long)integer
	   forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setBool: (bool)bool_
	forPath: (OFString *)path
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

- (OFString *)stringForPath: (OFString *)path
	       defaultValue: (OFString *)defaultValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (intmax_t)integerForPath: (OFString *)path
	      defaultValue: (intmax_t)defaultValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (bool)boolForPath: (OFString *)path
       defaultValue: (bool)defaultValue
{







|
|







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

- (OFString *)stringForPath: (OFString *)path
	       defaultValue: (OFString *)defaultValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (long long)integerForPath: (OFString *)path
	       defaultValue: (long long)defaultValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (bool)boolForPath: (OFString *)path
       defaultValue: (bool)defaultValue
{

Renamed and modified src/OFString+JSONValue.h [311031a35c] to src/OFString+JSONParsing.h [bc722e0fb3].

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

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFString_JSONValue_reference;
#ifdef __cplusplus
}
#endif

@interface OFString (JSONValue)
/*!
 * @brief The string interpreted as JSON and parsed as an object.
 *
 * @note This also allows parsing JSON5, an extension of JSON. See
 *	 http://json5.org/ for more details.
 *
 * @warning Although not specified by the JSON specification, this can also
 *          return primitives like strings and numbers. The rationale behind
 *          this is that most JSON parsers allow JSON data just consisting of a
 *          single primitive, leading to real world JSON files sometimes only
 *          consisting of a single primitive. Therefore, you should not make any
 *          assumptions about the object returned by this method if you don't
 *          want your program to terminate due to a message not understood, but
 *          instead check the returned object using @ref isKindOfClass:.
 */
@property (readonly, nonatomic) id JSONValue;

/*!
 * @brief Creates an object from the JSON value of the string.
 *
 * @note This also allows parsing JSON5, an extension of JSON. See
 *	 http://json5.org/ for more details.
 *







|




|















|







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

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFString_JSONParsing_reference;
#ifdef __cplusplus
}
#endif

@interface OFString (JSONParsing)
/*!
 * @brief The string interpreted as JSON and parsed as an object.
 *
 * @note This also allows parsing JSON5, an extension of JSON. See
 *	 http://json5.org/ for more details.
 *
 * @warning Although not specified by the JSON specification, this can also
 *          return primitives like strings and numbers. The rationale behind
 *          this is that most JSON parsers allow JSON data just consisting of a
 *          single primitive, leading to real world JSON files sometimes only
 *          consisting of a single primitive. Therefore, you should not make any
 *          assumptions about the object returned by this method if you don't
 *          want your program to terminate due to a message not understood, but
 *          instead check the returned object using @ref isKindOfClass:.
 */
@property (readonly, nonatomic) id objectByParsingJSON;

/*!
 * @brief Creates an object from the JSON value of the string.
 *
 * @note This also allows parsing JSON5, an extension of JSON. See
 *	 http://json5.org/ for more details.
 *
61
62
63
64
65
66
67
68
69
70
71
 *          instead check the returned object using @ref isKindOfClass:.
 *
 * @param depthLimit The maximum depth the parser should accept (defaults to 32
 *		     if not specified, 0 means no limit (insecure!))
 *
 * @return An object
 */
- (id)JSONValueWithDepthLimit: (size_t)depthLimit;
@end

OF_ASSUME_NONNULL_END







|



61
62
63
64
65
66
67
68
69
70
71
 *          instead check the returned object using @ref isKindOfClass:.
 *
 * @param depthLimit The maximum depth the parser should accept (defaults to 32
 *		     if not specified, 0 means no limit (insecure!))
 *
 * @return An object
 */
- (id)objectByParsingJSONWithDepthLimit: (size_t)depthLimit;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFString+JSONValue.m [ac798fd712] to src/OFString+JSONParsing.m [706b49d04b].

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdlib.h>
#include <string.h>

#include <math.h>

#include <assert.h>

#import "OFString+JSONValue.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFNumber.h"
#import "OFNull.h"

#import "OFInvalidJSONException.h"

int _OFString_JSONValue_reference;

static id nextObject(const char **pointer, const char *stop, size_t *line,
    size_t depthLimit);

static void
skipWhitespaces(const char **pointer, const char *stop, size_t *line)
{







|







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdlib.h>
#include <string.h>

#include <math.h>

#include <assert.h>

#import "OFString+JSONParsing.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFNumber.h"
#import "OFNull.h"

#import "OFInvalidJSONException.h"

int _OFString_JSONParsing_reference;

static id nextObject(const char **pointer, const char *stop, size_t *line,
    size_t depthLimit);

static void
skipWhitespaces(const char **pointer, const char *stop, size_t *line)
{
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

	return dictionary;
}

static inline OFNumber *
parseNumber(const char **pointer, const char *stop, size_t *line)
{
	bool isHex = (*pointer + 1 < stop && (*pointer)[1] == 'x');
	bool hasDecimal = false;
	size_t i;
	OFString *string;
	OFNumber *number;

	for (i = 0; *pointer + i < stop; i++) {
		if ((*pointer)[i] == '.')







|







524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

	return dictionary;
}

static inline OFNumber *
parseNumber(const char **pointer, const char *stop, size_t *line)
{
	bool isNegative = (*pointer < stop && (*pointer)[0] == '-');
	bool hasDecimal = false;
	size_t i;
	OFString *string;
	OFNumber *number;

	for (i = 0; *pointer + i < stop; i++) {
		if ((*pointer)[i] == '.')
553
554
555
556
557
558
559
560
561
562
563
564
565
566



567
568
569
570
571
572
573
574
575
576
					       length: i];
	*pointer += i;

	@try {
		if (hasDecimal)
			number = [OFNumber numberWithDouble:
			    string.doubleValue];
		else if (isHex)
			number = [OFNumber numberWithIntMax:
			    string.hexadecimalValue];
		else if ([string isEqual: @"Infinity"])
			number = [OFNumber numberWithDouble: INFINITY];
		else if ([string isEqual: @"-Infinity"])
			number = [OFNumber numberWithDouble: -INFINITY];



		else
			number = [OFNumber numberWithIntMax:
			    string.decimalValue];
	} @finally {
		[string release];
	}

	return number;
}








<
<
<




>
>
>

|
|







553
554
555
556
557
558
559



560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
					       length: i];
	*pointer += i;

	@try {
		if (hasDecimal)
			number = [OFNumber numberWithDouble:
			    string.doubleValue];



		else if ([string isEqual: @"Infinity"])
			number = [OFNumber numberWithDouble: INFINITY];
		else if ([string isEqual: @"-Infinity"])
			number = [OFNumber numberWithDouble: -INFINITY];
		else if (isNegative)
			number = [OFNumber numberWithLongLong:
			    [string longLongValueWithBase: 0]];
		else
			number = [OFNumber numberWithUnsignedLongLong:
			    [string unsignedLongLongValueWithBase: 0]];
	} @finally {
		[string release];
	}

	return number;
}

637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
	case 'I':
		return parseNumber(pointer, stop, line);
	default:
		return nil;
	}
}

@implementation OFString (JSONValue)
- (id)JSONValue
{
	return [self JSONValueWithDepthLimit: 32];
}

- (id)JSONValueWithDepthLimit: (size_t)depthLimit
{
	void *pool = objc_autoreleasePoolPush();
	const char *pointer = self.UTF8String;
	const char *stop = pointer + self.UTF8StringLength;
	id object;
	size_t line = 1;








|
|

|


|







637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
	case 'I':
		return parseNumber(pointer, stop, line);
	default:
		return nil;
	}
}

@implementation OFString (JSONParsing)
- (id)objectByParsingJSON
{
	return [self objectByParsingJSONWithDepthLimit: 32];
}

- (id)objectByParsingJSONWithDepthLimit: (size_t)depthLimit
{
	void *pool = objc_autoreleasePoolPush();
	const char *pointer = self.UTF8String;
	const char *stop = pointer + self.UTF8StringLength;
	id object;
	size_t line = 1;

Renamed and modified src/OFString+PropertyListValue.h [6c64f3e60f] to src/OFString+PropertyListParsing.h [e83b475868].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#import "OFString.h"

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFString_PropertyListValue_reference;
#ifdef __cplusplus
}
#endif

@interface OFString (PropertyListValue)
/*!
 * @brief The string interpreted as a property list and parsed as an object.
 *
 * @note This only supports XML property lists!
 */
@property (readonly, nonatomic) id propertyListValue;
@end

OF_ASSUME_NONNULL_END







|




|





|



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#import "OFString.h"

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFString_PropertyListParsing_reference;
#ifdef __cplusplus
}
#endif

@interface OFString (PropertyListParsing)
/*!
 * @brief The string interpreted as a property list and parsed as an object.
 *
 * @note This only supports XML property lists!
 */
@property (readonly, nonatomic) id objectByParsingPropertyList;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFString+PropertyListValue.m [30b7ec9161] to src/OFString+PropertyListParsing.m [3c0b0b5b63].

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
 * 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 "OFString+PropertyListValue.h"
#import "OFArray.h"
#import "OFData.h"
#import "OFDate.h"
#import "OFDictionary.h"
#import "OFNumber.h"
#import "OFXMLAttribute.h"
#import "OFXMLElement.h"

#import "OFInvalidFormatException.h"
#import "OFUnsupportedVersionException.h"

int _OFString_PropertyListValue_reference;

static id parseElement(OFXMLElement *element);

static OFArray *
parseArrayElement(OFXMLElement *element)
{
	OFMutableArray *ret = [OFMutableArray array];







|











|







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
 * 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 "OFString+PropertyListParsing.h"
#import "OFArray.h"
#import "OFData.h"
#import "OFDate.h"
#import "OFDictionary.h"
#import "OFNumber.h"
#import "OFXMLAttribute.h"
#import "OFXMLElement.h"

#import "OFInvalidFormatException.h"
#import "OFUnsupportedVersionException.h"

int _OFString_PropertyListParsing_reference;

static id parseElement(OFXMLElement *element);

static OFArray *
parseArrayElement(OFXMLElement *element)
{
	OFMutableArray *ret = [OFMutableArray array];
121
122
123
124
125
126
127









128







129
130
131
132
133
134
135
{
	return [OFNumber numberWithDouble: element.doubleValue];
}

static OFNumber *
parseIntegerElement(OFXMLElement *element)
{









	return [OFNumber numberWithIntMax: element.decimalValue];







}

static id
parseElement(OFXMLElement *element)
{
	OFString *elementName;








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







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
{
	return [OFNumber numberWithDouble: element.doubleValue];
}

static OFNumber *
parseIntegerElement(OFXMLElement *element)
{
	void *pool = objc_autoreleasePoolPush();
	OFString *stringValue;
	OFNumber *ret;

	stringValue = element.stringValue.stringByDeletingEnclosingWhitespaces;

	if ([stringValue hasPrefix: @"-"])
		ret = [OFNumber numberWithLongLong: stringValue.longLongValue];
	else
		ret = [OFNumber numberWithUnsignedLongLong:
		    stringValue.unsignedLongLongValue];

	[ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

static id
parseElement(OFXMLElement *element)
{
	OFString *elementName;

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
		return parseRealElement(element);
	else if ([elementName isEqual: @"integer"])
		return parseIntegerElement(element);
	else
		@throw [OFInvalidFormatException exception];
}

@implementation OFString (PropertyListValue)
- (id)propertyListValue
{
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *rootElement = [OFXMLElement elementWithXMLString: self];
	OFXMLAttribute *versionAttribute;
	OFArray OF_GENERIC(OFXMLElement *) *elements;
	id ret;








|
|







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
		return parseRealElement(element);
	else if ([elementName isEqual: @"integer"])
		return parseIntegerElement(element);
	else
		@throw [OFInvalidFormatException exception];
}

@implementation OFString (PropertyListParsing)
- (id)objectByParsingPropertyList
{
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *rootElement = [OFXMLElement elementWithXMLString: self];
	OFXMLAttribute *versionAttribute;
	OFArray OF_GENERIC(OFXMLElement *) *elements;
	id ret;

Modified src/OFString+Serialization.m from [49a22d9861] to [0b468db6b6].

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
		@throw [OFInvalidArgumentException exception];
	}

	version = [root attributeForName: @"version"].stringValue;
	if (version == nil)
		@throw [OFInvalidArgumentException exception];

	if (version.decimalValue != 1)
		@throw [OFUnsupportedVersionException
		    exceptionWithVersion: version];

	elements = [root elementsForNamespace: OF_SERIALIZATION_NS];

	if (elements.count != 1)
		@throw [OFInvalidArgumentException exception];







|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
		@throw [OFInvalidArgumentException exception];
	}

	version = [root attributeForName: @"version"].stringValue;
	if (version == nil)
		@throw [OFInvalidArgumentException exception];

	if (version.unsignedLongLongValue != 1)
		@throw [OFUnsupportedVersionException
		    exceptionWithVersion: version];

	elements = [root elementsForNamespace: OF_SERIALIZATION_NS];

	if (elements.count != 1)
		@throw [OFInvalidArgumentException exception];

Modified src/OFString.h from [18fc9bbd71] to [7689800b1d].

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
 * @note This only considers spaces, tabs and newlines to be word delimiters!
 *	 Also note that this might change in the future to all word delimiters
 *	 specified by Unicode!
 */
@property (readonly, nonatomic) OFString *capitalizedString;

/*!
 * @brief The decimal value of the string as an `intmax_t`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into an `intmax_t`, an
 * @ref OFOutOfRangeException is thrown.
 */
@property (readonly, nonatomic) intmax_t decimalValue;

/*!
 * @brief The hexadecimal value of the string as an `uintmax_t`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into an `uintmax_t`, an
 * @ref OFOutOfRangeException is thrown.
 */
@property (readonly, nonatomic) uintmax_t hexadecimalValue;

/*!
 * @brief The octal value of the string as an `uintmax_t`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into an `uintmax_t`, an
 * @ref OFOutOfRangeException is thrown.
 */
@property (readonly, nonatomic) uintmax_t octalValue;

/*!
 * @brief The float value of the string as a float.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 */







|






|


|


|






|


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







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
 * @note This only considers spaces, tabs and newlines to be word delimiters!
 *	 Also note that this might change in the future to all word delimiters
 *	 specified by Unicode!
 */
@property (readonly, nonatomic) OFString *capitalizedString;

/*!
 * @brief The decimal value of the string as a `long long`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into a `long long`, an
 * @ref OFOutOfRangeException is thrown.
 */
@property (readonly, nonatomic) long long longLongValue;

/*!
 * @brief The decimal value of the string as an `unsigned long long`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into an `unsigned long long`, an
 * @ref OFOutOfRangeException is thrown.
 */













@property (readonly, nonatomic) unsigned long long unsignedLongLongValue;

/*!
 * @brief The float value of the string as a float.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 */
1021
1022
1023
1024
1025
1026
1027







































1028
1029
1030
1031
1032
1033
1034
 * @brief Creates a substring with the specified range.
 *
 * @param range The range of the substring
 * @return The substring as a new autoreleased OFString
 */
- (OFString *)substringWithRange: (of_range_t)range;








































/*!
 * @brief Creates a new string by appending another string.
 *
 * @param string The string to append
 * @return A new, autoreleased OFString with the specified string appended
 */
- (OFString *)stringByAppendingString: (OFString *)string;







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







1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
 * @brief Creates a substring with the specified range.
 *
 * @param range The range of the substring
 * @return The substring as a new autoreleased OFString
 */
- (OFString *)substringWithRange: (of_range_t)range;

/*!
 * @brief The value of the string in the specified base as a `long long`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into a `long long`, an
 * @ref OFOutOfRangeException is thrown.
 *
 * @param base The base to use. If the base is 0, base 16 is assumed if the
 * 	       string starts with 0x (after stripping white spaces). If the
 * 	       string starts with 0, base 8 is assumed. Otherwise, base 10 is
 * 	       assumed.
 * @return The value of the string in the specified base
 */
- (long long)longLongValueWithBase: (int)base;

/*!
 * @brief The value of the string in the specified base as an
 *	  `unsigned long long`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into an `unsigned long long`, an
 * @ref OFOutOfRangeException is thrown.
 *
 * @param base The base to use. If the base is 0, base 16 is assumed if the
 * 	       string starts with 0x (after stripping white spaces). If the
 * 	       string starts with 0, base 8 is assumed. Otherwise, base 10 is
 * 	       assumed.
 * @return The value of the string in the specified base
 */
- (unsigned long long)unsignedLongLongValueWithBase: (int)base;

/*!
 * @brief Creates a new string by appending another string.
 *
 * @param string The string to append
 * @return A new, autoreleased OFString with the specified string appended
 */
- (OFString *)stringByAppendingString: (OFString *)string;
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268

OF_ASSUME_NONNULL_END

#include "OFConstantString.h"
#include "OFMutableString.h"
#ifdef __OBJC__
# import "OFString+CryptoHashing.h"
# import "OFString+JSONValue.h"
# ifdef OF_HAVE_FILES
#  import "OFString+PathAdditions.h"
# endif
# import "OFString+PropertyListValue.h"
# import "OFString+Serialization.h"
# import "OFString+URLEncoding.h"
# import "OFString+XMLEscaping.h"
# import "OFString+XMLUnescaping.h"
#endif

#if defined(__OBJC__) && !defined(NSINTEGER_DEFINED) && !__has_feature(modules)







|



|







1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294

OF_ASSUME_NONNULL_END

#include "OFConstantString.h"
#include "OFMutableString.h"
#ifdef __OBJC__
# import "OFString+CryptoHashing.h"
# import "OFString+JSONParsing.h"
# ifdef OF_HAVE_FILES
#  import "OFString+PathAdditions.h"
# endif
# import "OFString+PropertyListParsing.h"
# import "OFString+Serialization.h"
# import "OFString+URLEncoding.h"
# import "OFString+XMLEscaping.h"
# import "OFString+XMLUnescaping.h"
#endif

#if defined(__OBJC__) && !defined(NSINTEGER_DEFINED) && !__has_feature(modules)

Modified src/OFString.m from [e1b9c425c7] to [ed5bfcb060].

13
14
15
16
17
18
19

20
21
22
23
24
25
26
 * 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 <errno.h>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L)







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * 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 <ctype.h>
#include <errno.h>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L)
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
    size_t, bool);

/* References for static linking */
void
_references_to_categories_of_OFString(void)
{
	_OFString_CryptoHashing_reference = 1;
	_OFString_JSONValue_reference = 1;
#ifdef OF_HAVE_FILES
	_OFString_PathAdditions_reference = 1;
#endif
	_OFString_PropertyListValue_reference = 1;
	_OFString_Serialization_reference = 1;
	_OFString_URLEncoding_reference = 1;
	_OFString_XMLEscaping_reference = 1;
	_OFString_XMLUnescaping_reference = 1;
}

void







|



|







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
    size_t, bool);

/* References for static linking */
void
_references_to_categories_of_OFString(void)
{
	_OFString_CryptoHashing_reference = 1;
	_OFString_JSONParsing_reference = 1;
#ifdef OF_HAVE_FILES
	_OFString_PathAdditions_reference = 1;
#endif
	_OFString_PropertyListParsing_reference = 1;
	_OFString_Serialization_reference = 1;
	_OFString_URLEncoding_reference = 1;
	_OFString_XMLEscaping_reference = 1;
	_OFString_XMLUnescaping_reference = 1;
}

void
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
				   encoding: OF_STRING_ENCODING_UTF_8];
}

- (instancetype)initWithContentsOfFile: (OFString *)path
			      encoding: (of_string_encoding_t)encoding
{
	char *tmp;
	uintmax_t fileSize;

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFFile *file = nil;

		@try {
			fileSize = [[OFFileManager defaultManager]
			    attributesOfItemAtPath: path].fileSize;
		} @catch (OFRetrieveItemAttributesFailedException *e) {
			@throw [OFOpenItemFailedException
			    exceptionWithPath: path
					 mode: @"r"
					errNo: e.errNo];
		}

		objc_autoreleasePoolPop(pool);

# if UINTMAX_MAX > SIZE_MAX
		if (fileSize > SIZE_MAX)
			@throw [OFOutOfRangeException exception];
#endif

		/*
		 * We need one extra byte for the terminating zero if we want
		 * to use -[initWithUTF8StringNoCopy:length:freeWhenDone:].







|

















|







987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
				   encoding: OF_STRING_ENCODING_UTF_8];
}

- (instancetype)initWithContentsOfFile: (OFString *)path
			      encoding: (of_string_encoding_t)encoding
{
	char *tmp;
	unsigned long long fileSize;

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFFile *file = nil;

		@try {
			fileSize = [[OFFileManager defaultManager]
			    attributesOfItemAtPath: path].fileSize;
		} @catch (OFRetrieveItemAttributesFailedException *e) {
			@throw [OFOpenItemFailedException
			    exceptionWithPath: path
					 mode: @"r"
					errNo: e.errNo];
		}

		objc_autoreleasePoolPop(pool);

# if ULLONG_MAX > SIZE_MAX
		if (fileSize > SIZE_MAX)
			@throw [OFOutOfRangeException exception];
#endif

		/*
		 * We need one extra byte for the terminating zero if we want
		 * to use -[initWithUTF8StringNoCopy:length:freeWhenDone:].
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327

2328
2329
2330
2331
2332
2333
2334
2335

2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350



2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376

2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512



2513
2514
2515
2516

2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563



2564
2565
2566

2567
2568
2569
2570
2571
2572
2573
2574
	[array makeImmutable];

	objc_autoreleasePoolPop(pool);

	return array;
}

- (intmax_t)decimalValue
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = self.characters;
	size_t i = 0, length = self.length;
	intmax_t value = 0;
	bool expectWhitespace = false;

	while (length > 0 && of_ascii_isspace(*characters)) {
		characters++;
		length--;
	}


	if (length == 0) {
		objc_autoreleasePoolPop(pool);
		return 0;
	}

	if (characters[0] == '-' || characters[0] == '+')
		i++;


	for (; i < length; i++) {
		if (expectWhitespace) {
			if (of_ascii_isspace(characters[i]))
				continue;

			@throw [OFInvalidFormatException exception];
		}

		if (characters[i] >= '0' && characters[i] <= '9') {
			if (INTMAX_MAX / 10 < value ||
			    INTMAX_MAX - value * 10 < characters[i] - '0')
				@throw [OFOutOfRangeException exception];

			value = (value * 10) + (characters[i] - '0');



		} else if (of_ascii_isspace(characters[i]))
			expectWhitespace = true;
		else
			@throw [OFInvalidFormatException exception];
	}

	if (characters[0] == '-')
		value *= -1;

	objc_autoreleasePoolPop(pool);

	return value;
}

- (uintmax_t)hexadecimalValue
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = self.characters;
	size_t i = 0, length = self.length;
	uintmax_t value = 0;
	bool expectWhitespace = false, foundValue = false;

	while (length > 0 && of_ascii_isspace(*characters)) {
		characters++;
		length--;
	}


	if (length == 0) {
		objc_autoreleasePoolPop(pool);
		return 0;
	}

	if (length >= 2 && characters[0] == '0' && characters[1] == 'x')
		i = 2;
	else if (length >= 1 && (characters[0] == 'x' || characters[0] == '$'))
		i = 1;

	for (; i < length; i++) {
		uintmax_t newValue;

		if (expectWhitespace) {
			if (of_ascii_isspace(characters[i]))
				continue;

			@throw [OFInvalidFormatException exception];
		}

		if (characters[i] >= '0' && characters[i] <= '9') {
			newValue = (value << 4) | (characters[i] - '0');
			foundValue = true;
		} else if (characters[i] >= 'A' && characters[i] <= 'F') {
			newValue = (value << 4) | (characters[i] - 'A' + 10);
			foundValue = true;
		} else if (characters[i] >= 'a' && characters[i] <= 'f') {
			newValue = (value << 4) | (characters[i] - 'a' + 10);
			foundValue = true;
		} else if (characters[i] == 'h' ||
		    of_ascii_isspace(characters[i])) {
			expectWhitespace = true;
			continue;
		} else
			@throw [OFInvalidFormatException exception];

		if (newValue < value)
			@throw [OFOutOfRangeException exception];

		value = newValue;
	}

	if (!foundValue)
		@throw [OFInvalidFormatException exception];

	objc_autoreleasePoolPop(pool);

	return value;
}

- (uintmax_t)octalValue
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = self.characters;
	size_t i = 0, length = self.length;
	uintmax_t value = 0;
	bool expectWhitespace = false;

	while (length > 0 && of_ascii_isspace(*characters)) {
		characters++;
		length--;
	}

	if (length == 0) {
		objc_autoreleasePoolPop(pool);
		return 0;
	}

	for (; i < length; i++) {
		uintmax_t newValue;

		if (expectWhitespace) {
			if (of_ascii_isspace(characters[i]))
				continue;

			@throw [OFInvalidFormatException exception];
		}

		if (characters[i] >= '0' && characters[i] <= '7')
			newValue = (value << 3) | (characters[i] - '0');
		else if (of_ascii_isspace(characters[i])) {
			expectWhitespace = true;
			continue;
		} else
			@throw [OFInvalidFormatException exception];

		if (newValue < value)
			@throw [OFOutOfRangeException exception];

		value = newValue;
	}

	objc_autoreleasePoolPop(pool);

	return value;
}

- (float)floatValue
{
	void *pool = objc_autoreleasePoolPush();

#if defined(OF_AMIGAOS_M68K) || defined(OF_MORPHOS)
	OFString *stripped = self.stringByDeletingEnclosingWhitespaces;

	if ([stripped caseInsensitiveCompare: @"INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME)
		return INFINITY;
	if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME)
		return -INFINITY;
#endif

#ifdef HAVE_STRTOF_L
	const char *UTF8String = self.UTF8String;
#else
	/*
	 * If we have no strtof_l, we have no other choice but to replace "."
	 * with the locale's decimal point.
	 */
	OFString *decimalPoint = [OFLocale decimalPoint];
	const char *UTF8String = [self
	    stringByReplacingOccurrencesOfString: @"."
				      withString: decimalPoint].UTF8String;
#endif
	char *endPointer = NULL;
	float value;

	while (of_ascii_isspace(*UTF8String))
		UTF8String++;

#ifdef HAVE_STRTOF_L
	value = strtof_l(UTF8String, &endPointer, cLocale);
#else
	value = strtof(UTF8String, &endPointer);
#endif




	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)

			if (!of_ascii_isspace(*endPointer))
				@throw [OFInvalidFormatException exception];

	objc_autoreleasePoolPop(pool);

	return value;
}

- (double)doubleValue
{
	void *pool = objc_autoreleasePoolPush();

#if defined(OF_AMIGAOS_M68K) || defined(OF_MORPHOS)
	OFString *stripped = self.stringByDeletingEnclosingWhitespaces;

	if ([stripped caseInsensitiveCompare: @"INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME)
		return INFINITY;
	if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME)
		return -INFINITY;
#endif

#ifdef HAVE_STRTOD_L
	const char *UTF8String = self.UTF8String;
#else
	/*
	 * If we have no strtod_l, we have no other choice but to replace "."
	 * with the locale's decimal point.
	 */
	OFString *decimalPoint = [OFLocale decimalPoint];
	const char *UTF8String = [self
	    stringByReplacingOccurrencesOfString: @"."
				      withString: decimalPoint].UTF8String;
#endif
	char *endPointer = NULL;
	double value;

	while (of_ascii_isspace(*UTF8String))
		UTF8String++;

#ifdef HAVE_STRTOD_L
	value = strtod_l(UTF8String, &endPointer, cLocale);
#else
	value = strtod(UTF8String, &endPointer);
#endif




	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)

			if (!of_ascii_isspace(*endPointer))
				@throw [OFInvalidFormatException exception];

	objc_autoreleasePoolPop(pool);

	return value;
}








|

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

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

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






|

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

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


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









<
<








<
















<
<
|





>
>
>




>
|










<
<








<
















<
<
|






>
>
>



>
|







2310
2311
2312
2313
2314
2315
2316
2317
2318



2319

2320



2321
2322
2323

2324


2325
2326

2327
2328



2329
2330

2331
2332



2333
2334

2335
2336
2337
2338
2339

2340




2341
2342
2343
2344
2345
2346
2347
2348



2349

2350



2351
2352
2353

2354


2355




2356


2357



2358


2359















2360


2361

2362
2363

2364
2365

2366


2367

2368



2369

2370



2371
2372




2373


2374



2375


2376






2377






2378
2379
2380
2381
2382
2383
2384
2385
2386


2387
2388
2389
2390
2391
2392
2393
2394

2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410


2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435


2436
2437
2438
2439
2440
2441
2442
2443

2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459


2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
	[array makeImmutable];

	objc_autoreleasePoolPop(pool);

	return array;
}

- (long long)longLongValue
{



	return [self longLongValueWithBase: 10];

}




- (long long)longLongValueWithBase: (int)base
{

	void *pool = objc_autoreleasePoolPush();


	const char *UTF8String = self.UTF8String;
	char *endPointer = NULL;

	long long value;




	errno = 0;
	value = strtoll(UTF8String, &endPointer, base);


	if ((value == LLONG_MIN || value == LLONG_MAX) && errno == ERANGE)



		@throw [OFOutOfRangeException exception];


	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)
			/* Use isspace since strtoll uses the same. */
			if (!isspace((unsigned char)*endPointer))

				@throw [OFInvalidFormatException exception];





	objc_autoreleasePoolPop(pool);

	return value;
}

- (unsigned long long)unsignedLongLongValue
{



	return [self unsignedLongLongValueWithBase: 10];

}




- (unsigned long long)unsignedLongLongValueWithBase: (int)base
{

	void *pool = objc_autoreleasePoolPush();


	const char *UTF8String = self.UTF8String;




	char *endPointer = NULL;


	unsigned long long value;






	/* Use isspace since strtoull uses the same. */















	while (isspace((unsigned char)*UTF8String))


		UTF8String++;


	if (*UTF8String == '-')

		@throw [OFInvalidFormatException exception];


	errno = 0;


	value = strtoull(UTF8String, &endPointer, base);





	if (value == ULLONG_MAX && errno == ERANGE)

		@throw [OFOutOfRangeException exception];




	/* Check if there are any invalid chars left */




	if (endPointer != NULL)


		for (; *endPointer != '\0'; endPointer++)



			/* Use isspace since strtoull uses the same. */


			if (!isspace((unsigned char)*endPointer))






				@throw [OFInvalidFormatException exception];







	objc_autoreleasePoolPop(pool);

	return value;
}

- (float)floatValue
{
	void *pool = objc_autoreleasePoolPush();


	OFString *stripped = self.stringByDeletingEnclosingWhitespaces;

	if ([stripped caseInsensitiveCompare: @"INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME)
		return INFINITY;
	if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME)
		return -INFINITY;


#ifdef HAVE_STRTOF_L
	const char *UTF8String = self.UTF8String;
#else
	/*
	 * If we have no strtof_l, we have no other choice but to replace "."
	 * with the locale's decimal point.
	 */
	OFString *decimalPoint = [OFLocale decimalPoint];
	const char *UTF8String = [self
	    stringByReplacingOccurrencesOfString: @"."
				      withString: decimalPoint].UTF8String;
#endif
	char *endPointer = NULL;
	float value;



	errno = 0;
#ifdef HAVE_STRTOF_L
	value = strtof_l(UTF8String, &endPointer, cLocale);
#else
	value = strtof(UTF8String, &endPointer);
#endif

	if (value == HUGE_VALF && errno == ERANGE)
		@throw [OFOutOfRangeException exception];

	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)
			/* Use isspace since strtof uses the same. */
			if (!isspace((unsigned char)*endPointer))
				@throw [OFInvalidFormatException exception];

	objc_autoreleasePoolPop(pool);

	return value;
}

- (double)doubleValue
{
	void *pool = objc_autoreleasePoolPush();


	OFString *stripped = self.stringByDeletingEnclosingWhitespaces;

	if ([stripped caseInsensitiveCompare: @"INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME)
		return INFINITY;
	if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME)
		return -INFINITY;


#ifdef HAVE_STRTOD_L
	const char *UTF8String = self.UTF8String;
#else
	/*
	 * If we have no strtod_l, we have no other choice but to replace "."
	 * with the locale's decimal point.
	 */
	OFString *decimalPoint = [OFLocale decimalPoint];
	const char *UTF8String = [self
	    stringByReplacingOccurrencesOfString: @"."
				      withString: decimalPoint].UTF8String;
#endif
	char *endPointer = NULL;
	double value;



	errno = 0;
#ifdef HAVE_STRTOD_L
	value = strtod_l(UTF8String, &endPointer, cLocale);
#else
	value = strtod(UTF8String, &endPointer);
#endif

	if (value == HUGE_VAL && errno == ERANGE)
		@throw [OFOutOfRangeException exception];

	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)
			/* Use isspace since strtod uses the same. */
			if (!isspace((unsigned char)*endPointer))
				@throw [OFInvalidFormatException exception];

	objc_autoreleasePoolPop(pool);

	return value;
}

Modified src/OFSystemInfo.m from [0f92abda7c] to [4e15025453].

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#if defined(OF_IOS) || defined(OF_MACOS)
# ifdef OF_HAVE_FILES
	void *pool = objc_autoreleasePoolPush();

	@try {
		OFDictionary *propertyList = [OFString stringWithContentsOfFile:
		    @"/System/Library/CoreServices/SystemVersion.plist"]
		    .propertyListValue;

		operatingSystemVersion = [[propertyList
		    objectForKey: @"ProductVersion"] copy];
	} @finally {
		objc_autoreleasePoolPop(pool);
	}
# endif







|







148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#if defined(OF_IOS) || defined(OF_MACOS)
# ifdef OF_HAVE_FILES
	void *pool = objc_autoreleasePoolPush();

	@try {
		OFDictionary *propertyList = [OFString stringWithContentsOfFile:
		    @"/System/Library/CoreServices/SystemVersion.plist"]
		    .objectByParsingPropertyList;

		operatingSystemVersion = [[propertyList
		    objectForKey: @"ProductVersion"] copy];
	} @finally {
		objc_autoreleasePoolPop(pool);
	}
# endif

Modified src/OFTarArchiveEntry.h from [77a315dfd8] to [c15723d4d0].

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
 * @class OFTarArchiveEntry OFTarArchiveEntry.h ObjFW/OFTarArchiveEntry.h
 *
 * @brief A class which represents an entry of a tar archive.
 */
@interface OFTarArchiveEntry: OFObject <OFCopying, OFMutableCopying>
{
	OFString *_fileName;
	uint32_t _mode;
	uint64_t _size;
	uint32_t _UID, _GID;
	OFDate *_modificationDate;
	of_tar_archive_entry_type_t _type;
	OFString *_Nullable _targetFileName;
	OFString *_Nullable _owner, *_Nullable _group;
	uint32_t _deviceMajor, _deviceMinor;
	OF_RESERVE_IVARS(4)
}

/*!
 * @brief The file name of the entry.
 */
@property (readonly, copy, nonatomic) OFString *fileName;

/*!
 * @brief The mode of the entry.
 */
@property (readonly, nonatomic) uint32_t mode;

/*!
 * @brief The UID of the owner.
 */
@property (readonly, nonatomic) uint32_t UID;

/*!
 * @brief The GID of the group.
 */
@property (readonly, nonatomic) uint32_t GID;

/*!
 * @brief The size of the file.
 */
@property (readonly, nonatomic) uint64_t size;

/*!
 * @brief The date of the last modification of the file.
 */
@property (readonly, retain, nonatomic) OFDate *modificationDate;

/*!







|
|
|




|











|




|




|




|







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
 * @class OFTarArchiveEntry OFTarArchiveEntry.h ObjFW/OFTarArchiveEntry.h
 *
 * @brief A class which represents an entry of a tar archive.
 */
@interface OFTarArchiveEntry: OFObject <OFCopying, OFMutableCopying>
{
	OFString *_fileName;
	unsigned long _mode;
	unsigned long long _size;
	unsigned long _UID, _GID;
	OFDate *_modificationDate;
	of_tar_archive_entry_type_t _type;
	OFString *_Nullable _targetFileName;
	OFString *_Nullable _owner, *_Nullable _group;
	unsigned long _deviceMajor, _deviceMinor;
	OF_RESERVE_IVARS(4)
}

/*!
 * @brief The file name of the entry.
 */
@property (readonly, copy, nonatomic) OFString *fileName;

/*!
 * @brief The mode of the entry.
 */
@property (readonly, nonatomic) unsigned long mode;

/*!
 * @brief The UID of the owner.
 */
@property (readonly, nonatomic) unsigned long UID;

/*!
 * @brief The GID of the group.
 */
@property (readonly, nonatomic) unsigned long GID;

/*!
 * @brief The size of the file.
 */
@property (readonly, nonatomic) unsigned long long size;

/*!
 * @brief The date of the last modification of the file.
 */
@property (readonly, retain, nonatomic) OFDate *modificationDate;

/*!
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
 * @brief The group of the file.
 */
@property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *group;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readonly, nonatomic) uint32_t deviceMajor;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readonly, nonatomic) uint32_t deviceMinor;

/*!
 * @brief Creates a new OFTarArchiveEntry with the specified file name.
 *
 * @param fileName The file name for the OFTarArchiveEntry
 * @return A new, autoreleased OFTarArchiveEntry
 */







|




|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
 * @brief The group of the file.
 */
@property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *group;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readonly, nonatomic) unsigned long deviceMajor;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readonly, nonatomic) unsigned long deviceMinor;

/*!
 * @brief Creates a new OFTarArchiveEntry with the specified file name.
 *
 * @param fileName The file name for the OFTarArchiveEntry
 * @return A new, autoreleased OFTarArchiveEntry
 */

Modified src/OFTarArchiveEntry.m from [aa73e544ea] to [5e09222260].

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

	memcpy(buffer, [string cStringWithEncoding: encoding], cStringLength);

	for (size_t i = cStringLength; i < length; i++)
		buffer[i] = '\0';
}

static uintmax_t
octalValueFromBuffer(const unsigned char *buffer, size_t length, uintmax_t max)

{
	uintmax_t value = 0;

	if (length == 0)
		return 0;

	if (buffer[0] == 0x80) {
		for (size_t i = 1; i < length; i++)
			value = (value << 8) | buffer[i];
	} else
		value = stringFromBuffer(buffer, length,
		    OF_STRING_ENCODING_ASCII).octalValue;

	if (value > max)
		@throw [OFOutOfRangeException exception];

	return value;
}








|
|
>

|








|
|







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

	memcpy(buffer, [string cStringWithEncoding: encoding], cStringLength);

	for (size_t i = cStringLength; i < length; i++)
		buffer[i] = '\0';
}

static unsigned long long
octalValueFromBuffer(const unsigned char *buffer, size_t length,
    unsigned long long max)
{
	unsigned long long value = 0;

	if (length == 0)
		return 0;

	if (buffer[0] == 0x80) {
		for (size_t i = 1; i < length; i++)
			value = (value << 8) | buffer[i];
	} else
		value = [stringFromBuffer(buffer, length,
		    OF_STRING_ENCODING_ASCII) unsignedLongLongValueWithBase: 8];

	if (value > max)
		@throw [OFOutOfRangeException exception];

	return value;
}

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
	self = [super init];

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

		_fileName = [stringFromBuffer(header, 100, encoding) copy];
		_mode = (uint32_t)octalValueFromBuffer(
		    header + 100, 8, UINT32_MAX);
		_UID = (uint32_t)octalValueFromBuffer(
		    header + 108, 8, UINT32_MAX);
		_GID = (uint32_t)octalValueFromBuffer(
		    header + 116, 8, UINT32_MAX);
		_size = (uint64_t)octalValueFromBuffer(
		    header + 124, 12, UINT64_MAX);
		_modificationDate = [[OFDate alloc]
		    initWithTimeIntervalSince1970:
		    (of_time_interval_t)octalValueFromBuffer(
		    header + 136, 12, UINTMAX_MAX)];
		_type = header[156];

		targetFileName = stringFromBuffer(header + 157, 100, encoding);
		if (targetFileName.length > 0)
			_targetFileName = [targetFileName copy];

		if (_type == '\0')
			_type = OF_TAR_ARCHIVE_ENTRY_TYPE_FILE;

		if (memcmp(header + 257, "ustar\0" "00", 8) == 0) {
			OFString *prefix;

			_owner = [stringFromBuffer(header + 265, 32, encoding)
			    copy];
			_group = [stringFromBuffer(header + 297, 32, encoding)
			    copy];

			_deviceMajor = (uint32_t)octalValueFromBuffer(
			    header + 329, 8, UINT32_MAX);
			_deviceMinor = (uint32_t)octalValueFromBuffer(
			    header + 337, 8, UINT32_MAX);

			prefix = stringFromBuffer(header + 345, 155, encoding);
			if (prefix.length > 0) {
				OFString *fileName = [OFString
				    stringWithFormat: @"%@/%@",
						      prefix, _fileName];
				[_fileName release];







|
|
|
|
|
|
|
|



|

















|
|
|
|







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
	self = [super init];

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

		_fileName = [stringFromBuffer(header, 100, encoding) copy];
		_mode = (unsigned long)octalValueFromBuffer(
		    header + 100, 8, ULONG_MAX);
		_UID = (unsigned long)octalValueFromBuffer(
		    header + 108, 8, ULONG_MAX);
		_GID = (unsigned long)octalValueFromBuffer(
		    header + 116, 8, ULONG_MAX);
		_size = (unsigned long long)octalValueFromBuffer(
		    header + 124, 12, ULLONG_MAX);
		_modificationDate = [[OFDate alloc]
		    initWithTimeIntervalSince1970:
		    (of_time_interval_t)octalValueFromBuffer(
		    header + 136, 12, ULLONG_MAX)];
		_type = header[156];

		targetFileName = stringFromBuffer(header + 157, 100, encoding);
		if (targetFileName.length > 0)
			_targetFileName = [targetFileName copy];

		if (_type == '\0')
			_type = OF_TAR_ARCHIVE_ENTRY_TYPE_FILE;

		if (memcmp(header + 257, "ustar\0" "00", 8) == 0) {
			OFString *prefix;

			_owner = [stringFromBuffer(header + 265, 32, encoding)
			    copy];
			_group = [stringFromBuffer(header + 297, 32, encoding)
			    copy];

			_deviceMajor = (unsigned long)octalValueFromBuffer(
			    header + 329, 8, ULONG_MAX);
			_deviceMinor = (unsigned long)octalValueFromBuffer(
			    header + 337, 8, ULONG_MAX);

			prefix = stringFromBuffer(header + 345, 155, encoding);
			if (prefix.length > 0) {
				OFString *fileName = [OFString
				    stringWithFormat: @"%@/%@",
						      prefix, _fileName];
				[_fileName release];
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
}

- (OFString *)fileName
{
	return _fileName;
}

- (uint32_t)mode
{
	return _mode;
}

- (uint32_t)UID
{
	return _UID;
}

- (uint32_t)GID
{
	return _GID;
}

- (uint64_t)size
{
	return _size;
}

- (OFDate *)modificationDate
{
	return _modificationDate;







|




|




|




|







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
}

- (OFString *)fileName
{
	return _fileName;
}

- (unsigned long)mode
{
	return _mode;
}

- (unsigned long)UID
{
	return _UID;
}

- (unsigned long)GID
{
	return _GID;
}

- (unsigned long long)size
{
	return _size;
}

- (OFDate *)modificationDate
{
	return _modificationDate;
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
}

- (OFString *)group
{
	return _group;
}

- (uint32_t)deviceMajor
{
	return _deviceMajor;
}

- (uint32_t)deviceMinor
{
	return _deviceMinor;
}

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







|




|







250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
}

- (OFString *)group
{
	return _group;
}

- (unsigned long)deviceMajor
{
	return _deviceMajor;
}

- (unsigned long)deviceMinor
{
	return _deviceMinor;
}

- (OFString *)description
{
	void *pool = objc_autoreleasePoolPush();
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
	return [ret autorelease];
}

- (void)of_writeToStream: (OFStream *)stream
		encoding: (of_string_encoding_t)encoding
{
	unsigned char buffer[512];
	uint64_t modificationDate;
	uint16_t checksum = 0;

	stringToBuffer(buffer, _fileName, 100, encoding);
	stringToBuffer(buffer + 100,
	    [OFString stringWithFormat: @"%06" PRIo16 " ", _mode], 8,
	    OF_STRING_ENCODING_ASCII);
	stringToBuffer(buffer + 108,
	    [OFString stringWithFormat: @"%06" PRIo16 " ", _UID], 8,
	    OF_STRING_ENCODING_ASCII);
	stringToBuffer(buffer + 116,
	    [OFString stringWithFormat: @"%06" PRIo16 " ", _GID], 8,
	    OF_STRING_ENCODING_ASCII);
	stringToBuffer(buffer + 124,
	    [OFString stringWithFormat: @"%011" PRIo64 " ", _size], 12,
	    OF_STRING_ENCODING_ASCII);
	modificationDate = _modificationDate.timeIntervalSince1970;
	stringToBuffer(buffer + 136,
	    [OFString stringWithFormat: @"%011" PRIo64 " ", modificationDate],
	    12, OF_STRING_ENCODING_ASCII);

	/*
	 * During checksumming, the checksum field is expected to be set to 8
	 * spaces.
	 */
	memset(buffer + 148, ' ', 8);







|

















|







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
	return [ret autorelease];
}

- (void)of_writeToStream: (OFStream *)stream
		encoding: (of_string_encoding_t)encoding
{
	unsigned char buffer[512];
	unsigned long long modificationDate;
	uint16_t checksum = 0;

	stringToBuffer(buffer, _fileName, 100, encoding);
	stringToBuffer(buffer + 100,
	    [OFString stringWithFormat: @"%06" PRIo16 " ", _mode], 8,
	    OF_STRING_ENCODING_ASCII);
	stringToBuffer(buffer + 108,
	    [OFString stringWithFormat: @"%06" PRIo16 " ", _UID], 8,
	    OF_STRING_ENCODING_ASCII);
	stringToBuffer(buffer + 116,
	    [OFString stringWithFormat: @"%06" PRIo16 " ", _GID], 8,
	    OF_STRING_ENCODING_ASCII);
	stringToBuffer(buffer + 124,
	    [OFString stringWithFormat: @"%011" PRIo64 " ", _size], 12,
	    OF_STRING_ENCODING_ASCII);
	modificationDate = _modificationDate.timeIntervalSince1970;
	stringToBuffer(buffer + 136,
	    [OFString stringWithFormat: @"%011llo", modificationDate],
	    12, OF_STRING_ENCODING_ASCII);

	/*
	 * During checksumming, the checksum field is expected to be set to 8
	 * spaces.
	 */
	memset(buffer + 148, ' ', 8);

Modified src/OFURL.m from [2524e037d6] to [a6ef5631a2].

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
				}

				portString = [OFString
				    stringWithUTF8String: tmp2
						  length: UTF8String - tmp2];

				if (portString.length == 0 ||
				    portString.decimalValue > 65535)
					@throw [OFInvalidFormatException
					    exception];

				_port = [[OFNumber alloc] initWithUInt16:
				    (uint16_t)portString.decimalValue];
			} else if (*UTF8String != '\0')
				@throw [OFInvalidFormatException exception];

			isIPv6Host = true;
		} else if ((tmp2 = strchr(UTF8String, ':')) != NULL) {
			OFString *portString;

			*tmp2 = '\0';
			tmp2++;

			_URLEncodedHost = [[OFString alloc]
			    initWithUTF8String: UTF8String];

			portString = [OFString stringWithUTF8String: tmp2];

			if (portString.decimalValue > 65535)
				@throw [OFInvalidFormatException exception];

			_port = [[OFNumber alloc] initWithUInt16:
			    (uint16_t)portString.decimalValue];
		} else
			_URLEncodedHost = [[OFString alloc]
			    initWithUTF8String: UTF8String];

		if (!isIPv6Host)
			of_url_verify_escaped(_URLEncodedHost,
			    [OFCharacterSet URLHostAllowedCharacterSet]);







|



|
|















|


|
|







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
				}

				portString = [OFString
				    stringWithUTF8String: tmp2
						  length: UTF8String - tmp2];

				if (portString.length == 0 ||
				    portString.unsignedLongLongValue > 65535)
					@throw [OFInvalidFormatException
					    exception];

				_port = [[OFNumber alloc] initWithUnsignedShort:
				    portString.unsignedLongLongValue];
			} else if (*UTF8String != '\0')
				@throw [OFInvalidFormatException exception];

			isIPv6Host = true;
		} else if ((tmp2 = strchr(UTF8String, ':')) != NULL) {
			OFString *portString;

			*tmp2 = '\0';
			tmp2++;

			_URLEncodedHost = [[OFString alloc]
			    initWithUTF8String: UTF8String];

			portString = [OFString stringWithUTF8String: tmp2];

			if (portString.unsignedLongLongValue > 65535)
				@throw [OFInvalidFormatException exception];

			_port = [[OFNumber alloc] initWithUnsignedShort:
			    portString.unsignedLongLongValue];
		} else
			_URLEncodedHost = [[OFString alloc]
			    initWithUTF8String: UTF8String];

		if (!isIPv6Host)
			of_url_verify_escaped(_URLEncodedHost,
			    [OFCharacterSet URLHostAllowedCharacterSet]);

Modified src/OFXMLNode.h from [d1608da1d3] to [fb7dfbb539].

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 *
 * For an @ref OFXMLElement, setting it removes all children and creates a
 * single child with the specified string value.
 */
@property (nonatomic, copy) OFString *stringValue;

/*!
 * @brief The contents of the receiver as a decimal value.
 */
@property (readonly, nonatomic) intmax_t decimalValue;

/*!
 * @brief The contents of the receiver as a hexadecimal value.
 */
@property (readonly, nonatomic) uintmax_t hexadecimalValue;

/*!
 * @brief The contents of the receiver as a float value.
 */
@property (readonly, nonatomic) float floatValue;

/*!







|

|


|

|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 *
 * For an @ref OFXMLElement, setting it removes all children and creates a
 * single child with the specified string value.
 */
@property (nonatomic, copy) OFString *stringValue;

/*!
 * @brief The contents of the receiver as a `long long` value.
 */
@property (readonly, nonatomic) long long longLongValue;

/*!
 * @brief The contents of the receiver as an `unsigned long long` value.
 */
@property (readonly, nonatomic) unsigned long long unsignedLongLongValue;

/*!
 * @brief The contents of the receiver as a float value.
 */
@property (readonly, nonatomic) float floatValue;

/*!
85
86
87
88
89
90
91


























92
93
94
 * @param indentation The indentation for the XML string
 * @param level The level of indentation
 * @return An OFString representing the OFXMLNode as an XML string with
 *	   indentation
 */
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				 level: (unsigned int)level;


























@end

OF_ASSUME_NONNULL_END







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



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
 * @param indentation The indentation for the XML string
 * @param level The level of indentation
 * @return An OFString representing the OFXMLNode as an XML string with
 *	   indentation
 */
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				 level: (unsigned int)level;

/*!
 * @brief The contents of the receiver as a `long long` value in the specified
 *	  base.
 *
 * @param base The base to use. If the base is 0, base 16 is assumed if the
 * 	       string starts with 0x (after stripping white spaces). If the
 * 	       string starts with 0, base 8 is assumed. Otherwise, base 10 is
 * 	       assumed.
 * @return The contents of the receiver as a `long long` value in the specified
 *	   base
 */
- (long long)longLongValueWithBase: (int)base;

/*!
 * @brief The contents of the receiver as an `unsigned long long` value in the
 *	  specified base.
 *
 * @param base The base to use. If the base is 0, base 16 is assumed if the
 * 	       string starts with 0x (after stripping white spaces). If the
 * 	       string starts with 0, base 8 is assumed. Otherwise, base 10 is
 * 	       assumed.
 * @return The contents of the receiver as an `unsigned long long` value in the
 * 	   specified base
 */
- (unsigned long long)unsignedLongLongValueWithBase: (int)base;
@end

OF_ASSUME_NONNULL_END

Modified src/OFXMLNode.m from [8f7acafb9c] to [089c365f8a].

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




54

55
56





57
58
59
60
61
62
63
}

- (void)setStringValue: (OFString *)stringValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (intmax_t)decimalValue
{
	return self.stringValue.decimalValue;
}





- (uintmax_t)hexadecimalValue

{
	return self.stringValue.hexadecimalValue;





}

- (float)floatValue
{
	return self.stringValue.floatValue;
}








|

|


>
>
>
>
|
>

|
>
>
>
>
>







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
}

- (void)setStringValue: (OFString *)stringValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (long long)longLongValue
{
	return self.stringValue.longLongValue;
}

- (long long)longLongValueWithBase: (int)base
{
	return [self.stringValue longLongValueWithBase: base];
}

- (unsigned long long)unsignedLongLongValue
{
	return self.stringValue.unsignedLongLongValue;
}

- (unsigned long long)unsignedLongLongValueWithBase: (int)base
{
	return [self.stringValue unsignedLongLongValueWithBase: base];
}

- (float)floatValue
{
	return self.stringValue.floatValue;
}

Modified src/bridge/Info.plist.in from [8dcff1a319] to [41c8e4dc54].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>ObjFWBridge</string>
	<key>CFBundleName</key>
	<string>ObjFWBridge</string>
	<key>CFBundleIdentifier</key>
	<string>zone.heap.objfw.bridge</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>FMWK</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>MinimumOSVersion</key>
	<string>9.0</string>
</dict>
</plist>









|












1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>ObjFWBridge</string>
	<key>CFBundleName</key>
	<string>ObjFWBridge</string>
	<key>CFBundleIdentifier</key>
	<string>im.nil.objfw.bridge</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>FMWK</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>MinimumOSVersion</key>
	<string>9.0</string>
</dict>
</plist>

Added src/runtime/Info.plist.in version [0388a9733c].













































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>ObjFWRT</string>
	<key>CFBundleName</key>
	<string>ObjFWRT</string>
	<key>CFBundleIdentifier</key>
	<string>im.nil.objfw.rt</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>FMWK</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>MinimumOSVersion</key>
	<string>9.0</string>
</dict>
</plist>

Modified src/runtime/Makefile from [578f05e231] to [0941bab434].

1
2
3
4
5

6
7
8
9
10
11
12
include ../../extra.mk

SUBDIRS = lookup-asm
SUBDIRS_AFTER = ${LINKLIB}
CLEAN = amiga-library-functable.inc inline.h


SHARED_LIB = ${OBJFWRT_SHARED_LIB}
STATIC_LIB = ${OBJFWRT_STATIC_LIB}
FRAMEWORK = ${OBJFWRT_FRAMEWORK}
AMIGA_LIB = ${OBJFWRT_AMIGA_LIB}
LIB_MAJOR = ${OBJFWRT_LIB_MAJOR}
LIB_MINOR = ${OBJFWRT_LIB_MINOR}





>







1
2
3
4
5
6
7
8
9
10
11
12
13
include ../../extra.mk

SUBDIRS = lookup-asm
SUBDIRS_AFTER = ${LINKLIB}
CLEAN = amiga-library-functable.inc inline.h
DISTCLEAN = Info.plist

SHARED_LIB = ${OBJFWRT_SHARED_LIB}
STATIC_LIB = ${OBJFWRT_STATIC_LIB}
FRAMEWORK = ${OBJFWRT_FRAMEWORK}
AMIGA_LIB = ${OBJFWRT_AMIGA_LIB}
LIB_MAJOR = ${OBJFWRT_LIB_MAJOR}
LIB_MINOR = ${OBJFWRT_LIB_MINOR}

Modified src/socket.m from [fb89efec65] to [0757bca949].

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

	if (components.count != 4)
		@throw [OFInvalidFormatException exception];

	addr = 0;

	for (OFString *component in components) {
		intmax_t number;

		if (component.length == 0)
			@throw [OFInvalidFormatException exception];

		if ([component indexOfCharacterFromSet:
		    whitespaceCharacterSet] != OF_NOT_FOUND)
			@throw [OFInvalidFormatException exception];

		number = component.decimalValue;

		if (number < 0 || number > UINT8_MAX)
			@throw [OFInvalidFormatException exception];

		addr = (addr << 8) | (number & 0xFF);
	}

	addrIn->sin_addr.s_addr = OF_BSWAP32_IF_LE(addr);

	objc_autoreleasePoolPop(pool);

	return ret;
}

static uint16_t
parseIPv6Component(OFString *component)
{
	uintmax_t number;

	if ([component indexOfCharacterFromSet:
	    [OFCharacterSet whitespaceCharacterSet]] != OF_NOT_FOUND)
		@throw [OFInvalidFormatException exception];

	number = component.hexadecimalValue;

	if (number > UINT16_MAX)
		@throw [OFInvalidFormatException exception];

	return (uint16_t)number;
}








|








|

|















|





|







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

	if (components.count != 4)
		@throw [OFInvalidFormatException exception];

	addr = 0;

	for (OFString *component in components) {
		unsigned long long number;

		if (component.length == 0)
			@throw [OFInvalidFormatException exception];

		if ([component indexOfCharacterFromSet:
		    whitespaceCharacterSet] != OF_NOT_FOUND)
			@throw [OFInvalidFormatException exception];

		number = component.unsignedLongLongValue;

		if (number > UINT8_MAX)
			@throw [OFInvalidFormatException exception];

		addr = (addr << 8) | (number & 0xFF);
	}

	addrIn->sin_addr.s_addr = OF_BSWAP32_IF_LE(addr);

	objc_autoreleasePoolPop(pool);

	return ret;
}

static uint16_t
parseIPv6Component(OFString *component)
{
	unsigned long long number;

	if ([component indexOfCharacterFromSet:
	    [OFCharacterSet whitespaceCharacterSet]] != OF_NOT_FOUND)
		@throw [OFInvalidFormatException exception];

	number = [component unsignedLongLongValueWithBase: 16];

	if (number > UINT16_MAX)
		@throw [OFInvalidFormatException exception];

	return (uint16_t)number;
}

Modified tests/Info.plist.in from [f12e2c6ff1] to [90a9f008a2].

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleVersion</key>
	<string>@PACKAGE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@PACKAGE_VERSION@</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>
	<key>UIMainStoryboardFile</key>
	<string>Main</string>
	<key>UIRequiredDeviceCapabilities</key>







|

|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>
	<key>UIMainStoryboardFile</key>
	<string>Main</string>
	<key>UIRequiredDeviceCapabilities</key>

Modified tests/Makefile from [5e05094c6b] to [198bd5cd10].

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
include ../extra.mk

SUBDIRS = ${TESTPLUGIN}

CLEAN = EBOOT.PBP		\
	boot.dol		\
	${PROG_NOINST}.arm9	\
	${PROG_NOINST}.nds
DISTCLEAN = Info.plist

PROG_NOINST = tests${PROG_SUFFIX}
STATIC_LIB_NOINST = ${TESTS_STATIC_LIB}
SRCS = ForwardingTests.m		\

       OFASN1DERRepresentationTests.m	\
       OFASN1DERValueTests.m		\
       OFArrayTests.m			\
       ${OF_BLOCK_TESTS_M}		\
       OFCharacterSetTests.m		\
       OFDataTests.m			\
       OFDateTests.m			\
       OFDictionaryTests.m		\
       OFInvocationTests.m		\













>

<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
include ../extra.mk

SUBDIRS = ${TESTPLUGIN}

CLEAN = EBOOT.PBP		\
	boot.dol		\
	${PROG_NOINST}.arm9	\
	${PROG_NOINST}.nds
DISTCLEAN = Info.plist

PROG_NOINST = tests${PROG_SUFFIX}
STATIC_LIB_NOINST = ${TESTS_STATIC_LIB}
SRCS = ForwardingTests.m		\
       OFASN1DERParsingTests.m		\
       OFASN1DERRepresentationTests.m	\

       OFArrayTests.m			\
       ${OF_BLOCK_TESTS_M}		\
       OFCharacterSetTests.m		\
       OFDataTests.m			\
       OFDateTests.m			\
       OFDictionaryTests.m		\
       OFInvocationTests.m		\

Renamed and modified tests/OFASN1DERValueTests.m [668efc201f] to tests/OFASN1DERParsingTests.m [dd4c3da7d2].

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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

207
208
209
210

211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226

227
228

229

230
231
232

233

234
235
236

237
238
239
240
241

242
243
244
245

246
247
248
249

250
251
252
253
254
255
256
257
258
259

260
261
262
263
264
265
266
267
268
269
270
271

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

284
285
286
287

288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432

433
434
435
436
437
 * file.
 */

#include "config.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFData+ASN1DERValue";

@implementation TestsAppDelegate (OFASN1DERValueTests)
- (void)ASN1DERValueTests
{
	void *pool = objc_autoreleasePoolPush();
	OFASN1BitString *bitString;
	OFArray *array;
	OFSet *set;
	OFEnumerator *enumerator;

	/* Boolean */
	TEST(@"Parsing of boolean",
	    ![[[OFData dataWithItems: "\x01\x01\x00"

			       count: 3] ASN1DERValue] booleanValue] &&
	    [[[OFData dataWithItems: "\x01\x01\xFF"
			      count: 3] ASN1DERValue] booleanValue])

	EXPECT_EXCEPTION(@"Detection of invalid boolean #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x01\x01\x01"

						       count: 3] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of invalid boolean #2",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x01\x02\x00\x00"

						       count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of invalid boolean #3",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x01\x00"

						       count: 2] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated boolean",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x01\x01"

						       count: 2] ASN1DERValue])

	/* Integer */
	TEST(@"Parsing of integer",
	    [[[OFData dataWithItems: "\x02\x00"

			      count: 2] ASN1DERValue] integerValue] == 0 &&
	    [[[OFData dataWithItems: "\x02\x01\x01"

			      count: 3] ASN1DERValue] integerValue] == 1 &&
	    [[[OFData dataWithItems: "\x02\x02\x01\x04"

			      count: 4] ASN1DERValue] integerValue] == 260 &&
	    [[[OFData dataWithItems: "\x02\x01\xFF"

			      count: 3] ASN1DERValue] integerValue] == -1 &&
	    [[[OFData dataWithItems: "\x02\x03\xFF\x00\x00"

			      count: 5] ASN1DERValue] integerValue] == -65536 &&
	    (uintmax_t)[[[OFData dataWithItems: "\x02\x09\x00\xFF\xFF\xFF\xFF"
						"\xFF\xFF\xFF\xFF"

					 count: 11] ASN1DERValue]
	    integerValue] == UINTMAX_MAX)

	EXPECT_EXCEPTION(@"Detection of invalid integer #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\x00\x00"

						       count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of invalid integer #2",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\x00\x7F"

						       count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of invalid integer #3",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\xFF\x80"

						       count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of out of range integer",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x02\x09\x01"
				    "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
			     count: 11] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated integer",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x02\x02\x00"

						       count: 3] ASN1DERValue])

	/* Bit string */
	TEST(@"Parsing of bit string",
	    (bitString = [[OFData dataWithItems: "\x03\x01\x00"
					  count: 3] ASN1DERValue]) &&
	    [bitString.bitStringValue isEqual: [OFData dataWithItems: ""
					count: 0]] &&
	    bitString.bitStringLength == 0 &&
	    (bitString = [[OFData dataWithItems: "\x03\x0D\x01Hello World\x80"
					  count: 15] ASN1DERValue]) &&
	    [bitString.bitStringValue
	    isEqual: [OFData dataWithItems: "Hello World\x80"
				     count: 12]] &&
	    bitString.bitStringLength == 95 &&
	    (bitString = [[OFData dataWithItems: "\x03\x81\x80\x00xxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
					  count: 131] ASN1DERValue]) &&
	    [bitString.bitStringValue
	    isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxx"
				     count: 127]] &&
	    bitString.bitStringLength == 127 * 8)

	EXPECT_EXCEPTION(@"Detection of invalid bit string #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x03\x00"

						       count: 2] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of invalid bit string #2",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x03\x01\x01"

						       count: 3] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of out of range bit string",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x03\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated bit string",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x03\x01"

						       count: 2] ASN1DERValue])

	/* Octet string */
	TEST(@"Parsing of octet string",
	    [[[[OFData dataWithItems: "\x04\x0CHello World!"
			      count: 14] ASN1DERValue] octetStringValue]
	    isEqual: [OFData dataWithItems: "Hello World!"
				     count: 12]] &&
	    [[[[OFData dataWithItems: "\x04\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxx"

			       count: 131] ASN1DERValue] octetStringValue]
	    isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxx"
				     count: 128]])

	EXPECT_EXCEPTION(@"Detection of out of range octet string",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x04\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated octet string",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x04\x01"

						       count: 2] ASN1DERValue])

	/* Null */
	TEST(@"Parsing of null",
	    [[[OFData dataWithItems: "\x05\x00"

			      count: 2] ASN1DERValue] isEqual: [OFNull null]])

	EXPECT_EXCEPTION(@"Detection of invalid null",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x05\x01\x00"

						       count: 3] ASN1DERValue])

	/* Object Identifier */
	TEST(@"Parsing of Object Identifier",
	    (array = [[[OFData dataWithItems: "\x06\x01\x27"
				       count: 3] ASN1DERValue]
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 0 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 39 &&
	    (array = [[[OFData dataWithItems: "\x06\x01\x4F"
				       count: 3] ASN1DERValue]
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 39 &&
	    (array = [[[OFData dataWithItems: "\x06\x02\x88\x37"
				       count: 4] ASN1DERValue]
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 2 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 999 &&
	    (array = [[[OFData dataWithItems: "\x06\x09\x2A\x86\x48\x86\xF7\x0D"
					      "\x01\x01\x0B"
				       count: 11] ASN1DERValue]
	    subidentifiers]) && array.count == 7 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 2 &&
	    [[array objectAtIndex: 2] uIntMaxValue] == 840 &&
	    [[array objectAtIndex: 3] uIntMaxValue] == 113549 &&
	    [[array objectAtIndex: 4] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 5] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 6] uIntMaxValue] == 11)

	EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x06\x01\x81"

						       count: 3] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #2",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x06\x02\x80\x01"

						       count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of out of range Object Identifier",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x06\x0A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
				    "\xFF\x7F"
			     count: 12] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated Object Identifier",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x06\x02\x00"

						       count: 3] ASN1DERValue])

	/* Enumerated */
	TEST(@"Parsing of enumerated",
	    [[[OFData dataWithItems: "\x0A\x00"
			      count: 2] ASN1DERValue] integerValue] == 0 &&

	    [[[OFData dataWithItems: "\x0A\x01\x01"
			      count: 3] ASN1DERValue] integerValue] == 1 &&

	    [[[OFData dataWithItems: "\x0A\x02\x01\x04"

			      count: 4] ASN1DERValue] integerValue] == 260 &&
	    [[[OFData dataWithItems: "\x0A\x01\xFF"
			      count: 3] ASN1DERValue] integerValue] == -1 &&

	    [[[OFData dataWithItems: "\x0A\x03\xFF\x00\x00"

			      count: 5] ASN1DERValue] integerValue] == -65536 &&
	    (uintmax_t)[[[OFData dataWithItems: "\x0A\x09\x00\xFF\xFF\xFF\xFF"
						"\xFF\xFF\xFF\xFF"

					 count: 11] ASN1DERValue]
	    integerValue] == UINTMAX_MAX)

	EXPECT_EXCEPTION(@"Detection of invalid enumerated #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\x00\x00"

						       count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of invalid enumerated #2",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\x00\x7F"

						       count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of invalid enumerated #3",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\xFF\x80"

						       count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of out of range enumerated",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x0A\x09\x01"
				    "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
			     count: 11] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated enumerated",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x0A\x02\x00"

						       count: 3] ASN1DERValue])

	/* UTF-8 string */
	TEST(@"Parsing of UTF-8 string",
	    [[[[OFData dataWithItems: "\x0C\x0EHällo Wörld!"
			       count: 16] ASN1DERValue] UTF8StringValue]
	    isEqual: @"Hällo Wörld!"] &&
	    [[[[OFData dataWithItems: "\x0C\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxx"
			       count: 131] ASN1DERValue] UTF8StringValue]

	    isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
		     @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
		     @"xxxxxxxxxxxxxxxx"])

	EXPECT_EXCEPTION(@"Detection of out of range UTF-8 string",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x0C\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated UTF-8 string",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x0C\x01"

						       count: 2] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated length",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x0C\x83\x01\x01"

						       count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x0C\x81\x7F"

						       count: 3] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #2",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x0C\x82\x00\x80xxxxxxxxxxxxxxxxxxxxxxxxxx"
				    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				    "xxxxxxxxxxxxxxxxxx"
			     count: 132] ASN1DERValue])

	/* Sequence */
	TEST(@"Parsing of sequence",
	    (array = [[OFData dataWithItems: "\x30\x00"
				      count: 2] ASN1DERValue]) &&
	    [array isKindOfClass: [OFArray class]] && array.count == 0 &&
	    (array = [[OFData dataWithItems: "\x30\x09\x02\x01\x7B\x0C\x04Test"
				      count: 11] ASN1DERValue]) &&
	    [array isKindOfClass: [OFArray class]] && array.count == 2 &&
	    [[array objectAtIndex: 0] integerValue] == 123 &&
	    [[[array objectAtIndex: 1] stringValue] isEqual: @"Test"])

	EXPECT_EXCEPTION(@"Detection of truncated sequence #1",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x30\x01"

						       count: 2] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated sequence #2",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x30\x04\x02\x01\x01\x00\x00"
			     count: 7] ASN1DERValue])

	/* Set */
	TEST(@"Parsing of set",
	    (set = [[OFData dataWithItems: "\x31\x00"
				    count: 2] ASN1DERValue]) &&
	    [set isKindOfClass: [OFSet class]] && set.count == 0 &&
	    (set = [[OFData dataWithItems: "\x31\x09\x02\x01\x7B\x0C\x04Test"
				    count: 11] ASN1DERValue]) &&
	    [set isKindOfClass: [OFSet class]] && set.count == 2 &&
	    (enumerator = [set objectEnumerator]) &&
	    [[enumerator nextObject] integerValue] == 123 &&
	    [[[enumerator nextObject] stringValue] isEqual: @"Test"])

	EXPECT_EXCEPTION(@"Detection of invalid set",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x31\x06\x02\x01\x02\x02\x01\x01"
			     count: 8] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated set #1",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x31\x01"

						       count: 2] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated set #2",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x31\x04\x02\x01\x01\x00\x00"
			     count: 7] ASN1DERValue])

	/* NumericString */
	TEST(@"Parsing of NumericString",
	    [[[[OFData dataWithItems: "\x12\x0B" "12345 67890"
			      count: 13] ASN1DERValue] numericStringValue]
	    isEqual: @"12345 67890"] &&
	    [[[[OFData dataWithItems: "\x12\x81\x80" "0000000000000000000000000"
				      "0000000000000000000000000000000000000000"
				      "0000000000000000000000000000000000000000"
				      "00000000000000000000000"

			       count: 131] ASN1DERValue] numericStringValue]
	    isEqual: @"00000000000000000000000000000000000000000000000000000000"
		     @"00000000000000000000000000000000000000000000000000000000"
		     @"0000000000000000"])

	EXPECT_EXCEPTION(@"Detection of invalid NumericString",
	    OFInvalidEncodingException,
	    [[OFData dataWithItems: "\x12\x02."
			     count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of out of range NumericString",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x12\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated NumericString",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x12\x01"

						       count: 2] ASN1DERValue])

	/* PrintableString */
	TEST(@"Parsing of PrintableString",
	    [[[[OFData dataWithItems: "\x13\x0CHello World."
			       count: 14] ASN1DERValue] printableStringValue]
	    isEqual: @"Hello World."] &&
	    [[[[OFData dataWithItems: "\x13\x81\x80 '()+,-./:=?abcdefghijklmnop"
				      "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()"
				      "+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEF"
				      "GHIJKLMNOPQRSTUVWXYZ"
			       count: 131] ASN1DERValue] printableStringValue]
	    isEqual: @" '()+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR"

		     @"STUVWXYZ '()+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEFGHIJ"
		     @"KLMNOPQRSTUVWXYZ"])

	EXPECT_EXCEPTION(@"Detection of invalid PrintableString",
	    OFInvalidEncodingException,
	    [[OFData dataWithItems: "\x13\x02;"
			     count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of out of range PrintableString",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x13\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated PrintableString",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x13\x01"

						       count: 2] ASN1DERValue])

	/* IA5String */
	TEST(@"Parsing of IA5String",
	    [[[[OFData dataWithItems: "\x16\x0CHello World!"
			       count: 14] ASN1DERValue] IA5StringValue]
	    isEqual: @"Hello World!"] &&
	    [[[[OFData dataWithItems: "\x16\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxx"
			       count: 131] ASN1DERValue] IA5StringValue]

	    isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
		     @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
		     @"xxxxxxxxxxxxxxxx"])

	EXPECT_EXCEPTION(@"Detection of invalid IA5String",
	    OFInvalidEncodingException,
	    [[OFData dataWithItems: "\x16\x02ä"
			     count: 4] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of out of range IA5String",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x16\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated IA5String",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x16\x01"

						       count: 2] ASN1DERValue])

	objc_autoreleasePoolPop(pool);
}
@end







|

|
|










>
|

|


|
>
|


|
>
|


|
>
|


|
>
|




>
|

>
|

>
|

>
|

>
|
|
|
>
|
|


|
>
|


|
>
|


|
>
|





|


|
>
|




|

|


|









|









|
>
|


|
>
|





|


|
>
|




|
|
|




>
|
|
|
|
<
|





|


|
>
|




>
|


|
>
|




|

|
|

|

|
|

|

|
|


|

|
|
|
|
|
|
|


|
>
|


|
>
|





|


|
>
|




|
>

|
>

>
|

|
>

>
|
|
|
>
|
|


|
>
|


|
>
|


|
>
|





|


|
>
|




|
|




|
>
|
|
|





|


|
>
|


|
>
|


|
>
|







|




|


|

|



|
>
|




|




|


|


|





|


|
>
|




|




|
|




>
|
|
|
|




|





|


|
>
|




|
|




|
|
>
|
|




|





|


|
>
|




|
|




|
>
|
|
|




|





|


|
>
|




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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
 * file.
 */

#include "config.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFData+ASN1DERParsing";

@implementation TestsAppDelegate (OFASN1DERParsingTests)
- (void)ASN1DERParsingTests
{
	void *pool = objc_autoreleasePoolPush();
	OFASN1BitString *bitString;
	OFArray *array;
	OFSet *set;
	OFEnumerator *enumerator;

	/* Boolean */
	TEST(@"Parsing of boolean",
	    ![[[OFData dataWithItems: "\x01\x01\x00"
			       count: 3] objectByParsingASN1DER]
	    booleanValue] &&
	    [[[OFData dataWithItems: "\x01\x01\xFF"
			      count: 3] objectByParsingASN1DER] booleanValue])

	EXPECT_EXCEPTION(@"Detection of invalid boolean #1",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x01\x01\x01"
			     count: 3] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid boolean #2",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x01\x02\x00\x00"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid boolean #3",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x01\x00"
			     count: 2] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated boolean",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x01\x01"
			     count: 2] objectByParsingASN1DER])

	/* Integer */
	TEST(@"Parsing of integer",
	    [[[OFData dataWithItems: "\x02\x00"
			      count: 2] objectByParsingASN1DER]
	    longLongValue] == 0 &&
	    [[[OFData dataWithItems: "\x02\x01\x01"
			      count: 3] objectByParsingASN1DER]
	    longLongValue] == 1 &&
	    [[[OFData dataWithItems: "\x02\x02\x01\x04"
			      count: 4] objectByParsingASN1DER]
	    longLongValue] == 260 &&
	    [[[OFData dataWithItems: "\x02\x01\xFF"
			      count: 3] objectByParsingASN1DER]
	    longLongValue] == -1 &&
	    [[[OFData dataWithItems: "\x02\x03\xFF\x00\x00"
			      count: 5] objectByParsingASN1DER]
	    longLongValue] == -65536 &&
	    (unsigned long long)[[[OFData dataWithItems: "\x02\x09\x00\xFF\xFF"
							 "\xFF\xFF\xFF\xFF\xFF"
							 "\xFF"
						  count: 11]
	    objectByParsingASN1DER] longLongValue] == ULLONG_MAX)

	EXPECT_EXCEPTION(@"Detection of invalid integer #1",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x02\x02\x00\x00"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid integer #2",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x02\x02\x00\x7F"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid integer #3",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x02\x02\xFF\x80"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range integer",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x02\x09\x01"
				    "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated integer",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x02\x02\x00"
			     count: 3] objectByParsingASN1DER])

	/* Bit string */
	TEST(@"Parsing of bit string",
	    (bitString = [[OFData dataWithItems: "\x03\x01\x00"
					  count: 3] objectByParsingASN1DER]) &&
	    [bitString.bitStringValue isEqual: [OFData dataWithItems: ""
							       count: 0]] &&
	    bitString.bitStringLength == 0 &&
	    (bitString = [[OFData dataWithItems: "\x03\x0D\x01Hello World\x80"
					  count: 15] objectByParsingASN1DER]) &&
	    [bitString.bitStringValue
	    isEqual: [OFData dataWithItems: "Hello World\x80"
				     count: 12]] &&
	    bitString.bitStringLength == 95 &&
	    (bitString = [[OFData dataWithItems: "\x03\x81\x80\x00xxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
					 count: 131] objectByParsingASN1DER]) &&
	    [bitString.bitStringValue
	    isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxx"
				     count: 127]] &&
	    bitString.bitStringLength == 127 * 8)

	EXPECT_EXCEPTION(@"Detection of invalid bit string #1",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x03\x00"
			     count: 2] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid bit string #2",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x03\x01\x01"
			     count: 3] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range bit string",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x03\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated bit string",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x03\x01"
			     count: 2] objectByParsingASN1DER])

	/* Octet string */
	TEST(@"Parsing of octet string",
	    [[[[OFData dataWithItems: "\x04\x0CHello World!"
			       count: 14] objectByParsingASN1DER]
	    octetStringValue] isEqual: [OFData dataWithItems: "Hello World!"
						       count: 12]] &&
	    [[[[OFData dataWithItems: "\x04\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxx"
			       count: 131] objectByParsingASN1DER]
	    octetStringValue] isEqual:
	    [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				   "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				   "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

			    count: 128]])

	EXPECT_EXCEPTION(@"Detection of out of range octet string",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x04\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated octet string",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x04\x01"
			     count: 2] objectByParsingASN1DER])

	/* Null */
	TEST(@"Parsing of null",
	    [[[OFData dataWithItems: "\x05\x00"
			      count: 2] objectByParsingASN1DER]
	    isEqual: [OFNull null]])

	EXPECT_EXCEPTION(@"Detection of invalid null",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x05\x01\x00"
			     count: 3] objectByParsingASN1DER])

	/* Object Identifier */
	TEST(@"Parsing of Object Identifier",
	    (array = [[[OFData dataWithItems: "\x06\x01\x27"
				       count: 3] objectByParsingASN1DER]
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] unsignedLongLongValue] == 0 &&
	    [[array objectAtIndex: 1] unsignedLongLongValue] == 39 &&
	    (array = [[[OFData dataWithItems: "\x06\x01\x4F"
				       count: 3] objectByParsingASN1DER]
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] unsignedLongLongValue] == 1 &&
	    [[array objectAtIndex: 1] unsignedLongLongValue] == 39 &&
	    (array = [[[OFData dataWithItems: "\x06\x02\x88\x37"
				       count: 4] objectByParsingASN1DER]
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] unsignedLongLongValue] == 2 &&
	    [[array objectAtIndex: 1] unsignedLongLongValue] == 999 &&
	    (array = [[[OFData dataWithItems: "\x06\x09\x2A\x86\x48\x86\xF7\x0D"
					      "\x01\x01\x0B"
				       count: 11] objectByParsingASN1DER]
	    subidentifiers]) && array.count == 7 &&
	    [[array objectAtIndex: 0] unsignedLongLongValue] == 1 &&
	    [[array objectAtIndex: 1] unsignedLongLongValue] == 2 &&
	    [[array objectAtIndex: 2] unsignedLongLongValue] == 840 &&
	    [[array objectAtIndex: 3] unsignedLongLongValue] == 113549 &&
	    [[array objectAtIndex: 4] unsignedLongLongValue] == 1 &&
	    [[array objectAtIndex: 5] unsignedLongLongValue] == 1 &&
	    [[array objectAtIndex: 6] unsignedLongLongValue] == 11)

	EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #1",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x06\x01\x81"
			     count: 3] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #2",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x06\x02\x80\x01"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range Object Identifier",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x06\x0A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
				    "\xFF\x7F"
			     count: 12] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated Object Identifier",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x06\x02\x00"
			     count: 3] objectByParsingASN1DER])

	/* Enumerated */
	TEST(@"Parsing of enumerated",
	    [[[OFData dataWithItems: "\x0A\x00"
			     count: 2] objectByParsingASN1DER] longLongValue] ==
	    0 &&
	    [[[OFData dataWithItems: "\x0A\x01\x01"
			     count: 3] objectByParsingASN1DER] longLongValue] ==
	    1 &&
	    [[[OFData dataWithItems: "\x0A\x02\x01\x04"
			     count: 4] objectByParsingASN1DER] longLongValue] ==
	    260 &&
	    [[[OFData dataWithItems: "\x0A\x01\xFF"
			     count: 3] objectByParsingASN1DER] longLongValue] ==
	    -1 &&
	    [[[OFData dataWithItems: "\x0A\x03\xFF\x00\x00"
			     count: 5] objectByParsingASN1DER] longLongValue] ==
	    -65536 &&
	    (unsigned long long)[[[OFData dataWithItems: "\x0A\x09\x00\xFF\xFF"
							 "\xFF\xFF\xFF\xFF\xFF"
							 "\xFF"
						  count: 11]
	    objectByParsingASN1DER] longLongValue] == ULLONG_MAX)

	EXPECT_EXCEPTION(@"Detection of invalid enumerated #1",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x0A\x02\x00\x00"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid enumerated #2",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x0A\x02\x00\x7F"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid enumerated #3",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x0A\x02\xFF\x80"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range enumerated",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x0A\x09\x01"
				    "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated enumerated",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x0A\x02\x00"
			     count: 3] objectByParsingASN1DER])

	/* UTF-8 string */
	TEST(@"Parsing of UTF-8 string",
	    [[[[OFData dataWithItems: "\x0C\x0EHällo Wörld!"
			       count: 16] objectByParsingASN1DER]
	    UTF8StringValue] isEqual: @"Hällo Wörld!"] &&
	    [[[[OFData dataWithItems: "\x0C\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxx"
			       count: 131] objectByParsingASN1DER]
	    UTF8StringValue] isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      @"xxxxxxxxxxx"])

	EXPECT_EXCEPTION(@"Detection of out of range UTF-8 string",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x0C\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated UTF-8 string",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x0C\x01"
			     count: 2] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated length",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x0C\x83\x01\x01"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #1",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x0C\x81\x7F"
			     count: 3] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #2",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x0C\x82\x00\x80xxxxxxxxxxxxxxxxxxxxxxxxxx"
				    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				    "xxxxxxxxxxxxxxxxxx"
			     count: 132] objectByParsingASN1DER])

	/* Sequence */
	TEST(@"Parsing of sequence",
	    (array = [[OFData dataWithItems: "\x30\x00"
				      count: 2] objectByParsingASN1DER]) &&
	    [array isKindOfClass: [OFArray class]] && array.count == 0 &&
	    (array = [[OFData dataWithItems: "\x30\x09\x02\x01\x7B\x0C\x04Test"
				      count: 11] objectByParsingASN1DER]) &&
	    [array isKindOfClass: [OFArray class]] && array.count == 2 &&
	    [[array objectAtIndex: 0] longLongValue] == 123 &&
	    [[[array objectAtIndex: 1] stringValue] isEqual: @"Test"])

	EXPECT_EXCEPTION(@"Detection of truncated sequence #1",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x30\x01"
			     count: 2] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated sequence #2",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x30\x04\x02\x01\x01\x00\x00"
			     count: 7] objectByParsingASN1DER])

	/* Set */
	TEST(@"Parsing of set",
	    (set = [[OFData dataWithItems: "\x31\x00"
				    count: 2] objectByParsingASN1DER]) &&
	    [set isKindOfClass: [OFSet class]] && set.count == 0 &&
	    (set = [[OFData dataWithItems: "\x31\x09\x02\x01\x7B\x0C\x04Test"
				    count: 11] objectByParsingASN1DER]) &&
	    [set isKindOfClass: [OFSet class]] && set.count == 2 &&
	    (enumerator = [set objectEnumerator]) &&
	    [[enumerator nextObject] longLongValue] == 123 &&
	    [[[enumerator nextObject] stringValue] isEqual: @"Test"])

	EXPECT_EXCEPTION(@"Detection of invalid set",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x31\x06\x02\x01\x02\x02\x01\x01"
			     count: 8] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated set #1",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x31\x01"
			     count: 2] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated set #2",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x31\x04\x02\x01\x01\x00\x00"
			     count: 7] objectByParsingASN1DER])

	/* NumericString */
	TEST(@"Parsing of NumericString",
	    [[[[OFData dataWithItems: "\x12\x0B" "12345 67890"
			       count: 13] objectByParsingASN1DER]
	    numericStringValue] isEqual: @"12345 67890"] &&
	    [[[[OFData dataWithItems: "\x12\x81\x80" "0000000000000000000000000"
				      "0000000000000000000000000000000000000000"
				      "0000000000000000000000000000000000000000"
				      "00000000000000000000000"
			       count: 131] objectByParsingASN1DER]
	    numericStringValue] isEqual: @"000000000000000000000000000000000000"
					 @"000000000000000000000000000000000000"
					 @"000000000000000000000000000000000000"
					 @"00000000000000000000"])

	EXPECT_EXCEPTION(@"Detection of invalid NumericString",
	    OFInvalidEncodingException,
	    [[OFData dataWithItems: "\x12\x02."
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range NumericString",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x12\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated NumericString",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x12\x01"
			     count: 2] objectByParsingASN1DER])

	/* PrintableString */
	TEST(@"Parsing of PrintableString",
	    [[[[OFData dataWithItems: "\x13\x0CHello World."
			       count: 14] objectByParsingASN1DER]
	    printableStringValue] isEqual: @"Hello World."] &&
	    [[[[OFData dataWithItems: "\x13\x81\x80 '()+,-./:=?abcdefghijklmnop"
				      "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()"
				      "+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEF"
				      "GHIJKLMNOPQRSTUVWXYZ"
			       count: 131] objectByParsingASN1DER]
	    printableStringValue] isEqual: @" '()+,-./:=?abcdefghijklmnopqrstuv"
					   @"wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()"
					   @"+,-./:=?abcdefghijklmnopqrstuvwxyz"
					   @"ABCDEFGHIJKLMNOPQRSTUVWXYZ"])

	EXPECT_EXCEPTION(@"Detection of invalid PrintableString",
	    OFInvalidEncodingException,
	    [[OFData dataWithItems: "\x13\x02;"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range PrintableString",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x13\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated PrintableString",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x13\x01"
			     count: 2] objectByParsingASN1DER])

	/* IA5String */
	TEST(@"Parsing of IA5String",
	    [[[[OFData dataWithItems: "\x16\x0CHello World!"
			       count: 14] objectByParsingASN1DER]
	    IA5StringValue] isEqual: @"Hello World!"] &&
	    [[[[OFData dataWithItems: "\x16\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxx"
			       count: 131] objectByParsingASN1DER]
	    IA5StringValue] isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				     @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				     @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				     @"xxxxxxxx"])

	EXPECT_EXCEPTION(@"Detection of invalid IA5String",
	    OFInvalidEncodingException,
	    [[OFData dataWithItems: "\x16\x02ä"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range IA5String",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x16\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated IA5String",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x16\x01"
			     count: 2] objectByParsingASN1DER])

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFArrayTests.m from [52ca507d81] to [650205073d].

418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
		return left;
	    }])
#endif

	TEST(@"-[valueForKey:]",
	    [[[arrayClass arrayWithObjects: @"foo", @"bar", @"quxqux", nil]
	    valueForKey: @"length"] isEqual:
	    [arrayClass arrayWithObjects: [OFNumber numberWithSize: 3],
	    [OFNumber numberWithSize: 3], [OFNumber numberWithSize: 6], nil]] &&
	    [[[arrayClass arrayWithObjects: @"1", @"2", nil]
	    valueForKey: @"@count"] isEqual: [OFNumber numberWithSize: 2]])

	m[0] = [mutableArrayClass arrayWithObjects:
	    [OFMutableURL URLWithString: @"http://foo.bar/"],
	    [OFMutableURL URLWithString: @"http://bar.qux/"],
	    [OFMutableURL URLWithString: @"http://qux.quxqux/"], nil];
	TEST(@"-[setValue:forKey:]",
	    R([m[0] setValue: [OFNumber numberWithShort: 1234]







|
|

|







418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
		return left;
	    }])
#endif

	TEST(@"-[valueForKey:]",
	    [[[arrayClass arrayWithObjects: @"foo", @"bar", @"quxqux", nil]
	    valueForKey: @"length"] isEqual:
	    [arrayClass arrayWithObjects: [OFNumber numberWithInt: 3],
	    [OFNumber numberWithInt: 3], [OFNumber numberWithInt: 6], nil]] &&
	    [[[arrayClass arrayWithObjects: @"1", @"2", nil]
	    valueForKey: @"@count"] isEqual: [OFNumber numberWithInt: 2]])

	m[0] = [mutableArrayClass arrayWithObjects:
	    [OFMutableURL URLWithString: @"http://foo.bar/"],
	    [OFMutableURL URLWithString: @"http://bar.qux/"],
	    [OFMutableURL URLWithString: @"http://qux.quxqux/"], nil];
	TEST(@"-[setValue:forKey:]",
	    R([m[0] setValue: [OFNumber numberWithShort: 1234]

Modified tests/OFDictionaryTests.m from [f19c5b9455] to [a25483183f].

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
	    [[mutDict objectForKey: keys[0]] isEqual: values[0]] &&
	    [[mutDict objectForKey: keys[1]] isEqual: values[1]] &&
	    [mutDict objectForKey: @"key3"] == nil)

	TEST(@"-[valueForKey:]",
	    [[mutDict valueForKey: keys[0]] isEqual: values[0]] &&
	    [[mutDict valueForKey: @"@count"] isEqual:
	    [OFNumber numberWithSize: 2]])

	EXPECT_EXCEPTION(@"Catching -[setValue:forKey:] on immutable "
	    @"dictionary", OFUndefinedKeyException,
	    [[dictionaryClass dictionary] setValue: @"x"
					    forKey: @"x"])

	TEST(@"-[containsObject:]",







|







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
	    [[mutDict objectForKey: keys[0]] isEqual: values[0]] &&
	    [[mutDict objectForKey: keys[1]] isEqual: values[1]] &&
	    [mutDict objectForKey: @"key3"] == nil)

	TEST(@"-[valueForKey:]",
	    [[mutDict valueForKey: keys[0]] isEqual: values[0]] &&
	    [[mutDict valueForKey: @"@count"] isEqual:
	    [OFNumber numberWithInt: 2]])

	EXPECT_EXCEPTION(@"Catching -[setValue:forKey:] on immutable "
	    @"dictionary", OFUndefinedKeyException,
	    [[dictionaryClass dictionary] setValue: @"x"
					    forKey: @"x"])

	TEST(@"-[containsObject:]",

Modified tests/OFJSONTests.m from [9395f43f69] to [dda895677f].

34
35
36
37
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
	    [OFNumber numberWithInt: 0xF],
	    [OFNull null],
	    @"foo",
	    [OFNumber numberWithBool: false],
	    nil],
	    nil];

	TEST(@"-[JSONValue] #1", [s.JSONValue isEqual: d])

	TEST(@"-[JSONRepresentation]", [[d JSONRepresentation] isEqual:
	    @"{\"x\":[0.5,15,null,\"foo\",false],\"foo\":\"b\\na\\r\"}"])

	TEST(@"OF_JSON_REPRESENTATION_PRETTY",
	    [[d JSONRepresentationWithOptions: OF_JSON_REPRESENTATION_PRETTY]
	    isEqual: @"{\n\t\"x\": [\n\t\t0.5,\n\t\t15,\n\t\tnull,\n\t\t"
		     @"\"foo\",\n\t\tfalse\n\t],\n\t\"foo\": \"b\\na\\r\"\n}"])

	TEST(@"OF_JSON_REPRESENTATION_JSON5",
	    [[d JSONRepresentationWithOptions: OF_JSON_REPRESENTATION_JSON5]
	    isEqual: @"{x:[0.5,15,null,\"foo\",false],foo:\"b\\\na\\r\"}"])

	EXPECT_EXCEPTION(@"-[JSONValue] #2", OFInvalidJSONException,
	    [@"{" JSONValue])
	EXPECT_EXCEPTION(@"-[JSONValue] #3", OFInvalidJSONException,
	    [@"]" JSONValue])
	EXPECT_EXCEPTION(@"-[JSONValue] #4", OFInvalidJSONException,
	    [@"bar" JSONValue])
	EXPECT_EXCEPTION(@"-[JSONValue] #5", OFInvalidJSONException,
	    [@"[\"a\" \"b\"]" JSONValue])

	TEST(@"-[JSONValue] #6",
	    [@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
	    .JSONValue isEqual: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject:
	    [OFDictionary dictionary]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]])

	EXPECT_EXCEPTION(@"-[JSONValue] #7", OFInvalidJSONException,
	    [@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
	    JSONValue])

	objc_autoreleasePoolPop(pool);
}
@end







|













|
|
|
|
|
|
|
|

|

|

















|

|




34
35
36
37
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
	    [OFNumber numberWithInt: 0xF],
	    [OFNull null],
	    @"foo",
	    [OFNumber numberWithBool: false],
	    nil],
	    nil];

	TEST(@"-[objectByParsingJSON] #1", [s.objectByParsingJSON isEqual: d])

	TEST(@"-[JSONRepresentation]", [[d JSONRepresentation] isEqual:
	    @"{\"x\":[0.5,15,null,\"foo\",false],\"foo\":\"b\\na\\r\"}"])

	TEST(@"OF_JSON_REPRESENTATION_PRETTY",
	    [[d JSONRepresentationWithOptions: OF_JSON_REPRESENTATION_PRETTY]
	    isEqual: @"{\n\t\"x\": [\n\t\t0.5,\n\t\t15,\n\t\tnull,\n\t\t"
		     @"\"foo\",\n\t\tfalse\n\t],\n\t\"foo\": \"b\\na\\r\"\n}"])

	TEST(@"OF_JSON_REPRESENTATION_JSON5",
	    [[d JSONRepresentationWithOptions: OF_JSON_REPRESENTATION_JSON5]
	    isEqual: @"{x:[0.5,15,null,\"foo\",false],foo:\"b\\\na\\r\"}"])

	EXPECT_EXCEPTION(@"-[objectByParsingJSON] #2", OFInvalidJSONException,
	    [@"{" objectByParsingJSON])
	EXPECT_EXCEPTION(@"-[objectByParsingJSON] #3", OFInvalidJSONException,
	    [@"]" objectByParsingJSON])
	EXPECT_EXCEPTION(@"-[objectByParsingJSON] #4", OFInvalidJSONException,
	    [@"bar" objectByParsingJSON])
	EXPECT_EXCEPTION(@"-[objectByParsingJSON] #5", OFInvalidJSONException,
	    [@"[\"a\" \"b\"]" objectByParsingJSON])

	TEST(@"-[objectByParsingJSON] #6",
	    [@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
	    .objectByParsingJSON isEqual: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject:
	    [OFDictionary dictionary]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]])

	EXPECT_EXCEPTION(@"-[objectByParsingJSON] #7", OFInvalidJSONException,
	    [@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
	    objectByParsingJSON])

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFNumberTests.m from [dde130d271] to [ccb8cb8682].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

@implementation TestsAppDelegate (OFNumberTests)
- (void)numberTests
{
	void *pool = objc_autoreleasePoolPush();
	OFNumber *num;

	TEST(@"+[numberWithIntMax:]",
	    (num = [OFNumber numberWithIntMax: 123456789]))

	TEST(@"-[isEqual:]",
	    [num isEqual: [OFNumber numberWithUInt32: 123456789]])

	TEST(@"-[hash]", num.hash == 0x82D8BC42)

	TEST(@"-[charValue]", num.charValue == 21)

	TEST(@"-[doubleValue]", num.doubleValue == 123456789.L)

	objc_autoreleasePoolPop(pool);
}
@end







|
|


|










23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

@implementation TestsAppDelegate (OFNumberTests)
- (void)numberTests
{
	void *pool = objc_autoreleasePoolPush();
	OFNumber *num;

	TEST(@"+[numberWithLongLong:]",
	    (num = [OFNumber numberWithLongLong: 123456789]))

	TEST(@"-[isEqual:]",
	    [num isEqual: [OFNumber numberWithLong: 123456789]])

	TEST(@"-[hash]", num.hash == 0x82D8BC42)

	TEST(@"-[charValue]", num.charValue == 21)

	TEST(@"-[doubleValue]", num.doubleValue == 123456789.L)

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFPropertyListTests.m from [709f5222a8] to [0566a8c454].

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
	    [OFDate dateWithTimeIntervalSince1970: 1521030896],
	    [OFNumber numberWithBool: true],
	    [OFNumber numberWithBool: false],
	    [OFNumber numberWithFloat: 12.25],
	    [OFNumber numberWithInt: -10],
	    nil];

	TEST(@"-[propertyListValue:] #1",
	    [PLIST1.propertyListValue isEqual: @"Hello"])

	TEST(@"-[propertyListValue:] #2",
	    [PLIST2.propertyListValue isEqual: array])

	TEST(@"-[propertyListValue:] #3",
	    [PLIST3.propertyListValue isEqual:
	    [OFDictionary dictionaryWithKeysAndObjects:
	    @"array", array,
	    @"foo", @"bar",
	    nil]])

	EXPECT_EXCEPTION(@"-[propertyListValue] detecting unsupported version",
	    OFUnsupportedVersionException,
	    [[PLIST(@"<string/>") stringByReplacingOccurrencesOfString: @"1.0"
							    withString: @"1.1"]
	    propertyListValue])

	EXPECT_EXCEPTION(
	    @"-[propertyListValue] detecting invalid format #1",
	    OFInvalidFormatException,
	    [PLIST(@"<string x='b'/>") propertyListValue])

	EXPECT_EXCEPTION(
	    @"-[propertyListValue] detecting invalid format #2",
	    OFInvalidFormatException,
	    [PLIST(@"<string xmlns='foo'/>") propertyListValue])

	EXPECT_EXCEPTION(
	    @"-[propertyListValue] detecting invalid format #3",
	    OFInvalidFormatException,
	    [PLIST(@"<dict count='0'/>") propertyListValue])

	EXPECT_EXCEPTION(
	    @"-[propertyListValue] detecting invalid format #4",
	    OFInvalidFormatException,
	    [PLIST(@"<dict><key/><string/><key/></dict>") propertyListValue])


	EXPECT_EXCEPTION(
	    @"-[propertyListValue] detecting invalid format #5",
	    OFInvalidFormatException,
	    [PLIST(@"<dict><key x='x'/><string/></dict>") propertyListValue])


	objc_autoreleasePoolPop(pool);
}
@end







|
|

|
|

|
|





|



|


|

|


|

|


|

|


|

|
>


|

|
>




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
	    [OFDate dateWithTimeIntervalSince1970: 1521030896],
	    [OFNumber numberWithBool: true],
	    [OFNumber numberWithBool: false],
	    [OFNumber numberWithFloat: 12.25],
	    [OFNumber numberWithInt: -10],
	    nil];

	TEST(@"-[objectByParsingPropertyList:] #1",
	    [PLIST1.objectByParsingPropertyList isEqual: @"Hello"])

	TEST(@"-[objectByParsingPropertyList:] #2",
	    [PLIST2.objectByParsingPropertyList isEqual: array])

	TEST(@"-[objectByParsingPropertyList:] #3",
	    [PLIST3.objectByParsingPropertyList isEqual:
	    [OFDictionary dictionaryWithKeysAndObjects:
	    @"array", array,
	    @"foo", @"bar",
	    nil]])

	EXPECT_EXCEPTION(@"Detecting unsupported version",
	    OFUnsupportedVersionException,
	    [[PLIST(@"<string/>") stringByReplacingOccurrencesOfString: @"1.0"
							    withString: @"1.1"]
	    objectByParsingPropertyList])

	EXPECT_EXCEPTION(
	    @"-[objectByParsingPropertyList] detecting invalid format #1",
	    OFInvalidFormatException,
	    [PLIST(@"<string x='b'/>") objectByParsingPropertyList])

	EXPECT_EXCEPTION(
	    @"-[objectByParsingPropertyList] detecting invalid format #2",
	    OFInvalidFormatException,
	    [PLIST(@"<string xmlns='foo'/>") objectByParsingPropertyList])

	EXPECT_EXCEPTION(
	    @"-[objectByParsingPropertyList] detecting invalid format #3",
	    OFInvalidFormatException,
	    [PLIST(@"<dict count='0'/>") objectByParsingPropertyList])

	EXPECT_EXCEPTION(
	    @"-[objectByParsingPropertyList] detecting invalid format #4",
	    OFInvalidFormatException,
	    [PLIST(@"<dict><key/><string/><key/></dict>")
	    objectByParsingPropertyList])

	EXPECT_EXCEPTION(
	    @"-[objectByParsingPropertyList] detecting invalid format #5",
	    OFInvalidFormatException,
	    [PLIST(@"<dict><key x='x'/><string/></dict>")
	    objectByParsingPropertyList])

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFSetTests.m from [5ad06a7715] to [1aa6d32b7b].

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
	}

	TEST(@"Detection of mutation during Fast Enumeration", ok);

	TEST(@"-[valueForKey:]",
	    [(set1 = [[setClass setWithObjects: @"a", @"ab", @"abc", @"b", nil]
	    valueForKey: @"length"]) isEqual: [setClass setWithObjects:
	    [OFNumber numberWithSize: 1], [OFNumber numberWithSize: 2],
	    [OFNumber numberWithSize: 3], nil]] &&
	    [[set1 valueForKey: @"@count"] isEqual:
	    [OFNumber numberWithSize: 3]])

	objc_autoreleasePoolPop(pool);
}

- (void)setTests
{
	module = @"OFSet";







|
|

|







274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
	}

	TEST(@"Detection of mutation during Fast Enumeration", ok);

	TEST(@"-[valueForKey:]",
	    [(set1 = [[setClass setWithObjects: @"a", @"ab", @"abc", @"b", nil]
	    valueForKey: @"length"]) isEqual: [setClass setWithObjects:
	    [OFNumber numberWithInt: 1], [OFNumber numberWithInt: 2],
	    [OFNumber numberWithInt: 3], nil]] &&
	    [[set1 valueForKey: @"@count"] isEqual:
	    [OFNumber numberWithInt: 3]])

	objc_autoreleasePoolPop(pool);
}

- (void)setTests
{
	module = @"OFSet";

Modified tests/OFStringTests.m from [bf0332c491] to [1ca0b0e0e8].

1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075

1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089






1090
1091
1092
1093
1094
1095
1096
	    [C(@"\\\\foo\\..\\bar\\qux").stringByStandardizingPath
	    isEqual: @"\\\\bar\\qux"] &&
	    [C(@"c:\\..\\asd").stringByStandardizingPath
	    isEqual: @"c:\\..\\asd"])
# endif
#endif

	TEST(@"-[decimalValue]",
	    C(@"1234").decimalValue == 1234 &&
	    C(@"\r\n+123  ").decimalValue == 123 &&
	    C(@"-500\t").decimalValue == -500 &&

	    C(@"\t\t\r\n").decimalValue == 0)

	TEST(@"-[hexadecimalValue]",
	    C(@"123f").hexadecimalValue == 0x123f &&
	    C(@"\t\n0xABcd\r").hexadecimalValue == 0xABCD &&
	    C(@"  xbCDE").hexadecimalValue == 0xBCDE &&
	    C(@"$CdEf").hexadecimalValue == 0xCDEF &&
	    C(@"\rFeh ").hexadecimalValue == 0xFE &&
	    C(@"\r\t").hexadecimalValue == 0)

	TEST(@"-[octalValue]",
	    C(@"1234567").octalValue == 01234567 &&
	    C(@"\r\n123").octalValue == 0123 &&
	    C(@"765\t").octalValue == 0765 && C(@"\t\t\r\n").octalValue == 0)







	/*
	 * These test numbers can be generated without rounding if we have IEEE
	 * floating point numbers, thus we can use == on them.
	 */
	TEST(@"-[floatValue]",
	    C(@"\t-0.25 ").floatValue == -0.25 &&







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

|
|
|
|
>
>
>
>
>
>







1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078


1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
	    [C(@"\\\\foo\\..\\bar\\qux").stringByStandardizingPath
	    isEqual: @"\\\\bar\\qux"] &&
	    [C(@"c:\\..\\asd").stringByStandardizingPath
	    isEqual: @"c:\\..\\asd"])
# endif
#endif

	TEST(@"-[longLongValue]",
	    C(@"1234").longLongValue == 1234 &&
	    C(@"\r\n+123  ").longLongValue == 123 &&
	    C(@"-500\t").longLongValue == -500 &&
	    [C(@"-0x10\t") longLongValueWithBase: 0] == -0x10 &&
	    C(@"\t\t\r\n").longLongValue == 0 &&
	    [C(@"123f") longLongValueWithBase: 16] == 0x123f &&


	    [C(@"\t\n0xABcd\r") longLongValueWithBase: 0] == 0xABCD &&
	    [C(@"1234567") longLongValueWithBase: 8] == 01234567 &&
	    [C(@"\r\n0123") longLongValueWithBase: 0] == 0123 &&
	    [C(@"765\t") longLongValueWithBase: 8] == 0765 &&
	    [C(@"\t\t\r\n") longLongValueWithBase: 8] == 0)

	TEST(@"-[unsignedLongLongValue]",
	    C(@"1234").unsignedLongLongValue == 1234 &&
	    C(@"\r\n+123  ").unsignedLongLongValue == 123 &&
	    C(@"\t\t\r\n").unsignedLongLongValue == 0 &&
	    [C(@"123f") unsignedLongLongValueWithBase: 16] == 0x123f &&
	    [C(@"\t\n0xABcd\r") unsignedLongLongValueWithBase: 0] == 0xABCD &&
	    [C(@"1234567") unsignedLongLongValueWithBase: 8] == 01234567 &&
	    [C(@"\r\n0123") unsignedLongLongValueWithBase: 0] == 0123 &&
	    [C(@"765\t") unsignedLongLongValueWithBase: 8] == 0765 &&
	    [C(@"\t\t\r\n") unsignedLongLongValueWithBase: 8] == 0)

	/*
	 * These test numbers can be generated without rounding if we have IEEE
	 * floating point numbers, thus we can use == on them.
	 */
	TEST(@"-[floatValue]",
	    C(@"\t-0.25 ").floatValue == -0.25 &&
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
#else
/* Android, Solaris, DJGPP and AmigaOS3 do not accept 0x for strtod() */
# if (!defined(OF_SOLARIS) || !defined(OF_X86)) && !defined(OF_AMIGAOS_M68K)
#  define INPUT @"\t-0.123456789 "
#  define EXPECTED -0.123456789
# else
/*
 * Solaris' strtod() has weird rounding on x86, but not on x86_64/
 * AmigaOS 3 with libnix has weird rounding as well.
 */
#  define INPUT @"\t-0.125 "
#  define EXPECTED -0.125
# endif
#endif
	TEST(@"-[doubleValue]",
	    INPUT.doubleValue == EXPECTED &&
	    C(@"\r\n\tINF\t\n").doubleValue == INFINITY &&
	    C(@"\r -INFINITY\n").doubleValue == -INFINITY &&
	    isnan(C(@"   NAN\t\t").doubleValue))
#undef INPUT
#undef EXPECTED

	EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #1",
	    OFInvalidFormatException, [C(@"abc") decimalValue])
	EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #2",
	    OFInvalidFormatException, [C(@"0a") decimalValue])
	EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #3",
	    OFInvalidFormatException, [C(@"0 1") decimalValue])

	EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #1",
	    OFInvalidFormatException, [C(@"0xABCDEFG") hexadecimalValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #2",
	    OFInvalidFormatException, [C(@"0x") hexadecimalValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #3",
	    OFInvalidFormatException, [C(@"$") hexadecimalValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #4",
	    OFInvalidFormatException, [C(@"$ ") hexadecimalValue])

	EXPECT_EXCEPTION(@"Detect invalid chars in -[floatValue] #1",
	    OFInvalidFormatException, [C(@"0.0a") floatValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[floatValue] #2",
	    OFInvalidFormatException, [C(@"0 0") floatValue])
#ifdef HAVE_STRTOF_L
	/*







|














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







1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137

1138


1139

1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
#else
/* Android, Solaris, DJGPP and AmigaOS3 do not accept 0x for strtod() */
# if (!defined(OF_SOLARIS) || !defined(OF_X86)) && !defined(OF_AMIGAOS_M68K)
#  define INPUT @"\t-0.123456789 "
#  define EXPECTED -0.123456789
# else
/*
 * Solaris' strtod() has weird rounding on x86, but not on x86_64.
 * AmigaOS 3 with libnix has weird rounding as well.
 */
#  define INPUT @"\t-0.125 "
#  define EXPECTED -0.125
# endif
#endif
	TEST(@"-[doubleValue]",
	    INPUT.doubleValue == EXPECTED &&
	    C(@"\r\n\tINF\t\n").doubleValue == INFINITY &&
	    C(@"\r -INFINITY\n").doubleValue == -INFINITY &&
	    isnan(C(@"   NAN\t\t").doubleValue))
#undef INPUT
#undef EXPECTED

	EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #1",
	    OFInvalidFormatException, [C(@"abc") longLongValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #2",
	    OFInvalidFormatException, [C(@"0a") longLongValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #3",
	    OFInvalidFormatException, [C(@"0 1") longLongValue])

	EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #4",


	    OFInvalidFormatException,

	    [C(@"0xABCDEFG") longLongValueWithBase: 0])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #5",
	    OFInvalidFormatException, [C(@"0x") longLongValueWithBase: 0])

	EXPECT_EXCEPTION(@"Detect invalid chars in -[floatValue] #1",
	    OFInvalidFormatException, [C(@"0.0a") floatValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[floatValue] #2",
	    OFInvalidFormatException, [C(@"0 0") floatValue])
#ifdef HAVE_STRTOF_L
	/*
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
	 * Only do this if we have strtod_l, as the locale might allow the
	 * comma.
	 */
	EXPECT_EXCEPTION(@"Detect invalid chars in -[doubleValue] #3",
	    OFInvalidFormatException, [C(@"0,0") doubleValue])
#endif

	EXPECT_EXCEPTION(@"Detect out of range in -[decimalValue]",
	    OFOutOfRangeException,
	    [C(@"12345678901234567890123456789012345678901234567890"
	       @"12345678901234567890123456789012345678901234567890")
	    decimalValue])

	EXPECT_EXCEPTION(@"Detect out of range in -[hexadecimalValue]",
	    OFOutOfRangeException,
	    [C(@"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
	       @"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF")
	    hexadecimalValue])

	TEST(@"-[characters]", (ua = C(@"fööbär🀺").characters) &&
	    !memcmp(ua, ucstr + 1, sizeof(ucstr) - 8))

#ifdef OF_BIG_ENDIAN
# define SWAPPED_BYTE_ORDER OF_BYTE_ORDER_LITTLE_ENDIAN
#else







|

|

|

|



|







1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
	 * Only do this if we have strtod_l, as the locale might allow the
	 * comma.
	 */
	EXPECT_EXCEPTION(@"Detect invalid chars in -[doubleValue] #3",
	    OFInvalidFormatException, [C(@"0,0") doubleValue])
#endif

	EXPECT_EXCEPTION(@"Detect out of range in -[longLongValue]",
	    OFOutOfRangeException,
	    [C(@"-12345678901234567890123456789012345678901234567890"
	       @"12345678901234567890123456789012345678901234567890")
	    longLongValueWithBase: 16])

	EXPECT_EXCEPTION(@"Detect out of range in -[unsignedLongLongValue]",
	    OFOutOfRangeException,
	    [C(@"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
	       @"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF")
	    unsignedLongLongValueWithBase: 16])

	TEST(@"-[characters]", (ua = C(@"fööbär🀺").characters) &&
	    !memcmp(ua, ucstr + 1, sizeof(ucstr) - 8))

#ifdef OF_BIG_ENDIAN
# define SWAPPED_BYTE_ORDER OF_BYTE_ORDER_LITTLE_ENDIAN
#else

Modified tests/OFURLTests.m from [8b6c1d8b68] to [52cea266a3].

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

	TEST(@"-[user]", [u1.user isEqual: @"us:er"] && u4.user == nil)
	TEST(@"-[password]",
	    [u1.password isEqual: @"p@w"] && u4.password == nil)
	TEST(@"-[host]", [u1.host isEqual: @"ho:st"] &&
	    [u6.host isEqual: @"12:34::56:abcd"] &&
	    [u7.host isEqual: @"12:34::56:abcd"])
	TEST(@"-[port]", [u1.port isEqual: [OFNumber numberWithUInt16: 1234]] &&
	    [u4 port] == nil &&
	    [u7.port isEqual: [OFNumber numberWithUInt16: 234]])
	TEST(@"-[path]",
	    [u1.path isEqual: @"/pa?th"] && [u4.path isEqual: @"/etc/passwd"])
	TEST(@"-[pathComponents]",
	    [u1.pathComponents isEqual:
	    [OFArray arrayWithObjects: @"/", @"pa?th", nil]] &&
	    [u4.pathComponents isEqual:
	    [OFArray arrayWithObjects: @"/", @"etc", @"passwd", nil]] &&







|
|
<







152
153
154
155
156
157
158
159
160

161
162
163
164
165
166
167

	TEST(@"-[user]", [u1.user isEqual: @"us:er"] && u4.user == nil)
	TEST(@"-[password]",
	    [u1.password isEqual: @"p@w"] && u4.password == nil)
	TEST(@"-[host]", [u1.host isEqual: @"ho:st"] &&
	    [u6.host isEqual: @"12:34::56:abcd"] &&
	    [u7.host isEqual: @"12:34::56:abcd"])
	TEST(@"-[port]", u1.port.unsignedShortValue == 1234 &&
	    [u4 port] == nil && u7.port.unsignedShortValue == 234)

	TEST(@"-[path]",
	    [u1.path isEqual: @"/pa?th"] && [u4.path isEqual: @"/etc/passwd"])
	TEST(@"-[pathComponents]",
	    [u1.pathComponents isEqual:
	    [OFArray arrayWithObjects: @"/", @"pa?th", nil]] &&
	    [u4.pathComponents isEqual:
	    [OFArray arrayWithObjects: @"/", @"etc", @"passwd", nil]] &&

Modified tests/TestsAppDelegate.h from [9cb5b35481] to [0e4b40ac71].

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
	     inModule: (OFString *)module;
- (void)outputSuccess: (OFString *)test
	     inModule: (OFString *)module;
- (void)outputFailure: (OFString *)test
	     inModule: (OFString *)module;
@end

@interface TestsAppDelegate (OFASN1DERValueTests)
- (void)ASN1DERValueTests;
@end

@interface TestsAppDelegate (OFASN1DERRepresentationTests)
- (void)ASN1DERRepresentationTests;
@end

@interface TestsAppDelegate (OFArrayTests)







|
|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
	     inModule: (OFString *)module;
- (void)outputSuccess: (OFString *)test
	     inModule: (OFString *)module;
- (void)outputFailure: (OFString *)test
	     inModule: (OFString *)module;
@end

@interface TestsAppDelegate (OFASN1DERParsingTests)
- (void)ASN1DERParsingTests;
@end

@interface TestsAppDelegate (OFASN1DERRepresentationTests)
- (void)ASN1DERRepresentationTests;
@end

@interface TestsAppDelegate (OFArrayTests)

Modified tests/TestsAppDelegate.m from [3cf677c3a1] to [6a1c29e396].

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
	[self XMLNodeTests];
	[self XMLElementBuilderTests];
#ifdef OF_HAVE_FILES
	[self serializationTests];
#endif
	[self JSONTests];
	[self propertyListTests];
	[self ASN1DERValueTests];
	[self ASN1DERRepresentationTests];
#if defined(OF_HAVE_PLUGINS)
	[self pluginTests];
#endif
#ifdef OF_WINDOWS
	[self windowsRegistryKeyTests];
#endif







|







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
	[self XMLNodeTests];
	[self XMLElementBuilderTests];
#ifdef OF_HAVE_FILES
	[self serializationTests];
#endif
	[self JSONTests];
	[self propertyListTests];
	[self ASN1DERParsingTests];
	[self ASN1DERRepresentationTests];
#if defined(OF_HAVE_PLUGINS)
	[self pluginTests];
#endif
#ifdef OF_WINDOWS
	[self windowsRegistryKeyTests];
#endif

Modified tests/iOS.xcodeproj/project.pbxproj from [f9b1054ae0] to [feb9f04764].

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
				INFOPLIST_FILE = Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				LIBRARY_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)",
				);
				OTHER_LDFLAGS = "-ObjC";
				PRODUCT_BUNDLE_IDENTIFIER = zone.heap.objfw.tests;
				PRODUCT_NAME = "$(TARGET_NAME)";
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Debug;
		};
		4BEBFB732013934E002E8710 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				CODE_SIGN_STYLE = Automatic;
				DEVELOPMENT_TEAM = MXKNFCKFL6;
				FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../src";
				INFOPLIST_FILE = Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				LIBRARY_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)",
				);
				OTHER_LDFLAGS = "-ObjC";
				PRODUCT_BUNDLE_IDENTIFIER = zone.heap.objfw.tests;
				PRODUCT_NAME = "$(TARGET_NAME)";
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Release;
		};
/* End XCBuildConfiguration section */








|



















|







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
				INFOPLIST_FILE = Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				LIBRARY_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)",
				);
				OTHER_LDFLAGS = "-ObjC";
				PRODUCT_BUNDLE_IDENTIFIER = im.nil.objfw.tests;
				PRODUCT_NAME = "$(TARGET_NAME)";
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Debug;
		};
		4BEBFB732013934E002E8710 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				CODE_SIGN_STYLE = Automatic;
				DEVELOPMENT_TEAM = MXKNFCKFL6;
				FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../src";
				INFOPLIST_FILE = Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				LIBRARY_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)",
				);
				OTHER_LDFLAGS = "-ObjC";
				PRODUCT_BUNDLE_IDENTIFIER = im.nil.objfw.tests;
				PRODUCT_NAME = "$(TARGET_NAME)";
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

Modified tests/plugin/Info.plist.in from [e94bac378f] to [bbe65d4bbd].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>TestPlugin</string>
	<key>CFBundleName</key>
	<string>TestPlugin</string>
	<key>CFBundleIdentifier</key>
	<string>zone.heap.objfw.testplugin</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>BNDL</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>MinimumOSVersion</key>
	<string>9.0</string>
</dict>
</plist>









|












1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>TestPlugin</string>
	<key>CFBundleName</key>
	<string>TestPlugin</string>
	<key>CFBundleIdentifier</key>
	<string>im.nil.objfw.tests.plugin</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>BNDL</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>MinimumOSVersion</key>
	<string>9.0</string>
</dict>
</plist>

Modified tests/serialization.xml from [904cd48eb0] to [c1b84078b7].

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    <object>
      <OFString>data</OFString>
    </object>
    <key>
      <OFArray>
        <OFString>Qu&quot;xbar
test</OFString>
        <OFNumber type='unsigned'>1234</OFNumber>
        <OFNumber type='float'>40934a456d5cfaad</OFNumber>
        <OFMutableString>asd</OFMutableString>
        <OFDate>40934a456d5cfaad</OFDate>
      </OFArray>
    </key>
    <object>
      <OFString>Hello</OFString>







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    <object>
      <OFString>data</OFString>
    </object>
    <key>
      <OFArray>
        <OFString>Qu&quot;xbar
test</OFString>
        <OFNumber type='signed'>1234</OFNumber>
        <OFNumber type='float'>40934a456d5cfaad</OFNumber>
        <OFMutableString>asd</OFMutableString>
        <OFDate>40934a456d5cfaad</OFDate>
      </OFArray>
    </key>
    <object>
      <OFString>Hello</OFString>

Modified utils/ofarc/LHAArchive.m from [b717d78c4a] to [da084987c7].

42
43
44
45
46
47
48



49
50
51
52
53
54
55
setPermissions(OFString *path, OFLHAArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	OFNumber *mode = entry.mode;

	if (mode == nil)
		return;




	of_file_attributes_t attributes = [OFDictionary
	    dictionaryWithObject: mode
			  forKey: of_file_attribute_key_posix_permissions];

	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];







>
>
>







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
setPermissions(OFString *path, OFLHAArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	OFNumber *mode = entry.mode;

	if (mode == nil)
		return;

	mode = [OFNumber numberWithUnsignedShort:
	    mode.unsignedShortValue & 0777];

	of_file_attributes_t attributes = [OFDictionary
	    dictionaryWithObject: mode
			  forKey: of_file_attribute_key_posix_permissions];

	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];
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
			    @"%" PRIu32, entry.uncompressedSize];
			OFString *CRC16 = [OFString stringWithFormat:
			    @"%04" PRIX16, entry.CRC16];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compressed_size",
			    [@"["
			     @"    'Compressed: ',"
			     @"    ["
			     @"        {'size == 1': '1 byte'},"
			     @"        {'': '%[size] bytes'}"
			     @"    ]"
			     @"]" JSONValue],
			    @"size", compressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_uncompressed_size",
			    [@"["
			     @"    'Uncompressed: ',"
			     @"    ["
			     @"        {'size == 1': '1 byte'},"
			     @"        {'': '%[size] bytes'}"
			     @"    ]"
			     @"]" JSONValue],
			    @"size", uncompressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compression_method",
			    @"Compression method: %[method]",
			    @"method", entry.compressionMethod)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_crc16",
			    @"CRC16: %[crc16]",
			    @"crc16", CRC16)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_date",
			    @"Date: %[date]",
			    @"date", date)];

			if (entry.mode != nil) {
				OFString *modeString = [OFString
				    stringWithFormat:
				    @"%" PRIo16, entry.mode.uInt16Value];

				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(@"list_mode",
				    @"Mode: %[mode]",
				    @"mode", modeString)];
			}
			if (entry.UID != nil) {







|
|
|
|
|
|
|




|
|
|
|
|
|
|


















|







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
			    @"%" PRIu32, entry.uncompressedSize];
			OFString *CRC16 = [OFString stringWithFormat:
			    @"%04" PRIX16, entry.CRC16];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compressed_size",
			    @"["
			    @"    'Compressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", compressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_uncompressed_size",
			    @"["
			    @"    'Uncompressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", uncompressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compression_method",
			    @"Compression method: %[method]",
			    @"method", entry.compressionMethod)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_crc16",
			    @"CRC16: %[crc16]",
			    @"crc16", CRC16)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_date",
			    @"Date: %[date]",
			    @"date", date)];

			if (entry.mode != nil) {
				OFString *modeString = [OFString
				    stringWithFormat:
				    @"%ho", entry.mode.unsignedShortValue];

				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(@"list_mode",
				    @"Mode: %[mode]",
				    @"mode", modeString)];
			}
			if (entry.UID != nil) {
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
			    @"file", fileName)];

		attributes = [fileManager attributesOfItemAtPath: fileName];
		type = attributes.fileType;
		entry = [OFMutableLHAArchiveEntry entryWithFileName: fileName];

#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
		entry.mode = [OFNumber numberWithUInt16:
		    attributes.filePOSIXPermissions];
#endif
		entry.date = attributes.fileModificationDate;

#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
		entry.UID =
		    [OFNumber numberWithUInt16: attributes.filePOSIXUID];
		entry.GID =
		    [OFNumber numberWithUInt16: attributes.filePOSIXGID];
		entry.owner = attributes.fileOwner;
		entry.group = attributes.fileGroup;
#endif

		if ([type isEqual: of_file_type_directory])
			entry.compressionMethod = @"-lhd-";

		output = [_archive streamForWritingEntry: entry];

		if ([type isEqual: of_file_type_regular]) {

			uintmax_t written = 0, size = attributes.fileSize;
			int8_t percent = -1, newPercent;

			OFFile *input = [OFFile fileWithPath: fileName
							mode: @"r"];

			while (!input.atEndOfStream) {
				ssize_t length = [app







|






|

|










>
|







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
			    @"file", fileName)];

		attributes = [fileManager attributesOfItemAtPath: fileName];
		type = attributes.fileType;
		entry = [OFMutableLHAArchiveEntry entryWithFileName: fileName];

#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
		entry.mode = [OFNumber numberWithUnsignedLong:
		    attributes.filePOSIXPermissions];
#endif
		entry.date = attributes.fileModificationDate;

#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
		entry.UID =
		    [OFNumber numberWithUnsignedLong: attributes.filePOSIXUID];
		entry.GID =
		    [OFNumber numberWithUnsignedLong: attributes.filePOSIXGID];
		entry.owner = attributes.fileOwner;
		entry.group = attributes.fileGroup;
#endif

		if ([type isEqual: of_file_type_directory])
			entry.compressionMethod = @"-lhd-";

		output = [_archive streamForWritingEntry: entry];

		if ([type isEqual: of_file_type_regular]) {
			unsigned long long written = 0;
			unsigned long long size = attributes.fileSize;
			int8_t percent = -1, newPercent;

			OFFile *input = [OFFile fileWithPath: fileName
							mode: @"r"];

			while (!input.atEndOfStream) {
				ssize_t length = [app

Modified utils/ofarc/TarArchive.m from [ed61f78528] to [3ca97fcaef].

31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46

static OFArc *app;

static void
setPermissions(OFString *path, OFTarArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS

	of_file_attributes_t attributes = [OFDictionary
	    dictionaryWithObject: [OFNumber numberWithUInt16: entry.mode]
			  forKey: of_file_attribute_key_posix_permissions];

	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];
#endif
}








>

|







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

static OFArc *app;

static void
setPermissions(OFString *path, OFTarArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	OFNumber *mode = [OFNumber numberWithUnsignedShort: entry.mode & 0777];
	of_file_attributes_t attributes = [OFDictionary
	    dictionaryWithObject: mode
			  forKey: of_file_attribute_key_posix_permissions];

	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];
#endif
}

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
			OFString *UID = [OFString stringWithFormat:
			    @"%u", entry.UID];
			OFString *GID = [OFString stringWithFormat:
			    @"%u", entry.GID];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_size",
			    [@"["
			     @"    'Size: ',"
			     @"    ["
			     @"        {'size == 1': '1 byte'},"
			     @"        {'': '%[size] bytes'}"
			     @"    ]"
			     @"]" JSONValue],
			    @"size", size)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_mode",
			    @"Mode: %[mode]",
			    @"mode", mode)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_uid",







|
|
|
|
|
|
|







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
			OFString *UID = [OFString stringWithFormat:
			    @"%u", entry.UID];
			OFString *GID = [OFString stringWithFormat:
			    @"%u", entry.GID];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_size",
			    @"["
			    @"    'Size: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", size)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_mode",
			    @"Mode: %[mode]",
			    @"mode", mode)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_uid",

Modified utils/ofarc/ZIPArchive.m from [251b5d4973] to [4b4d3715d0].

40
41
42
43
44
45
46

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

static void
setPermissions(OFString *path, OFZIPArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	if ((entry.versionMadeBy >> 8) ==
	    OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_UNIX) {

		uint16_t mode = entry.versionSpecificAttributes >> 16;
		of_file_attribute_key_t key =
		    of_file_attribute_key_posix_permissions;
		of_file_attributes_t attributes = [OFDictionary
		    dictionaryWithObject: [OFNumber numberWithUInt16: mode]
				  forKey: key];

		[[OFFileManager defaultManager] setAttributes: attributes
						 ofItemAtPath: path];
	}
#endif
}







>
|



|







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

static void
setPermissions(OFString *path, OFZIPArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	if ((entry.versionMadeBy >> 8) ==
	    OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_UNIX) {
		OFNumber *mode = [OFNumber numberWithUnsignedShort:
		    (entry.versionSpecificAttributes >> 16) & 0777];
		of_file_attribute_key_t key =
		    of_file_attribute_key_posix_permissions;
		of_file_attributes_t attributes = [OFDictionary
		    dictionaryWithObject: mode
				  forKey: key];

		[[OFFileManager defaultManager] setAttributes: attributes
						 ofItemAtPath: path];
	}
#endif
}
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
			    stringWithFormat: @"%08" PRIX32, entry.CRC32];
			OFString *modificationDate = [entry.modificationDate
			    localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compressed_size",
			    [@"["
			     @"    'Compressed: ',"
			     @"    ["
			     @"        {'size == 1': '1 byte'},"
			     @"        {'': '%[size] bytes'}"
			     @"    ]"
			     @"]" JSONValue],
			    @"size", compressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_uncompressed_size",
			    [@"["
			     @"    'Uncompressed: ',"
			     @"    ["
			     @"        {'size == 1': '1 byte'},"
			     @"        {'': '%[size] bytes'}"
			     @"    ]"
			     @"]" JSONValue],
			    @"size", uncompressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compression_method",
			    @"Compression method: %[method]",
			    @"method", compressionMethod)];
			[of_stdout writeString: @"\t"];







|
|
|
|
|
|
|




|
|
|
|
|
|
|







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
			    stringWithFormat: @"%08" PRIX32, entry.CRC32];
			OFString *modificationDate = [entry.modificationDate
			    localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compressed_size",
			    @"["
			    @"    'Compressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", compressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_uncompressed_size",
			    @"["
			    @"    'Uncompressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", uncompressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compression_method",
			    @"Compression method: %[method]",
			    @"method", compressionMethod)];
			[of_stdout writeString: @"\t"];
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
	for (OFString *localFileName in files) {
		void *pool = objc_autoreleasePoolPush();
		OFArray OF_GENERIC (OFString *) *components;
		OFString *fileName;
		of_file_attributes_t attributes;
		bool isDirectory = false;
		OFMutableZIPArchiveEntry *entry;
		uintmax_t size;
		OFStream *output;

		components = localFileName.pathComponents;
		fileName = [components componentsJoinedByString: @"/"];

		attributes = [fileManager
		    attributesOfItemAtPath: localFileName];







|







418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
	for (OFString *localFileName in files) {
		void *pool = objc_autoreleasePoolPush();
		OFArray OF_GENERIC (OFString *) *components;
		OFString *fileName;
		of_file_attributes_t attributes;
		bool isDirectory = false;
		OFMutableZIPArchiveEntry *entry;
		unsigned long long size;
		OFStream *output;

		components = localFileName.pathComponents;
		fileName = [components componentsJoinedByString: @"/"];

		attributes = [fileManager
		    attributesOfItemAtPath: localFileName];
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
		entry.modificationDate = attributes.fileModificationDate;

		[entry makeImmutable];

		output = [_archive streamForWritingEntry: entry];

		if (!isDirectory) {
			uintmax_t written = 0;
			int8_t percent = -1, newPercent;

			OFFile *input = [OFFile fileWithPath: fileName
							mode: @"r"];

			while (!input.atEndOfStream) {
				ssize_t length = [app







|







455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
		entry.modificationDate = attributes.fileModificationDate;

		[entry makeImmutable];

		output = [_archive streamForWritingEntry: entry];

		if (!isDirectory) {
			unsigned long long written = 0;
			int8_t percent = -1, newPercent;

			OFFile *input = [OFFile fileWithPath: fileName
							mode: @"r"];

			while (!input.atEndOfStream) {
				ssize_t length = [app

Modified utils/ofhttp/OFHTTP.m from [da5c2f66e5] to [d4c7821db4].

24
25
26
27
28
29
30



31
32
33
34
35
36
37
#import "OFFile.h"
#import "OFFileManager.h"
#import "OFHTTPClient.h"
#import "OFHTTPRequest.h"
#import "OFHTTPResponse.h"
#import "OFLocale.h"
#import "OFOptionsParser.h"



#import "OFSandbox.h"
#import "OFStdIOStream.h"
#import "OFSystemInfo.h"
#import "OFTCPSocket.h"
#import "OFTLSSocket.h"
#import "OFURL.h"








>
>
>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#import "OFFile.h"
#import "OFFileManager.h"
#import "OFHTTPClient.h"
#import "OFHTTPRequest.h"
#import "OFHTTPResponse.h"
#import "OFLocale.h"
#import "OFOptionsParser.h"
#ifdef OF_HAVE_PLUGINS
# import "OFPlugin.h"
#endif
#import "OFSandbox.h"
#import "OFStdIOStream.h"
#import "OFSystemInfo.h"
#import "OFTCPSocket.h"
#import "OFTLSSocket.h"
#import "OFURL.h"

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
	bool _detectedFileName, _quiet, _verbose, _insecure;
	OFStream *_body;
	of_http_request_method_t _method;
	OFMutableDictionary *_clientHeaders;
	OFHTTPClient *_HTTPClient;
	char *_buffer;
	OFStream *_output;
	intmax_t _received, _length, _resumedFrom;
	ProgressBar *_progressBar;
}

- (void)downloadNextURL;
@end

OF_APPLICATION_DELEGATE(OFHTTP)







|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
	bool _detectedFileName, _quiet, _verbose, _insecure;
	OFStream *_body;
	of_http_request_method_t _method;
	OFMutableDictionary *_clientHeaders;
	OFHTTPClient *_HTTPClient;
	char *_buffer;
	OFStream *_output;
	unsigned long long _received, _length, _resumedFrom;
	ProgressBar *_progressBar;
}

- (void)downloadNextURL;
@end

OF_APPLICATION_DELEGATE(OFHTTP)
270
271
272
273
274
275
276











277
278
279
280
281
282
283

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

@implementation OFHTTP











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

	@try {
		_method = OF_HTTP_REQUEST_METHOD_GET;








>
>
>
>
>
>
>
>
>
>
>







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

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

@implementation OFHTTP
#ifdef OF_HAVE_PLUGINS
+ (void)initialize
{
	if (self != [OFHTTP class])
		return;

	/* Opportunistically try loading ObjOpenSSL and ignore any errors. */
	of_dlopen(@"objopenssl", OF_RTLD_LAZY);
}
#endif

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

	@try {
		_method = OF_HTTP_REQUEST_METHOD_GET;

330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
	if ([path isEqual: @"-"])
		_body = [of_stdin copy];
	else {
		_body = [[OFFile alloc] initWithPath: path
						mode: @"r"];

		@try {

			uintmax_t fileSize = [[OFFileManager defaultManager]
			    attributesOfItemAtPath: path].fileSize;

			contentLength =
			    [OFString stringWithFormat: @"%ju", fileSize];
			[_clientHeaders setObject: contentLength
					   forKey: @"Content-Length"];
		} @catch (OFRetrieveItemAttributesFailedException *e) {







>
|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
	if ([path isEqual: @"-"])
		_body = [of_stdin copy];
	else {
		_body = [[OFFile alloc] initWithPath: path
						mode: @"r"];

		@try {
			unsigned long long fileSize =
			    [[OFFileManager defaultManager]
			    attributesOfItemAtPath: path].fileSize;

			contentLength =
			    [OFString stringWithFormat: @"%ju", fileSize];
			[_clientHeaders setObject: contentLength
					   forKey: @"Content-Length"];
		} @catch (OFRetrieveItemAttributesFailedException *e) {
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
- (void)setProxy: (OFString *)proxy
{
	@try {
		size_t pos = [proxy
		    rangeOfString: @":"
			  options: OF_STRING_SEARCH_BACKWARDS].location;
		OFString *host;
		intmax_t port;

		if (pos == OF_NOT_FOUND)
			@throw [OFInvalidFormatException exception];

		host = [proxy substringWithRange: of_range(0, pos)];
		port = [proxy substringWithRange:
		    of_range(pos + 1, proxy.length - pos - 1)].decimalValue;

		if (port > UINT16_MAX)
			@throw [OFOutOfRangeException exception];

		[OFTCPSocket setSOCKS5Host: host];
		[OFTCPSocket setSOCKS5Port: (uint16_t)port];
	} @catch (OFInvalidFormatException *e) {







|





|
|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
- (void)setProxy: (OFString *)proxy
{
	@try {
		size_t pos = [proxy
		    rangeOfString: @":"
			  options: OF_STRING_SEARCH_BACKWARDS].location;
		OFString *host;
		unsigned long long port;

		if (pos == OF_NOT_FOUND)
			@throw [OFInvalidFormatException exception];

		host = [proxy substringWithRange: of_range(0, pos)];
		port = [proxy substringWithRange: of_range(pos + 1,
		    proxy.length - pos - 1)].unsignedLongLongValue;

		if (port > UINT16_MAX)
			@throw [OFOutOfRangeException exception];

		[OFTCPSocket setSOCKS5Host: host];
		[OFTCPSocket setSOCKS5Port: (uint16_t)port];
	} @catch (OFInvalidFormatException *e) {
717
718
719
720
721
722
723
724
725



726
727
728
729
730
731
732
		OFString *URL;

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

		if (!_quiet)
			[of_stdout writeString: @"\n  Error!\n"];




		URL = [_URLs objectAtIndex: _URLIndex - 1];
		[of_stderr writeLine: OF_LOCALIZED(
		    @"download_failed_exception",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  %[exception]",
		    @"prog", [OFApplication programName],







|
|
>
>
>







732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
		OFString *URL;

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

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

		URL = [_URLs objectAtIndex: _URLIndex - 1];
		[of_stderr writeLine: OF_LOCALIZED(
		    @"download_failed_exception",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  %[exception]",
		    @"prog", [OFApplication programName],
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795

		[of_stdout writeFormat: @" ➜ %d\n", statusCode];

		if (type == nil)
			type = OF_LOCALIZED(@"type_unknown", @"unknown");

		if (lengthString != nil) {
			_length = lengthString.decimalValue;

			if (_resumedFrom + _length >= GIBIBYTE) {
				lengthString = [OFString stringWithFormat:
				    @"%,.2f",
				    (float)(_resumedFrom + _length) / GIBIBYTE];
				lengthString = OF_LOCALIZED(@"size_gib",
				    @"%[num] GiB",







|







799
800
801
802
803
804
805
806
807
808
809
810
811
812
813

		[of_stdout writeFormat: @" ➜ %d\n", statusCode];

		if (type == nil)
			type = OF_LOCALIZED(@"type_unknown", @"unknown");

		if (lengthString != nil) {
			_length = lengthString.unsignedLongLongValue;

			if (_resumedFrom + _length >= GIBIBYTE) {
				lengthString = [OFString stringWithFormat:
				    @"%,.2f",
				    (float)(_resumedFrom + _length) / GIBIBYTE];
				lengthString = OF_LOCALIZED(@"size_gib",
				    @"%[num] GiB",
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
				lengthString = OF_LOCALIZED(@"size_kib",
				    @"%[num] KiB",
				    @"num", lengthString);
			} else {
				lengthString = [OFString stringWithFormat:
				    @"%jd", _resumedFrom + _length];
				lengthString = OF_LOCALIZED(@"size_bytes",
				    [@"["
				     @"    ["
				     @"        {'num == 1': '1 byte'},"
				     @"        {'': '%[num] bytes'}"
				     @"    ]"
				     @"]" JSONValue],
				    @"num", lengthString);
			}
		} else
			lengthString =
			    OF_LOCALIZED(@"size_unknown", @"unknown");

		if (_verbose) {







|
|
|
|
|
|







826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
				lengthString = OF_LOCALIZED(@"size_kib",
				    @"%[num] KiB",
				    @"num", lengthString);
			} else {
				lengthString = [OFString stringWithFormat:
				    @"%jd", _resumedFrom + _length];
				lengthString = OF_LOCALIZED(@"size_bytes",
				    @"["
				    @"    ["
				    @"        {'num == 1': '1 byte'},"
				    @"        {'': '%[num] bytes'}"
				    @"    ]"
				    @"]".objectByParsingJSON,
				    @"num", lengthString);
			}
		} else
			lengthString =
			    OF_LOCALIZED(@"size_unknown", @"unknown");

		if (_verbose) {
1006
1007
1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
		_currentFileName = [_outputPath copy];

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

	if (_continue) {
		@try {

			uintmax_t size = [[OFFileManager defaultManager]
			    attributesOfItemAtPath: _currentFileName].fileSize;
			OFString *range;

			if (size > INTMAX_MAX)
				@throw [OFOutOfRangeException exception];

			_resumedFrom = (intmax_t)size;

			range = [OFString stringWithFormat: @"bytes=%jd-",
							    _resumedFrom];
			[clientHeaders setObject: range
					  forKey: @"Range"];
		} @catch (OFRetrieveItemAttributesFailedException *e) {
		}







>
|



|


|







1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
		_currentFileName = [_outputPath copy];

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

	if (_continue) {
		@try {
			unsigned long long size =
			    [[OFFileManager defaultManager]
			    attributesOfItemAtPath: _currentFileName].fileSize;
			OFString *range;

			if (size > ULLONG_MAX)
				@throw [OFOutOfRangeException exception];

			_resumedFrom = (unsigned long long)size;

			range = [OFString stringWithFormat: @"bytes=%jd-",
							    _resumedFrom];
			[clientHeaders setObject: range
					  forKey: @"Range"];
		} @catch (OFRetrieveItemAttributesFailedException *e) {
		}

Modified utils/ofhttp/ProgressBar.h from [5832428778] to [187685081a].

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

@class OFDate;
@class OFTimer;



@interface ProgressBar: OFObject
{
	intmax_t _received, _lastReceived, _length, _resumedFrom;
	OFDate *_startDate, *_lastReceivedDate;
	OFTimer *_drawTimer, *_BPSTimer;
	bool _stopped;
	float _BPS;
	double _ETA;


}

- (instancetype)initWithLength: (intmax_t)length
		   resumedFrom: (intmax_t)resumedFrom;
- (void)setReceived: (intmax_t)received;
- (void)draw;
- (void)calculateBPSAndETA;
- (void)stop;
@end







>
>



|





>
>


|
|
|




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

#import "OFObject.h"

@class OFDate;
@class OFTimer;

#define BPS_WINDOW_SIZE 10

@interface ProgressBar: OFObject
{
	unsigned long long _received, _lastReceived, _length, _resumedFrom;
	OFDate *_startDate, *_lastReceivedDate;
	OFTimer *_drawTimer, *_BPSTimer;
	bool _stopped;
	float _BPS;
	double _ETA;
	float _BPSWindow[BPS_WINDOW_SIZE];
	size_t _BPSWindowIndex, _BPSWindowLength;
}

- (instancetype)initWithLength: (unsigned long long)length
		   resumedFrom: (unsigned long long)resumedFrom;
- (void)setReceived: (unsigned long long)received;
- (void)draw;
- (void)calculateBPSAndETA;
- (void)stop;
@end

Modified utils/ofhttp/ProgressBar.m from [813833df71] to [814de8c246].

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#define GIBIBYTE (1024 * 1024 * 1024)
#define MEBIBYTE (1024 * 1024)
#define KIBIBYTE (1024)

#define UPDATE_INTERVAL 0.1

@implementation ProgressBar
- (instancetype)initWithLength: (intmax_t)length
		   resumedFrom: (intmax_t)resumedFrom
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();

		_length = length;







|
|







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#define GIBIBYTE (1024 * 1024 * 1024)
#define MEBIBYTE (1024 * 1024)
#define KIBIBYTE (1024)

#define UPDATE_INTERVAL 0.1

@implementation ProgressBar
- (instancetype)initWithLength: (unsigned long long)length
		   resumedFrom: (unsigned long long)resumedFrom
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();

		_length = length;
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
	[_lastReceivedDate release];
	[_drawTimer release];
	[_BPSTimer release];

	[super dealloc];
}

- (void)setReceived: (intmax_t)received
{
	_received = received;
}

- (void)_drawProgress
{
	float bars, percent;







|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
	[_lastReceivedDate release];
	[_drawTimer release];
	[_BPSTimer release];

	[super dealloc];
}

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

- (void)_drawProgress
{
	float bars, percent;
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
		[of_stdout writeString: OF_LOCALIZED(@"progress_kib",
		    @"%[num] KiB",
		    @"num", num)];
	} else {
		OFString *num = [OFString stringWithFormat:
		    @"%jd", _resumedFrom + _received];
		[of_stdout writeString: OF_LOCALIZED(@"progress_bytes",
		    [@"["
		     @"    ["
		     @"        {'num == 1': '1 byte '},"
		     @"        {'': '%[num] bytes'}"
		     @"    ]"
		     @"]" JSONValue],
		    @"num", num)];
	}

	[of_stdout writeString: @" "];

	if (_stopped)
		_BPS = (float)_received /







|
|
|
|
|
|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
		[of_stdout writeString: OF_LOCALIZED(@"progress_kib",
		    @"%[num] KiB",
		    @"num", num)];
	} else {
		OFString *num = [OFString stringWithFormat:
		    @"%jd", _resumedFrom + _received];
		[of_stdout writeString: OF_LOCALIZED(@"progress_bytes",
		    @"["
		    @"    ["
		    @"        {'num == 1': '1 byte '},"
		    @"        {'': '%[num] bytes'}"
		    @"    ]"
		    @"]".objectByParsingJSON,
		    @"num", num)];
	}

	[of_stdout writeString: @" "];

	if (_stopped)
		_BPS = (float)_received /
252
253
254
255
256
257
258

259
260









261
262
263
264
265
266
267
		[self _drawProgress];
	else
		[self _drawReceived];
}

- (void)calculateBPSAndETA
{

	_BPS = (float)(_received - _lastReceived) /
	    -(float)_lastReceivedDate.timeIntervalSinceNow;









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

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








>
|

>
>
>
>
>
>
>
>
>







252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
		[self _drawProgress];
	else
		[self _drawReceived];
}

- (void)calculateBPSAndETA
{
	_BPSWindow[_BPSWindowIndex++ % BPS_WINDOW_SIZE] =
	    (float)(_received - _lastReceived) /
	    -(float)_lastReceivedDate.timeIntervalSinceNow;

	if (_BPSWindowLength < BPS_WINDOW_SIZE)
		_BPSWindowLength++;

	_BPS = 0;
	for (size_t i = 0; i < _BPSWindowLength; i++)
		_BPS += _BPSWindow[i];
	_BPS /= _BPSWindowLength;

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

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

Modified utils/ofhttp/lang/de.json from [ef4298a3ca] to [ccf7a0ea89].

64
65
66
67
68
69
70

71
72
73
74
75
76
77
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  %[error]: %[exception]"
    ],
    "download_failed": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  HTTP Status-Code: %[code]"
    ],

    "download_failed_exception": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  %[exception]"
    ],
    "download_done": "Fertig!",
    "invalid_url": "%[prog]: Ungültige URL: <%[url]>!",
    "invalid_scheme": "%[prog]: Ungültiges Schema: <%[url]>!",







>







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  %[error]: %[exception]"
    ],
    "download_failed": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  HTTP Status-Code: %[code]"
    ],
    "download_error": "Fehler!",
    "download_failed_exception": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  %[exception]"
    ],
    "download_done": "Fertig!",
    "invalid_url": "%[prog]: Ungültige URL: <%[url]>!",
    "invalid_scheme": "%[prog]: Ungültiges Schema: <%[url]>!",

Modified utils/ofsock/OFSock.m from [0c75e9be8d] to [9ce3b460c5].

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

		if (URL.port == nil) {
			[of_stderr writeLine: @"Need a port!"];
			[OFApplication terminateWithStatus: 1];
		}

		[sock connectToHost: URL.host
			       port: URL.port.uInt16Value];

		return [OFPair pairWithFirstObject: sock
				      secondObject: sock];
	}

	[of_stderr writeFormat: @"Invalid protocol: %@\n", scheme];
	[OFApplication terminateWithStatus: 1];







|







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

		if (URL.port == nil) {
			[of_stderr writeLine: @"Need a port!"];
			[OFApplication terminateWithStatus: 1];
		}

		[sock connectToHost: URL.host
			       port: URL.port.shortValue];

		return [OFPair pairWithFirstObject: sock
				      secondObject: sock];
	}

	[of_stderr writeFormat: @"Invalid protocol: %@\n", scheme];
	[OFApplication terminateWithStatus: 1];