Index: .gitignore ================================================================== --- .gitignore +++ .gitignore @@ -17,5 +17,6 @@ ObjXMPP.xcodeproj/*.mode1v3 ObjXMPP.xcodeproj/*.pbxuser ObjXMPP.xcodeproj/project.xcworkspace ObjXMPP.xcodeproj/xcuserdata tests/tests +tests/storage.binarypack Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -12,11 +12,11 @@ XMPPContactManager.m \ XMPPExceptions.m \ XMPPEXTERNALAuth.m \ XMPPIQ.m \ XMPPJID.m \ - XMPPJSONFileStorage.m \ + XMPPFileStorage.m \ XMPPMessage.m \ XMPPMulticastDelegate.m \ XMPPPLAINAuth.m \ XMPPPresence.m \ XMPPRoster.m \ ADDED src/XMPPFileStorage.h Index: src/XMPPFileStorage.h ================================================================== --- src/XMPPFileStorage.h +++ src/XMPPFileStorage.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, Jonathan Schleifer + * + * 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. + */ + +#import + +#import "XMPPStorage.h" + +@class OFMutableDictionary; + +@interface XMPPFileStorage: OFObject +{ + OFString *_file; + OFMutableDictionary *_data; +} + +- initWithFile: (OFString*)file; +@end ADDED src/XMPPFileStorage.m Index: src/XMPPFileStorage.m ================================================================== --- src/XMPPFileStorage.m +++ src/XMPPFileStorage.m @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2012, Jonathan Schleifer + * + * 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 + +#import +#import +#import +#import +#import +#import + +#import + +#import "XMPPFileStorage.h" + +@implementation XMPPFileStorage +- init +{ + Class c = [self class]; + [self release]; + @throw [OFNotImplementedException exceptionWithClass: c + selector: _cmd]; +} + +- initWithFile: (OFString*)file +{ + self = [super init]; + + @try { + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + + _file = [file copy]; + @try { + _data = [[[OFDataArray dataArrayWithContentsOfFile: + file] binaryPackValue] retain]; + } @catch (id e) { + _data = [OFMutableDictionary new]; + } + + [pool release]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_file release]; + [_data release]; + + [super dealloc]; +} + +- (void)save +{ + [[_data binaryPackRepresentation] writeToFile: _file]; +} + +- (void)XMPP_setObject: (id)object + forPath: (OFString*)path +{ + OFArray *pathComponents = [path componentsSeparatedByString: @"."]; + OFMutableDictionary *iter = _data; + OFEnumerator *enumerator = [pathComponents objectEnumerator]; + OFString *component; + size_t i = 0, components = [pathComponents count]; + + while ((component = [enumerator nextObject]) != nil) { + if (i++ == components - 1) + continue; + + OFMutableDictionary *iter2 = [iter objectForKey: component]; + + if (iter2 == nil) { + iter2 = [OFMutableDictionary dictionary]; + [iter setObject: iter2 + forKey: component]; + } + + iter = iter2; + } + + if (object != nil) + [iter setObject: object + forKey: [pathComponents lastObject]]; + else + [iter removeObjectForKey: [pathComponents lastObject]]; +} + +- (id)XMPP_objectForPath: (OFString*)path +{ + OFArray *pathComponents = [path componentsSeparatedByString: @"."]; + OFEnumerator *enumerator = [pathComponents objectEnumerator]; + OFString *component; + id object = _data; + + while ((component = [enumerator nextObject]) != nil) + object = [object objectForKey: component]; + + return object; +} + +- (void)setStringValue: (OFString*)string + forPath: (OFString*)path +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + + [self XMPP_setObject: string + forPath: path]; + + [pool release]; +} + +- (OFString*)stringValueForPath: (OFString*)path +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + OFString *string; + + string = [self XMPP_objectForPath: path]; + + [pool release]; + + return string; +} + +- (void)setBooleanValue: (BOOL)boolean + forPath: (OFString*)path +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + + [self XMPP_setObject: [OFNumber numberWithBool: boolean] + forPath: path]; + + [pool release]; +} + +- (BOOL)booleanValueForPath: (OFString*)path +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + BOOL boolean; + + boolean = [[self XMPP_objectForPath: path] boolValue]; + + [pool release]; + + return boolean; +} + +- (void)setIntegerValue: (intmax_t)integer + forPath: (OFString*)path +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + + [self XMPP_setObject: [OFNumber numberWithIntMax: integer] + forPath: path]; + + [pool release]; +} + +- (intmax_t)integerValueForPath: (OFString*)path +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + intmax_t integer; + + integer = [[self XMPP_objectForPath: path] intMaxValue]; + + [pool release]; + + return integer; +} + +- (void)setArray: (OFArray*)array + forPath: (OFString*)path +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + + [self XMPP_setObject: array + forPath: path]; + + [pool release]; +} + +- (OFArray*)arrayForPath: (OFString*)path +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + OFArray *array; + + array = [self XMPP_objectForPath: path]; + + [pool release]; + + return array; +} + +- (void)setDictionary: (OFDictionary*)dictionary + forPath: (OFString*)path +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + + [self XMPP_setObject: dictionary + forPath: path]; + + [pool release]; +} + +- (OFDictionary*)dictionaryForPath: (OFString*)path +{ + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + OFDictionary *dictionary; + + dictionary = [self XMPP_objectForPath: path]; + + [pool release]; + + return dictionary; +} +@end DELETED src/XMPPJSONFileStorage.h Index: src/XMPPJSONFileStorage.h ================================================================== --- src/XMPPJSONFileStorage.h +++ src/XMPPJSONFileStorage.h @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2012, Jonathan Schleifer - * - * 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. - */ - -#import - -#import "XMPPStorage.h" - -@class OFMutableDictionary; - -@interface XMPPJSONFileStorage: OFObject -{ - OFString *_file; - OFMutableDictionary *_data; -} - -- initWithFile: (OFString*)file; -@end DELETED src/XMPPJSONFileStorage.m Index: src/XMPPJSONFileStorage.m ================================================================== --- src/XMPPJSONFileStorage.m +++ src/XMPPJSONFileStorage.m @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2012, Jonathan Schleifer - * - * 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 - -#import -#import -#import -#import -#import - -#import - -#import "XMPPJSONFileStorage.h" - -@implementation XMPPJSONFileStorage -- init -{ - Class c = [self class]; - [self release]; - @throw [OFNotImplementedException exceptionWithClass: c - selector: _cmd]; -} - -- initWithFile: (OFString*)file_ -{ - self = [super init]; - - @try { - OFAutoreleasePool *pool = [OFAutoreleasePool new]; - - _file = [file_ copy]; - @try { - _data = [[[OFString stringWithContentsOfFile: - _file] JSONValue] retain]; - } @catch (id e) { - _data = [OFMutableDictionary new]; - } - - [pool release]; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (void)dealloc -{ - [_file release]; - [_data release]; - - [super dealloc]; -} - -- (void)save -{ - [[_data JSONRepresentation] writeToFile: _file]; -} - -- (void)XMPP_setObject: (id)object - forPath: (OFString*)path -{ - OFArray *pathComponents = [path componentsSeparatedByString: @"."]; - OFMutableDictionary *iter = _data; - OFEnumerator *enumerator = [pathComponents objectEnumerator]; - OFString *component; - size_t i = 0, components = [pathComponents count]; - - while ((component = [enumerator nextObject]) != nil) { - if (i++ == components - 1) - continue; - - OFMutableDictionary *iter2 = [iter objectForKey: component]; - - if (iter2 == nil) { - iter2 = [OFMutableDictionary dictionary]; - [iter setObject: iter2 - forKey: component]; - } - - iter = iter2; - } - - if (object != nil) - [iter setObject: object - forKey: [pathComponents lastObject]]; - else - [iter removeObjectForKey: [pathComponents lastObject]]; -} - -- (id)XMPP_objectForPath: (OFString*)path -{ - OFArray *pathComponents = [path componentsSeparatedByString: @"."]; - OFEnumerator *enumerator = [pathComponents objectEnumerator]; - OFString *component; - id object = _data; - - while ((component = [enumerator nextObject]) != nil) - object = [object objectForKey: component]; - - return object; -} - -- (void)setStringValue: (OFString*)string - forPath: (OFString*)path -{ - OFAutoreleasePool *pool = [OFAutoreleasePool new]; - - [self XMPP_setObject: string - forPath: path]; - - [pool release]; -} - -- (OFString*)stringValueForPath: (OFString*)path -{ - OFAutoreleasePool *pool = [OFAutoreleasePool new]; - OFString *string; - - string = [self XMPP_objectForPath: path]; - - [pool release]; - - return string; -} - -- (void)setBooleanValue: (BOOL)boolean - forPath: (OFString*)path -{ - OFAutoreleasePool *pool = [OFAutoreleasePool new]; - - [self XMPP_setObject: [OFNumber numberWithBool: boolean] - forPath: path]; - - [pool release]; -} - -- (BOOL)booleanValueForPath: (OFString*)path -{ - OFAutoreleasePool *pool = [OFAutoreleasePool new]; - BOOL boolean; - - boolean = [[self XMPP_objectForPath: path] boolValue]; - - [pool release]; - - return boolean; -} - -- (void)setIntegerValue: (intmax_t)integer - forPath: (OFString*)path -{ - OFAutoreleasePool *pool = [OFAutoreleasePool new]; - - [self XMPP_setObject: [OFNumber numberWithIntMax: integer] - forPath: path]; - - [pool release]; -} - -- (intmax_t)integerValueForPath: (OFString*)path -{ - OFAutoreleasePool *pool = [OFAutoreleasePool new]; - intmax_t integer; - - integer = [[self XMPP_objectForPath: path] intMaxValue]; - - [pool release]; - - return integer; -} - -- (void)setArray: (OFArray*)array - forPath: (OFString*)path -{ - OFAutoreleasePool *pool = [OFAutoreleasePool new]; - - [self XMPP_setObject: array - forPath: path]; - - [pool release]; -} - -- (OFArray*)arrayForPath: (OFString*)path -{ - OFAutoreleasePool *pool = [OFAutoreleasePool new]; - OFArray *array; - - array = [self XMPP_objectForPath: path]; - - [pool release]; - - return array; -} - -- (void)setDictionary: (OFDictionary*)dictionary - forPath: (OFString*)path -{ - OFAutoreleasePool *pool = [OFAutoreleasePool new]; - - [self XMPP_setObject: dictionary - forPath: path]; - - [pool release]; -} - -- (OFDictionary*)dictionaryForPath: (OFString*)path -{ - OFAutoreleasePool *pool = [OFAutoreleasePool new]; - OFDictionary *dictionary; - - dictionary = [self XMPP_objectForPath: path]; - - [pool release]; - - return dictionary; -} -@end Index: src/XMPPRoster.m ================================================================== --- src/XMPPRoster.m +++ src/XMPPRoster.m @@ -303,21 +303,21 @@ [rosterItem setGroups: groups]; return rosterItem; } -- (void)XMPP_handleInitialRosterForConnection: (XMPPConnection*)connection_ - IQ: (XMPPIQ*)iq +- (void)XMPP_handleInitialRosterForConnection: (XMPPConnection*)connection + IQ: (XMPPIQ*)IQ { OFXMLElement *rosterElement; OFEnumerator *enumerator; OFXMLElement *element; - rosterElement = [iq elementForName: @"query" + rosterElement = [IQ elementForName: @"query" namespace: XMPP_NS_ROSTER]; - if ([_connection supportsRosterVersioning]) { + if ([connection supportsRosterVersioning]) { if (rosterElement == nil) { OFDictionary *items = [_dataStorage dictionaryForPath: @"roster.items"]; OFEnumerator *enumerator = [items objectEnumerator]; OFDictionary *item; @@ -359,11 +359,11 @@ [self XMPP_updateRosterItem: rosterItem]; [pool release]; } - if ([_connection supportsRosterVersioning] && rosterElement != nil) { + if ([connection supportsRosterVersioning] && rosterElement != nil) { OFString *ver = [[rosterElement attributeForName: @"ver"] stringValue]; [_dataStorage setStringValue: ver forPath: @"roster.ver"]; [_dataStorage save]; Index: tests/test.m ================================================================== --- tests/test.m +++ tests/test.m @@ -31,11 +31,11 @@ #import "XMPPIQ.h" #import "XMPPMessage.h" #import "XMPPPresence.h" #import "XMPPRoster.h" #import "XMPPStreamManagement.h" -#import "XMPPJSONFileStorage.h" +#import "XMPPFileStorage.h" @interface AppDelegate: OFObject #ifdef OF_HAVE_OPTIONAL_PROTOCOLS #endif @@ -105,12 +105,12 @@ conn = [[XMPPConnection alloc] init]; [conn addDelegate: self]; - XMPPJSONFileStorage *storage = - [[XMPPJSONFileStorage alloc] initWithFile: @"storage.json"]; + XMPPFileStorage *storage = + [[XMPPFileStorage alloc] initWithFile: @"storage.binarypack"]; [conn setDataStorage: storage]; roster = [[XMPPRoster alloc] initWithConnection: conn]; [roster addDelegate: self];