Changeset 3079

Show
Ignore:
Timestamp:
12/24/05 18:56:59 (3 years ago)
Author:
timothy
Message:
  • Connecting to IRC will now send the PASS, NICK and USER commands to initialize the connection.
  • Cleaned up the parsing code.
  • The trailing argument will be added to the parameters array as an NSData to allow other code to parse the encoding (important for per room/chat encodings and CTCP where non-printable chars are used.) The other parameters are made to NSStrings with the connection encoding.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/cocoa-networking/Chat Core/MVIRCChatConnection.h

    r3076 r3079  
    2727@interface MVChatConnection (MVIRCChatConnectionPrivate) 
    2828- (void) _readNextMessageFromServer; 
     29- (void) _handleCommand:(id) command parameters:(NSArray *) parameters fromSender:(NSString *) sender username:(NSString *) user host:(NSString *) host; 
    2930 
    3031+ (const char *) _flattenedIRCStringForMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) enc andChatFormat:(MVChatMessageFormat) format; 
  • branches/cocoa-networking/Chat Core/MVIRCChatConnection.m

    r3078 r3079  
    14241424        [_chatConnection writeData:data withTimeout:-1. tag:0]; 
    14251425        [data release]; 
     1426 
     1427        [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotRawMessageNotification object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:raw, @"message", [NSNumber numberWithBool:YES], @"outbound", nil]]; 
    14261428} 
    14271429 
     
    15891591 
    15901592- (void) socket:(AsyncSocket *) sock didConnectToHost:(NSString *) host port:(UInt16) port { 
     1593        if( [[self password] length] ) [self sendRawMessageWithFormat:@"PASS %@", [self password]]; 
     1594        [self sendRawMessageWithFormat:@"NICK %@", [self nickname]]; 
     1595        [self sendRawMessageWithFormat:@"USER %@ %@ %@ :%@", [self username], [[NSHost currentHost] name], [self server], [self realName]]; 
    15911596        [self _didConnect]; 
    15921597        [self _readNextMessageFromServer]; 
    1593 } 
    1594  
    1595 - (void) _readNextMessageFromServer { 
    1596         static NSData *delimeter = nil; 
    1597         if( ! delimeter ) delimeter = [[NSData allocWithZone:nil] initWithBytes:"\x0D\x0A" length:2]; 
    1598         [_chatConnection readDataToData:delimeter withTimeout:-1. tag:0]; 
    15991598} 
    16001599 
     
    16091608        char *command = NULL; 
    16101609        char *currentParameter = NULL; 
    1611         NSMutableArray *parameters = [[NSMutableArray allocWithZone:nil] initWithCapacity:10]; 
     1610 
     1611        NSString *senderString = nil; 
     1612        NSString *usernameString = nil; 
     1613        NSString *hostString = nil; 
     1614        id commandObject = nil; 
     1615        NSMutableArray *parameters = [[NSMutableArray allocWithZone:nil] initWithCapacity:15]; 
     1616 
     1617        // Parsing as defined in 2.3.1 at http://www.irchelp.org/irchelp/rfc/rfc2812.txt 
    16121618 
    16131619        if( len <= 2 || len > 512 ) 
    16141620                goto end; // bad message 
    16151621 
     1622#define checkAndMarkIfDone() if( *line == '\r' || *line == '\f' || *line == '\0' ) done = YES 
     1623#define consumeWhitespace() while( *line == ' ' && ! done ) line++ 
     1624#define notEndOfLine() *line != '\r' && *line != '\f' && *line != '\0' && ! done 
     1625 
    16161626        BOOL done = NO; 
    1617         if( *line != '\r' && ! done ) { 
     1627        if( notEndOfLine() ) { 
    16181628                if( *line == ':' ) { 
    16191629                        // prefix: ':' <sender> [ '!' <user> ] [ '@' <host> ] ' ' { ' ' } 
    16201630                        sender = ++line; 
    1621                         while( *line != '\r' && *line != ' ' && *line != '!' && *line != '@' ) line++; 
    1622                         if( *line == '\r' ) done = YES
     1631                        while( notEndOfLine() && *line != ' ' && *line != '!' && *line != '@' ) line++; 
     1632                        checkAndMarkIfDone()
    16231633 
    16241634                        if( *line == '!' ) { 
    16251635                                *line++ = '\0'; 
    16261636                                user = line; 
    1627                                 while( *line != '\r' && *line != ' ' && *line != '@' && ! done ) line++; 
    1628                                 if( *line == '\r' ) done = YES
     1637                                while( notEndOfLine() && *line != ' ' && *line != '@' ) line++; 
     1638                                checkAndMarkIfDone()
    16291639                                if( *line != '@' ) *line = '\0'; 
    16301640                        } 
     
    16331643                                *line++ = '\0'; 
    16341644                                host = line; 
    1635                                 while( *line != '\r' && *line != ' ' && ! done ) line++; 
    1636                                 if( *line == '\r' ) done = YES
     1645                                while( notEndOfLine() && *line != ' ' ) line++; 
     1646                                checkAndMarkIfDone()
    16371647                                *line = '\0'; 
    16381648                        } 
    16391649 
    1640                         if( *line == ' ' ) { 
    1641                                 *line++ = '\0'; 
    1642                                 while( *line == ' ' && ! done ) line++; 
    1643                         } 
     1650                        *line++ = '\0'; 
     1651                        consumeWhitespace(); 
    16441652                } 
    16451653 
    1646                 if( *line != '\r' && ! done ) { 
     1654                if( notEndOfLine() ) { 
    16471655                        // command: <letter> { <letter> } | <number> <number> <number> 
    16481656                        // letter: 'a' ... 'z' | 'A' ... 'Z' 
    16491657                        // number: '0' ... '9' 
    16501658                        command = line; 
    1651                         while( *line != '\r' && *line != ' ' && ! done ) line++; 
    1652                         if( *line == ' ' ) { 
    1653                                 *line++ = '\0'; 
    1654                                 while( *line == ' ' && ! done ) line++; 
    1655                         } 
     1659                        while( notEndOfLine() && *line != ' ' ) line++; 
     1660                        *line++ = '\0'; 
     1661                        consumeWhitespace(); 
    16561662                } 
    16571663 
    1658                 NSString *param = nil; 
    1659                 while( *line != '\r' && ! done ) { 
     1664                id param = nil; 
     1665                while( notEndOfLine() ) { 
    16601666                        // params: [ ':' <trailing data> | <letter> { <letter> } ] [ ' ' { ' ' } ] [ <params> ] 
    16611667                        currentParameter = NULL; 
     
    16631669                        if( *line == ':' ) { 
    16641670                                currentParameter = ++line; 
    1665                                 while( *line != '\r' && ! done ) line++; 
     1671                                while( notEndOfLine() ) line++; 
    16661672                                *line = '\0'; 
    16671673                                done = YES; 
     1674                                param = [[NSData allocWithZone:nil] initWithBytes:currentParameter length:(line - currentParameter)]; 
    16681675                        } else { 
    16691676                                currentParameter = line; 
    1670                                 while( *line != '\r' && *line != ' ' && ! done ) line++; 
    1671                                 if( *line == '\r' ) done = YES
     1677                                while( notEndOfLine() && *line != ' ' ) line++; 
     1678                                checkAndMarkIfDone()
    16721679                                *line++ = '\0'; 
     1680                                param = [[NSString allocWithZone:nil] initWithBytes:currentParameter encoding:[self encoding]]; 
    16731681                        } 
    16741682 
    1675                         if( currentParameter )  
    1676                                 param = [NSString stringWithBytes:currentParameter encoding:[self encoding]]; 
    16771683                        if( param ) [parameters addObject:param]; 
    1678  
    1679                         while( *line == ' ' && ! done ) line++; 
     1684                        [param release]; 
     1685 
     1686                        consumeWhitespace(); 
    16801687                } 
    16811688        } 
    16821689 
     1690#undef checkAndMarkIfDone() 
     1691#undef consumeWhitespace() 
     1692#undef notEndOfLine() 
     1693 
    16831694end: 
    1684         NSLog(@"%s %s %s %s %@", sender, user, host, command, [parameters description] ); 
    1685  
    1686         NSNotification *note = [NSNotification notificationWithName:MVChatConnectionGotRawMessageNotification object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:rawString, @"message", [NSNumber numberWithBool:NO], @"outbound", nil]]; 
    1687         [[NSNotificationCenter defaultCenter] postNotification:note]; 
     1695        if( sender ) senderString = [[NSString allocWithZone:nil] initWithBytes:sender encoding:[self encoding]]; 
     1696        if( user ) usernameString = [[NSString allocWithZone:nil] initWithBytes:user encoding:[self encoding]]; 
     1697        if( host ) hostString = [[NSString allocWithZone:nil] initWithBytes:host encoding:[self encoding]]; 
     1698        if( command ) { 
     1699                if( strlen( command ) == 3 && isdigit( command[0] ) && isdigit( command[1] ) && isdigit( command[2] ) ) { 
     1700                        unsigned long commandNumber = strtoul( command, NULL, 10 ); 
     1701                        commandObject = [[NSNumber allocWithZone:nil] initWithUnsignedLong:commandNumber]; 
     1702                } else commandObject = [[NSString allocWithZone:nil] initWithBytes:command encoding:[self encoding]]; 
     1703        } 
     1704 
     1705        [self _handleCommand:commandObject parameters:parameters fromSender:senderString username:usernameString host:hostString]; 
     1706 
     1707        [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotRawMessageNotification object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:rawString, @"message", [NSNumber numberWithBool:NO], @"outbound", nil]]; 
    16881708        [rawString release]; 
    16891709 
     1710        [senderString release]; 
     1711        [usernameString release]; 
     1712        [hostString release]; 
     1713        [commandObject release]; 
    16901714        [parameters release]; 
     1715 
    16911716        [self _readNextMessageFromServer]; 
     1717} 
     1718 
     1719- (void) _readNextMessageFromServer { 
     1720        static NSData *delimeter = nil; 
     1721        if( ! delimeter ) delimeter = [[NSData allocWithZone:nil] initWithBytes:"\x0D\x0A" length:2]; 
     1722        [_chatConnection readDataToData:delimeter withTimeout:-1. tag:0]; 
     1723} 
     1724 
     1725- (void) _handleCommand:(id) command parameters:(NSArray *) parameters fromSender:(NSString *) sender username:(NSString *) user host:(NSString *) host { 
     1726        NSLog(@"%@ %@ %@ %@ %@", sender, user, host, command, [parameters description] ); 
    16921727} 
    16931728