From 8f4e29a4664a1a0a69dc09bcc4debce0c60f2985 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Wed, 16 Feb 2011 23:36:50 +0100 Subject: [PATCH] Use exceptions. --- src/XMPPConnection.m | 55 +++++++++--------- src/XMPPExceptions.h | 56 ++++++++++++++++++ src/XMPPExceptions.m | 131 +++++++++++++++++++++++++++++++++++++++++++ src/XMPPIQ.m | 20 ++++--- src/XMPPStanza.m | 13 +++-- 5 files changed, 234 insertions(+), 41 deletions(-) create mode 100644 src/XMPPExceptions.h create mode 100644 src/XMPPExceptions.m diff --git a/src/XMPPConnection.m b/src/XMPPConnection.m index 10e3163..c072cac 100644 --- a/src/XMPPConnection.m +++ b/src/XMPPConnection.m @@ -29,6 +29,7 @@ #import "XMPPStanza.h" #import "XMPPJID.h" #import "XMPPIQ.h" +#import "XMPPExceptions.h" #define NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind" #define NS_CLIENT @"jabber:client" @@ -36,14 +37,7 @@ #define NS_STREAM @"http://etherx.jabber.org/streams" @implementation XMPPConnection -@synthesize username; -@synthesize password; -@synthesize server; -@synthesize resource; -@synthesize JID; -@synthesize port; -@synthesize useTLS; -@synthesize delegate; +@synthesize username, password, server, resource, JID, port, useTLS, delegate; - init { @@ -77,13 +71,14 @@ { OFString *old = username; char *node; - Stringprep_rc rc; + if ((rc = stringprep_profile([username_ cString], &node, - "SASLprep", 0)) != STRINGPREP_OK) { - of_log(@"SASLprep failed: %s", stringprep_strerror(rc)); - assert(0); - } + "SASLprep", 0)) != STRINGPREP_OK) + @throw [XMPPStringPrepFailedException newWithClass: isa + connection: self + profile: @"SASLprep" + string: username_]; @try { username = [[OFString alloc] initWithCString: node]; @@ -98,13 +93,15 @@ { 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); - } + "Resourceprep", 0)) != STRINGPREP_OK) + @throw [XMPPStringPrepFailedException + newWithClass: isa + connection: self + profile: @"Resourceprep" + string: resource_]; @try { resource = [[OFString alloc] initWithCString: res]; @@ -119,13 +116,14 @@ { OFString *old = server; char *srv; - Stringprep_rc rc; + if ((rc = stringprep_profile([server_ cString], &srv, - "Nameprep", 0)) != STRINGPREP_OK) { - of_log(@"Nameprep failed: %s", stringprep_strerror(rc)); - assert(0); - } + "Nameprep", 0)) != STRINGPREP_OK) + @throw [XMPPStringPrepFailedException newWithClass: isa + connection: self + profile: @"Nameprep" + string: server_]; @try { server = [[OFString alloc] initWithCString: srv]; @@ -140,13 +138,14 @@ { OFString *old = password; char *pass; - Stringprep_rc rc; + if ((rc = stringprep_profile([password_ cString], &pass, - "SASLprep", 0)) != STRINGPREP_OK) { - of_log(@"SASLprep failed: %s", stringprep_strerror(rc)); - assert(0); - } + "SASLprep", 0)) != STRINGPREP_OK) + @throw [XMPPStringPrepFailedException newWithClass: isa + connection: self + profile: @"SASLprep" + string: password_]; @try { password = [[OFString alloc] initWithCString: pass]; diff --git a/src/XMPPExceptions.h b/src/XMPPExceptions.h new file mode 100644 index 0000000..09b2006 --- /dev/null +++ b/src/XMPPExceptions.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011, Jonathan Schleifer + * + * 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 + +@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 diff --git a/src/XMPPExceptions.m b/src/XMPPExceptions.m new file mode 100644 index 0000000..0cfb1a0 --- /dev/null +++ b/src/XMPPExceptions.m @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2011, Jonathan Schleifer + * + * 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 diff --git a/src/XMPPIQ.m b/src/XMPPIQ.m index d6eb600..b1847b1 100644 --- a/src/XMPPIQ.m +++ b/src/XMPPIQ.m @@ -34,14 +34,20 @@ - initWithType: (OFString*)type_ ID: (OFString*)ID_ { - if (![type_ isEqual: @"get"] && - ![type_ isEqual: @"set"] && - ![type_ isEqual: @"result"] && - ![type_ isEqual: @"error"]) - of_log(@"Invalid IQ type!"); - - return [super initWithName: @"iq" + self = [super initWithName: @"iq" type: type_ 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 diff --git a/src/XMPPStanza.m b/src/XMPPStanza.m index 482f31e..d10cb6f 100644 --- a/src/XMPPStanza.m +++ b/src/XMPPStanza.m @@ -57,7 +57,8 @@ ID: ID_] autorelease]; } -+ stanzaWithElement: (OFXMLElement*)elem { ++ stanzaWithElement: (OFXMLElement*)elem +{ return [[[self alloc] initWithElement: elem] autorelease]; } @@ -88,14 +89,14 @@ type: (OFString*)type_ ID: (OFString*)ID_ { - if (![name_ isEqual: @"iq"] && - ![name_ isEqual: @"message"] && - ![name_ isEqual: @"presence"]) - of_log(@"Invalid stanza name!"); - self = [super initWithName: name_]; @try { + if (![name_ isEqual: @"iq"] && ![name_ isEqual: @"message"] && + ![name_ isEqual: @"presence"]) + @throw [OFInvalidArgumentException newWithClass: isa + selector: _cmd]; + [self setDefaultNamespace: @"jabber:client"]; if (type_)