ObjFW  Check-in [9d74d1b74e]

Overview
Comment:OFData: Make parameter order more consistent
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 9d74d1b74ec514869b3b2b517129cc51d78c84b29821b23d476cf29ee6115e0c
User & Date: js on 2020-11-06 02:12:39
Other Links: manifest | tags
Context
2020-11-06
02:24
Future-proof some code using freeWhenDone check-in: a2b4238850 user: js tags: trunk
02:12
OFData: Make parameter order more consistent check-in: 9d74d1b74e user: js tags: trunk
01:56
OFString: Avoid -[allocMemoryWithSize:] check-in: 54d900fb66 user: js tags: trunk
Changes

Modified src/OFArray.m from [d8de445b42] to [84ddc75d7b].

248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
			 inRange: of_range(0, count)];
	} @catch (id e) {
		free(buffer);
		@throw e;
	}

	return [OFData dataWithItemsNoCopy: buffer
				  itemSize: sizeof(id)
				     count: count

			      freeWhenDone: true].items;
}

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







<

>







248
249
250
251
252
253
254

255
256
257
258
259
260
261
262
263
			 inRange: of_range(0, count)];
	} @catch (id e) {
		free(buffer);
		@throw e;
	}

	return [OFData dataWithItemsNoCopy: buffer

				     count: count
				  itemSize: sizeof(id)
			      freeWhenDone: true].items;
}

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

Modified src/OFData.h from [bbb0884145] to [7785f4eec7].

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
			count: (size_t)count;

/**
 * @brief Creates a new OFData with the specified `count` items of the
 *	  specified size.
 *
 * @param items The items to store in the OFData
 * @param itemSize The item size of a single item in bytes
 * @param count The number of items

 * @return A new autoreleased OFData
 */
+ (instancetype)dataWithItems: (const void *)items
		     itemSize: (size_t)itemSize
			count: (size_t)count;


/**
 * @brief Creates a new OFData with the specified `count` items of size 1 by
 *	  taking over ownership of the specified items pointer.
 *
 * @param items The items to store in the OFData
 * @param count The number of items
 * @param freeWhenDone Whether to free the pointer when it is no longer needed
 *		       by the OFData
 * @return A new autoreleased OFData
 */
+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone;

/**
 * @brief Creates a new OFData with the specified `count` items of the
 *	  specified size by taking ownership of the specified items pointer.
 *
 * @param items The items to store in the OFData
 * @param itemSize The item size of a single item in bytes
 * @param count The number of items

 * @param freeWhenDone Whether to free the pointer when it is no longer needed
 *		       by the OFData
 * @return A new autoreleased OFData
 */
+ (instancetype)dataWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count

		       freeWhenDone: (bool)freeWhenDone;

#ifdef OF_HAVE_FILES
/**
 * @brief Creates a new OFData with an item size of 1, containing the data of
 *	  the specified file.
 *







<

>



<
|
>




















<

>





<

>







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
			count: (size_t)count;

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

 * @param count The number of items
 * @param itemSize The item size of a single item in bytes
 * @return A new autoreleased OFData
 */
+ (instancetype)dataWithItems: (const void *)items

			count: (size_t)count
		     itemSize: (size_t)itemSize;

/**
 * @brief Creates a new OFData with the specified `count` items of size 1 by
 *	  taking over ownership of the specified items pointer.
 *
 * @param items The items to store in the OFData
 * @param count The number of items
 * @param freeWhenDone Whether to free the pointer when it is no longer needed
 *		       by the OFData
 * @return A new autoreleased OFData
 */
+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone;

/**
 * @brief Creates a new OFData with the specified `count` items of the
 *	  specified size by taking ownership of the specified items pointer.
 *
 * @param items The items to store in the OFData

 * @param count The number of items
 * @param itemSize The item size of a single item in bytes
 * @param freeWhenDone Whether to free the pointer when it is no longer needed
 *		       by the OFData
 * @return A new autoreleased OFData
 */
+ (instancetype)dataWithItemsNoCopy: (void *)items

			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone;

#ifdef OF_HAVE_FILES
/**
 * @brief Creates a new OFData with an item size of 1, containing the data of
 *	  the specified file.
 *
192
193
194
195
196
197
198
199
200

201
202
203
204
205

206
207
208
209
210
211
212
			count: (size_t)count;

/**
 * @brief Initialized an already allocated OFData with the specified `count`
 *	  items of the specified size.
 *
 * @param items The items to store in the OFData
 * @param itemSize The item size of a single item in bytes
 * @param count The number of items

 * @return An initialized OFData
 */
- (instancetype)initWithItems: (const void *)items
		     itemSize: (size_t)itemSize
			count: (size_t)count;


