ObjFW  Check-in [064dbe5127]

Overview
Comment:Include an exception in delegate methods

Otherwise, there would be two methods for every operation: One for
success and one for failure. It also makes it easy to forget about
handling failure, so it's better to always pass an optional exception.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 064dbe51276f7d8b6491e08f2c7425d357f52dee3ee095d68b17f3d787fc3d68
User & Date: js on 2018-12-11 22:57:46
Other Links: manifest | tags
Context
2018-12-18
14:14
Use OFData instead of a buffer for async writes check-in: f218986f51 user: js tags: trunk
2018-12-11
22:57
Include an exception in delegate methods check-in: 064dbe5127 user: js tags: trunk
2018-12-08
22:01
Minor fix for OFDNSResolver and OFRunLoop check-in: 6387b16864 user: js tags: trunk
Changes

Modified src/OFDNSResolver.m from [c60b82a6b2] to [15c765674a].

1867
1868
1869
1870
1871
1872
1873

1874
1875
1876
1877
1878
1879



1880
1881
1882
1883
1884
1885
1886
	    nil, nil, nil, query->_context, exception);
}

-	  (bool)socket: (OF_KINDOF(OFUDPSocket *))sock
  didReceiveIntoBuffer: (void *)buffer_
		length: (size_t)length
		sender: (of_socket_address_t)sender

{
	unsigned char *buffer = buffer_;
	OFDictionary *answerRecords = nil, *authorityRecords = nil;
	OFDictionary *additionalRecords = nil;
	OFNumber *ID;
	OFDNSResolverQuery *query;




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

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







>






>
>
>







1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
	    nil, nil, nil, query->_context, exception);
}

-	  (bool)socket: (OF_KINDOF(OFUDPSocket *))sock
  didReceiveIntoBuffer: (void *)buffer_
		length: (size_t)length
		sender: (of_socket_address_t)sender
	     exception: (id)exception
{
	unsigned char *buffer = buffer_;
	OFDictionary *answerRecords = nil, *authorityRecords = nil;
	OFDictionary *additionalRecords = nil;
	OFNumber *ID;
	OFDNSResolverQuery *query;

	if (exception != nil)
		return true;

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

	ID = [OFNumber numberWithUInt16: (buffer[0] << 8) | buffer[1]];
	query = [[[_queries objectForKey: ID] retain] autorelease];
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
	callback(query->_target, query->_selector, self, query->_domainName,
	    answerRecords, authorityRecords, additionalRecords,
	    query->_context, nil);

	return true;
}

-		   (void)socket: (OF_KINDOF(OFUDPSocket *))sock
  didFailToReceiveWithException: (id)exception
{
	[sock asyncReceiveIntoBuffer: _buffer
			      length: BUFFER_LENGTH];
}

