ObjFW  Diff

Differences From Artifact [c782595990]:

To Artifact [d222b0db89]:

  • File src/OFDataArray.m — part of check-in [3d16a30f41] at 2013-06-22 12:12:36 on branch trunk — Rework exceptions.

    This mostly removes the argument for the class in which the exception
    occurred. As backtraces were recently added for all platforms, the
    passed class does not give any extra information on where the exception
    occurred anymore.

    This also removes a few other arguments which were not too helpful. In
    the past, the idea was to pass as many arguments as possible so that it
    is easier to find the origin of the exception. However, as backtraces
    are a much better way to find the origin, those are not useful anymore
    and just make the exception more cumbersome to use. The rule is now to
    only pass arguments that might help in recovering from the exception or
    provide information that is otherwise not easily accessible. (user: js, size: 17510) [annotate] [blame] [check-ins using]


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







-

-
+
-



















-
+
-








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

	if (itemSize == 0) {
		Class c = [self class];
		[self release];
		@throw [OFInvalidArgumentException exceptionWithClass: c
		@throw [OFInvalidArgumentException exception];
							     selector: _cmd];
	}

	_items = [self allocMemoryWithSize: itemSize
				     count: capacity];

	_itemSize = itemSize;
	_capacity = capacity;

	return self;
}

- initWithContentsOfFile: (OFString*)path
{
	@try {
		OFFile *file = [[OFFile alloc] initWithPath: path
						       mode: @"rb"];
		off_t size = [OFFile sizeOfFileAtPath: path];

		if (size > SIZE_MAX)
			@throw [OFOutOfRangeException
			@throw [OFOutOfRangeException exception];
			    exceptionWithClass: [self class]];

		self = [self initWithItemSize: 1
				     capacity: (size_t)size];

		@try {
			size_t pageSize = [OFSystemInfo pageSize];
			char *buffer = [self allocMemoryWithSize: pageSize];
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
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







-
-
-
+
+










-
+
-

-
+




















-
+
-


















-
+
-








-
+
-



















-
+
-
-
-
+
-
















-
+
-
-








	client = [OFHTTPClient client];
	request = [OFHTTPRequest requestWithURL: URL];
	reply = [client performRequest: request];

	if ([reply statusCode] != 200)
		@throw [OFHTTPRequestFailedException
		    exceptionWithClass: [request class]
			       request: request
				 reply: reply];
		    exceptionWithRequest: request
				   reply: reply];

	/*
	 * TODO: This can be optimized by allocating a data array with the
	 * capacity from the Content-Length header.
	 */
	self = [[reply readDataArrayTillEndOfStream] retain];

	headers = [reply headers];
	if ((contentLength = [headers objectForKey: @"Content-Length"]) != nil)
		if ([self count] != (size_t)[contentLength decimalValue])
			@throw [OFTruncatedDataException
			@throw [OFTruncatedDataException exception];
			    exceptionWithClass: [self class]];
#else
	@throw [OFUnsupportedProtocolException exceptionWithClass: c];
	@throw [OFUnsupportedProtocolException exceptionWithURL: URL];
#endif

	objc_autoreleasePoolPop(pool);

	return self;
}

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

	@try {
		const char *cString;
		size_t i;

		_itemSize = 1;
		_count = [string
		    cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII];

		if (_count % 2 != 0)
			@throw [OFInvalidFormatException
			@throw [OFInvalidFormatException exception];
			    exceptionWithClass: [self class]];

		_count /= 2;
		cString = [string
		    cStringWithEncoding: OF_STRING_ENCODING_ASCII];
		_items = [self allocMemoryWithSize: _count];

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

			if (c1 >= '0' && c1 <= '9')
				byte = (c1 - '0') << 4;
			else if (c1 >= 'a' && c1 <= 'f')
				byte = (c1 - 'a' + 10) << 4;
			else if (c1 >= 'A' && c1 <= 'F')
				byte = (c1 - 'A' + 10) << 4;
			else
				@throw [OFInvalidFormatException
				@throw [OFInvalidFormatException exception];
				    exceptionWithClass: [self class]];

			if (c2 >= '0' && c2 <= '9')
				byte |= c2 - '0';
			else if (c2 >= 'a' && c2 <= 'f')
				byte |= c2 - 'a' + 10;
			else if (c2 >= 'A' && c2 <= 'F')
				byte |= c2 - 'A' + 10;
			else
				@throw [OFInvalidFormatException
				@throw [OFInvalidFormatException exception];
				    exceptionWithClass: [self class]];

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

	return self;
}

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

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

	return self;
}

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

		if (![[element name] isEqual: [self className]] ||
		    ![[element namespace] isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException
			@throw [OFInvalidArgumentException exception];
			    exceptionWithClass: [self class]
				      selector: _cmd];

		stringValue = [element stringValue];

		self = [self initWithBase64EncodedString: stringValue];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
333
334
335
336
337
338
339

340
341
342
343
344
345
346
347







-
+







{
	return _items;
}

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

	return _items + index * _itemSize;
}