/**
 * @brief Initializes an already allocated OFData with the specified `count`
 *	  items of size 1 by taking over ownership of the specified items
 *	  pointer.
 *
 * @param items The items to store in the OFData







<

>



<
|
>







192
193
194
195
196
197
198

199
200
201
202
203

204
205
206
207
208
209
210
211
212
			count: (size_t)count;

/**
 * @brief Initialized an already allocated OFData with the specified `count`
 *	  items of the specified size.
 *
 * @param items The items to store in the OFData

 * @param count The number of items
 * @param itemSize The item size of a single item in bytes
 * @return An initialized OFData
 */
- (instancetype)initWithItems: (const void *)items

			count: (size_t)count
		     itemSize: (size_t)itemSize;

/**
 * @brief Initializes an already allocated OFData with the specified `count`
 *	  items of size 1 by taking over ownership of the specified items
 *	  pointer.
 *
 * @param items The items to store in the OFData
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236

237
238
239
240
241
242
243

/**
 * @brief Initializes an already allocated OFData with the specified `count`
 *	  items of the specified size by taking ownership of the specified
 *	  items pointer.
 *
 * @param items The items to store in the OFData
 * @param itemSize The item size of a single item in bytes
 * @param count The number of items

 * @param freeWhenDone Whether to free the pointer when it is no longer needed
 *		       by the OFData
 * @return An initialized OFData
 */
- (instancetype)initWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count

		       freeWhenDone: (bool)freeWhenDone;

#ifdef OF_HAVE_FILES
/**
 * @brief Initializes an already allocated OFData with an item size of 1,
 *	  containing the data of the specified file.
 *







<

>





<

>







221
222
223
224
225
226
227

228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243

/**
 * @brief Initializes an already allocated OFData with the specified `count`
 *	  items of the specified size by taking ownership of the specified
 *	  items pointer.
 *
 * @param items The items to store in the OFData

 * @param count The number of items
 * @param itemSize The item size of a single item in bytes
 * @param freeWhenDone Whether to free the pointer when it is no longer needed
 *		       by the OFData
 * @return An initialized OFData
 */
- (instancetype)initWithItemsNoCopy: (void *)items

			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone;

