Index: src/XMPPConnection.m ================================================================== --- src/XMPPConnection.m +++ src/XMPPConnection.m @@ -27,25 +27,19 @@ #import "XMPPConnection.h" #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" #define NS_SASL @"urn:ietf:params:xml:ns:xmpp-sasl" #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 { self = [super init]; @@ -75,17 +69,18 @@ - (void)setUsername: (OFString*)username_ { 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]; } @finally { free(node); @@ -96,17 +91,19 @@ - (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); - } + "Resourceprep", 0)) != STRINGPREP_OK) + @throw [XMPPStringPrepFailedException + newWithClass: isa + connection: self + profile: @"Resourceprep" + string: resource_]; @try { resource = [[OFString alloc] initWithCString: res]; } @finally { free(res); @@ -117,17 +114,18 @@ - (void)setServer: (OFString*)server_ { 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]; } @finally { free(srv); @@ -138,17 +136,18 @@ - (void)setPassword: (OFString*)password_ { 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]; } @finally { free(pass); ADDED src/XMPPExceptions.h Index: src/XMPPExceptions.h ================================================================== --- src/XMPPExceptions.h +++ 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 ADDED src/XMPPExceptions.m Index: src/XMPPExceptions.m ================================================================== --- src/XMPPExceptions.m +++ 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 Index: src/XMPPIQ.m ================================================================== --- src/XMPPIQ.m +++ src/XMPPIQ.m @@ -32,16 +32,22 @@ } - 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 Index: src/XMPPStanza.m ================================================================== --- src/XMPPStanza.m +++ src/XMPPStanza.m @@ -55,11 +55,12 @@ return [[[self alloc] initWithName: name type: type_ ID: ID_] autorelease]; } -+ stanzaWithElement: (OFXMLElement*)elem { ++ stanzaWithElement: (OFXMLElement*)elem +{ return [[[self alloc] initWithElement: elem] autorelease]; } - initWithName: (OFString*)name_ { @@ -86,18 +87,18 @@ - initWithName: (OFString*)name_ 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_) [self setType: type_];