- (void*)firstItem
{
	if (_items == NULL || _count == 0)
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384
357
358
359
360
361
362
363

364
365
366
367
368
369
370
371







-
+








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

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

	if (_count + 1 > _capacity) {
		_items = [self resizeMemory: _items
				       size: _itemSize
				      count: _count + 1];
		_capacity = _count + 1;
	}
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
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







-
+

















-
+







		    count: 1];
}

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

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

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

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

	if (_count + count > _capacity) {
		_items = [self resizeMemory: _items
				       size: _itemSize
				      count: _count + count];
		_capacity = _count + count;
	}
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440







-
+







	[self removeItemsInRange: of_range(index, 1)];
}

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

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

	_count -= range.length;
	@try {
517
518
519
520
521
522
523
524
525


526
527
528
529
530

531
532
533
534
535
536
537
538
539
504
505
506
507
508
509
510


511
512

513
514
515

516


517
518
519
520
521
522
523







-
-
+
+
-



-
+
-
-







- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	OFDataArray *dataArray;
	int comparison;
	size_t count, minCount;

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

			      selector: _cmd];
	dataArray = (OFDataArray*)object;

	if ([dataArray itemSize] != _itemSize)
		@throw [OFInvalidArgumentException
		@throw [OFInvalidArgumentException exception];
		    exceptionWithClass: [self class]
			      selector: _cmd];

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

	if ((comparison = memcmp(_items, [dataArray items],
	    minCount * _itemSize)) == 0) {
		if (_count > count)
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
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







-
+
-



















-
+
-
-








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

	if (_itemSize != 1)
		@throw [OFInvalidArgumentException
		@throw [OFInvalidArgumentException exception];
		    exceptionWithClass: [self class]];

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

	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}

- (OFDataArray*)messagePackRepresentation
{
	OFDataArray *data;

	if (_itemSize != 1)
		@throw [OFInvalidArgumentException
		@throw [OFInvalidArgumentException exception];
		    exceptionWithClass: [self class]
			      selector: _cmd];

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

		data = [OFDataArray dataArrayWithItemSize: 1
						 capacity: _count + 2];
674
675
676
677
678
679
680
681

682
683
684
685
686
687
688
655
656
657
658
659
660
661

662
663
664
665
666
667
668
669







-
+







		data = [OFDataArray dataArrayWithItemSize: 1
						 capacity: _count + 5];

		[data addItem: &type];
		[data addItems: &tmp
			 count: sizeof(tmp)];
	} else
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
		@throw [OFOutOfRangeException exception];

	[data addItems: _items
		 count: _count];

	return data;
}
@end
700
701
702
703
704
705
706
707

708
709
710
711
712
713
714
681
682
683
684
685
686
687

688
689
690
691
692
693
694
695







-
+







}

- (void)addItem: (const void*)item
{
	size_t size, lastPageByte;

	if (SIZE_MAX - _count < 1 || _count + 1 > SIZE_MAX / _itemSize)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
		@throw [OFOutOfRangeException exception];

	lastPageByte = [OFSystemInfo pageSize] - 1;
	size = ((_count + 1) * _itemSize + lastPageByte) & ~lastPageByte;

	if (size > _capacity) {
		_items = [self resizeMemory: _items
				       size: size];
723
724
725
726
727
728
729
730

731
732
733
734
735
736
737
704
705
706
707
708
709
710

711
712
713
714
715
716
717
718







-
+








- (void)addItems: (const void*)items
	   count: (size_t)count
{
	size_t size, lastPageByte;

	if (count > SIZE_MAX - _count || _count + count > SIZE_MAX / _itemSize)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
		@throw [OFOutOfRangeException exception];

	lastPageByte = [OFSystemInfo pageSize] - 1;
	size = ((_count + count) * _itemSize + lastPageByte) & ~lastPageByte;

	if (size > _capacity) {
		_items = [self resizeMemory: _items
				       size: size];
748
749
750
751
752
753
754
755

756
757
758
759
760
761
762
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743







-
+







	    atIndex: (size_t)index
	      count: (size_t)count
{
	size_t size, lastPageByte;

	if (count > SIZE_MAX - _count || index > _count ||
	    _count + count > SIZE_MAX / _itemSize)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];
		@throw [OFOutOfRangeException exception];

	lastPageByte = [OFSystemInfo pageSize] - 1;
	size = ((_count + count) * _itemSize + lastPageByte) & ~lastPageByte;

	if (size > _capacity) {
		_items = [self resizeMemory: _items
				       size: size];
773
774
775
776
777
778
779
780

781
782
783
784
785
786
787
754
755
756
757
758
759
760

761
762
763
764
765
766
767
768







-
+








- (void)removeItemsInRange: (of_range_t)range
{
	size_t pageSize, size;

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

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

	_count -= range.length;
	pageSize = [OFSystemInfo pageSize];