#ifdef OF_HAVE_FILES
/**
 * @brief Initializes an already allocated OFData with an item size of 1,
 *	  containing the data of the specified file.
 *

Modified src/OFData.m from [f4f38100bd] to [aa10f00100].

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
			count: (size_t)count
{
	return [[[self alloc] initWithItems: items
				      count: count] autorelease];
}

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

{
	return [[[self alloc] initWithItems: items

				   itemSize: itemSize
				      count: count] autorelease];
}

+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	return [[[self alloc] initWithItemsNoCopy: items
					    count: count
				     freeWhenDone: freeWhenDone] autorelease];
}

+ (instancetype)dataWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count

		       freeWhenDone: (bool)freeWhenDone
{
	return [[[self alloc] initWithItemsNoCopy: items
					 itemSize: itemSize
					    count: count

				     freeWhenDone: freeWhenDone] autorelease];
}

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







<

>


>
|
<












<

>



<

>







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
			count: (size_t)count
{
	return [[[self alloc] initWithItems: items
				      count: count] autorelease];
}

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

			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	return [[[self alloc] initWithItems: items
				      count: count
				   itemSize: itemSize] autorelease];

}

+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	return [[[self alloc] initWithItemsNoCopy: items
					    count: count
				     freeWhenDone: freeWhenDone] autorelease];
}

+ (instancetype)dataWithItemsNoCopy: (void *)items

			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	return [[[self alloc] initWithItemsNoCopy: items

					    count: count
					 itemSize: itemSize
				     freeWhenDone: freeWhenDone] autorelease];
}

#ifdef OF_HAVE_FILES
+ (instancetype)dataWithContentsOfFile: (OFString *)path
{
	return [[[self alloc] initWithContentsOfFile: path] autorelease];
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
	return [[[self alloc] initWithBase64EncodedString: string] autorelease];
}

- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
{
	return [self initWithItems: items

			  itemSize: 1
			     count: count];
}

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

{
	self = [super init];

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

		_items = of_malloc(count, itemSize);
		_itemSize = itemSize;
		_count = count;

		_freeWhenDone = true;

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

	return self;
}

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

			    freeWhenDone: freeWhenDone];
}

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

		       freeWhenDone: (bool)freeWhenDone
{
	self = [super init];

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

		_items = (unsigned char *)items;
		_itemSize = itemSize;
		_count = count;

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

	return self;







>
|
<



<

>








<

>
















<

>




<

>









<

>







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
	return [[[self alloc] initWithBase64EncodedString: string] autorelease];
}

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

}

- (instancetype)initWithItems: (const void *)items

			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	self = [super init];

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

		_items = of_malloc(count, itemSize);

		_count = count;
		_itemSize = itemSize;
		_freeWhenDone = true;

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

	return self;
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	return [self initWithItemsNoCopy: items

				   count: count
				itemSize: 1
			    freeWhenDone: freeWhenDone];
}

- (instancetype)initWithItemsNoCopy: (void *)items

			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	self = [super init];

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

		_items = (unsigned char *)items;

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

	return self;
240
241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
		if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil)
			@throw [OFUnsupportedProtocolException
			    exceptionWithURL: URL];

		stream = [URLHandler openItemAtURL: URL
					      mode: @"r"];

		_itemSize = 1;
		_count = 0;

		_freeWhenDone = true;

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

		@try {
			while (!stream.atEndOfStream) {







<

>







240
241
242
243
244
245
246

247
248
249
250
251
252
253
254
255
		if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil)
			@throw [OFUnsupportedProtocolException
			    exceptionWithURL: URL];

		stream = [URLHandler openItemAtURL: URL
					      mode: @"r"];


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

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

		@try {
			while (!stream.atEndOfStream) {
289
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304

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

		count /= 2;

		_items = of_malloc(count, 1);
		_itemSize = 1;
		_count = count;

		_freeWhenDone = true;

		cString = [string
		    cStringWithEncoding: OF_STRING_ENCODING_ASCII];

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







<

>







289
290
291
292
293
294
295

296
297
298
299
300
301
302
303
304

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

		count /= 2;

		_items = of_malloc(count, 1);

		_count = count;
		_itemSize = 1;
		_freeWhenDone = true;

		cString = [string
		    cStringWithEncoding: OF_STRING_ENCODING_ASCII];

		for (size_t i = 0; i < count; i++) {
			uint8_t c1 = cString[2 * i];
432
433
434
435
436
437
438

439
440
441
442
443
444
445
446
447
{
	return [self retain];
}

- (id)mutableCopy
{
	return [[OFMutableData alloc] initWithItems: _items

					   itemSize: _itemSize
					      count: _count];
}

- (bool)isEqual: (id)object
{
	OFData *data;

	if (object == self)







>
|
<







432
433
434
435
436
437
438
439
440

441
442
443
444
445
446
447
{
	return [self retain];
}

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

}

- (bool)isEqual: (id)object
{
	OFData *data;

	if (object == self)
512
513
514
515
516
517
518
519
520

521
522
523
524
525
526
527
	OFData *ret;

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

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

			     freeWhenDone: false];
	ret->_parentData = [(_parentData != nil ? _parentData : self) copy];

	return ret;
}

- (OFString *)description







<

>







512
513
514
515
516
517
518

519
520
521
522
523
524
525
526
527
	OFData *ret;

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

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

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

	return ret;
}

- (OFString *)description

Modified src/OFHostAddressResolver.m from [1663ef2651] to [9b355acb42].

275
276
277
278
279
280
281

282
283
284
285
286
287
288
289
290
		    of_socket_address_parse_ip(_host, 0);
		OFData *addresses = nil;
		id exception = nil;

		if (_addressFamily == address.family ||
		    _addressFamily == OF_SOCKET_ADDRESS_FAMILY_ANY)
			addresses = [OFData dataWithItems: &address

						 itemSize: sizeof(address)
						    count: 1];
		else
			exception = [OFInvalidArgumentException exception];

		callDelegateInMode(_runLoopMode, _delegate, _resolver, _host,
		    addresses, exception);

		objc_autoreleasePoolPop(pool);







>
|
<







275
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
		    of_socket_address_parse_ip(_host, 0);
		OFData *addresses = nil;
		id exception = nil;

		if (_addressFamily == address.family ||
		    _addressFamily == OF_SOCKET_ADDRESS_FAMILY_ANY)
			addresses = [OFData dataWithItems: &address
						    count: 1
						 itemSize: sizeof(address)];

		else
			exception = [OFInvalidArgumentException exception];

		callDelegateInMode(_runLoopMode, _delegate, _resolver, _host,
		    addresses, exception);

		objc_autoreleasePoolPop(pool);

Modified src/OFIPSocketAsyncConnector.m from [6a448fb9d2] to [35ca21ecbd].

242
243
244
245
246
247
248

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
{
	@try {
		of_socket_address_t address =
		    of_socket_address_parse_ip(_host, _port);

		_socketAddresses = [[OFData alloc]
		    initWithItems: &address

			 itemSize: sizeof(address)
			    count: 1];

		[self tryNextAddressWithRunLoopMode: runLoopMode];
		return;
	} @catch (OFInvalidFormatException *e) {
	}

	[[OFThread DNSResolver]
	    asyncResolveAddressesForHost: _host
			   addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY
			     runLoopMode: runLoopMode
				delegate: self];
}
@end







>
|
<













242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260
261
262
263
{
	@try {
		of_socket_address_t address =
		    of_socket_address_parse_ip(_host, _port);

		_socketAddresses = [[OFData alloc]
		    initWithItems: &address
			    count: 1
			 itemSize: sizeof(address)];


		[self tryNextAddressWithRunLoopMode: runLoopMode];
		return;
	} @catch (OFInvalidFormatException *e) {
	}

	[[OFThread DNSResolver]
	    asyncResolveAddressesForHost: _host
			   addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY
			     runLoopMode: runLoopMode
				delegate: self];
}
@end

Modified src/OFMutableData.m from [c516ce707c] to [7f5853c182].

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
		@throw e;
	}

	return self;
}

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

{
	self = [super initWithItems: items

			   itemSize: itemSize
			      count: count];

	_capacity = _count;

	return self;
}

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

		       freeWhenDone: (bool)freeWhenDone
{
	self = [self initWithItems: items

			  itemSize: itemSize
			     count: count];

	if (freeWhenDone)
		free(items);

	return self;
}








<

>


>
|
<







<

>



>
|
<







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
		@throw e;
	}

	return self;
}

- (instancetype)initWithItems: (const void *)items

			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	self = [super initWithItems: items
			      count: count
			   itemSize: itemSize];


	_capacity = _count;

	return self;
}

- (instancetype)initWithItemsNoCopy: (void *)items

			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	self = [self initWithItems: items
			     count: count
			  itemSize: itemSize];


	if (freeWhenDone)
		free(items);

	return self;
}

175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
- (OFData *)subdataWithRange: (of_range_t)range
{
	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > _count)
		@throw [OFOutOfRangeException exception];

	return [OFData dataWithItems: _items + (range.location * _itemSize)

			    itemSize: _itemSize
			       count: range.length];
}

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








>
|
<







175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
- (OFData *)subdataWithRange: (of_range_t)range
{
	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > _count)
		@throw [OFOutOfRangeException exception];

	return [OFData dataWithItems: _items + (range.location * _itemSize)
			       count: range.length
			    itemSize: _itemSize];

}

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

299
300
301
302
303
304
305

306
307
308
309
310
311
312
313
314
	_count = 0;
	_capacity = 0;
}

- (id)copy
{
	return [[OFData alloc] initWithItems: _items

				    itemSize: _itemSize
				       count: _count];
}

- (void)makeImmutable
{
	if (_capacity != _count) {
		@try {
			_items = of_realloc(_items, _count, _itemSize);







>
|
<







299
300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
	_count = 0;
	_capacity = 0;
}

- (id)copy
{
	return [[OFData alloc] initWithItems: _items
				       count: _count
				    itemSize: _itemSize];

}

- (void)makeImmutable
{
	if (_capacity != _count) {
		@try {
			_items = of_realloc(_items, _count, _itemSize);

Modified src/OFSecureData.h from [f20113d2e2] to [fe3dc9b9e1].

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
+ (instancetype)dataWithCount: (size_t)count
	allowsSwappableMemory: (bool)allowsSwappableMemory;

/**
 * @brief Creates a new, autoreleased OFSecureData with count items of the
 *	  specified item size, all set to zero.
 *
 * @param itemSize The size of a single item in the OFSecureData in bytes
 * @param count The number of zero items the OFSecureData should contain

 * @param allowsSwappableMemory Whether the data may be stored in swappable
 *			       memory
 * @return A new, autoreleased OFSecureData
 */
