@@ -26,44 +26,46 @@ @interface SiteStorage () - (void)_update; @end -static OFNumber *lengthField, *legacyField; +static OFNumber *lengthField, *legacyField, *keyFileField; @implementation SiteStorage + (void)initialize { lengthField = [@(UINT8_C(0)) retain]; legacyField = [@(UINT8_C(1)) retain]; + keyFileField = [@(UINT8_C(2)) retain]; } -- init +- (instancetype)init { self = [super init]; @try { - void *pool = objc_autoreleasePoolPush(); - OFFileManager *fileManager = [OFFileManager defaultManager]; - OFString *userDataPath = [OFSystemInfo userDataPath]; - - if (![fileManager directoryExistsAtPath: userDataPath]) - [fileManager createDirectoryAtPath: userDataPath]; - - _path = [[userDataPath stringByAppendingPathComponent: - @"sites.msgpack"] retain]; - - @try { - _storage = [[[OFData dataWithContentsOfFile: _path] - messagePackValue] mutableCopy]; - } @catch (id e) { - _storage = [[OFMutableDictionary alloc] init]; - } - - _sites = [[[_storage allKeys] sortedArray] retain]; - - objc_autoreleasePoolPop(pool); + @autoreleasepool { + OFFileManager *fileManager = + OFFileManager.defaultManager; + OFString *userDataPath = OFSystemInfo.userDataPath; + + if (![fileManager directoryExistsAtPath: userDataPath]) + [fileManager + createDirectoryAtPath: userDataPath]; + + _path = [[userDataPath stringByAppendingPathComponent: + @"sites.msgpack"] copy]; + + @try { + _storage = [[OFData dataWithContentsOfFile: + _path].messagePackValue mutableCopy]; + } @catch (id e) { + _storage = [[OFMutableDictionary alloc] init]; + } + + _sites = [_storage.allKeys.sortedArray retain]; + } } @catch (id e) { [self release]; @throw e; } @@ -79,25 +81,29 @@ [super dealloc]; } - (OFArray *)sitesWithFilter: (OFString *)filter { - void *pool = objc_autoreleasePoolPush(); - /* - * FIXME: We need case folding here, but there is no method for it yet. - */ - filter = [filter lowercaseString]; - OFArray *sites = [[[_storage allKeys] sortedArray] - filteredArrayUsingBlock: ^ (id name, size_t index) { - if (filter == nil) - return true; - - return [[name lowercaseString] containsString: filter]; - }]; - - [sites retain]; - objc_autoreleasePoolPop(pool); + OFArray *sites; + + @autoreleasepool { + /* + * FIXME: We need case folding here, but there is no method for + * it yet. + */ + filter = filter.lowercaseString; + sites = [_storage.allKeys.sortedArray + filteredArrayUsingBlock: ^ (OFString *name, size_t index) { + if (filter == nil) + return true; + + return [name.lowercaseString containsString: filter]; + }]; + + [sites retain]; + } + return [sites autorelease]; } - (bool)hasSite: (OFString *)name { @@ -104,41 +110,63 @@ return (_storage[name] != nil); } - (size_t)lengthForSite: (OFString *)name { - OFDictionary *site = _storage[name]; + OFDictionary *site = _storage[name]; if (site == nil) @throw [OFInvalidArgumentException exception]; return [site[lengthField] sizeValue]; } - (bool)isSiteLegacy: (OFString *)name { - OFDictionary *site = _storage[name]; + OFDictionary *site = _storage[name]; if (site == nil) @throw [OFInvalidArgumentException exception]; return [site[legacyField] boolValue]; } + +- (OFString *)keyFileForSite: (OFString *)name +{ + OFDictionary *site = _storage[name]; + OFString *keyFile; + + if (site == nil) + @throw [OFInvalidArgumentException exception]; + + keyFile = site[keyFileField]; + + if ([keyFile isEqual: [OFNull null]]) + return nil; + + return keyFile; +} - (void)setSite: (OFString *)site length: (size_t)length legacy: (bool)legacy -{ - void *pool = objc_autoreleasePoolPush(); - - _storage[site] = @{ - lengthField: @(length), - legacyField: @(legacy) - }; - [self _update]; - - objc_autoreleasePoolPop(pool); + keyFile: (OFString *)keyFile +{ + @autoreleasepool { + OFMutableDictionary *siteDictionary = + [OFMutableDictionary dictionary]; + + siteDictionary[lengthField] = @(length); + siteDictionary[legacyField] = @(legacy); + siteDictionary[keyFileField] = keyFile; + + [siteDictionary makeImmutable]; + + _storage[site] = siteDictionary; + + [self _update]; + } } - (void)removeSite: (OFString *)name { [_storage removeObjectForKey: name]; @@ -145,15 +173,13 @@ [self _update]; } - (void)_update { - void *pool = objc_autoreleasePoolPush(); - - [[_storage messagePackRepresentation] writeToFile: _path]; - - [_sites release]; - _sites = [[[_storage allKeys] sortedArray] retain]; - - objc_autoreleasePoolPop(pool); + @autoreleasepool { + [_storage.messagePackRepresentation writeToFile: _path]; + + [_sites release]; + _sites = [_storage.allKeys.sortedArray retain]; + } } @end