Move namespace definitions and add -[XMPPRoster addRosterItem:].

This commit is contained in:
Jonathan Schleifer 2011-03-28 17:30:40 +02:00
parent 902ab046c0
commit 823ea0eb5e
6 changed files with 103 additions and 37 deletions

View file

@ -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;
};

View file

@ -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;

View file

@ -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: @"<?xml version='1.0'?>\n"
@"<stream:stream to='%@' xmlns='" NS_CLIENT @"' "
@"xmlns:stream='" NS_STREAM @"' "
@"<stream:stream to='%@' "
@"xmlns='" XMPP_NS_CLIENT @"' "
@"xmlns:stream='" XMPP_NS_STREAM @"' "
@"version='1.0'>", 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]];

View file

@ -32,7 +32,7 @@
}
- initWithConnection: (XMPPConnection*)conn;
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem;
- (OFArray*)groups;
- (OFArray*)rosterItemsInGroup: (OFString*)group;
- (void)addRosterItem: (XMPPRosterItem*)rosterItem;
@end

View file

@ -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

27
src/XMPPRoster_private.h Normal file
View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org>
*
* 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