+ (instancetype)dataWithItemSize: (size_t)itemSize
			   count: (size_t)count
	   allowsSwappableMemory: (bool)allowsSwappableMemory;

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

		     itemSize: (size_t)itemSize
			count: (size_t)count OF_UNAVAILABLE;
+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE;
+ (instancetype)dataWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count

		       freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE;
#ifdef OF_HAVE_FILES
+ (instancetype)dataWithContentsOfFile: (OFString *)path OF_UNAVAILABLE;
#endif
+ (instancetype)dataWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE;
+ (instancetype)dataWithStringRepresentation: (OFString *)string OF_UNAVAILABLE;
+ (instancetype)dataWithBase64EncodedString: (OFString *)string OF_UNAVAILABLE;







<

>




|
|
|




>
|
<




<

>







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
+ (instancetype)dataWithCount: (size_t)count
	allowsSwappableMemory: (bool)allowsSwappableMemory;

/**
 * @brief Creates a new, autoreleased OFSecureData with count items of the
 *	  specified item size, all set to zero.
 *

 * @param count The number of zero items the OFSecureData should contain
 * @param itemSize The size of a single item in the OFSecureData in bytes
 * @param allowsSwappableMemory Whether the data may be stored in swappable
 *			       memory
 * @return A new, autoreleased OFSecureData
 */
+ (instancetype)dataWithCount: (size_t)count
		     itemSize: (size_t)itemSize
	allowsSwappableMemory: (bool)allowsSwappableMemory;

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

+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE;
+ (instancetype)dataWithItemsNoCopy: (void *)items

			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE;
