228 lines
4.9 KiB
Objective-C
228 lines
4.9 KiB
Objective-C
/*
|
|
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org>
|
|
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
|
|
*
|
|
* https://webkeks.org/git/?p=objxmpp.git
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <string.h>
|
|
|
|
#include <stringprep.h>
|
|
|
|
#import "XMPPJID.h"
|
|
#import "XMPPExceptions.h"
|
|
|
|
@implementation XMPPJID
|
|
+ JID
|
|
{
|
|
return [[[self alloc] init] autorelease];
|
|
}
|
|
|
|
+ JIDWithString: (OFString*)str
|
|
{
|
|
return [[[self alloc] initWithString: str] autorelease];
|
|
}
|
|
|
|
- initWithString: (OFString*)str
|
|
{
|
|
size_t nodesep, resourcesep;
|
|
|
|
self = [super init];
|
|
|
|
if (str == nil) {
|
|
[self release];
|
|
return nil;
|
|
}
|
|
|
|
nodesep = [str rangeOfString: @"@"].location;
|
|
resourcesep = [str rangeOfString: @"/"].location;
|
|
|
|
if (nodesep == SIZE_MAX)
|
|
[self setNode: nil];
|
|
else
|
|
[self setNode: [str substringWithRange: of_range(0, nodesep)]];
|
|
|
|
if (resourcesep == SIZE_MAX) {
|
|
[self setResource: nil];
|
|
resourcesep = [str length];
|
|
} else
|
|
[self setResource: [str substringWithRange:
|
|
of_range(resourcesep + 1, [str length] - resourcesep - 1)]];
|
|
|
|
[self setDomain: [str substringWithRange:
|
|
of_range(nodesep + 1, resourcesep - nodesep - 1)]];
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[node release];
|
|
[domain release];
|
|
[resource release];
|
|
|
|
[super dealloc];
|
|
}
|
|
|
|
- copy
|
|
{
|
|
XMPPJID *new = [[XMPPJID alloc] init];
|
|
|
|
@try {
|
|
new->node = [node copy];
|
|
new->domain = [domain copy];
|
|
new->resource = [resource copy];
|
|
} @catch (id e) {
|
|
[new release];
|
|
@throw e;
|
|
}
|
|
|
|
return new;
|
|
}
|
|
|
|
- (void)setNode: (OFString*)node_
|
|
{
|
|
OFString *old = node;
|
|
char *nodepart;
|
|
Stringprep_rc rc;
|
|
|
|
if (node_ == nil) {
|
|
[old release];
|
|
node = nil;
|
|
return;
|
|
}
|
|
|
|
if (((rc = stringprep_profile([node_ UTF8String], &nodepart,
|
|
"Nodeprep", 0)) != STRINGPREP_OK) || (nodepart[0] == '\0') ||
|
|
(strlen(nodepart) > 1023))
|
|
@throw [XMPPStringPrepFailedException
|
|
exceptionWithClass: [self class]
|
|
connection: nil
|
|
profile: @"Nodeprep"
|
|
string: node_];
|
|
|
|
@try {
|
|
node = [[OFString alloc] initWithUTF8String: nodepart];
|
|
} @finally {
|
|
free(nodepart);
|
|
}
|
|
|
|
[old release];
|
|
}
|
|
|
|
- (OFString*)node
|
|
{
|
|
return [[node copy] autorelease];
|
|
}
|
|
|
|
- (void)setDomain: (OFString*)domain_
|
|
{
|
|
OFString *old = domain;
|
|
char *srv;
|
|
Stringprep_rc rc;
|
|
|
|
if (((rc = stringprep_profile([domain_ UTF8String], &srv,
|
|
"Nameprep", 0)) != STRINGPREP_OK) || (srv[0] == '\0') ||
|
|
(strlen(srv) > 1023))
|
|
@throw [XMPPStringPrepFailedException
|
|
exceptionWithClass: [self class]
|
|
connection: nil
|
|
profile: @"Nameprep"
|
|
string: domain_];
|
|
|
|
@try {
|
|
domain = [[OFString alloc] initWithUTF8String: srv];
|
|
} @finally {
|
|
free(srv);
|
|
}
|
|
|
|
[old release];
|
|
}
|
|
|
|
- (OFString*)domain
|
|
{
|
|
return [[domain copy] autorelease];
|
|
}
|
|
|
|
- (void)setResource: (OFString*)resource_
|
|
{
|
|
OFString *old = resource;
|
|
char *res;
|
|
Stringprep_rc rc;
|
|
|
|
if (resource_ == nil) {
|
|
[old release];
|
|
resource = nil;
|
|
return;
|
|
}
|
|
|
|
if (((rc = stringprep_profile([resource_ UTF8String], &res,
|
|
"Resourceprep", 0)) != STRINGPREP_OK) || (res[0] == '\0') ||
|
|
(strlen(res) > 1023))
|
|
@throw [XMPPStringPrepFailedException
|
|
exceptionWithClass: [self class]
|
|
connection: nil
|
|
profile: @"Resourceprep"
|
|
string: resource_];
|
|
|
|
@try {
|
|
resource = [[OFString alloc] initWithUTF8String: res];
|
|
} @finally {
|
|
free(res);
|
|
}
|
|
|
|
[old release];
|
|
}
|
|
|
|
- (OFString*)resource
|
|
{
|
|
return [[resource copy] autorelease];
|
|
}
|
|
|
|
- (OFString*)bareJID
|
|
{
|
|
if (node != nil)
|
|
return [OFString stringWithFormat: @"%@@%@", node, domain];
|
|
else
|
|
return [OFString stringWithFormat: @"%@", domain];
|
|
}
|
|
|
|
- (OFString*)fullJID
|
|
{
|
|
/* If we don't have a resource, the full JID is equal to the bare JID */
|
|
if (resource == nil)
|
|
return [self bareJID];
|
|
|
|
if (node != nil)
|
|
return [OFString stringWithFormat: @"%@@%@/%@",
|
|
node, domain, resource];
|
|
else
|
|
return [OFString stringWithFormat: @"%@/%@",
|
|
domain, resource];
|
|
}
|
|
|
|
- (OFString*)description
|
|
{
|
|
return [self fullJID];
|
|
}
|
|
@end
|