Index: src/XMPPConnection.h ================================================================== --- src/XMPPConnection.h +++ src/XMPPConnection.h @@ -50,18 +50,18 @@ #endif - (void)connectionWasAuthenticated: (XMPPConnection*)conn; - (void)connection: (XMPPConnection*)conn wasBoundToJID: (XMPPJID*)jid; - (void)connectionDidReceiveRoster: (XMPPConnection*)conn; -- (void)connection: (XMPPConnection*)conn - didReceiveRosterItem: (XMPPRosterItem*)rosterItem; - (BOOL)connection: (XMPPConnection*)conn didReceiveIQ: (XMPPIQ*)iq; - (void)connection: (XMPPConnection*)conn didReceivePresence: (XMPPPresence*)pres; - (void)connection: (XMPPConnection*)conn didReceiveMessage: (XMPPMessage*)msg; +- (void)connection: (XMPPConnection*)conn + didReceiveRosterItem: (XMPPRosterItem*)rosterItem; - (void)connectionWasClosed: (XMPPConnection*)conn; - (void)connectionWillUpgradeToTLS: (XMPPConnection*)conn; - (void)connectionDidUpgradeToTLS: (XMPPConnection*)conn; @end Index: src/XMPPConnection.m ================================================================== --- src/XMPPConnection.m +++ src/XMPPConnection.m @@ -648,111 +648,84 @@ - (void)XMPP_handleRoster: (XMPPIQ*)iq { OFXMLElement *rosterElem; OFXMLElement *elem; + XMPPRosterItem *rosterItem = nil; OFString *subscription; + OFEnumerator *enumerator; + BOOL isPush = ![[iq ID] isEqual: rosterID]; rosterElem = [iq elementForName: @"query" namespace: XMPP_NS_ROSTER]; - if ([[iq ID] isEqual: rosterID]) { - OFEnumerator *enumerator; - - assert([[iq type] isEqual: @"result"]); - - enumerator = [[rosterElem children] objectEnumerator]; - while ((elem = [enumerator nextObject]) != nil) { - XMPPRosterItem *rosterItem; - OFMutableArray *groups = [OFMutableArray array]; - OFEnumerator *groupEnumerator; - OFXMLElement *groupElem; - - if (![[elem name] isEqual: @"item"] || - ![[elem namespace] isEqual: XMPP_NS_ROSTER]) - continue; - - rosterItem = [XMPPRosterItem rosterItem]; - [rosterItem setJID: [XMPPJID JIDWithString: - [[elem attributeForName: @"jid"] stringValue]]]; - [rosterItem setName: - [[elem attributeForName: @"name"] stringValue]]; - - subscription = [[elem attributeForName: - @"subscription"] stringValue]; - if ([subscription isEqual: @"none"] || - [subscription isEqual: @"to"] || - [subscription isEqual: @"from"] || - [subscription isEqual: @"both"]) - [rosterItem setSubscription: subscription]; - - groupEnumerator = - [[elem elementsForName: @"group" - namespace: XMPP_NS_ROSTER] - objectEnumerator]; - while ((groupElem = [groupEnumerator nextObject]) - != nil) - [groups addObject: [groupElem stringValue]]; - - if ([groups count] > 0) - [rosterItem setGroups: groups]; - - [roster XMPP_addRosterItem: rosterItem]; - } - - if ([delegate respondsToSelector: - @selector(connectionDidReceiveRoster:)]) - [delegate connectionDidReceiveRoster: self]; - - [rosterID release]; - rosterID = nil; - } else { - XMPPRosterItem *rosterItem; - OFMutableArray *groups = [OFMutableArray array]; - OFEnumerator *groupEnumerator; - OFXMLElement *groupElem; - XMPPIQ *response; - - assert([[iq type] isEqual: @"set"]); - - elem = [[rosterElem children] firstObject]; + if (isPush) + assert([[iq type] isEqual: @"set"]); + else + assert([[iq type] isEqual: @"result"]); + + enumerator = [[rosterElem children] objectEnumerator]; + while ((elem = [enumerator nextObject]) != nil) { + OFMutableArray *groups = [OFMutableArray array]; + OFEnumerator *groupEnumerator; + OFXMLElement *groupElem; + + if (![[elem name] isEqual: @"item"] || + ![[elem namespace] isEqual: XMPP_NS_ROSTER]) + continue; + rosterItem = [XMPPRosterItem rosterItem]; [rosterItem setJID: [XMPPJID JIDWithString: [[elem attributeForName: @"jid"] stringValue]]]; [rosterItem setName: [[elem attributeForName: @"name"] stringValue]]; subscription = [[elem attributeForName: @"subscription"] stringValue]; - if ([subscription isEqual: @"none"] || - [subscription isEqual: @"to"] || - [subscription isEqual: @"from"] || - [subscription isEqual: @"both"] || - [subscription isEqual: @"remove"]) - [rosterItem setSubscription: subscription]; + if (![subscription isEqual: @"none"] && + ![subscription isEqual: @"to"] && + ![subscription isEqual: @"from"] && + ![subscription isEqual: @"both"] && + (![subscription isEqual: @"remove"] || !isPush)) + subscription = @"none"; + [rosterItem setSubscription: subscription]; groupEnumerator = [[elem elementsForName: @"group" - namespace: XMPP_NS_ROSTER] objectEnumerator]; - while ((groupElem = [groupEnumerator nextObject]) != nil) + namespace: XMPP_NS_ROSTER] + objectEnumerator]; + while ((groupElem = [groupEnumerator nextObject]) + != nil) [groups addObject: [groupElem stringValue]]; if ([groups count] > 0) [rosterItem setGroups: groups]; - [roster XMPP_updateRosterItem: rosterItem]; - - response = [XMPPIQ IQWithType: @"result" - ID: [iq ID]]; - [response setTo: [iq from]]; - [self sendStanza: response]; - - if ([delegate respondsToSelector: + 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]; @@ -813,10 +786,15 @@ - (void)connection: (XMPPConnection*)conn didReceiveMessage: (XMPPMessage*)msg { } + +- (void)connection: (XMPPConnection*)conn + didReceiveRosterItem: (XMPPRosterItem*)rosterItem +{ +} - (void)connectionWasClosed: (XMPPConnection*)conn { } Index: tests/test.m ================================================================== --- tests/test.m +++ tests/test.m @@ -121,11 +121,11 @@ of_log(@"Bound to JID: %@", [jid fullJID]); [conn requestRoster]; } -- (void)connectionDidReceiveRoster :(XMPPConnection*)conn +- (void)connectionDidReceiveRoster: (XMPPConnection*)conn { XMPPPresence *pres; of_log(@"Got roster: %@", [[conn roster] rosterItems]);