Use exceptions.

This commit is contained in:
Jonathan Schleifer 2011-02-16 23:36:50 +01:00
parent fa34006321
commit 8f4e29a466
5 changed files with 234 additions and 41 deletions

View file

@ -29,6 +29,7 @@
#import "XMPPStanza.h" #import "XMPPStanza.h"
#import "XMPPJID.h" #import "XMPPJID.h"
#import "XMPPIQ.h" #import "XMPPIQ.h"
#import "XMPPExceptions.h"
#define NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind" #define NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind"
#define NS_CLIENT @"jabber:client" #define NS_CLIENT @"jabber:client"
@ -36,14 +37,7 @@
#define NS_STREAM @"http://etherx.jabber.org/streams" #define NS_STREAM @"http://etherx.jabber.org/streams"
@implementation XMPPConnection @implementation XMPPConnection
@synthesize username; @synthesize username, password, server, resource, JID, port, useTLS, delegate;
@synthesize password;
@synthesize server;
@synthesize resource;
@synthesize JID;
@synthesize port;
@synthesize useTLS;
@synthesize delegate;
- init - init
{ {
@ -77,13 +71,14 @@
{ {
OFString *old = username; OFString *old = username;
char *node; char *node;
Stringprep_rc rc; Stringprep_rc rc;
if ((rc = stringprep_profile([username_ cString], &node, if ((rc = stringprep_profile([username_ cString], &node,
"SASLprep", 0)) != STRINGPREP_OK) { "SASLprep", 0)) != STRINGPREP_OK)
of_log(@"SASLprep failed: %s", stringprep_strerror(rc)); @throw [XMPPStringPrepFailedException newWithClass: isa
assert(0); connection: self
} profile: @"SASLprep"
string: username_];
@try { @try {
username = [[OFString alloc] initWithCString: node]; username = [[OFString alloc] initWithCString: node];
@ -98,13 +93,15 @@
{ {
OFString *old = resource; OFString *old = resource;
char *res; char *res;
Stringprep_rc rc; Stringprep_rc rc;
if ((rc = stringprep_profile([resource_ cString], &res, if ((rc = stringprep_profile([resource_ cString], &res,
"Resourceprep", 0)) != STRINGPREP_OK) { "Resourceprep", 0)) != STRINGPREP_OK)
of_log(@"Resourceprep failed: %s", stringprep_strerror(rc)); @throw [XMPPStringPrepFailedException
assert(0); newWithClass: isa
} connection: self
profile: @"Resourceprep"
string: resource_];
@try { @try {
resource = [[OFString alloc] initWithCString: res]; resource = [[OFString alloc] initWithCString: res];
@ -119,13 +116,14 @@
{ {
OFString *old = server; OFString *old = server;
char *srv; char *srv;
Stringprep_rc rc; Stringprep_rc rc;
if ((rc = stringprep_profile([server_ cString], &srv, if ((rc = stringprep_profile([server_ cString], &srv,
"Nameprep", 0)) != STRINGPREP_OK) { "Nameprep", 0)) != STRINGPREP_OK)
of_log(@"Nameprep failed: %s", stringprep_strerror(rc)); @throw [XMPPStringPrepFailedException newWithClass: isa
assert(0); connection: self
} profile: @"Nameprep"
string: server_];
@try { @try {
server = [[OFString alloc] initWithCString: srv]; server = [[OFString alloc] initWithCString: srv];
@ -140,13 +138,14 @@
{ {
OFString *old = password; OFString *old = password;
char *pass; char *pass;
Stringprep_rc rc; Stringprep_rc rc;
if ((rc = stringprep_profile([password_ cString], &pass, if ((rc = stringprep_profile([password_ cString], &pass,
"SASLprep", 0)) != STRINGPREP_OK) { "SASLprep", 0)) != STRINGPREP_OK)
of_log(@"SASLprep failed: %s", stringprep_strerror(rc)); @throw [XMPPStringPrepFailedException newWithClass: isa
assert(0); connection: self
} profile: @"SASLprep"
string: password_];
@try { @try {
password = [[OFString alloc] initWithCString: pass]; password = [[OFString alloc] initWithCString: pass];

56
src/XMPPExceptions.h Normal file
View file

@ -0,0 +1,56 @@
/*
* 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 <ObjFW/ObjFW.h>
@class XMPPConnection;
@interface XMPPException: OFException
{
XMPPConnection *connection;
}
@property (readonly, nonatomic) XMPPConnection *connection;
+ newWithClass: (Class)class_
connection: (XMPPConnection*)conn;
- initWithClass: (Class)class_
connection: (XMPPConnection*)conn;
@end
@interface XMPPStringPrepFailedException: XMPPException
{
OFString *profile;
OFString *string;
}
@property (readonly, nonatomic) OFString *profile, *string;
+ newWithClass: (Class)class_
connection: (XMPPConnection*)conn
profile: (OFString*)profile
string: (OFString*)string;
- initWithClass: (Class)class_
connection: (XMPPConnection*)conn
profile: (OFString*)profile
string: (OFString*)string;
@end

131
src/XMPPExceptions.m Normal file
View file

@ -0,0 +1,131 @@
/*
* 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 "XMPPExceptions.h"
@implementation XMPPException
@synthesize connection;
+ newWithClass: (Class)class_
connection: (XMPPConnection*)conn
{
return [[self alloc] initWithClass: class_
connection: conn];
}
- initWithClass: (Class)class_
{
Class c = isa;
[self release];
@throw [OFNotImplementedException newWithClass: c
selector: _cmd];
}
- initWithClass: (Class)class_
connection: (XMPPConnection*)conn
{
self = [super initWithClass: class_];
@try {
connection = [conn retain];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[connection release];
[super dealloc];
}
- (OFString*)description
{
OFAutoreleasePool *pool;
if (description != nil)
return description;
pool = [[OFAutoreleasePool alloc] init];
description = [[OFString alloc]
initWithFormat: @"An exception occurred in class %@!",
[self className]];
[pool release];
return description;
}
@end
@implementation XMPPStringPrepFailedException
@synthesize profile, string;
+ newWithClass: (Class)class_
connection: (XMPPConnection*)conn
profile: (OFString*)profile
string: (OFString*)string
{
return [[self alloc] initWithClass: class_
connection: conn
profile: profile
string: string];
}
- initWithClass: (Class)class_
connection: (XMPPConnection*)conn
{
Class c = isa;
[self release];
@throw [OFNotImplementedException newWithClass: c
selector: _cmd];
}
- initWithClass: (Class)class_
connection: (XMPPConnection*)conn
profile: (OFString*)profile_
string: (OFString*)string_
{
self = [super initWithClass: class_
connection: conn];
@try {
profile = [profile_ copy];
string = [string_ copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[profile release];
[string release];
[super dealloc];
}
@end

View file

@ -34,14 +34,20 @@
- initWithType: (OFString*)type_ - initWithType: (OFString*)type_
ID: (OFString*)ID_ ID: (OFString*)ID_
{ {
if (![type_ isEqual: @"get"] && self = [super initWithName: @"iq"
![type_ isEqual: @"set"] &&
![type_ isEqual: @"result"] &&
![type_ isEqual: @"error"])
of_log(@"Invalid IQ type!");
return [super initWithName: @"iq"
type: type_ type: type_
ID: ID_]; ID: ID_];
@try {
if (![type_ isEqual: @"get"] && ![type_ isEqual: @"set"] &&
![type_ isEqual: @"result"] && ![type_ isEqual: @"error"])
@throw [OFInvalidArgumentException newWithClass: isa
selector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
return self;
} }
@end @end

View file

@ -57,7 +57,8 @@
ID: ID_] autorelease]; ID: ID_] autorelease];
} }
+ stanzaWithElement: (OFXMLElement*)elem { + stanzaWithElement: (OFXMLElement*)elem
{
return [[[self alloc] initWithElement: elem] autorelease]; return [[[self alloc] initWithElement: elem] autorelease];
} }
@ -88,14 +89,14 @@
type: (OFString*)type_ type: (OFString*)type_
ID: (OFString*)ID_ ID: (OFString*)ID_
{ {
if (![name_ isEqual: @"iq"] &&
![name_ isEqual: @"message"] &&
![name_ isEqual: @"presence"])
of_log(@"Invalid stanza name!");
self = [super initWithName: name_]; self = [super initWithName: name_];
@try { @try {
if (![name_ isEqual: @"iq"] && ![name_ isEqual: @"message"] &&
![name_ isEqual: @"presence"])
@throw [OFInvalidArgumentException newWithClass: isa
selector: _cmd];
[self setDefaultNamespace: @"jabber:client"]; [self setDefaultNamespace: @"jabber:client"];
if (type_) if (type_)