ObjFW  Diff

Differences From Artifact [f6e5cef596]:

To Artifact [e97aaf5fcc]:


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







-
-
+
+








-
-
+
+







-
+







		[buffer addItems: string
			   count: length];
	else {
		void *pool = objc_autoreleasePoolPush();
		OFString *tmp = [OFString stringWithCString: string
						   encoding: encoding
						     length: length];
		[buffer addItems: [tmp UTF8String]
			   count: [tmp UTF8StringLength]];
		[buffer addItems: tmp.UTF8String
			   count: tmp.UTF8StringLength];
		objc_autoreleasePoolPop(pool);
	}
}

static OFString *
transformString(OFXMLParser *parser, OFMutableData *buffer, size_t cut,
    bool unescape)
{
	char *items = [buffer items];
	size_t length = [buffer count] - cut;
	char *items = buffer.mutableItems;
	size_t length = buffer.count - cut;
	bool hasEntities = false;
	OFString *ret;

	for (size_t i = 0; i < length; i++) {
		if (items[i] == '\r') {
			if (i + 1 < length && items[i + 1] == '\n') {
				[buffer removeItemAtIndex: i];
				items = [buffer items];
				items = buffer.mutableItems;

				i--;
				length--;
			} else
				items[i] = '\n';
		} else if (items[i] == '&')
			hasEntities = true;
121
122
123
124
125
126
127
128
129


130
131
132
133
134
135
136
121
122
123
124
125
126
127


128
129
130
131
132
133
134
135
136







-
-
+
+








	return ret;
}

static OFString *
namespaceForPrefix(OFString *prefix, OFArray *namespaces)
{
	OFDictionary *const *objects = [namespaces objects];
	size_t count = [namespaces count];
	OFDictionary *const *objects = namespaces.objects;
	size_t count = namespaces.count;

	if (prefix == nil)
		prefix = @"";

	while (count > 0) {
		OFString *tmp;

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







-
-
+
+








-
+







	if (length - _last > 0 && _state != OF_XMLPARSER_IN_TAG)
		appendToBuffer(_buffer, _data + _last, _encoding,
		    length - _last);
}

- (void)parseString: (OFString *)string
{
	[self parseBuffer: [string UTF8String]
		   length: [string UTF8StringLength]];
	[self parseBuffer: string.UTF8String
		   length: string.UTF8StringLength];
}

- (void)parseStream: (OFStream *)stream
{
	size_t pageSize = [OFSystemInfo pageSize];
	char *buffer = [self allocMemoryWithSize: pageSize];

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

			[self parseBuffer: buffer
				   length: length];
		}
	} @finally {
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
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







-
+










-
+







}

/* Not in a tag */
- (void)of_outsideTagState
{
	size_t length;

	if ((_finishedParsing || [_previous count] < 1) && _data[_i] != ' ' &&
	if ((_finishedParsing || _previous.count < 1) && _data[_i] != ' ' &&
	    _data[_i] != '\t' && _data[_i] != '\n' && _data[_i] != '\r' &&
	    _data[_i] != '<')
		@throw [OFMalformedXMLException exceptionWithParser: self];

	if (_data[_i] != '<')
		return;

	if ((length = _i - _last) > 0)
		appendToBuffer(_buffer, _data + _last, _encoding, length);

	if ([_buffer count] > 0) {
	if (_buffer.count > 0) {
		void *pool = objc_autoreleasePoolPush();
		OFString *characters = transformString(self, _buffer, 0, true);

		if ([_delegate respondsToSelector:
		    @selector(parser:foundCharacters:)])
			[_delegate parser: self
			  foundCharacters: characters];
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408







-
+







		break;
	case '!':
		_last = _i + 1;
		_state = OF_XMLPARSER_IN_EXCLAMATIONMARK;
		_acceptProlog = false;
		break;
	default:
		if (_depthLimit > 0 && [_previous count] >= _depthLimit)
		if (_depthLimit > 0 && _previous.count >= _depthLimit)
			@throw [OFOutOfRangeException exception];

		_state = OF_XMLPARSER_IN_TAG_NAME;
		_acceptProlog = false;
		_i--;
		break;
	}
420
421
422
423
424
425
426
427
428


429
430
431


432
433
434
435
436
437
438
420
421
422
423
424
425
426


427
428
429


430
431
432
433
434
435
436
437
438







-
-
+
+

-
-
+
+







	bool hasVersion = false;

	if (!_acceptProlog)
		return false;

	_acceptProlog = false;

	pi = [pi substringWithRange: of_range(3, [pi length] - 3)];
	pi = [pi stringByDeletingEnclosingWhitespaces];
	pi = [pi substringWithRange: of_range(3, pi.length - 3)];
	pi = pi.stringByDeletingEnclosingWhitespaces;

	cString = [pi UTF8String];
	length = [pi UTF8StringLength];
	cString = pi.UTF8String;
	length = pi.UTF8StringLength;

	last = 0;
	for (size_t i = 0; i < length; i++) {
		switch (PIState) {
		case 0:
			if (cString[i] == ' ' || cString[i] == '\t' ||
			    cString[i] == '\r' || cString[i] == '\n')
543
544
545
546
547
548
549
550
551


552
553
554
555
556
557
558
543
544
545
546
547
548
549


550
551
552
553
554
555
556
557
558







-
-
+
+







		return;

	if ((length = _i - _last) > 0)
		appendToBuffer(_buffer, _data + _last, _encoding, length);

	pool = objc_autoreleasePoolPush();

	bufferCString = [_buffer items];
	bufferLength = [_buffer count];
	bufferCString = _buffer.items;
	bufferLength = _buffer.count;
	bufferString = [OFString stringWithUTF8String: bufferCString
					       length: bufferLength];

	if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) {
		_name = [[OFString alloc]
		    initWithUTF8String: tmp + 1
				length: bufferLength -
587
588
589
590
591
592
593
594

595
596
597
598
599
600
601
587
588
589
590
591
592
593

594
595
596
597
598
599
600
601







-
+







			if ([_delegate respondsToSelector:
			    @selector(parser:didEndElement:prefix:namespace:)])
				[_delegate parser: self
				    didEndElement: _name
					   prefix: _prefix
					namespace: namespace];

			if ([_previous count] == 0)
			if (_previous.count == 0)
				_finishedParsing = true;
		} else
			[_previous addObject: bufferString];

		[_name release];
		[_prefix release];
		_name = _prefix = nil;
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
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







-
-
+
+
















-
+







		return;

	if ((length = _i - _last) > 0)
		appendToBuffer(_buffer, _data + _last, _encoding, length);

	pool = objc_autoreleasePoolPush();

	bufferCString = [_buffer items];
	bufferLength = [_buffer count];
	bufferCString = _buffer.items;
	bufferLength = _buffer.count;
	bufferString = [OFString stringWithUTF8String: bufferCString
					       length: bufferLength];

	if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) {
		_name = [[OFString alloc]
		    initWithUTF8String: tmp + 1
				length: bufferLength -
					(tmp - bufferCString) - 1];
		_prefix = [[OFString alloc]
		    initWithUTF8String: bufferCString
				length: tmp - bufferCString];
	} else {
		_name = [bufferString copy];
		_prefix = nil;
	}

	if (![[_previous lastObject] isEqual: bufferString])
	if (![_previous.lastObject isEqual: bufferString])
		@throw [OFMalformedXMLException exceptionWithParser: self];

	[_previous removeLastObject];

	[_buffer removeAllItems];

	namespace = namespaceForPrefix(_prefix, _namespaces);
677
678
679
680
681
682
683
684

685
686
687
688
689
690
691
677
678
679
680
681
682
683

684
685
686
687
688
689
690
691







-
+







	_name = _prefix = nil;

	_last = _i + 1;
	_state = (_data[_i] == '>'
	    ? OF_XMLPARSER_OUTSIDE_TAG
	    : OF_XMLPARSER_EXPECT_SPACE_OR_TAG_CLOSE);

	if ([_previous count] == 0)
	if (_previous.count == 0)
		_finishedParsing = true;
}

/* Inside a tag, name found */
- (void)of_inTagState
{
	void *pool;
700
701
702
703
704
705
706
707
708


709
710
711
712
713
714
715
700
701
702
703
704
705
706


707
708
709
710
711
712
713
714
715







-
-
+
+







			_state = OF_XMLPARSER_IN_ATTRIBUTE_NAME;
			_i--;
		}

		return;
	}

	attributesObjects = [_attributes objects];
	attributesCount = [_attributes count];
	attributesObjects = _attributes.objects;
	attributesCount = _attributes.count;

	namespace = namespaceForPrefix(_prefix, _namespaces);

	if (_prefix != nil && namespace == nil)
		@throw [OFUnboundPrefixException exceptionWithPrefix: _prefix
							      parser: self];

731
732
733
734
735
736
737
738

739
740
741
742
743
744
745
731
732
733
734
735
736
737

738
739
740
741
742
743
744
745







-
+







		if ([_delegate respondsToSelector:
		    @selector(parser:didEndElement:prefix:namespace:)])
			[_delegate parser: self
			    didEndElement: _name
				   prefix: _prefix
				namespace: namespace];

		if ([_previous count] == 0)
		if (_previous.count == 0)
			_finishedParsing = true;

		[_namespaces removeLastObject];
	} else if (_prefix != nil) {
		OFString *str = [OFString stringWithFormat: @"%@:%@",
							    _prefix, _name];
		[_previous addObject: str];
772
773
774
775
776
777
778
779
780


781
782
783


784
785
786
787
788
789
790
772
773
774
775
776
777
778


779
780
781


782
783
784
785
786
787
788
789
790







-
-
+
+

-
-
+
+







		return;

	if ((length = _i - _last) > 0)
		appendToBuffer(_buffer, _data + _last, _encoding, length);

	pool = objc_autoreleasePoolPush();

	bufferString = [OFString stringWithUTF8String: [_buffer items]
					       length: [_buffer count]];
	bufferString = [OFString stringWithUTF8String: _buffer.items
					       length: _buffer.count];

	bufferCString = [bufferString UTF8String];
	bufferLength = [bufferString UTF8StringLength];
	bufferCString = bufferString.UTF8String;
	bufferLength = bufferString.UTF8StringLength;

	if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) {
		_attributeName = [[OFString alloc]
		    initWithUTF8String: tmp + 1
				length: bufferLength -
					(tmp - bufferCString) - 1];
		_attributePrefix = [[OFString alloc]
849
850
851
852
853
854
855
856
857


858
859
860


861
862
863
864
865
866
867
849
850
851
852
853
854
855


856
857
858


859
860
861
862
863
864
865
866
867







-
-
+
+

-
-
+
+







	if ((length = _i - _last) > 0)
		appendToBuffer(_buffer, _data + _last, _encoding, length);

	pool = objc_autoreleasePoolPush();
	attributeValue = transformString(self, _buffer, 0, true);

	if (_attributePrefix == nil && [_attributeName isEqual: @"xmlns"])
		[[_namespaces lastObject] setObject: attributeValue
					     forKey: @""];
		[_namespaces.lastObject setObject: attributeValue
					   forKey: @""];
	if ([_attributePrefix isEqual: @"xmlns"])
		[[_namespaces lastObject] setObject: attributeValue
					     forKey: _attributeName];
		[_namespaces.lastObject setObject: attributeValue
					   forKey: _attributeName];

	attribute = [OFXMLAttribute attributeWithName: _attributeName
					    namespace: _attributePrefix
					  stringValue: attributeValue];
	attribute->_useDoubleQuotes = (_delimiter == '"');
	[_attributes addObject: attribute];