#ifdef OF_HAVE_FILES
+ (instancetype)dataWithContentsOfFile: (OFString *)path OF_UNAVAILABLE;
#endif
+ (instancetype)dataWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE;
+ (instancetype)dataWithStringRepresentation: (OFString *)string OF_UNAVAILABLE;
+ (instancetype)dataWithBase64EncodedString: (OFString *)string OF_UNAVAILABLE;
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
 *
 * @param itemSize The size of a single item in the OFSecureData in bytes
 * @param count The number of zero items the OFSecureData should contain
 * @param allowsSwappableMemory Whether the data may be stored in swappable
 *				memory
 * @return An initialized OFSecureData
 */
- (instancetype)initWithItemSize: (size_t)itemSize
			   count: (size_t)count
	   allowsSwappableMemory: (bool)allowsSwappableMemory
    OF_DESIGNATED_INITIALIZER;

- (instancetype)initWithItems: (const void *)items
			count: (size_t)count OF_UNAVAILABLE;
- (instancetype)initWithItems: (const void *)items

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

		       freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE;
#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path OF_UNAVAILABLE;
#endif
- (instancetype)initWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE;
- (instancetype)initWithStringRepresentation: (OFString *)string OF_UNAVAILABLE;
- (instancetype)initWithBase64EncodedString: (OFString *)string OF_UNAVAILABLE;







|
|
|





>
|
<




<

>







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
 *
 * @param itemSize The size of a single item in the OFSecureData in bytes
 * @param count The number of zero items the OFSecureData should contain
 * @param allowsSwappableMemory Whether the data may be stored in swappable
 *				memory
 * @return An initialized OFSecureData
 */
- (instancetype)initWithCount: (size_t)count
		     itemSize: (size_t)itemSize
	allowsSwappableMemory: (bool)allowsSwappableMemory
    OF_DESIGNATED_INITIALIZER;

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

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE;
- (instancetype)initWithItemsNoCopy: (void *)items

			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE;
#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path OF_UNAVAILABLE;
#endif
- (instancetype)initWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE;
- (instancetype)initWithStringRepresentation: (OFString *)string OF_UNAVAILABLE;
- (instancetype)initWithBase64EncodedString: (OFString *)string OF_UNAVAILABLE;

Modified src/OFSecureData.m from [3742a91d29] to [8a522b1fcf].

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
	allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithCount: count
		      allowsSwappableMemory: allowsSwappableMemory]
	    autorelease];
}

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

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

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

{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)dataWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count

		       freeWhenDone: (bool)freeWhenDone
{
	OF_UNRECOGNIZED_SELECTOR
}

#ifdef OF_HAVE_FILES
+ (instancetype)dataWithContentsOfFile: (OFString *)path







|
|


|
|
|










<

>












<

>







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
	allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithCount: count
		      allowsSwappableMemory: allowsSwappableMemory]
	    autorelease];
}

+ (instancetype)dataWithCount: (size_t)count
		     itemSize: (size_t)itemSize
	   allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithCount: count
				   itemSize: itemSize
		      allowsSwappableMemory: allowsSwappableMemory]
	    autorelease];
}

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

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

			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)dataWithItemsNoCopy: (void *)items

			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	OF_UNRECOGNIZED_SELECTOR
}

#ifdef OF_HAVE_FILES
+ (instancetype)dataWithContentsOfFile: (OFString *)path
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
	OF_UNRECOGNIZED_SELECTOR
}


- (instancetype)initWithCount: (size_t)count
	allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [self initWithItemSize: 1
				count: count
		allowsSwappableMemory: allowsSwappableMemory];
}

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

	@try {
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
		size_t pageSize = [OFSystemInfo pageSize];
#endif







|
|
|


|
|
|







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
	OF_UNRECOGNIZED_SELECTOR
}


- (instancetype)initWithCount: (size_t)count
	allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [self initWithCount: count
			  itemSize: 1
	     allowsSwappableMemory: allowsSwappableMemory];
}

- (instancetype)initWithCount: (size_t)count
		     itemSize: (size_t)itemSize
	allowsSwappableMemory: (bool)allowsSwappableMemory
{
	self = [super init];

	@try {
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
		size_t pageSize = [OFSystemInfo pageSize];
#endif
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
#else
		} else
			@throw [OFNotImplementedException
			    exceptionWithSelector: _cmd
					   object: nil];
#endif

		_itemSize = itemSize;
		_count = count;

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

	return self;
}

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

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

{
	OF_INVALID_INIT_METHOD
}

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

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

		       freeWhenDone: (bool)freeWhenDone
{
	OF_INVALID_INIT_METHOD
}

#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path







<

>
















<

>












<

>







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
#else
		} else
			@throw [OFNotImplementedException
			    exceptionWithSelector: _cmd
					   object: nil];
#endif


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

	return self;
}

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

- (instancetype)initWithItems: (const void *)items

			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	OF_INVALID_INIT_METHOD
}

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

- (instancetype)initWithItemsNoCopy: (void *)items

			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	OF_INVALID_INIT_METHOD
}

