ObjFW  Diff

Differences From Artifact [ca2bfba7fb]:

To Artifact [9afe18d8f2]:


116
117
118
119
120
121
122
123
124


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


123
124
125
126
127
128
129
130
131







-
-
+
+







			char *buffer = [self allocMemoryWithSize: of_pagesize];

			while (![file isAtEndOfStream]) {
				size_t length;

				length = [file readIntoBuffer: buffer
						       length: of_pagesize];
				[self addItemsFromCArray: buffer
						   count: length];
				[self addItems: buffer
					 count: length];
			}

			[self freeMemory: buffer];
		} @finally {
			[file release];
		}
	} @catch (id e) {
183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197







-
+








		if (count & 1)
			@throw [OFInvalidFormatException
			    exceptionWithClass: [self class]];

		count >>= 1;
		cString = [string UTF8String];
		data = [self allocMemoryWithSize: count];
		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')
210
211
212
213
214
215
216
217

218
219
220
221
222
223
224
210
211
212
213
214
215
216

217
218
219
220
221
222
223
224







-
+







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

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

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







-
+

-
+







-
+




-
+


-
+




-
+


-
+







-
-
-
+
+
+

-
+







-
-
-
+
+
+


-
-
+
+

-
+


-
-
-
+
+
+

-
-
+
+


-
-
-
+
+
+

-
+


-
-
-
+
+
+

-
+

-
+

-
+













-
-
+
+




-
-
-
+
+
+












-
-
-
+
+
+







-
+

-
+







-
-
+
+
















-
+







}

- (size_t)itemSize
{
	return itemSize;
}

- (void*)cArray
- (void*)items
{
	return data;
	return items;
}

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

	return data + index * itemSize;
	return items + index * itemSize;
}

- (void*)firstItem
{
	if (data == NULL || count == 0)
	if (items == NULL || count == 0)
		return NULL;

	return data;
	return items;
}

- (void*)lastItem
{
	if (data == NULL || count == 0)
	if (items == NULL || count == 0)
		return NULL;

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

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

	data = [self resizeMemory: data
			     size: itemSize
			    count: count + 1];
	items = [self resizeMemory: items
			      size: itemSize
			     count: count + 1];

	memcpy(data + count * itemSize, item, itemSize);
	memcpy(items + count * itemSize, item, itemSize);

	count++;
}

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

- (void)addItemsFromCArray: (const void*)cArray
		     count: (size_t)nItems
- (void)addItems: (const void*)items_
	   count: (size_t)count_
{
	if (nItems > SIZE_MAX - count)
	if (count_ > SIZE_MAX - count)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	data = [self resizeMemory: data
			     size: itemSize
			    count: count + nItems];
	items = [self resizeMemory: items
			      size: itemSize
			     count: count + count_];

	memcpy(data + count * itemSize, cArray, nItems * itemSize);
	count += nItems;
	memcpy(items + count * itemSize, items_, count_ * itemSize);
	count += count_;
}

- (void)insertItemsFromCArray: (const void*)cArray
		      atIndex: (size_t)index
			count: (size_t)nItems
- (void)insertItems: (const void*)items_
	    atIndex: (size_t)index
	      count: (size_t)count_
{
	if (nItems > SIZE_MAX - count || index > count)
	if (count_ > SIZE_MAX - count || index > count)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	data = [self resizeMemory: data
			     size: itemSize
			    count: count + nItems];
	items = [self resizeMemory: items
			      size: itemSize
			     count: count + count_];

	memmove(data + (index + nItems) * itemSize, data + index * itemSize,
	memmove(items + (index + count_) * itemSize, items + index * itemSize,
	    (count - index) * itemSize);
	memcpy(data + index * itemSize, cArray, nItems * itemSize);
	memcpy(items + index * itemSize, items_, count_ * itemSize);

	count += nItems;
	count += count_;
}

- (void)removeItemAtIndex: (size_t)index
{
	[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]];

	memmove(data + range.location * itemSize,
	    data + (range.location + range.length) * itemSize,
	memmove(items + range.location * itemSize,
	    items + (range.location + range.length) * itemSize,
	    (count - range.location - range.length) * itemSize);

	count -= range.length;
	@try {
		data = [self resizeMemory: data
				     size: itemSize
				    count: count];
		items = [self resizeMemory: items
				      size: itemSize
				     count: count];
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
	}
}

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

	count--;
	@try {
		data = [self resizeMemory: data
				     size: itemSize
				    count: count];
		items = [self resizeMemory: items
				      size: itemSize
				     count: count];
	} @catch (OFOutOfMemoryException *e) {
		/* We don't care, as we only made it smaller */
	}
}