- (void)asyncResolveSocketAddressesForHost: (OFString *)host
				    target: (id)target
				  selector: (SEL)selector
				   context: (id)context
{
	[self asyncResolveSocketAddressesForHost: host
				   addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY







<
<
<
<
<
<
<







2012
2013
2014
2015
2016
2017
2018







2019
2020
2021
2022
2023
2024
2025
	callback(query->_target, query->_selector, self, query->_domainName,
	    answerRecords, authorityRecords, additionalRecords,
	    query->_context, nil);

	return true;
}








- (void)asyncResolveSocketAddressesForHost: (OFString *)host
				    target: (id)target
				  selector: (SEL)selector
				   context: (id)context
{
	[self asyncResolveSocketAddressesForHost: host
				   addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY

Modified src/OFHTTPClient.m from [a601f5af31] to [209c55758d].

525
526
527
528
529
530
531

532
533









534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574

575













576
577
578
579
580
581
582
			   forKey: key];

	return true;
}

- (bool)stream: (OF_KINDOF(OFStream *))sock
   didReadLine: (OFString *)line

{
	bool ret;










	@try {
		if (_firstLine) {
			_firstLine = false;
			ret = [self handleFirstLine: line];
		} else
			ret = [self handleServerHeader: line
						socket: sock];
	} @catch (id e) {
		[self raiseException: e];
		ret = false;
	}

	return ret;
}

-		(void)stream: (OF_KINDOF(OFStream *))sock
  didFailToReadWithException: (id)exception
{
	if ([exception isKindOfClass: [OFInvalidEncodingException class]])
		exception = [OFInvalidServerReplyException exception];

	[self raiseException: exception];
}

-		 (void)stream: (OF_KINDOF(OFStream *))sock
  didFailToWriteWithException: (id)exception
{
	if ([exception isKindOfClass: [OFWriteFailedException class]] &&
	    ([exception errNo] == ECONNRESET || [exception errNo] == EPIPE)) {
		/* In case a keep-alive connection timed out */
		[self closeAndReconnect];
		return;
	}

	[self raiseException: exception];
}

- (size_t)stream: (OF_KINDOF(OFStream *))sock
  didWriteBuffer: (const void **)request
	  length: (size_t)length

{













	_firstLine = true;

	[_requestString release];
	_requestString = nil;

	if ([[_request headers] objectForKey: @"Content-Length"] != nil) {
		[sock setDelegate: nil];







>


>
>
>
>
>
>
>
>
>
















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



>

>
>
>
>
>
>
>
>
>
>
>
>
>







525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559






















560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
			   forKey: key];

	return true;
}

- (bool)stream: (OF_KINDOF(OFStream *))sock
   didReadLine: (OFString *)line
     exception: (id)exception
{
	bool ret;

	if (exception != nil) {
		if ([exception isKindOfClass:
		    [OFInvalidEncodingException class]])
			exception = [OFInvalidServerReplyException exception];

		[self raiseException: exception];
		return false;
	}

	@try {
		if (_firstLine) {
			_firstLine = false;
			ret = [self handleFirstLine: line];
		} else
			ret = [self handleServerHeader: line
						socket: sock];
	} @catch (id e) {
		[self raiseException: e];
		ret = false;
	}

	return ret;
}























- (size_t)stream: (OF_KINDOF(OFStream *))sock
  didWriteBuffer: (const void **)request
	  length: (size_t)length
       exception: (id)exception
{
	if (exception != nil) {
		if ([exception isKindOfClass: [OFWriteFailedException class]] &&
		    ([exception errNo] == ECONNRESET ||
		    [exception errNo] == EPIPE)) {
			/* In case a keep-alive connection timed out */
			[self closeAndReconnect];
			return 0;
		}

		[self raiseException: exception];
		return 0;
	}

	_firstLine = true;

	[_requestString release];
	_requestString = nil;

	if ([[_request headers] objectForKey: @"Content-Length"] != nil) {
		[sock setDelegate: nil];
620
621
622
623
624
625
626

627
628





629
630
631
632
633
634
635
		return;
	}
}

-     (void)socket: (OF_KINDOF(OFTCPSocket *))sock
  didConnectToHost: (OFString *)host
	      port: (uint16_t)port

{
	[(OFTCPSocket *)sock setDelegate: self];






	if ([_client->_delegate respondsToSelector:
	    @selector(client:didCreateSocket:request:context:)])
		[_client->_delegate client: _client
			   didCreateSocket: sock
				   request: _request
				   context: _context];







>


>
>
>
>
>







622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
		return;
	}
}

-     (void)socket: (OF_KINDOF(OFTCPSocket *))sock
  didConnectToHost: (OFString *)host
	      port: (uint16_t)port
	 exception: (id)exception
{
	[(OFTCPSocket *)sock setDelegate: self];

	if (exception != nil) {
		[self raiseException: exception];
		return;
	}

	if ([_client->_delegate respondsToSelector:
	    @selector(client:didCreateSocket:request:context:)])
		[_client->_delegate client: _client
			   didCreateSocket: sock
				   request: _request
				   context: _context];

Modified src/OFHTTPServer.m from [814464cd03] to [aae9d41f78].

399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
	[_requestBody release];

	[super dealloc];
}

- (bool)stream: (OF_KINDOF(OFStream *))sock
   didReadLine: (OFString *)line

