From 823ea0eb5e4df2aa6ce59f61f03d5d81f551d1cc Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Mon, 28 Mar 2011 17:30:40 +0200 Subject: [PATCH] Move namespace definitions and add -[XMPPRoster addRosterItem:]. --- ObjXMPP.xcodeproj/project.pbxproj | 4 ++ src/XMPPConnection.h | 9 ++++ src/XMPPConnection.m | 68 +++++++++++++++---------------- src/XMPPRoster.h | 2 +- src/XMPPRoster.m | 30 ++++++++++++++ src/XMPPRoster_private.h | 27 ++++++++++++ 6 files changed, 103 insertions(+), 37 deletions(-) create mode 100644 src/XMPPRoster_private.h diff --git a/ObjXMPP.xcodeproj/project.pbxproj b/ObjXMPP.xcodeproj/project.pbxproj index d96e6aa..c384ed2 100644 --- a/ObjXMPP.xcodeproj/project.pbxproj +++ b/ObjXMPP.xcodeproj/project.pbxproj @@ -37,6 +37,7 @@ 4BD9BF5A134003F700DAB43A /* XMPPRosterItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD9BF58134003F700DAB43A /* XMPPRosterItem.m */; }; 4BDEF8071340B240000156D1 /* XMPPRoster.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BDEF8051340B240000156D1 /* XMPPRoster.h */; }; 4BDEF8081340B240000156D1 /* XMPPRoster.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDEF8061340B240000156D1 /* XMPPRoster.m */; }; + 4BF459B91340DE3600701BCC /* XMPPRoster_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF459B81340DE3600701BCC /* XMPPRoster_private.h */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -83,6 +84,7 @@ 4BD9BF58134003F700DAB43A /* XMPPRosterItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XMPPRosterItem.m; path = src/XMPPRosterItem.m; sourceTree = SOURCE_ROOT; }; 4BDEF8051340B240000156D1 /* XMPPRoster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMPPRoster.h; path = src/XMPPRoster.h; sourceTree = SOURCE_ROOT; }; 4BDEF8061340B240000156D1 /* XMPPRoster.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XMPPRoster.m; path = src/XMPPRoster.m; sourceTree = SOURCE_ROOT; }; + 4BF459B81340DE3600701BCC /* XMPPRoster_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMPPRoster_private.h; path = src/XMPPRoster_private.h; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -164,6 +166,7 @@ 4BC559E81337AC0900E345C7 /* XMPPPresence.h */, 4BC559E91337AC0900E345C7 /* XMPPPresence.m */, 4BDEF8051340B240000156D1 /* XMPPRoster.h */, + 4BF459B81340DE3600701BCC /* XMPPRoster_private.h */, 4BDEF8061340B240000156D1 /* XMPPRoster.m */, 4BD9BF57134003F700DAB43A /* XMPPRosterItem.h */, 4BD9BF58134003F700DAB43A /* XMPPRosterItem.m */, @@ -203,6 +206,7 @@ 4BC55A011337AC1800E345C7 /* XMPPStanza.h in Headers */, 4BD9BF59134003F700DAB43A /* XMPPRosterItem.h in Headers */, 4BDEF8071340B240000156D1 /* XMPPRoster.h in Headers */, + 4BF459B91340DE3600701BCC /* XMPPRoster_private.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/XMPPConnection.h b/src/XMPPConnection.h index 4689634..616502f 100644 --- a/src/XMPPConnection.h +++ b/src/XMPPConnection.h @@ -31,6 +31,15 @@ @class XMPPAuthenticator; @class XMPPRoster; +#define XMPP_NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind" +#define XMPP_NS_CLIENT @"jabber:client" +#define XMPP_NS_ROSTER @"jabber:iq:roster" +#define XMPP_NS_SASL @"urn:ietf:params:xml:ns:xmpp-sasl" +#define XMPP_NS_STARTTLS @"urn:ietf:params:xml:ns:xmpp-tls" +#define XMPP_NS_STANZAS @"urn:ietf:params:xml:ns:xmpp-stanzas" +#define XMPP_NS_SESSION @"urn:ietf:params:xml:ns:xmpp-session" +#define XMPP_NS_STREAM @"http://etherx.jabber.org/streams" + @protocol XMPPConnectionDelegate @optional - (void)connectionWasAuthenticated: (XMPPConnection*)conn; diff --git a/src/XMPPConnection.m b/src/XMPPConnection.m index 6c03b83..f3e7f0e 100644 --- a/src/XMPPConnection.m +++ b/src/XMPPConnection.m @@ -37,18 +37,10 @@ #import "XMPPMessage.h" #import "XMPPPresence.h" #import "XMPPRoster.h" +#import "XMPPRoster_private.h" #import "XMPPRosterItem.h" #import "XMPPExceptions.h" -#define NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind" -#define NS_CLIENT @"jabber:client" -#define NS_ROSTER @"jabber:iq:roster" -#define NS_SASL @"urn:ietf:params:xml:ns:xmpp-sasl" -#define NS_STARTTLS @"urn:ietf:params:xml:ns:xmpp-tls" -#define NS_STANZAS @"urn:ietf:params:xml:ns:xmpp-stanzas" -#define NS_SESSION @"urn:ietf:params:xml:ns:xmpp-session" -#define NS_STREAM @"http://etherx.jabber.org/streams" - @interface XMPPConnection () - (void)XMPP_startStream; - (void)XMPP_handleStanza: (OFXMLElement*)elem; @@ -269,7 +261,7 @@ OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] || - ![ns isEqual: NS_STREAM]) { + ![ns isEqual: XMPP_NS_STREAM]) { of_log(@"Did not get expected stream start!"); assert(0); } @@ -292,9 +284,9 @@ { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - elem.defaultNamespace = NS_CLIENT; + elem.defaultNamespace = XMPP_NS_CLIENT; [elem setPrefix: @"stream" - forNamespace: NS_STREAM]; + forNamespace: XMPP_NS_STREAM]; of_log(@"In: %@", elem); @@ -306,14 +298,15 @@ - (void)XMPP_startStream { [sock writeFormat: @"\n" - @"", server]; } - (void)XMPP_handleStanza: (OFXMLElement*)elem { - if ([elem.namespace isEqual: NS_CLIENT]) { + if ([elem.namespace isEqual: XMPP_NS_CLIENT]) { if ([elem.name isEqual: @"iq"]) { [self XMPP_handleIQ: [XMPPIQ stanzaWithElement: elem]]; return; @@ -334,7 +327,7 @@ assert(0); } - if ([elem.namespace isEqual: NS_STREAM]) { + if ([elem.namespace isEqual: XMPP_NS_STREAM]) { if ([elem.name isEqual: @"features"]) { [self XMPP_handleFeatures: elem]; return; @@ -343,7 +336,7 @@ assert(0); } - if ([elem.namespace isEqual: NS_STARTTLS]) { + if ([elem.namespace isEqual: XMPP_NS_STARTTLS]) { if ([elem.name isEqual: @"proceed"]) { /* FIXME: Catch errors here */ sock = [[GTLSSocket alloc] initWithSocket: sock]; @@ -361,7 +354,7 @@ assert(0); } - if ([elem.namespace isEqual: NS_SASL]) { + if ([elem.namespace isEqual: XMPP_NS_SASL]) { if ([elem.name isEqual: @"challenge"]) { OFXMLElement *responseTag; OFDataArray *challenge = @@ -370,8 +363,9 @@ OFDataArray *response = [authModule calculateResponseWithChallenge: challenge]; - responseTag = [OFXMLElement elementWithName: @"response" - namespace: NS_SASL]; + responseTag = [OFXMLElement + elementWithName: @"response" + namespace: XMPP_NS_SASL]; [responseTag addChild: [OFXMLElement elementWithCharacters: [response stringByBase64Encoding]]]; @@ -448,7 +442,7 @@ stringValue: @"cancel"]; [error addChild: [OFXMLElement elementWithName: @"service-unavailable" - namespace: NS_STANZAS]]; + namespace: XMPP_NS_STANZAS]]; [iq addChild: error]; [self sendStanza: iq]; @@ -475,18 +469,20 @@ { OFXMLElement *starttls = [elem elementsForName: @"starttls" - namespace: NS_STARTTLS].firstObject; + namespace: XMPP_NS_STARTTLS].firstObject; OFXMLElement *bind = [elem elementsForName: @"bind" - namespace: NS_BIND].firstObject; - OFXMLElement *session = [elem elementsForName: @"session" - namespace: NS_SESSION].firstObject; + namespace: XMPP_NS_BIND].firstObject; + OFXMLElement *session = + [elem elementsForName: @"session" + namespace: XMPP_NS_SESSION].firstObject; OFArray *mechs = [elem elementsForName: @"mechanisms" - namespace: NS_SASL]; + namespace: XMPP_NS_SASL]; OFMutableArray *mechanisms = [OFMutableArray array]; if (starttls != nil) { - [self sendStanza: [OFXMLElement elementWithName: @"starttls" - namespace: NS_STARTTLS]]; + [self sendStanza: + [OFXMLElement elementWithName: @"starttls" + namespace: XMPP_NS_STARTTLS]]; return; } @@ -531,7 +527,7 @@ OFXMLElement *authTag; authTag = [OFXMLElement elementWithName: @"auth" - namespace: NS_SASL]; + namespace: XMPP_NS_SASL]; [authTag addAttributeWithName: @"mechanism" stringValue: name]; [authTag addChild: [OFXMLElement elementWithCharacters: @@ -550,7 +546,7 @@ ID: bindID]; bind = [OFXMLElement elementWithName: @"bind" - namespace: NS_BIND]; + namespace: XMPP_NS_BIND]; if (resource != nil) [bind addChild: [OFXMLElement elementWithName: @"resource" @@ -572,7 +568,7 @@ bindElem = iq.children.firstObject; if (![bindElem.name isEqual: @"bind"] || - ![bindElem.namespace isEqual: NS_BIND]) + ![bindElem.namespace isEqual: XMPP_NS_BIND]) assert(0); jidElem = bindElem.children.firstObject; @@ -600,7 +596,7 @@ iq = [XMPPIQ IQWithType: @"set" ID: sessionID]; [iq addChild: [OFXMLElement elementWithName: @"session" - namespace: NS_SESSION]]; + namespace: XMPP_NS_SESSION]]; [self sendStanza: iq]; } @@ -628,7 +624,7 @@ iq = [XMPPIQ IQWithType: @"get" ID: rosterID]; [iq addChild: [OFXMLElement elementWithName: @"query" - namespace: NS_ROSTER]]; + namespace: XMPP_NS_ROSTER]]; [self sendStanza: iq]; } @@ -642,7 +638,7 @@ rosterElem = iq.children.firstObject; if (![rosterElem.name isEqual: @"query"] || - ![rosterElem.namespace isEqual: NS_ROSTER]) + ![rosterElem.namespace isEqual: XMPP_NS_ROSTER]) assert(0); for (OFXMLElement *elem in rosterElem.children) { @@ -650,7 +646,7 @@ OFMutableArray *groups = [OFMutableArray array]; if (![elem.name isEqual: @"item"] || - ![elem.ns isEqual: NS_ROSTER]) + ![elem.ns isEqual: XMPP_NS_ROSTER]) continue; rosterItem = [XMPPRosterItem rosterItem]; @@ -662,7 +658,7 @@ for (OFXMLElement *groupElem in [elem elementsForName: @"group" - namespace: NS_ROSTER]) + namespace: XMPP_NS_ROSTER]) [groups addObject: [groupElem.children.firstObject stringValue]]; diff --git a/src/XMPPRoster.h b/src/XMPPRoster.h index 424418b..53f7cbd 100644 --- a/src/XMPPRoster.h +++ b/src/XMPPRoster.h @@ -32,7 +32,7 @@ } - initWithConnection: (XMPPConnection*)conn; -- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem; - (OFArray*)groups; - (OFArray*)rosterItemsInGroup: (OFString*)group; +- (void)addRosterItem: (XMPPRosterItem*)rosterItem; @end diff --git a/src/XMPPRoster.m b/src/XMPPRoster.m index 237a702..26a3905 100644 --- a/src/XMPPRoster.m +++ b/src/XMPPRoster.m @@ -21,7 +21,11 @@ */ #import "XMPPRoster.h" +#import "XMPPRoster_private.h" #import "XMPPRosterItem.h" +#import "XMPPConnection.h" +#import "XMPPIQ.h" +#import "XMPPJID.h" @implementation XMPPRoster - initWithConnection: (XMPPConnection*)conn @@ -92,4 +96,30 @@ return [[[groups objectForKey: group] copy] autorelease]; } + +- (void)addRosterItem: (XMPPRosterItem*)rosterItem +{ + XMPPIQ *iq = [XMPPIQ IQWithType: @"set" + ID: [connection generateStanzaID]]; + OFXMLElement *query = [OFXMLElement elementWithName: @"query" + namespace: XMPP_NS_ROSTER]; + OFXMLElement *item = [OFXMLElement elementWithName: @"item" + namespace: XMPP_NS_ROSTER]; + + [item addAttributeWithName: @"jid" + stringValue: rosterItem.JID.bareJID]; + if (rosterItem.name != nil) + [item addAttributeWithName: @"name" + stringValue: rosterItem.name]; + + for (OFString *group in rosterItem.groups) + [item addChild: [OFXMLElement elementWithName: @"group" + namespace: XMPP_NS_ROSTER + stringValue: group]]; + + [query addChild: item]; + [iq addChild: query]; + + [connection sendStanza: iq]; +} @end diff --git a/src/XMPPRoster_private.h b/src/XMPPRoster_private.h new file mode 100644 index 0000000..a962657 --- /dev/null +++ b/src/XMPPRoster_private.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011, Jonathan Schleifer + * + * https://webkeks.org/hg/objxmpp/ + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "XMPPRoster.h" + +@interface XMPPRoster () +- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem; +@end