@@ -52,19 +52,11 @@ { self = [super init]; @try { sock = [[OFTCPSocket alloc] init]; - parser = [[OFXMLParser alloc] init]; - elementBuilder = [[OFXMLElementBuilder alloc] init]; - port = 5222; - - [parser setDelegate: self]; - [elementBuilder setDelegate: self]; - - roster = [[XMPPRoster alloc] initWithConnection: self]; } @catch (id e) { [self release]; @throw e; } @@ -236,10 +228,20 @@ @selector(connectionWasClosed:)]) [delegate connectionWasClosed: self]; [parser parseBuffer: buffer withLength: length]; + + if (oldParser != nil) { + [oldParser release]; + oldParser = nil; + } + + if (oldElementBuilder != nil) { + [oldElementBuilder release]; + oldElementBuilder = nil; + } } - (OFTCPSocket*)socket { return [[sock retain] autorelease]; @@ -258,34 +260,31 @@ - (void)parser: (OFXMLParser*)p didStartElement: (OFString*)name withPrefix: (OFString*)prefix namespace: (OFString*)ns - attributes: (OFArray*)attrs + attributes: (OFArray*)attributes { - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFEnumerator *enumerator; - OFXMLAttribute *attr; + OFXMLAttribute *attribute; if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] || ![ns isEqual: XMPP_NS_STREAM]) { of_log(@"Did not get expected stream start!"); assert(0); } - enumerator = [attrs objectEnumerator]; - while ((attr = [enumerator nextObject]) != nil) { - if ([[attr name] isEqual: @"from"] && - ![[attr stringValue] isEqual: server]) { + enumerator = [attributes objectEnumerator]; + while ((attribute = [enumerator nextObject]) != nil) { + if ([[attribute name] isEqual: @"from"] && + ![[attribute stringValue] isEqual: server]) { of_log(@"Got invalid from in stream start!"); assert(0); } } [parser setDelegate: elementBuilder]; - - [pool release]; } - (void)parser: (OFXMLParser*)p didEndElement: (OFString*)name withPrefix: (OFString*)prefix @@ -300,12 +299,10 @@ } - (void)elementBuilder: (OFXMLElementBuilder*)builder didBuildElement: (OFXMLElement*)element { - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - [element setDefaultNamespace: XMPP_NS_CLIENT]; [element setPrefix: @"stream" forNamespace: XMPP_NS_STREAM]; of_log(@"In: %@", element); @@ -319,16 +316,35 @@ if ([[element namespace] isEqual: XMPP_NS_STARTTLS]) [self XMPP_handleTLS: element]; if ([[element namespace] isEqual: XMPP_NS_SASL]) [self XMPP_handleSASL: element]; - - [pool release]; } - (void)XMPP_startStream { + /* Make sure we don't get any old events */ + [parser setDelegate: nil]; + [elementBuilder setDelegate: nil]; + + /* + * We can't release them now, as we are currently inside them. Release + * them the next time the parser returns. + */ + oldParser = parser; + oldElementBuilder = elementBuilder; + + [roster release]; + + parser = [[OFXMLParser alloc] init]; + [parser setDelegate: self]; + + elementBuilder = [[OFXMLElementBuilder alloc] init]; + [elementBuilder setDelegate: self]; + + roster = [[XMPPRoster alloc] initWithConnection: self]; + [sock writeFormat: @"\n" @"", server]; @@ -479,12 +495,12 @@ if ([delegate respondsToSelector: @selector(connectionDidUpgradeToTLS:)]) [delegate connectionDidUpgradeToTLS: self]; /* Stream restart */ - [parser setDelegate: self]; [self XMPP_startStream]; + return; } if ([[element name] isEqual: @"failure"]) /* TODO: Find/create an exception to throw here */ @@ -518,12 +534,12 @@ if ([delegate respondsToSelector: @selector(connectionWasAuthenticated:)]) [delegate connectionWasAuthenticated: self]; /* Stream restart */ - [parser setDelegate: self]; [self XMPP_startStream]; + return; } if ([[element name] isEqual: @"failure"]) { of_log(@"Auth failed!");