#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path
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
{
	of_explicit_memset(_items, 0, _count * _itemSize);
}

- (id)copy
{
	OFSecureData *copy = [[OFSecureData alloc]

		 initWithItemSize: _itemSize
			    count: _count
	    allowsSwappableMemory: _allowsSwappableMemory];

	memcpy(copy.mutableItems, _items, _count * _itemSize);

	return copy;
}

- (id)mutableCopy
{
	OFSecureData *copy = [[OFSecureData alloc]

		 initWithItemSize: _itemSize
			    count: _count
	    allowsSwappableMemory: _allowsSwappableMemory];

	memcpy(copy.mutableItems, _items, _count * _itemSize);

	return copy;
}








>
|
<










>
|
<







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

- (id)copy
{
	OFSecureData *copy = [[OFSecureData alloc]
		    initWithCount: _count
			 itemSize: _itemSize

	    allowsSwappableMemory: _allowsSwappableMemory];

	memcpy(copy.mutableItems, _items, _count * _itemSize);

	return copy;
}

- (id)mutableCopy
{
	OFSecureData *copy = [[OFSecureData alloc]
		    initWithCount: _count
			 itemSize: _itemSize

	    allowsSwappableMemory: _allowsSwappableMemory];

	memcpy(copy.mutableItems, _items, _count * _itemSize);

	return copy;
}

Modified src/OFStream.m from [c39ea2325e] to [b13d6173e0].

645
646
647
648
649
650
651
652
653

654
655
656
657
658
659
660

	buffer = of_malloc(count, itemSize);
	@try {
		[self readIntoBuffer: buffer
			 exactLength: count * itemSize];

		ret = [OFData dataWithItemsNoCopy: buffer
					 itemSize: itemSize
					    count: count

				     freeWhenDone: true];
	} @catch (id e) {
		free(buffer);
		@throw e;
	}

	return ret;







<

>







645
646
647
648
649
650
651

652
653
654
655
656
657
658
659
660

	buffer = of_malloc(count, itemSize);
	@try {
		[self readIntoBuffer: buffer
			 exactLength: count * itemSize];

		ret = [OFData dataWithItemsNoCopy: buffer

					    count: count
					 itemSize: itemSize
				     freeWhenDone: true];
	} @catch (id e) {
		free(buffer);
		@throw e;
	}

	return ret;

Modified src/OFString.m from [4797b99f7f] to [75be1c56bd].

2507
2508
2509
2510
2511
2512
2513
2514
2515

2516
2517
2518
2519
2520
2521
2522
			    inRange: of_range(0, length)];
	} @catch (id e) {
		free(buffer);
		@throw e;
	}

	return [OFData dataWithItemsNoCopy: buffer
				  itemSize: sizeof(of_unichar_t)
				     count: length

			      freeWhenDone: true].items;
}

- (const of_char16_t *)UTF16String
{
	return [self UTF16StringWithByteOrder: OF_BYTE_ORDER_NATIVE];
}







<

>







2507
2508
2509
2510
2511
2512
2513

2514
2515
2516
2517
2518
2519
2520
2521
2522
			    inRange: of_range(0, length)];
	} @catch (id e) {
		free(buffer);
		@throw e;
	}

	return [OFData dataWithItemsNoCopy: buffer

				     count: length
				  itemSize: sizeof(of_unichar_t)
			      freeWhenDone: true].items;
}

- (const of_char16_t *)UTF16String
{
	return [self UTF16StringWithByteOrder: OF_BYTE_ORDER_NATIVE];
}
2565
2566
2567
2568
2569
2570
2571
2572
2573

2574
2575
2576
2577
2578
2579
2580
	} @catch (OFOutOfMemoryException *e) {
		/* We don't care, as we only tried to make it smaller */
	}

	objc_autoreleasePoolPop(pool);

	return [OFData dataWithItemsNoCopy: buffer
				  itemSize: sizeof(of_char16_t)
				     count: j + 1

			      freeWhenDone: true].items;
}

- (size_t)UTF16StringLength
{
	const of_unichar_t *characters = self.characters;
	size_t length, UTF16StringLength;







<

>







2565
2566
2567
2568
2569
2570
2571

2572
2573
2574
2575
2576
2577
2578
2579
2580
	} @catch (OFOutOfMemoryException *e) {
		/* We don't care, as we only tried to make it smaller */
	}

	objc_autoreleasePoolPop(pool);

	return [OFData dataWithItemsNoCopy: buffer

				     count: j + 1
				  itemSize: sizeof(of_char16_t)
			      freeWhenDone: true].items;
}

