Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -1,7 +1,7 @@ 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: rm -f src/*.o tests/*.o tests/tests Index: src/XMPPConnection.h ================================================================== --- src/XMPPConnection.h +++ src/XMPPConnection.h @@ -1,6 +1,7 @@ #import +#import @class XMPPConnection; @class XMPPIQ; @class XMPPMessage; @class XMPPPresence; @@ -23,11 +24,11 @@ OFTCPSocket *sock; OFXMLParser *parser; OFXMLElementBuilder *elementBuilder; /** - * The username (local part of the JID) to connect with + * The username to connect with */ OFString *username; /** * The password to connect with @@ -42,10 +43,15 @@ /** * The resource to connect with */ OFString *resource; + /** + * The JID bound to this connection (this is determined by the server) + */ + XMPPJID *JID; + /** * The port to connect to */ short port; @@ -59,10 +65,11 @@ @property (copy) OFString *username; @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; /** Index: src/XMPPConnection.m ================================================================== --- src/XMPPConnection.m +++ src/XMPPConnection.m @@ -11,10 +11,11 @@ @implementation XMPPConnection @synthesize username; @synthesize password; @synthesize server; @synthesize resource; +@synthesize JID; @synthesize port; @synthesize useTLS; @synthesize delegate; - init @@ -216,12 +217,13 @@ { OFXMLElement *bindElem = iq.children.firstObject; 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]); } } - (void)_handleFeatures: (OFXMLElement*)elem { ADDED src/XMPPJID.h Index: src/XMPPJID.h ================================================================== --- src/XMPPJID.h +++ 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 ADDED src/XMPPJID.m Index: src/XMPPJID.m ================================================================== --- src/XMPPJID.m +++ 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