diff --git a/src/XMPPConnection.h b/src/XMPPConnection.h index 3e6dedb..393dabc 100644 --- a/src/XMPPConnection.h +++ b/src/XMPPConnection.h @@ -84,7 +84,7 @@ XMPPAuthenticator *authModule; BOOL needsSession; unsigned int lastID; - OFString *bindID, *sessionID, *rosterID; + OFString *bindID, *sessionID; XMPPRoster *roster; } @@ -143,11 +143,6 @@ */ - (OFString*)generateStanzaID; -/** - * Requests the roster. - */ -- (void)requestRoster; - - (void)setUsername: (OFString*)username; - (OFString*)username; - (void)setPassword: (OFString*)password; @@ -177,7 +172,6 @@ - (void)XMPP_handleResourceBind: (XMPPIQ*)iq; - (void)XMPP_sendSession; - (void)XMPP_handleSession: (XMPPIQ*)iq; -- (void)XMPP_handleRoster: (XMPPIQ*)iq; @end @interface OFObject (XMPPConnectionDelegate) diff --git a/src/XMPPConnection.m b/src/XMPPConnection.m index 6e80114..662da6e 100644 --- a/src/XMPPConnection.m +++ b/src/XMPPConnection.m @@ -77,7 +77,6 @@ [authModule release]; [bindID release]; [sessionID release]; - [rosterID release]; [roster release]; [super dealloc]; @@ -231,15 +230,11 @@ [parser parseBuffer: buffer withLength: length]; - if (oldParser != nil) { - [oldParser release]; - oldParser = nil; - } + [oldParser release]; + [oldElementBuilder release]; - if (oldElementBuilder != nil) { - [oldElementBuilder release]; - oldElementBuilder = nil; - } + oldParser = nil; + oldElementBuilder = nil; } - (OFTCPSocket*)socket @@ -568,10 +563,9 @@ } if ([iq elementForName: @"query" - namespace: XMPP_NS_ROSTER]) { - [self XMPP_handleRoster: iq]; - return; - } + namespace: XMPP_NS_ROSTER]) + if ([roster handleIQ: iq]) + return; if ([delegate respondsToSelector: @selector(connection:didReceiveIQ:)]) handled = [delegate connection: self @@ -762,101 +756,6 @@ sessionID = nil; } -- (void)requestRoster -{ - XMPPIQ *iq; - - if (rosterID != nil) - assert(0); - - rosterID = [[self generateStanzaID] retain]; - iq = [XMPPIQ IQWithType: @"get" - ID: rosterID]; - [iq addChild: [OFXMLElement elementWithName: @"query" - namespace: XMPP_NS_ROSTER]]; - [self sendStanza: iq]; -} - -- (void)XMPP_handleRoster: (XMPPIQ*)iq -{ - OFXMLElement *rosterElement; - OFXMLElement *element; - XMPPRosterItem *rosterItem = nil; - OFString *subscription; - OFEnumerator *enumerator; - BOOL isPush = ![[iq ID] isEqual: rosterID]; - - rosterElement = [iq elementForName: @"query" - namespace: XMPP_NS_ROSTER]; - - if (isPush) - assert([[iq type] isEqual: @"set"]); - else - assert([[iq type] isEqual: @"result"]); - - enumerator = [[rosterElement children] objectEnumerator]; - while ((element = [enumerator nextObject]) != nil) { - OFMutableArray *groups = [OFMutableArray array]; - OFEnumerator *groupEnumerator; - OFXMLElement *groupElement; - - if (![[element name] isEqual: @"item"] || - ![[element namespace] isEqual: XMPP_NS_ROSTER]) - continue; - - rosterItem = [XMPPRosterItem rosterItem]; - [rosterItem setJID: [XMPPJID JIDWithString: - [[element attributeForName: @"jid"] stringValue]]]; - [rosterItem setName: - [[element attributeForName: @"name"] stringValue]]; - - subscription = [[element attributeForName: - @"subscription"] stringValue]; - - if (![subscription isEqual: @"none"] && - ![subscription isEqual: @"to"] && - ![subscription isEqual: @"from"] && - ![subscription isEqual: @"both"] && - (![subscription isEqual: @"remove"] || !isPush)) - subscription = @"none"; - - [rosterItem setSubscription: subscription]; - - groupEnumerator = [[element - elementsForName: @"group" - namespace: XMPP_NS_ROSTER] objectEnumerator]; - while ((groupElement = [groupEnumerator nextObject]) != nil) - [groups addObject: [groupElement stringValue]]; - - if ([groups count] > 0) - [rosterItem setGroups: groups]; - - if ([subscription isEqual: @"remove"]) - [roster XMPP_deleteRosterItem: rosterItem]; - else - [roster XMPP_addRosterItem: rosterItem]; - - if (isPush && [delegate respondsToSelector: - @selector(connection:didReceiveRosterItem:)]) - [delegate connection:self - didReceiveRosterItem: rosterItem]; - } - - if (isPush) { - XMPPIQ *response = [XMPPIQ IQWithType: @"result" - ID: [iq ID]]; - [response setTo: [iq from]]; - [self sendStanza: response]; - } else { - if ([delegate respondsToSelector: - @selector(connectionDidReceiveRoster:)]) - [delegate connectionDidReceiveRoster: self]; - - [rosterID release]; - rosterID = nil; - } -} - - (XMPPJID*)JID { return [[JID copy] autorelease]; diff --git a/src/XMPPRoster.h b/src/XMPPRoster.h index 4e2cf99..fe5db1c 100644 --- a/src/XMPPRoster.h +++ b/src/XMPPRoster.h @@ -24,11 +24,13 @@ @class XMPPConnection; @class XMPPRosterItem; +@class XMPPIQ; @interface XMPPRoster: OFObject { XMPPConnection *connection; OFMutableDictionary *rosterItems; + OFString *rosterID; } - initWithConnection: (XMPPConnection*)conn; @@ -36,6 +38,8 @@ - (void)XMPP_updateRosterItem: (XMPPRosterItem*)rosterItem; - (void)XMPP_deleteRosterItem: (XMPPRosterItem*)rosterItem; - (OFDictionary*)rosterItems; +- (BOOL)handleIQ: (XMPPIQ*)iq; +- (void)requestRoster; - (void)addRosterItem: (XMPPRosterItem*)rosterItem; - (void)updateRosterItem: (XMPPRosterItem*)rosterItem; - (void)deleteRosterItem: (XMPPRosterItem*)rosterItem; diff --git a/src/XMPPRoster.m b/src/XMPPRoster.m index 8d0ace0..01adc9b 100644 --- a/src/XMPPRoster.m +++ b/src/XMPPRoster.m @@ -20,6 +20,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + #import "XMPPRoster.h" #import "XMPPRosterItem.h" #import "XMPPConnection.h" @@ -45,6 +47,8 @@ - (void)dealloc { [connection release]; + [rosterItems release]; + [rosterID release]; [super dealloc]; } @@ -70,6 +74,110 @@ return [[rosterItems copy] autorelease]; } +- (void)requestRoster +{ + XMPPIQ *iq; + + if (rosterID != nil) + assert(0); + + rosterID = [[connection generateStanzaID] retain]; + iq = [XMPPIQ IQWithType: @"get" + ID: rosterID]; + [iq addChild: [OFXMLElement elementWithName: @"query" + namespace: XMPP_NS_ROSTER]]; + [connection sendStanza: iq]; +} + +- (BOOL)handleIQ: (XMPPIQ*)iq +{ + OFXMLElement *rosterElement; + OFXMLElement *element; + XMPPRosterItem *rosterItem = nil; + OFString *subscription; + OFEnumerator *enumerator; + BOOL isPush = ![[iq ID] isEqual: rosterID]; + + rosterElement = [iq elementForName: @"query" + namespace: XMPP_NS_ROSTER]; + + if (rosterElement == nil) + return NO; + + if (isPush) { + if (![[iq type] isEqual: @"set"]) + return NO; + } else { + if (![[iq type] isEqual: @"result"]) + return NO; + } + + enumerator = [[rosterElement children] objectEnumerator]; + while ((element = [enumerator nextObject]) != nil) { + OFMutableArray *groups = [OFMutableArray array]; + OFEnumerator *groupEnumerator; + OFXMLElement *groupElement; + + if (![[element name] isEqual: @"item"] || + ![[element namespace] isEqual: XMPP_NS_ROSTER]) + continue; + + rosterItem = [XMPPRosterItem rosterItem]; + [rosterItem setJID: [XMPPJID JIDWithString: + [[element attributeForName: @"jid"] stringValue]]]; + [rosterItem setName: + [[element attributeForName: @"name"] stringValue]]; + + subscription = [[element attributeForName: + @"subscription"] stringValue]; + + if (![subscription isEqual: @"none"] && + ![subscription isEqual: @"to"] && + ![subscription isEqual: @"from"] && + ![subscription isEqual: @"both"] && + (![subscription isEqual: @"remove"] || !isPush)) + subscription = @"none"; + + [rosterItem setSubscription: subscription]; + + groupEnumerator = [[element + elementsForName: @"group" + namespace: XMPP_NS_ROSTER] objectEnumerator]; + while ((groupElement = [groupEnumerator nextObject]) != nil) + [groups addObject: [groupElement stringValue]]; + + if ([groups count] > 0) + [rosterItem setGroups: groups]; + + if ([subscription isEqual: @"remove"]) + [self XMPP_deleteRosterItem: rosterItem]; + else + [self XMPP_addRosterItem: rosterItem]; + + if (isPush && [[connection delegate] respondsToSelector: + @selector(connection:didReceiveRosterItem:)]) + [[connection delegate] connection: connection + didReceiveRosterItem: rosterItem]; + } + + if (isPush) { + XMPPIQ *response = [XMPPIQ IQWithType: @"result" + ID: [iq ID]]; + [response setTo: [iq from]]; + [connection sendStanza: response]; + } else { + if ([[connection delegate] respondsToSelector: + @selector(connectionDidReceiveRoster:)]) + [[connection delegate] + connectionDidReceiveRoster: connection]; + + [rosterID release]; + rosterID = nil; + } + + return YES; +} + - (void)addRosterItem: (XMPPRosterItem*)rosterItem { [self updateRosterItem: rosterItem]; diff --git a/tests/test.m b/tests/test.m index ff3df62..82fdcc4 100644 --- a/tests/test.m +++ b/tests/test.m @@ -120,7 +120,7 @@ OF_APPLICATION_DELEGATE(AppDelegate) { of_log(@"Bound to JID: %@", [jid fullJID]); - [conn requestRoster]; + [[conn roster] requestRoster]; } - (void)connectionDidReceiveRoster: (XMPPConnection*)conn