- (size_t)UTF16StringLength
{
	const of_unichar_t *characters = self.characters;
	size_t length, UTF16StringLength;
2609
2610
2611
2612
2613
2614
2615
2616
2617

2618
2619
2620
2621
2622
2623
2624
	}

	if (byteOrder != OF_BYTE_ORDER_NATIVE)
		for (size_t i = 0; i < length; i++)
			buffer[i] = OF_BSWAP32(buffer[i]);

	return [OFData dataWithItemsNoCopy: buffer
				  itemSize: sizeof(of_char32_t)
				     count: length + 1

			      freeWhenDone: true].items;
}

- (OFData *)dataWithEncoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFData *data =







<

>







2609
2610
2611
2612
2613
2614
2615

2616
2617
2618
2619
2620
2621
2622
2623
2624
	}

	if (byteOrder != OF_BYTE_ORDER_NATIVE)
		for (size_t i = 0; i < length; i++)
			buffer[i] = OF_BSWAP32(buffer[i]);

	return [OFData dataWithItemsNoCopy: buffer

				     count: length + 1
				  itemSize: sizeof(of_char32_t)
			      freeWhenDone: true].items;
}

- (OFData *)dataWithEncoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFData *data =

Modified src/scrypt.m from [163ddcc8f1] to [b6bce8773e].

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
		uint32_t *tmpItems, *bufferItems;

		if (param.costFactor > SIZE_MAX - 1 ||
		    (param.costFactor + 1) > SIZE_MAX / 128)
			@throw [OFOutOfRangeException exception];

		tmp = [[OFSecureData alloc]
			 initWithItemSize: param.blockSize
				    count: (param.costFactor + 1) * 128

		    allowsSwappableMemory: param.allowsSwappableMemory];
		tmpItems = tmp.mutableItems;

		if (param.parallelization > SIZE_MAX / 128)
			@throw [OFOutOfRangeException exception];

		buffer = [[OFSecureData alloc]
			 initWithItemSize: param.blockSize
				    count: param.parallelization * 128

		    allowsSwappableMemory: param.allowsSwappableMemory];
		bufferItems = buffer.mutableItems;

		HMAC = [[OFHMAC alloc]
			initWithHashClass: [OFSHA256Hash class]
		    allowsSwappableMemory: param.allowsSwappableMemory];








<
|
>







<
|
>







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
		uint32_t *tmpItems, *bufferItems;

		if (param.costFactor > SIZE_MAX - 1 ||
		    (param.costFactor + 1) > SIZE_MAX / 128)
			@throw [OFOutOfRangeException exception];

		tmp = [[OFSecureData alloc]

			    initWithCount: (param.costFactor + 1) * 128
				 itemSize: param.blockSize
		    allowsSwappableMemory: param.allowsSwappableMemory];
		tmpItems = tmp.mutableItems;

		if (param.parallelization > SIZE_MAX / 128)
			@throw [OFOutOfRangeException exception];

		buffer = [[OFSecureData alloc]

			    initWithCount: param.parallelization * 128
				 itemSize: param.blockSize
		    allowsSwappableMemory: param.allowsSwappableMemory];
		bufferItems = buffer.mutableItems;

		HMAC = [[OFHMAC alloc]
			initWithHashClass: [OFSHA256Hash class]
		    allowsSwappableMemory: param.allowsSwappableMemory];

Modified tests/OFDataTests.m from [ec82a4e0aa] to [a550decdef].

51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66

	TEST(@"-[lastItem]", memcmp(mutable.lastItem, raw[1], 4096) == 0)

	TEST(@"-[count]", mutable.count == 2)

	TEST(@"-[isEqual:]",
	    (immutable = [OFData dataWithItems: mutable.items

				      itemSize: mutable.itemSize
					 count: mutable.count]) &&
	    [immutable isEqual: mutable] &&
	    R([mutable removeLastItem]) && ![mutable isEqual: immutable])

	TEST(@"-[mutableCopy]",
	    (mutable = [[immutable mutableCopy] autorelease]) &&
	    [mutable isEqual: immutable])








>
|
<







