From 6dc9e5e217be52c1922c36992c480511202681f9 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Sun, 13 Feb 2011 01:36:25 +0100 Subject: [PATCH] Add a class for handling JIDs. --- Makefile | 2 +- src/XMPPConnection.h | 9 ++- src/XMPPConnection.m | 6 +- src/XMPPJID.h | 60 ++++++++++++++++++++ src/XMPPJID.m | 127 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 200 insertions(+), 4 deletions(-) create mode 100644 src/XMPPJID.h create mode 100644 src/XMPPJID.m diff --git a/Makefile b/Makefile index a59d008..237eb1b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ all: tests/tests -tests/tests: tests/test.m src/XMPPConnection.m src/XMPPStanza.m +tests/tests: tests/test.m src/XMPPConnection.m src/XMPPStanza.m src/XMPPJID.m objfw-compile -o $@ $^ -lidn -Wall -Werror -Isrc clean: diff --git a/src/XMPPConnection.h b/src/XMPPConnection.h index 1d5c705..b6649eb 100644 --- a/src/XMPPConnection.h +++ b/src/XMPPConnection.h @@ -1,4 +1,5 @@ #import +#import @class XMPPConnection; @class XMPPIQ; @@ -25,7 +26,7 @@ OFXMLElementBuilder *elementBuilder; /** - * The username (local part of the JID) to connect with + * The username to connect with */ OFString *username; @@ -44,6 +45,11 @@ */ OFString *resource; + /** + * The JID bound to this connection (this is determined by the server) + */ + XMPPJID *JID; + /** * The port to connect to */ @@ -61,6 +67,7 @@ @property (copy) OFString *password; @property (copy) OFString *server; @property (copy) OFString *resource; +@property (readonly) XMPPJID *JID; @property (assign) short port; @property (assign) BOOL useTLS; @property (retain) id delegate; diff --git a/src/XMPPConnection.m b/src/XMPPConnection.m index 03db019..5ac0aed 100644 --- a/src/XMPPConnection.m +++ b/src/XMPPConnection.m @@ -13,6 +13,7 @@ @synthesize password; @synthesize server; @synthesize resource; +@synthesize JID; @synthesize port; @synthesize useTLS; @synthesize delegate; @@ -218,8 +219,9 @@ if ([bindElem.name isEqual: @"bind"] && [bindElem.namespace isEqual: NS_BIND]) { OFXMLElement *jidElem = bindElem.children.firstObject; - of_log(@"Bound to JID: %@", [jidElem.children.firstObject - stringValue]); + JID = [[XMPPJID alloc] initWithString: + [jidElem.children.firstObject stringValue]]; + of_log(@"Bound to JID: %@", [JID fullJID]); } } diff --git a/src/XMPPJID.h b/src/XMPPJID.h new file mode 100644 index 0000000..fe2ce41 --- /dev/null +++ b/src/XMPPJID.h @@ -0,0 +1,60 @@ +#import + +/** + * \brief A class for easy handling of JIDs + */ +@interface XMPPJID: OFObject +{ + /** + * The JID's localpart + */ + OFString *node; + + /** + * The JID's domainpart + */ + OFString *domain; + + /** + * The JID's resourcepart + */ + OFString *resource; +} + +@property (copy) OFString *node; +@property (copy) OFString *domain; +@property (copy) OFString *resource; + +/** + * Creates a new XMPPJID + * + * \return A new autoreleased XMPPJID + */ ++ JID; + +/** + * Creates a new XMPPJID from a OFString + * + * \param str The string to parse into a JID object + * \return A new autoreleased XMPPJID + */ ++ JIDWithString: (OFString*)str; + +/** + * Initializes an already allocated XMPPJID using a OFString + * + * \param str The string to parse into a JID object + * \return A initialized XMPPJID + */ +- initWithString: (OFString*)str; + +/** + * \return A OFString containing the bare JID + */ +- (OFString*)bareJID; + +/** + * \return A OFString containing the full JID + */ +- (OFString*)fullJID; +@end diff --git a/src/XMPPJID.m b/src/XMPPJID.m new file mode 100644 index 0000000..3ab9e83 --- /dev/null +++ b/src/XMPPJID.m @@ -0,0 +1,127 @@ +#include +#include +#import "XMPPJID.h" + +@implementation XMPPJID +@synthesize node; +@synthesize domain; +@synthesize resource; + ++ JID +{ + return [[[self alloc] init] autorelease]; +} + ++ JIDWithString: (OFString*)str +{ + return [[[self alloc] initWithString: str] autorelease]; +} + +- initWithString: (OFString*)str +{ + self = [super init]; + + size_t nodesep, resourcesep; + nodesep = [str indexOfFirstOccurrenceOfString: @"@"]; + resourcesep = [str indexOfFirstOccurrenceOfString: @"/"]; + + if (nodesep == -1) + [self setNode: @""]; + else + [self setNode: [str substringFromIndex: 0 + toIndex: nodesep]]; + + if (resourcesep == -1) { + [self setResource: @""]; + resourcesep = [str length]; + } else + [self setResource: [str substringFromIndex: resourcesep + 1 + toIndex: [str length]]]; + + [self setDomain: [str substringFromIndex: nodesep + 1 + toIndex: resourcesep]]; + + return self; +} + +- (void)setNode: (OFString*)node_ +{ + OFString *old = node; + char *nodepart; + + Stringprep_rc rc; + if ((rc = stringprep_profile([node_ cString], &nodepart, "Nodeprep", 0)) + != STRINGPREP_OK) { + of_log(@"Nodeprep failed: %s", stringprep_strerror(rc)); + assert(0); + } + + @try { + node = [[OFString alloc] initWithCString: nodepart]; + } @finally { + free(nodepart); + } + + [old release]; +} + +- (void)setDomain: (OFString*)domain_ +{ + OFString *old = domain; + char *srv; + + Stringprep_rc rc; + if ((rc = stringprep_profile([domain_ cString], &srv, "Nameprep", 0)) + != STRINGPREP_OK) { + of_log(@"Nameprep failed: %s", stringprep_strerror(rc)); + assert(0); + } + + @try { + domain = [[OFString alloc] initWithCString: srv]; + } @finally { + free(srv); + } + + [old release]; +} + +- (void)setResource: (OFString*)resource_ +{ + OFString *old = resource; + char *res; + + Stringprep_rc rc; + if ((rc = stringprep_profile([resource_ cString], &res, + "Resourceprep", 0)) != STRINGPREP_OK) { + of_log(@"Resourceprep failed: %s", stringprep_strerror(rc)); + assert(0); + } + + @try { + resource = [[OFString alloc] initWithCString: res]; + } @finally { + free(res); + } + + [old release]; +} + +- (OFString*)bareJID +{ + if ([node length]) + return [OFString stringWithFormat: @"%@@%@", node, domain]; + else + return [OFString stringWithFormat: @"%@", domain]; +} + +- (OFString*)fullJID +{ + if ([node length]) + return [OFString stringWithFormat: @"%@@%@/%@", + node, domain, resource]; + else + return [OFString stringWithFormat: @"%@/%@", + domain, resource]; +} +@end