Index: src/IRCConnection.h ================================================================== --- src/IRCConnection.h +++ src/IRCConnection.h @@ -35,10 +35,12 @@ - (void)connection: (IRCConnection *)connection didReceiveLine: (OFString *)line; - (void)connection: (IRCConnection *)connection didSendLine: (OFString *)line; - (void)connectionWasEstablished: (IRCConnection *)connection; +- (void)connection: (IRCConnection *)connection + didFailToConnectWithException: (id)exception; - (void)connection: (IRCConnection *)connection didSeeUser: (IRCUser *)user joinChannel: (OFString *)channel; - (void)connection: (IRCConnection *)connection didSeeUser: (IRCUser *)user @@ -86,10 +88,11 @@ id _Nullable _delegate; of_string_encoding_t _fallbackEncoding; of_time_interval_t _pingInterval, _pingTimeout; OFString *_Nullable _pingData; OFTimer *_Nullable _pingTimer; + bool _fallbackEncodingUsed; } @property (readonly, nonatomic) Class socketClass; @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *server; @property (nonatomic) uint16_t port; @@ -118,11 +121,9 @@ to: (OFString *)to; - (void)kickUser: (OFString *)user channel: (OFString *)channel reason: (nullable OFString *)reason; - (void)changeNicknameTo: (OFString *)nickname; -- (void)processLine: (OFString *)line; -- (void)handleConnection; - (nullable OFSet OF_GENERIC(OFString *) *)usersInChannel: (OFString *)channel; @end OF_ASSUME_NONNULL_END Index: src/IRCConnection.m ================================================================== --- src/IRCConnection.m +++ src/IRCConnection.m @@ -34,10 +34,13 @@ #import #import "IRCConnection.h" #import "IRCUser.h" + +@interface IRCConnection () +@end @implementation IRCConnection @synthesize socketClass = _socketClass; @synthesize server = _server, port = _port; @synthesize nickname = _nickname, username = _username, realname = _realname; @@ -89,22 +92,40 @@ if (_socket != nil) @throw [OFAlreadyConnectedException exception]; _socket = [[_socketClass alloc] init]; + [_socket setDelegate: self]; + [_socket asyncConnectToHost: _server + port: _port]; + + objc_autoreleasePoolPop(pool); +} + +- (void)socket: (OF_KINDOF(OFTCPSocket *))socket + didConnectToHost: (OFString *)host + port: (uint16_t)port + exception: (id)exception +{ + if (exception != nil) { + if ([_delegate respondsToSelector: + @selector(connection:didFailToConnectWithException:)]) + [_delegate connection: self + didFailToConnectWithException: exception]; + + return; + } + if ([_delegate respondsToSelector: @selector(connection:didCreateSocket:)]) [_delegate connection: self didCreateSocket: _socket]; - [_socket connectToHost: _server - port: _port]; - [self sendLineWithFormat: @"NICK %@", _nickname]; [self sendLineWithFormat: @"USER %@ * 0 :%@", _username, _realname]; - objc_autoreleasePoolPop(pool); + [socket asyncReadLine]; } - (void)disconnect { [self disconnectWithReason: nil]; @@ -573,54 +594,29 @@ [_socket cancelAsyncRequests]; [_socket release]; _socket = nil; } -- (void)processLine: (OFString *)line -{ - void *pool = objc_autoreleasePoolPush(); - - [self irc_processLine: line]; - - objc_autoreleasePoolPop(pool); -} - -- (bool)irc_socket: (OFTCPSocket *)socket - didReceiveWronglyEncodedLine: (OFString *)line - context: (id)context - exception: (OFException *)exception -{ - if (line != nil) { - [self irc_processLine: line]; - [socket asyncReadLineWithTarget: self - selector: @selector(irc_socket: - didReceiveLine:context: - exception:) - context: nil]; - } - - return false; -} - -- (bool)irc_socket: (OFTCPSocket *)socket - didReceiveLine: (OFString *)line - context: (id)context - exception: (OFException *)exception -{ - if (line != nil) { - [self irc_processLine: line]; +- (bool)stream: (OF_KINDOF(OFStream *))stream + didReadLine: (OFString *)line + exception: (OFException *)exception +{ + if (line != nil) { + [self irc_processLine: line]; + + if (_fallbackEncodingUsed) { + _fallbackEncodingUsed = false; + [stream asyncReadLine]; + return false; + } + return true; } if ([exception isKindOfClass: [OFInvalidEncodingException class]]) { - [socket - asyncReadLineWithEncoding: _fallbackEncoding - target: self - selector: @selector(irc_socket: - didReceiveWronglyEncodedLine: - context:exception:) - context: nil]; + _fallbackEncodingUsed = true; + [stream asyncReadLineWithEncoding: _fallbackEncoding]; return false; } if ([_delegate respondsToSelector: @selector(connectionWasClosed:)]) [_delegate connectionWasClosed: self]; @@ -633,18 +629,10 @@ _socket = nil; return false; } -- (void)handleConnection -{ - [_socket asyncReadLineWithTarget: self - selector: @selector(irc_socket:didReceiveLine: - context:exception:) - context: nil]; -} - - (OFSet OF_GENERIC(OFString *) *)usersInChannel: (OFString *)channel { return [[[_channels objectForKey: channel] copy] autorelease]; } @end Index: tests/tests.m ================================================================== --- tests/tests.m +++ tests/tests.m @@ -42,11 +42,10 @@ [connection setUsername: @"ObjIRC"]; [connection setRealname: @"ObjIRC"]; [connection setDelegate: self]; [connection connect]; - [connection handleConnection]; } - (void)connection: (IRCConnection*)connection didReceiveLine: (OFString*)line { @@ -61,10 +60,18 @@ - (void)connectionWasEstablished: (IRCConnection*)connection { [connection joinChannel: @"#objfw"]; } + +- (void)connection: (IRCConnection *)connection + didFailToConnectWithException: (id)exception +{ + [of_stderr writeFormat: @"Failed to connect: %@\n", exception]; + + [OFApplication terminateWithStatus: 1]; +} - (void)connection: (IRCConnection*)connection didSeeUser: (IRCUser*)user joinChannel: (OFString*)channel {