51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66

	TEST(@"-[lastItem]", memcmp(mutable.lastItem, raw[1], 4096) == 0)

	TEST(@"-[count]", mutable.count == 2)

	TEST(@"-[isEqual:]",
	    (immutable = [OFData dataWithItems: mutable.items
					 count: mutable.count
				      itemSize: mutable.itemSize]) &&

	    [immutable isEqual: mutable] &&
	    R([mutable removeLastItem]) && ![mutable isEqual: immutable])

	TEST(@"-[mutableCopy]",
	    (mutable = [[immutable mutableCopy] autorelease]) &&
	    [mutable isEqual: immutable])

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
	TEST(@"-[insertItems:atIndex:count:]",
	    R([mutable insertItems: "bc"
			   atIndex: 1
			     count: 2]) && mutable.count == 5 &&
	    memcmp(mutable.items, "abcde", 5) == 0)

	immutable = [OFData dataWithItems: "aaabaccdacaabb"

				 itemSize: 2
				    count: 7];
	TEST(@"-[rangeOfString:options:range:]",
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"
							   itemSize: 2
							      count: 1]

				     options: 0
				       range: of_range(0, 7)]) &&
	    range.location == 0 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"
							   itemSize: 2
							      count: 1]

				     options: OF_DATA_SEARCH_BACKWARDS
				       range: of_range(0, 7)]) &&
	    range.location == 5 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "ac"
							   itemSize: 2
							      count: 1]

				     options: 0
				       range: of_range(0, 7)]) &&
	    range.location == 2 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aabb"
							   itemSize: 2
							      count: 2]

				     options: 0
				       range: of_range(0, 7)]) &&
	    range.location == 5 && range.length == 2 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"
							   itemSize: 2
							      count: 1]

				     options: 0
				       range: of_range(1, 6)]) &&
	    range.location == 5 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"
							   itemSize: 2
							      count: 1]

				     options: OF_DATA_SEARCH_BACKWARDS
				       range: of_range(0, 5)]) &&
	    range.location == 0 && range.length == 1)

	EXPECT_EXCEPTION(
	    @"-[rangeOfString:options:range:] failing on different itemSize",
	    OFInvalidArgumentException,
	    [immutable rangeOfData: [OFData dataWithItems: "aaa"
						 itemSize: 3
						    count: 1]

			   options: 0
			     range: of_range(0, 1)])

	EXPECT_EXCEPTION(
	    @"-[rangeOfData:options:range:] failing on out of range",
	    OFOutOfRangeException,
	    [immutable rangeOfData: [OFData dataWithItems: ""
						 itemSize: 2
						    count: 0]

			   options: 0
			     range: of_range(8, 1)])

	TEST(@"-[subdataWithRange:]",
	    [[immutable subdataWithRange: of_range(2, 4)]
	    isEqual: [OFData dataWithItems: "accdacaa"

				  itemSize: 2
				     count: 4]] &&
	    [[mutable subdataWithRange: of_range(2, 3)]
	    isEqual: [OFData dataWithItems: "cde"
				     count: 3]])

	EXPECT_EXCEPTION(@"-[subdataWithRange:] failing on out of range #1",
	    OFOutOfRangeException, [immutable subdataWithRange: of_range(7, 1)])








>
|
<


<
|
>




<
|
>




<
|
>




<
|
>




<
|
>




<
|
>








<
|
>







<
|
>






>
|
<







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
	TEST(@"-[insertItems:atIndex:count:]",
	    R([mutable insertItems: "bc"
			   atIndex: 1
			     count: 2]) && mutable.count == 5 &&
	    memcmp(mutable.items, "abcde", 5) == 0)

	immutable = [OFData dataWithItems: "aaabaccdacaabb"
				    count: 7
				 itemSize: 2];

	TEST(@"-[rangeOfString:options:range:]",
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"

							      count: 1
							   itemSize: 2]
				     options: 0
				       range: of_range(0, 7)]) &&
	    range.location == 0 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"

							      count: 1
							   itemSize: 2]
				     options: OF_DATA_SEARCH_BACKWARDS
				       range: of_range(0, 7)]) &&
	    range.location == 5 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "ac"

							      count: 1
							   itemSize: 2]
				     options: 0
				       range: of_range(0, 7)]) &&
	    range.location == 2 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aabb"

							      count: 2
							   itemSize: 2]
				     options: 0
				       range: of_range(0, 7)]) &&
	    range.location == 5 && range.length == 2 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"

							      count: 1
							   itemSize: 2]
				     options: 0
				       range: of_range(1, 6)]) &&
	    range.location == 5 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"

							      count: 1
							   itemSize: 2]
				     options: OF_DATA_SEARCH_BACKWARDS
				       range: of_range(0, 5)]) &&
	    range.location == 0 && range.length == 1)

	EXPECT_EXCEPTION(
	    @"-[rangeOfString:options:range:] failing on different itemSize",
	    OFInvalidArgumentException,
	    [immutable rangeOfData: [OFData dataWithItems: "aaa"

						    count: 1
						 itemSize: 3]
			   options: 0
			     range: of_range(0, 1)])

	EXPECT_EXCEPTION(
	    @"-[rangeOfData:options:range:] failing on out of range",
	    OFOutOfRangeException,
	    [immutable rangeOfData: [OFData dataWithItems: ""

						    count: 0
						 itemSize: 2]
			   options: 0
			     range: of_range(8, 1)])

	TEST(@"-[subdataWithRange:]",
	    [[immutable subdataWithRange: of_range(2, 4)]
	    isEqual: [OFData dataWithItems: "accdacaa"
				     count: 4
				  itemSize: 2]] &&

	    [[mutable subdataWithRange: of_range(2, 3)]
	    isEqual: [OFData dataWithItems: "cde"
				     count: 3]])

	EXPECT_EXCEPTION(@"-[subdataWithRange:] failing on out of range #1",
	    OFOutOfRangeException, [immutable subdataWithRange: of_range(7, 1)])