diff --git a/src/XMPPConnection.h b/src/XMPPConnection.h index 07f9fd4..35a5be5 100644 --- a/src/XMPPConnection.h +++ b/src/XMPPConnection.h @@ -245,7 +245,7 @@ - (BOOL)checkCertificateAndGetReason: (OFString**)reason; /** - * \brief Starts a loop handling incomming data. + * \brief Adds the connection to the run loop. */ - (void)handleConnection; @@ -258,7 +258,7 @@ * \param length The length of the buffer. If length is 0, it is assumed that * the connection was closed. */ -- (void)parseBuffer: (const char*)buffer +- (void)parseBuffer: (const void*)buffer length: (size_t)length; /** diff --git a/src/XMPPConnection.m b/src/XMPPConnection.m index d6fbc0d..2d47303 100644 --- a/src/XMPPConnection.m +++ b/src/XMPPConnection.m @@ -56,6 +56,8 @@ #import +#define BUFFER_LENGTH 512 + @implementation XMPPConnection + connection { @@ -292,38 +294,42 @@ - (void)handleConnection { - char buffer[512]; + char *buffer = [self allocMemoryWithSize: BUFFER_LENGTH]; - for (;;) { - size_t length = [sock readIntoBuffer: buffer - length: 512]; - - [self parseBuffer: buffer - length: length]; - - if (length < 1) - return; - } + [sock asyncReadIntoBuffer: buffer + length: BUFFER_LENGTH + target: self + selector: @selector(stream:didReadIntoBuffer:length:)]; } -- (void)parseBuffer: (const char*)buffer - length: (size_t)length +- (BOOL)XMPP_parseBuffer: (const void*)buffer + length: (size_t)length { - if (length < 1) { + if ([sock isAtEndOfStream]) { [delegates broadcastSelector: @selector(connectionWasClosed:) withObject: self]; - return; + return NO; } @try { [parser parseBuffer: buffer - length: length]; + length: length]; } @catch (OFMalformedXMLException *e) { [self XMPP_sendStreamError: @"bad-format" text: nil]; [self close]; + return NO; } + return YES; +} + +- (void)parseBuffer: (const void*)buffer + length: (size_t)length +{ + [self XMPP_parseBuffer: buffer + length: length]; + [oldParser release]; [oldElementBuilder release]; @@ -331,6 +337,33 @@ oldElementBuilder = nil; } +- (BOOL)stream: (OFStream*)stream + didReadIntoBuffer: (char*)buffer + length: (size_t)length +{ + if (![self XMPP_parseBuffer: buffer + length: length]) + return NO; + + if (oldParser != nil || oldElementBuilder != nil) { + [oldParser release]; + [oldElementBuilder release]; + + oldParser = nil; + oldElementBuilder = nil; + + [sock asyncReadIntoBuffer: buffer + length: BUFFER_LENGTH + target: self + selector: @selector(stream: + didReadIntoBuffer:length:)]; + + return NO; + } + + return YES; +} + - (OFTCPSocket*)socket { return [[sock retain] autorelease]; diff --git a/tests/test.m b/tests/test.m index 39bfed4..2b32236 100644 --- a/tests/test.m +++ b/tests/test.m @@ -146,7 +146,8 @@ OF_APPLICATION_DELEGATE(AppDelegate) wasBoundToJID: (XMPPJID*)jid { of_log(@"Bound to JID: %@", [jid fullJID]); - of_log(@"Supports SM: %@", [conn_ supportsStreamManagement] ? @"YES" : @"NO"); + of_log(@"Supports SM: %@", + [conn_ supportsStreamManagement] ? @"YES" : @"NO"); [roster requestRoster]; }