{
	if (line == nil)
		return false;

	@try {
		switch (_state) {
		case AWAITING_PROLOG:
			return [self parseProlog: line];
		case PARSING_HEADERS:







>

|







399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
	[_requestBody release];

	[super dealloc];
}

- (bool)stream: (OF_KINDOF(OFStream *))sock
   didReadLine: (OFString *)line
     exception: (id)exception
{
	if (line == nil || exception != nil)
		return false;

	@try {
		switch (_state) {
		case AWAITING_PROLOG:
			return [self parseProlog: line];
		case PARSING_HEADERS:
785
786
787
788
789
790
791

792
793











794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
	[_listeningSocket cancelAsyncRequests];
	[_listeningSocket release];
	_listeningSocket = nil;
}

-    (bool)socket: (OF_KINDOF(OFTCPSocket *))sock
  didAcceptSocket: (OF_KINDOF(OFTCPSocket *))acceptedSocket

{
	OFHTTPServer_Connection *connection = [[[OFHTTPServer_Connection alloc]











	    initWithSocket: acceptedSocket
		    server: self] autorelease];

	[(OFTCPSocket *)acceptedSocket setDelegate: connection];
	[acceptedSocket asyncReadLine];

	return true;
}

-		  (void)stream: (OF_KINDOF(OFStream *))stream
  didFailToAcceptWithException: (id)exception
{
	if ([_delegate respondsToSelector:
	    @selector(server:didReceiveExceptionOnListeningSocket:)])
		if ([_delegate			  server: self
		    didReceiveExceptionOnListeningSocket: exception])
			[stream asyncAccept];
}
@end







>

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








<
<
<
<
<
<
<
<
<
<

786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814










815
	[_listeningSocket cancelAsyncRequests];
	[_listeningSocket release];
	_listeningSocket = nil;
}

-    (bool)socket: (OF_KINDOF(OFTCPSocket *))sock
  didAcceptSocket: (OF_KINDOF(OFTCPSocket *))acceptedSocket
	exception: (id)exception
{
	OFHTTPServer_Connection *connection;

	if (exception != nil) {
		if (![_delegate respondsToSelector:
		    @selector(server:didReceiveExceptionOnListeningSocket:)])
			return false;

		return [_delegate		  server: self
		    didReceiveExceptionOnListeningSocket: exception];
	}

	connection = [[[OFHTTPServer_Connection alloc]
	    initWithSocket: acceptedSocket
		    server: self] autorelease];

	[(OFTCPSocket *)acceptedSocket setDelegate: connection];
	[acceptedSocket asyncReadLine];

	return true;
}










@end

Modified src/OFRunLoop.m from [536375a07c] to [2b70c16414].

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
	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, _buffer, length, exception);
	else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(stream:didReadIntoBuffer:length:)])
				return false;

			return [_delegate stream: object
			       didReadIntoBuffer: _buffer
					  length: length];
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailToReadWithException:)])
				[_delegate		stream: object
				    didFailToReadWithException: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc







<
|
|
|

|
|
|
<
<
<
<
|
<
<
<







319
320
321
322
323
324
325

326
327
328
329
330
331
332




333



334
335
336
337
338
339
340
	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, _buffer, length, exception);
	else {
# endif

		if (![_delegate respondsToSelector:
		    @selector(stream:didReadIntoBuffer:length:exception:)])
			return false;

		return [_delegate stream: object
		       didReadIntoBuffer: _buffer
				  length: length




			       exception: exception];



# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
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
		if (!_block(object, _buffer, _readLength, exception))
			return false;

		_readLength = 0;
		return true;
	} else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(stream:didReadIntoBuffer:length:)])
				return false;

			if (![_delegate stream: object
			     didReadIntoBuffer: _buffer
					length: _readLength])

				return false;

			_readLength = 0;
			return true;
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailToReadWithException:)])
				[_delegate		stream: object
				    didFailToReadWithException: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc







<
|
|
|

|
|
|
>
|

|
|
<
<
<
<
<
<
<
<







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
		if (!_block(object, _buffer, _readLength, exception))
			return false;

		_readLength = 0;
		return true;
	} else {
# endif

		if (![_delegate respondsToSelector:
		    @selector(stream:didReadIntoBuffer:length:exception:)])
			return false;

		if (![_delegate stream: object
		     didReadIntoBuffer: _buffer
				length: _readLength
			     exception: exception])
			return false;

		_readLength = 0;
		return true;








# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
		return true;

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, line, exception);
	else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(stream:didReadLine:)])
				return false;

			return [_delegate stream: object
				     didReadLine: line];
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailToReadWithException:)])
				[_delegate		stream: object
				    didFailToReadWithException: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc







<
|
|
|

|
|
<
<
<
<
|
<
<
<







419
420
421
422
423
424
425

426
427
428
429
430
431




432



433
434
435
436
437
438
439
		return true;

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, line, exception);
	else {
# endif

		if (![_delegate respondsToSelector:
		    @selector(stream:didReadLine:exception:)])
			return false;

		return [_delegate stream: object
			     didReadLine: line




			       exception: exception];



# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
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
		if (_length == 0)
			return false;

		_writtenLength = 0;
		return true;
	} else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(stream:didWriteBuffer:length:)])
				return false;

			_length = [_delegate stream: object
				     didWriteBuffer: &_buffer
					     length: _length];


			if (_length == 0)
				return false;

			_writtenLength = 0;
			return true;
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailToWriteWithException:)])
				[_delegate		 stream: object
				    didFailToWriteWithException: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc







<
|
|
|

|
|
|
>

|
|

|
|
<
<
<
<
<
<
<
<







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
		if (_length == 0)
			return false;

		_writtenLength = 0;
		return true;
	} else {
# endif

		if (![_delegate respondsToSelector:
		    @selector(stream:didWriteBuffer:length:exception:)])
			return false;

		_length = [_delegate stream: object
			     didWriteBuffer: &_buffer
				     length: _length
				  exception: exception];

		if (_length == 0)
			return false;

		_writtenLength = 0;
		return true;








# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, acceptedSocket, exception);
	else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(socket:didAcceptSocket:)])
				return false;

			return [_delegate socket: object
				 didAcceptSocket: acceptedSocket];
		} else {
			if ([_delegate respondsToSelector:
			    @selector(socket:didFailToAcceptWithException:)])
				[_delegate		  socket: object
				    didFailToAcceptWithException: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc







<
|
|
|

|
|
<
<
<
<
|
<
<
<







540
541
542
543
544
545
546

547
548
549
550
551
552




553



554
555
556
557
558
559
560
	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, acceptedSocket, exception);
	else {
# endif

		if (![_delegate respondsToSelector:
		    @selector(socket:didAcceptSocket:exception:)])
			return false;

		return [_delegate socket: object
			 didAcceptSocket: acceptedSocket




			       exception: exception];



# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
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
	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, _buffer, length, address, exception);
	else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector: @selector(socket:
			    didReceiveIntoBuffer:length:sender:)])
				return false;

			return [_delegate socket: object
			    didReceiveIntoBuffer: _buffer
					  length: length
					  sender: address];
		} else {
			if ([_delegate respondsToSelector:
			    @selector(socket:didFailToReceiveWithException:)])
				[_delegate		   socket: object
				    didFailToReceiveWithException: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc







<
|
|
|

|
|
|
|
<
<
<
<
|
<
<
<







583
584
585
586
587
588
589

590
591
592
593
594
595
596
597




598



599
600
601
602
603
604
605
	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, _buffer, length, address, exception);
	else {
# endif

		if (![_delegate respondsToSelector: @selector(
		    socket:didReceiveIntoBuffer:length:sender:exception:)])
			return false;

		return [_delegate socket: object
		    didReceiveIntoBuffer: _buffer
				  length: length
				  sender: address




			       exception: exception];



# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
	if (_block != NULL) {
		_length = _block(object, &_buffer,
		    (exception == nil ? _length : 0), &_receiver, exception);

		return (_length > 0);
	} else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(socket:didSendBuffer:length:receiver:)])
				return false;

			_length = [_delegate socket: object
				      didSendBuffer: &_buffer
					     length: _length
					   receiver: &_receiver];

			return (_length > 0);
		} else {
			if ([_delegate respondsToSelector:
			    @selector(socket:didFailToSendWithException:)])
				[_delegate		socket: object
				    didFailToSendWithException: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc







<
|
|
|

|
|
|
|
<
<
<
<
<
<
|

|
<







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
	if (_block != NULL) {
		_length = _block(object, &_buffer,
		    (exception == nil ? _length : 0), &_receiver, exception);

		return (_length > 0);
	} else {
# endif

		if (![_delegate respondsToSelector:
		    @selector(socket:didSendBuffer:length:receiver:exception:)])
			return false;

		_length = [_delegate socket: object
			      didSendBuffer: &_buffer
				     length: (exception == nil ? _length : 0)
				   receiver: &_receiver






				  exception: exception];

		return (_length > 0);

# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc

Modified src/OFStream.h from [ea19b2f833] to [ba57cd6e80].

99
100
101
102
103
104
105

106
107
108
109
110

111
112
113
114
115
116
117
118

119
120
121
122

123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*!
 * @brief This method is called when data was read asynchronously from a
 *	  stream.
 *
 * @param stream The stream on which data was read
 * @param buffer A buffer with the data that has been read
 * @param length The length of the data that has been read

 * @return A bool whether the read should be repeated
 */
-      (bool)stream: (OF_KINDOF(OFStream *))stream
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length;


/*!
 * @brief This method is called when a line was read asynchronously from a
 *	  stream.
 *
 * @param stream The stream on which a line was read
 * @param line The line which has been read or `nil` when the end of stream
 *	       occurred

 * @return A bool whether the read should be repeated
 */
- (bool)stream: (OF_KINDOF(OFStream *))stream
   didReadLine: (nullable OFString *)line;


/*!
 * @brief This method is called when data was written asynchronously to a
 *	  stream.
 *
 * @param stream The stream to which data was written
 * @param buffer A pointer to the buffer which was written to the stream. This
 *		 can be changed to point to a different buffer to be used on the
 *		 next write.
 * @param length The length of the buffer that has been written

 * @return The length to repeat the write with or 0 if it should not repeat.
 *	   The buffer may be changed, so that every time a new buffer and
 *	   length can be specified
 */
- (size_t)stream: (OF_KINDOF(OFStream *))stream
  didWriteBuffer: (const void *_Nonnull *_Nonnull)buffer
	  length: (size_t)length;

/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous read on a stream.
 *
 * @param stream The stream for which an exception occurred
 * @param exception The exception which occurred for the stream
 */
-		(void)stream: (OF_KINDOF(OFStream *))stream
  didFailToReadWithException: (id)exception;

/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous write on a stream.
 *
 * @param stream The stream for which an exception occurred
 * @param exception The exception which occurred for the stream
 */
-		 (void)stream: (OF_KINDOF(OFStream *))stream
  didFailToWriteWithException: (id)exception;
@end

/*!
 * @class OFStream OFStream.h ObjFW/OFStream.h
 *
 * @brief A base class for different types of streams.
 *







>




|
>








>



|
>










>






|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
/*!
 * @brief This method is called when data was read asynchronously from a
 *	  stream.
 *
 * @param stream The stream on which data was read
 * @param buffer A buffer with the data that has been read
 * @param length The length of the data that has been read
 * @param exception An exception that occurred while reading, or nil on success
 * @return A bool whether the read should be repeated
 */
-      (bool)stream: (OF_KINDOF(OFStream *))stream
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length
	  exception: (nullable id)exception;

/*!
 * @brief This method is called when a line was read asynchronously from a
 *	  stream.
 *
 * @param stream The stream on which a line was read
 * @param line The line which has been read or `nil` when the end of stream
 *	       occurred
 * @param exception An exception that occurred while reading, or nil on success
 * @return A bool whether the read should be repeated
 */
- (bool)stream: (OF_KINDOF(OFStream *))stream
   didReadLine: (nullable OFString *)line
     exception: (nullable id)exception;

/*!
 * @brief This method is called when data was written asynchronously to a
 *	  stream.
 *
 * @param stream The stream to which data was written
 * @param buffer A pointer to the buffer which was written to the stream. This
 *		 can be changed to point to a different buffer to be used on the
 *		 next write.
 * @param length The length of the buffer that has been written
 * @param exception An exception that occurred while writing, or nil on success
 * @return The length to repeat the write with or 0 if it should not repeat.
 *	   The buffer may be changed, so that every time a new buffer and
 *	   length can be specified
 */
- (size_t)stream: (OF_KINDOF(OFStream *))stream
  didWriteBuffer: (const void *_Nonnull *_Nonnull)buffer
	  length: (size_t)length
       exception: (nullable id)exception;



















@end

/*!
 * @class OFStream OFStream.h ObjFW/OFStream.h
 *
 * @brief A base class for different types of streams.
 *

Modified src/OFTCPSocket.h from [077e4589a5] to [e932bc199a].

60
61
62
63
64
65
66




67
68
69
70

71
72
73
74
75
76


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
 */
@protocol OFTCPSocketDelegate <OFStreamDelegate>
@optional
/*!
 * @brief A method which is called when a socket connected.
 *
 * @param socket The socket which connected




 */
-     (void)socket: (OF_KINDOF(OFTCPSocket *))socket
  didConnectToHost: (OFString *)host
	      port: (uint16_t)port;


/*!
 * @brief A method which is called when a socket accepted a connection.
 *
 * @param socket The socket which accepted the connection
 * @param acceptedSocket The socket which has been accepted


 * @return A bool whether to accept the next incoming connection
 */
-    (bool)socket: (OF_KINDOF(OFTCPSocket *))socket
  didAcceptSocket: (OF_KINDOF(OFTCPSocket *))acceptedSocket;

/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous connect.
 *
 * @param socket The socket for which an exception occurred
 * @param exception The exception which occurred for the stream
 * @param host The host to which the connection failed
 * @param port The port on the host to which the connection failed
 */
-		   (void)socket: (OF_KINDOF(OFTCPSocket *))socket
  didFailToConnectWithException: (id)exception
			   host: (OFString *)host
			   port: (uint16_t)port;

/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous accept.
 *
 * @param socket The socket for which an exception occurred
 * @param exception The exception which occurred for the stream
 */
-		  (void)socket: (OF_KINDOF(OFTCPSocket *))socket
  didFailToAcceptWithException: (id)exception;
@end

/*!
 * @class OFTCPSocket OFTCPSocket.h ObjFW/OFTCPSocket.h
 *
 * @brief A class which provides methods to create and use TCP sockets.
 *







>
>
>
>



|
>






>
>



|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
 */
@protocol OFTCPSocketDelegate <OFStreamDelegate>
@optional
/*!
 * @brief A method which is called when a socket connected.
 *
 * @param socket The socket which connected
 * @param host The host connected to
 * @param port The port on the host connected to
 * @param exception An exception that occurred while connecting, or nil on
 *		    success
 */
-     (void)socket: (OF_KINDOF(OFTCPSocket *))socket
  didConnectToHost: (OFString *)host
	      port: (uint16_t)port
	 exception: (nullable id)exception;

/*!
 * @brief A method which is called when a socket accepted a connection.
 *
 * @param socket The socket which accepted the connection
 * @param acceptedSocket The socket which has been accepted
 * @param exception An exception that occurred while accepting, or nil on
 *		    success
 * @return A bool whether to accept the next incoming connection
 */
-    (bool)socket: (OF_KINDOF(OFTCPSocket *))socket
  didAcceptSocket: (OF_KINDOF(OFTCPSocket *))acceptedSocket
	exception: (nullable id)exception;























@end

/*!
 * @class OFTCPSocket OFTCPSocket.h ObjFW/OFTCPSocket.h
 *
 * @brief A class which provides methods to create and use TCP sockets.
 *

Modified src/OFTCPSocket.m from [349339a041] to [dd4630f033].

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
#ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(_socket, _exception);
	else {
#endif
		[_socket setDelegate: _delegate];

		if (_exception == nil) {
			if ([_delegate respondsToSelector:
			    @selector(socket:didConnectToHost:port:)])
				[_delegate    socket: _socket
				    didConnectToHost: _host
						port: _port];
		} else {
			if ([_delegate respondsToSelector: @selector(socket:
			    didFailToConnectWithException:host:port:)])
				[_delegate		   socket: _socket
				    didFailToConnectWithException: _exception
							     host: _host
							     port: _port];
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif
}

- (void)of_socketDidConnect: (OF_KINDOF(OFTCPSocket *))sock
		  exception: (id)exception







<
|
|
|
|
|
<
<
<
<
|
<
<
<







208
209
210
211
212
213
214

215
216
217
218
219




220



221
222
223
224
225
226
227
#ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(_socket, _exception);
	else {
#endif
		[_socket setDelegate: _delegate];


		if ([_delegate respondsToSelector:
		    @selector(socket:didConnectToHost:port:exception:)])
			[_delegate    socket: _socket
			    didConnectToHost: _host
					port: _port




				   exception: _exception];



#ifdef OF_HAVE_BLOCKS
	}
#endif
}

- (void)of_socketDidConnect: (OF_KINDOF(OFTCPSocket *))sock
		  exception: (id)exception
376
377
378
379
380
381
382

383
384
385
386
387
388
389
390








391
392
393
394
395
396
397
			   length: 3
		      runLoopMode: [[OFRunLoop currentRunLoop] currentMode]];
}

-      (bool)stream: (OF_KINDOF(OFStream *))sock
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length

{
	of_run_loop_mode_t runLoopMode =
	    [[OFRunLoop currentRunLoop] currentMode];
	unsigned char *SOCKSVersion;
	uint8_t hostLength;
	unsigned char port[2];
	unsigned char *response, *addressLength;









	switch (_SOCKS5State) {
	case SOCKS5_STATE_READ_VERSION:
		SOCKSVersion = buffer;

		if (SOCKSVersion[0] != 5 || SOCKSVersion[1] != 0) {
			_exception = [[OFConnectionFailedException alloc]
			    initWithHost: _host







>

|
<





>
>
>
>
>
>
>
>







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
			   length: 3
		      runLoopMode: [[OFRunLoop currentRunLoop] currentMode]];
}

-      (bool)stream: (OF_KINDOF(OFStream *))sock
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length
	  exception: (id)exception
{
	of_run_loop_mode_t runLoopMode;

	unsigned char *SOCKSVersion;
	uint8_t hostLength;
	unsigned char port[2];
	unsigned char *response, *addressLength;

	if (exception != nil) {
		_exception = [exception retain];
		[self didConnect];
		return false;
	}

	runLoopMode = [[OFRunLoop currentRunLoop] currentMode];

	switch (_SOCKS5State) {
	case SOCKS5_STATE_READ_VERSION:
		SOCKSVersion = buffer;

		if (SOCKSVersion[0] != 5 || SOCKSVersion[1] != 0) {
			_exception = [[OFConnectionFailedException alloc]
			    initWithHost: _host
522
523
524
525
526
527
528

529
530







531
532
533
534
535
536
537
538
		return false;
	}
}

- (size_t)stream: (OF_KINDOF(OFStream *))sock
  didWriteBuffer: (const void **)buffer
	  length: (size_t)length

{
	of_run_loop_mode_t runLoopMode =







	    [[OFRunLoop currentRunLoop] currentMode];

	switch (_SOCKS5State) {
	case SOCKS5_STATE_SEND_AUTHENTICATION:
		_SOCKS5State = SOCKS5_STATE_READ_VERSION;
		[_socket asyncReadIntoBuffer: _buffer
				 exactLength: 2
				 runLoopMode: runLoopMode];







>

|
>
>
>
>
>
>
>
|







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
		return false;
	}
}

- (size_t)stream: (OF_KINDOF(OFStream *))sock
  didWriteBuffer: (const void **)buffer
	  length: (size_t)length
       exception: (id)exception
{
	of_run_loop_mode_t runLoopMode;

	if (exception != nil) {
		_exception = [exception retain];
		[self didConnect];
		return 0;
	}

	runLoopMode = [[OFRunLoop currentRunLoop] currentMode];

	switch (_SOCKS5State) {
	case SOCKS5_STATE_SEND_AUTHENTICATION:
		_SOCKS5State = SOCKS5_STATE_READ_VERSION;
		[_socket asyncReadIntoBuffer: _buffer
				 exactLength: 2
				 runLoopMode: runLoopMode];
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
				 runLoopMode: runLoopMode];
		return 0;
	default:
		assert(0);
		return 0;
	}
}

-		(void)stream: (OF_KINDOF(OFStream *))sock
  didFailToReadWithException: (id)exception
{
	_exception = [exception retain];
	[self didConnect];
}

-		 (void)stream: (OF_KINDOF(OFStream *))sock
  didFailToWriteWithException: (id)exception
{
	_exception = [exception retain];
	[self didConnect];
}
@end

@implementation OFTCPSocket_ConnectDelegate
- (void)dealloc
{
	[_exception release];

	[super dealloc];
}

-     (void)socket: (OF_KINDOF(OFTCPSocket *))sock
  didConnectToHost: (OFString *)host
	      port: (uint16_t)port
{
	_done = true;
}

-		   (void)socket: (OF_KINDOF(OFTCPSocket *))sock
  didFailToConnectWithException: (id)exception
{
	_done = true;
	_exception = [exception retain];
}
@end

@implementation OFTCPSocket







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













<
<
<
<
<
|







555
556
557
558
559
560
561














562
563
564
565
566
567
568
569
570
571
572
573
574





575
576
577
578
579
580
581
582
				 runLoopMode: runLoopMode];
		return 0;
	default:
		assert(0);
		return 0;
	}
}














@end

@implementation OFTCPSocket_ConnectDelegate
- (void)dealloc
{
	[_exception release];

	[super dealloc];
}

-     (void)socket: (OF_KINDOF(OFTCPSocket *))sock
  didConnectToHost: (OFString *)host
	      port: (uint16_t)port





	 exception: (id)exception
{
	_done = true;
	_exception = [exception retain];
}
@end

@implementation OFTCPSocket

Modified src/OFUDPSocket.h from [6654ade8b5] to [ab6554e3b4].

76
77
78
79
80
81
82


83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*!
 * @brief This method is called when a packet has been received.
 *
 * @param socket The UDP socket which received a packet
 * @param buffer The buffer the packet has been written to
 * @param length The length of the packet
 * @param sender The address of the sender of the packet


 * @return A bool whether the same block should be used for the next receive
 */
-	  (bool)socket: (OF_KINDOF(OFUDPSocket *))socket
  didReceiveIntoBuffer: (void *)buffer
		length: (size_t)length
		sender: (of_socket_address_t)sender;


/*!
 * @brief This which is called when a packet has been sent.
 *
 * @param socket The UDP socket which sent a packet
 * @param buffer A pointer to the buffer which was sent. This can be changed to
 *		 point to a different buffer to be used on the next send.
 * @param length The length of the buffer that has been sent
 * @param receiver The receiver for the UDP packet. This may be set to a new
 *		   receiver to which the next packet is sent.

 * @return The length to repeat the send with or 0 if it should not repeat.
 *	   The buffer and receiver may be changed, so that every time a new
 *	   buffer, length and receiver can be specified while the callback
 *	   stays the same.
 */
- (size_t)socket: (OF_KINDOF(OFUDPSocket *))socket
   didSendBuffer: (const void *_Nonnull *_Nonnull)buffer
	  length: (size_t)length
	receiver: (of_socket_address_t *_Nonnull)receiver;

/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous receive on the socket.
 *
 * @param socket The socket for which an exception occurred
 * @param exception The exception which occurred for the socket
 */
-		   (void)socket: (OF_KINDOF(OFUDPSocket *))socket
  didFailToReceiveWithException: (id)exception;

/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous send on the socket.
 *
 * @param socket The socket for which an exception occurred
 * @param exception The exception which occurred for the socket
 */
-		(void)socket: (OF_KINDOF(OFUDPSocket *))socket
  didFailToSendWithException: (id)exception;
@end

/*!
 * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h
 *
 * @brief A class which provides methods to create and use UDP sockets.
 *







>
>





|
>










>








|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112



















113
114
115
116
117
118
119
/*!
 * @brief This method is called when a packet has been received.
 *
 * @param socket The UDP socket which received a packet
 * @param buffer The buffer the packet has been written to
 * @param length The length of the packet
 * @param sender The address of the sender of the packet
 * @param exception An exception that occurred while receiving, or nil on
 *		    success
 * @return A bool whether the same block should be used for the next receive
 */
-	  (bool)socket: (OF_KINDOF(OFUDPSocket *))socket
  didReceiveIntoBuffer: (void *)buffer
		length: (size_t)length
		sender: (of_socket_address_t)sender
	     exception: (nullable id)exception;

/*!
 * @brief This which is called when a packet has been sent.
 *
 * @param socket The UDP socket which sent a packet
 * @param buffer A pointer to the buffer which was sent. This can be changed to
 *		 point to a different buffer to be used on the next send.
 * @param length The length of the buffer that has been sent
 * @param receiver The receiver for the UDP packet. This may be set to a new
 *		   receiver to which the next packet is sent.
 * @param exception An exception that occurred while sending, or nil on success
 * @return The length to repeat the send with or 0 if it should not repeat.
 *	   The buffer and receiver may be changed, so that every time a new
 *	   buffer, length and receiver can be specified while the callback
 *	   stays the same.
 */
- (size_t)socket: (OF_KINDOF(OFUDPSocket *))socket
   didSendBuffer: (const void *_Nonnull *_Nonnull)buffer
	  length: (size_t)length
	receiver: (of_socket_address_t *_Nonnull)receiver
       exception: (nullable id)exception;



















@end

/*!
 * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h
 *
 * @brief A class which provides methods to create and use UDP sockets.
 *

Modified utils/ofhttp/OFHTTP.m from [31817d3b24] to [c4c7ef8326].

652
653
654
655
656
657
658

659

























660
661
662
663
664
665
666
	[self performSelector: @selector(downloadNextURL)
		   afterDelay: 0];
}

-      (bool)stream: (OF_KINDOF(OFStream *))response
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length

{

























	_received += length;

	[_output writeBuffer: buffer
		      length: length];

	[_progressBar setReceived: _received];








>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	[self performSelector: @selector(downloadNextURL)
		   afterDelay: 0];
}

-      (bool)stream: (OF_KINDOF(OFStream *))response
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length
	  exception: (id)exception
{
	if (exception != nil) {
		OFString *URL;

		[_progressBar stop];
		[_progressBar draw];
		[_progressBar release];
		_progressBar = nil;

		if (!_quiet)
			[of_stdout writeString: @"\n  Error!\n"];

		URL = [_URLs objectAtIndex: _URLIndex - 1];
		[of_stderr writeLine: OF_LOCALIZED(
		    @"download_failed_exception",
		    @"%[prog]: Failed to download <%[url]>: %[exception]",
		    @"prog", [OFApplication programName],
		    @"url", URL,
		    @"exception", exception)];

		_errorCode = 1;
		[self performSelector: @selector(downloadNextURL)
			   afterDelay: 0];
		return false;
	}

	_received += length;

	[_output writeBuffer: buffer
		      length: length];

	[_progressBar setReceived: _received];

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
			   afterDelay: 0];
		return false;
	}

	return true;
}

-	  (void)stream: (OF_KINDOF(OFStream *))response
  didFailWithException: (id)exception
{
	OFString *URL;

	[_progressBar stop];
	[_progressBar draw];
	[_progressBar release];
	_progressBar = nil;

	if (!_quiet)
		[of_stdout writeString: @"\n  Error!\n"];

	URL = [_URLs objectAtIndex: _URLIndex - 1];
	[of_stderr writeLine: OF_LOCALIZED(
	    @"download_failed_exception",
	    @"%[prog]: Failed to download <%[url]>: %[exception]",
	    @"prog", [OFApplication programName],
	    @"url", URL,
	    @"exception", exception)];

	_errorCode = 1;
	[self performSelector: @selector(downloadNextURL)
		   afterDelay: 0];
}

-      (void)client: (OFHTTPClient *)client
  didReceiveHeaders: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headers
	 statusCode: (int)statusCode
	    request: (OFHTTPRequest *)request
	    context: (id)context
{
	if (!_quiet) {







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







707
708
709
710
711
712
713


























714
715
716
717
718
719
720
			   afterDelay: 0];
		return false;
	}

	return true;
}



























-      (void)client: (OFHTTPClient *)client
  didReceiveHeaders: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headers
	 statusCode: (int)statusCode
	    request: (OFHTTPRequest *)request
	    context: (id)context
{
	if (!_quiet) {