- (void)removeAllItems
{
	[self freeMemory: data];
	[self freeMemory: items];

	data = NULL;
	items = NULL;
	count = 0;
}

- copy
{
	OFDataArray *copy = [[[self class] alloc] initWithItemSize: itemSize];

	[copy addItemsFromCArray: data
			   count: count];
	[copy addItems: items
		 count: count];

	return copy;
}

- (BOOL)isEqual: (id)object
{
	OFDataArray *otherDataArray;

	if (![object isKindOfClass: [OFDataArray class]])
		return NO;

	otherDataArray = object;

	if ([otherDataArray count] != count ||
	    [otherDataArray itemSize] != itemSize)
		return NO;
	if (memcmp([otherDataArray cArray], data, count * itemSize))
	if (memcmp([otherDataArray items], items, count * itemSize))
		return NO;

	return YES;
}

- (of_comparison_result_t)compare: (id <OFComparing>)object
{
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
465
466
467
468
469
470
471

472
473
474
475
476
477
478
479







-
+







		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	otherCount = [otherDataArray count];
	minimumCount = (count > otherCount ? otherCount : count);

	if ((comparison = memcmp(data, [otherDataArray cArray],
	if ((comparison = memcmp(items, [otherDataArray items],
	    minimumCount * itemSize)) == 0) {
		if (count > otherCount)
			return OF_ORDERED_DESCENDING;
		if (count < otherCount)
			return OF_ORDERED_ASCENDING;
		return OF_ORDERED_SAME;
	}
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
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







-
+


















-
+















-
+







-
+








-
+




















-
+







{
	uint32_t hash;
	size_t i;

	OF_HASH_INIT(hash);

	for (i = 0; i < count * itemSize; i++)
		OF_HASH_ADD(hash, ((char*)data)[i]);
		OF_HASH_ADD(hash, ((uint8_t*)items)[i]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

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

	for (i = 0; i < count; i++) {
		size_t j;

		if (i > 0)
			[ret appendString: @" "];

		for (j = 0; j < itemSize; j++)
			[ret appendFormat: @"%02x", data[i * itemSize + j]];
			[ret appendFormat: @"%02x", items[i * itemSize + j]];
	}

	[ret appendString: @">"];

	[ret makeImmutable];
	return ret;
}

- (OFString*)stringRepresentation
{
	OFMutableString *ret = [OFMutableString string];
	size_t i, j;

	for (i = 0; i < count; i++)
		for (j = 0; j < itemSize; j++)
			[ret appendFormat: @"%02x", data[i * itemSize + j]];
			[ret appendFormat: @"%02x", items[i * itemSize + j]];

	[ret makeImmutable];
	return ret;
}

- (OFString*)stringByBase64Encoding
{
	return of_base64_encode(data, count * itemSize);
	return of_base64_encode(items, count * itemSize);
}

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

	@try {
		[file writeBuffer: data
		[file writeBuffer: items
			   length: count * itemSize];
	} @finally {
		[file release];
	}
}

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

	if (itemSize != 1)
		@throw [OFNotImplementedException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	pool = objc_autoreleasePoolPush();
	element = [OFXMLElement
	    elementWithName: [self className]
		  namespace: OF_SERIALIZATION_NS
		stringValue: of_base64_encode(data, count * itemSize)];
		stringValue: of_base64_encode(items, count * itemSize)];

	[element retain];

	objc_autoreleasePoolPop(pool);

	return [element autorelease];
}
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
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







-
-
+
+

-
+





-
-
+
+



-
+



-
+


-
-
+
+

-
+

-
+



-
-
-
+
+
+



-
-
+
+



-
+


-
-
+
+

-
+

-
+

-
+











-
-
+
+







-
-
+
+
















-
-
+
+










-
+

-
+




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

	lastPageByte = of_pagesize - 1;
	newSize = ((count + 1) * itemSize + lastPageByte) & ~lastPageByte;

	if (size != newSize)
		data = [self resizeMemory: data
				     size: newSize];
		items = [self resizeMemory: items
				      size: newSize];

	memcpy(data + count * itemSize, item, itemSize);
	memcpy(items + count * itemSize, item, itemSize);

	count++;
	size = newSize;
}

- (void)addItemsFromCArray: (const void*)cArray
		     count: (size_t)nItems
- (void)addItems: (const void*)items_
	   count: (size_t)count_
{
	size_t newSize, lastPageByte;

	if (nItems > SIZE_MAX - count || count + nItems > SIZE_MAX / itemSize)
	if (count_ > SIZE_MAX - count || count + count_ > SIZE_MAX / itemSize)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	lastPageByte = of_pagesize - 1;
	newSize = ((count + nItems) * itemSize + lastPageByte) & ~lastPageByte;
	newSize = ((count + count_) * itemSize + lastPageByte) & ~lastPageByte;

	if (size != newSize)
		data = [self resizeMemory: data
				     size: newSize];
		items = [self resizeMemory: items
				      size: newSize];

	memcpy(data + count * itemSize, cArray, nItems * itemSize);
	memcpy(items + count * itemSize, items_, count_ * itemSize);

	count += nItems;
	count += count_;
	size = newSize;
}

- (void)insertItemsFromCArray: (const void*)cArray
		      atIndex: (size_t)index
			count: (size_t)nItems
- (void)insertItems: (const void*)items_
	    atIndex: (size_t)index
	      count: (size_t)count_
{
	size_t newSize, lastPageByte;

	if (nItems > SIZE_MAX - count || index > count ||
	    count + nItems > SIZE_MAX / itemSize)
	if (count_ > SIZE_MAX - count || index > count ||
	    count + count_ > SIZE_MAX / itemSize)
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	lastPageByte = of_pagesize - 1;
	newSize = ((count + nItems) * itemSize + lastPageByte) & ~lastPageByte;
	newSize = ((count + count_) * itemSize + lastPageByte) & ~lastPageByte;

	if (size != newSize)
		data = [self resizeMemory: data
				     size: newSize];
		items = [self resizeMemory: items
				      size: newSize];

	memmove(data + (index + nItems) * itemSize, data + index * itemSize,
	memmove(items + (index + count_) * itemSize, items + index * itemSize,
	    (count - index) * itemSize);
	memcpy(data + index * itemSize, cArray, nItems * itemSize);
	memcpy(items + index * itemSize, items_, count_ * itemSize);

	count += nItems;
	count += count_;
	size = newSize;
}

- (void)removeItemsInRange: (of_range_t)range
{
	size_t newSize, lastPageByte;

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

	memmove(data + range.location * itemSize,
	    data + (range.location + range.length) * itemSize,
	memmove(items + range.location * itemSize,
	    items + (range.location + range.length) * itemSize,
	    (count - range.location - range.length) * itemSize);

	count -= range.length;
	lastPageByte = of_pagesize - 1;
	newSize = (count * itemSize + lastPageByte) & ~lastPageByte;

	if (size != newSize)
		data = [self resizeMemory: data
				     size: newSize];
		items = [self resizeMemory: items
				      size: newSize];
	size = newSize;
}

- (void)removeLastItem
{
	size_t newSize, lastPageByte;

	if (count == 0)
		return;

	count--;
	lastPageByte = of_pagesize - 1;
	newSize = (count * itemSize + lastPageByte) & ~lastPageByte;

	if (size != newSize) {
		@try {
			data = [self resizeMemory: data
					     size: newSize];
			items = [self resizeMemory: items
					      size: newSize];
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only made it smaller */
		}

		size = newSize;
	}
}

- (void)removeAllItems
{
	[self freeMemory: data];
	[self freeMemory: items];

	data = NULL;
	items = NULL;
	count = 0;
	size = 0;
}
@end