Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -317,10 +317,14 @@ 4B7DD58818943D4A00990FD6 /* socket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B7DD58718943D4A00990FD6 /* socket.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B7FF3B4133CED6200000324 /* OFConditionStillWaitingException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B7FF3B2133CED6100000324 /* OFConditionStillWaitingException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B7FF3B5133CED6200000324 /* OFConditionStillWaitingException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FF3B3133CED6100000324 /* OFConditionStillWaitingException.m */; }; 4B837D7916829C5F007A3E83 /* block.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B837D7716829C5F007A3E83 /* block.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B837D7A16829C5F007A3E83 /* instance.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B837D7816829C5F007A3E83 /* instance.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B8385161951BF9500D5358A /* OFSettings_INIFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B8385121951BF9500D5358A /* OFSettings_INIFile.h */; }; + 4B8385171951BF9500D5358A /* OFSettings_INIFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B8385131951BF9500D5358A /* OFSettings_INIFile.m */; }; + 4B8385181951BF9500D5358A /* OFSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B8385141951BF9500D5358A /* OFSettings.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B8385191951BF9500D5358A /* OFSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B8385151951BF9500D5358A /* OFSettings.m */; }; 4B86E7CB17F8B98200ACA680 /* OFDeflateStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B86E7C917F8B98200ACA680 /* OFDeflateStream.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B86E7CC17F8B98200ACA680 /* OFDeflateStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B86E7CA17F8B98200ACA680 /* OFDeflateStream.m */; }; 4B879A8C177231F000EBCEA4 /* OFDataArray+MessagePackValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B879A89177231F000EBCEA4 /* OFDataArray+MessagePackValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B879A8D177231F000EBCEA4 /* OFDataArray+MessagePackValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B879A8A177231F000EBCEA4 /* OFDataArray+MessagePackValue.m */; }; 4B879A8E177231F000EBCEA4 /* OFMessagePackRepresentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B879A8B177231F000EBCEA4 /* OFMessagePackRepresentation.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -774,10 +778,14 @@ 4B7DD58918944A7900990FD6 /* apple-forwarding-arm64.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; name = "apple-forwarding-arm64.S"; path = "src/forwarding/apple-forwarding-arm64.S"; sourceTree = ""; }; 4B7FF3B2133CED6100000324 /* OFConditionStillWaitingException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFConditionStillWaitingException.h; path = src/exceptions/OFConditionStillWaitingException.h; sourceTree = ""; }; 4B7FF3B3133CED6100000324 /* OFConditionStillWaitingException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFConditionStillWaitingException.m; path = src/exceptions/OFConditionStillWaitingException.m; sourceTree = ""; }; 4B837D7716829C5F007A3E83 /* block.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = block.h; path = src/block.h; sourceTree = ""; }; 4B837D7816829C5F007A3E83 /* instance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = instance.h; path = src/instance.h; sourceTree = ""; }; + 4B8385121951BF9500D5358A /* OFSettings_INIFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSettings_INIFile.h; path = src/OFSettings_INIFile.h; sourceTree = ""; }; + 4B8385131951BF9500D5358A /* OFSettings_INIFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSettings_INIFile.m; path = src/OFSettings_INIFile.m; sourceTree = ""; }; + 4B8385141951BF9500D5358A /* OFSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSettings.h; path = src/OFSettings.h; sourceTree = ""; }; + 4B8385151951BF9500D5358A /* OFSettings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSettings.m; path = src/OFSettings.m; sourceTree = ""; }; 4B86E7C917F8B98200ACA680 /* OFDeflateStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFDeflateStream.h; path = src/OFDeflateStream.h; sourceTree = ""; }; 4B86E7CA17F8B98200ACA680 /* OFDeflateStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDeflateStream.m; path = src/OFDeflateStream.m; sourceTree = ""; }; 4B879A89177231F000EBCEA4 /* OFDataArray+MessagePackValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFDataArray+MessagePackValue.h"; path = "src/OFDataArray+MessagePackValue.h"; sourceTree = ""; }; 4B879A8A177231F000EBCEA4 /* OFDataArray+MessagePackValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OFDataArray+MessagePackValue.m"; path = "src/OFDataArray+MessagePackValue.m"; sourceTree = ""; }; 4B879A8B177231F000EBCEA4 /* OFMessagePackRepresentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMessagePackRepresentation.h; path = src/OFMessagePackRepresentation.h; sourceTree = ""; }; @@ -1300,10 +1308,14 @@ 4B989C2E13771A3700109A30 /* OFSerialization.h */, 4B39844013D3A24600E6F825 /* OFSet.h */, 4B39844113D3A24600E6F825 /* OFSet.m */, 4BA85BC8140ECCE800E91D51 /* OFSet_hashtable.h */, 4BA85BC9140ECCE800E91D51 /* OFSet_hashtable.m */, + 4B8385141951BF9500D5358A /* OFSettings.h */, + 4B8385151951BF9500D5358A /* OFSettings.m */, + 4B8385121951BF9500D5358A /* OFSettings_INIFile.h */, + 4B8385131951BF9500D5358A /* OFSettings_INIFile.m */, 4BF1BCC411C9663F0025511F /* OFSHA1Hash.h */, 4BF1BCC511C9663F0025511F /* OFSHA1Hash.m */, 4B141BA215FCDF74000C21A8 /* OFSortedList.h */, 4B141BA315FCDF74000C21A8 /* OFSortedList.m */, 4B0256E2172B60400062B5F1 /* OFStdIOStream.h */, @@ -1566,10 +1578,11 @@ 4B674405163C395900EB1E59 /* OFRecursiveMutex.h in Headers */, 4B325EDD1605F3A0007836CA /* OFRunLoop.h in Headers */, 4B3D23D31337FCB000DD29B8 /* OFSeekableStream.h in Headers */, 4B989C2F13771A3700109A30 /* OFSerialization.h in Headers */, 4B39844213D3A24600E6F825 /* OFSet.h in Headers */, + 4B8385181951BF9500D5358A /* OFSettings.h in Headers */, 4B3D23D41337FCB000DD29B8 /* OFSHA1Hash.h in Headers */, 4B141BA415FCDF74000C21A8 /* OFSortedList.h in Headers */, 4B0256E4172B60400062B5F1 /* OFStdIOStream.h in Headers */, 4B3D23D51337FCB000DD29B8 /* OFStream.h in Headers */, 4B3D23D71337FCB000DD29B8 /* OFStreamSocket.h in Headers */, @@ -1684,10 +1697,11 @@ 4B2B3E83140D430500EC2F7C /* OFMutableDictionary_hashtable.h in Headers */, 4BA85BCC140ECCE800E91D51 /* OFMutableSet_hashtable.h in Headers */, 4B552552147AA5DB0003BF47 /* OFMutableString_UTF8.h in Headers */, 4B6C8AD817BD5C2E00B194F2 /* OFRunLoop+Private.h in Headers */, 4BA85BCE140ECCE800E91D51 /* OFSet_hashtable.h in Headers */, + 4B8385161951BF9500D5358A /* OFSettings_INIFile.h in Headers */, 4B6C8AD917BD5C2E00B194F2 /* OFStream+Private.h in Headers */, 4B552554147AA5DB0003BF47 /* OFString_UTF8.h in Headers */, 4B6C8ADB17BD5C2E00B194F2 /* OFString_UTF8+Private.h in Headers */, 4BD653C5143B8489006182F0 /* OFTCPSocket+SOCKS5.h in Headers */, 4B6C8ADC17BD5C2E00B194F2 /* OFThread+Private.h in Headers */, @@ -1944,10 +1958,12 @@ 4B674406163C395900EB1E59 /* OFRecursiveMutex.m in Sources */, 4B325EDE1605F3A0007836CA /* OFRunLoop.m in Sources */, 4B3D23A11337FC0D00DD29B8 /* OFSeekableStream.m in Sources */, 4B39844313D3A24600E6F825 /* OFSet.m in Sources */, 4BA85BCF140ECCE800E91D51 /* OFSet_hashtable.m in Sources */, + 4B8385191951BF9500D5358A /* OFSettings.m in Sources */, + 4B8385171951BF9500D5358A /* OFSettings_INIFile.m in Sources */, 4B3D23A21337FC0D00DD29B8 /* OFSHA1Hash.m in Sources */, 4B141BA515FCDF74000C21A8 /* OFSortedList.m in Sources */, 4B0256E5172B60400062B5F1 /* OFStdIOStream.m in Sources */, 4B3D23A31337FC0D00DD29B8 /* OFStream.m in Sources */, 4B3D23A51337FC0D00DD29B8 /* OFStreamSocket.m in Sources */, Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -77,10 +77,11 @@ ${USE_SRCS_SOCKETS} \ ${USE_SRCS_THREADS} SRCS_FILES = OFFile.m \ OFINICategory.m \ OFINIFile.m \ + OFSettings.m \ OFZIPArchive.m \ OFZIPArchiveEntry.m SRCS_PLUGINS = OFPlugin.m SRCS_SOCKETS = OFHTTPClient.m \ OFHTTPRequest.m \ @@ -131,10 +132,11 @@ codepage_437.m \ ${FOUNDATION_COMPAT_M} \ ${INSTANCE_M} \ iso_8859_15.m \ windows_1252.m +SRCS_FILES += OFSettings_INIFile.m SRCS_SOCKETS += ${OFKERNELEVENTOBSERVER_KQUEUE_M} \ ${OFKERNELEVENTOBSERVER_POLL_M} \ ${OFKERNELEVENTOBSERVER_SELECT_M} \ OFTCPSocket+SOCKS5.m Index: src/OFINICategory.m ================================================================== --- src/OFINICategory.m +++ src/OFINICategory.m @@ -428,10 +428,13 @@ pairs = [OFMutableArray arrayWithCapacity: [array count]]; while ((object = [enumerator nextObject]) != nil) { OFINICategory_Pair *pair; + if (![object isKindOfClass: [OFString class]]) + @throw [OFInvalidArgumentException exception]; + pair = [[[OFINICategory_Pair alloc] init] autorelease]; pair->_key = [key copy]; pair->_value = [object copy]; [pairs addObject: pair]; ADDED src/OFSettings.h Index: src/OFSettings.h ================================================================== --- src/OFSettings.h +++ src/OFSettings.h @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFObject.h" + +@class OFString; +@class OFArray; + +/*! + * @class OFSettings OFSettings.h ObjFW/OFSettings.h + * + * Paths are delimited by dots, for example `category.subcategory.key`. + * + * @note The behaviour when accessing a path with a different type than it has + * been accessed with before is undefined! If you want to change the type + * for a path, remove it and then set it with the new type. + * + * @brief A class for storing and retrieving settings + */ +@interface OFSettings: OFObject +{ + OFString *_applicationName; +} + +#ifdef OF_HAVE_PROPERTIES +@property (readonly, copy) OFString *applicationName; +#endif + +/*! + * @brief Create a new OFSettings instance for the application with the + * specified name. + * + * @param applicationName The name of the application whose settings should be + * accessed + * @return A new, autoreleased OFSettings instance + */ ++ (instancetype)settingsWithApplicationName: (OFString*)applicationName; + +/*! + * @brief Initializes an already allocated OFSettings instance with the + * specified application name. + * + * @param applicationName The name of the application whose settings should be + * accessed + * @return An initialized OFSettings instance + */ +- initWithApplicationName: (OFString*)applicationName; + +/*! + * @brief Returns the name of the application whose settings are accessed by + * the instance + * + * @return The name of the application whose settings are accessed by the + * instance + */ +- (OFString*)applicationName; + +/*! + * @brief Sets the specified path to the specified string. + * + * @param string The string to set + * @param path The path to store the string at + */ +- (void)setString: (OFString*)string + forPath: (OFString*)path; + +/*! + * @brief Sets the specified path to the specified integer. + * + * @param integer The integer to set + * @param path The path to store the integer at + */ +- (void)setInteger: (intmax_t)integer + forPath: (OFString*)path; + +/*! + * @brief Sets the specified path to the specified bool. + * + * @param bool_ The bool to set + * @param path The path to store the bool at + */ +- (void)setBool: (bool)bool_ + forPath: (OFString*)path; + +/*! + * @brief Sets the specified path to the specified float. + * + * @param float_ The float to set + * @param path The path to store the float at + */ +- (void)setFloat: (float)float_ + forPath: (OFString*)path; + +/*! + * @brief Sets the specified path to the specified double. + * + * @param double_ The double to set + * @param path The path to store the double at + */ +- (void)setDouble: (double)double_ + forPath: (OFString*)path; + +/*! + * @brief Sets the specified path to the specified array of strings. + * + * @param array The array of strings to set + * @param path The path to store the array of strings at + */ +- (void)setArray: (OFArray*)array + forPath: (OFString*)path; + +/*! + * @brief Returns the string for the specified path, or nil if the path does + * not exist. + * + * @param path The path for which the string value should be returned + * @return The string value of the specified path + */ +- (OFString*)stringForPath: (OFString*)path; + +/*! + * @brief Returns the string for the specified path, or the default value if + * the path does not exist. + * + * @param path The path for which the string value should be returned + * @param defaultValue The default value to return if the path does not exist + * @return The string value of the specified path + */ +- (OFString*)stringForPath: (OFString*)path + defaultValue: (OFString*)defaultValue; + +/*! + * @brief Returns the integer for the specified path, or the default value if + * the path does not exist. + * + * @param path The path for which the integer value should be returned + * @param defaultValue The default value to return if the path does not exist + * @return The integer value of the specified path + */ +- (intmax_t)integerForPath: (OFString*)path + defaultValue: (intmax_t)defaultValue; + +/*! + * @brief Returns the bool for the specified path, or the default value if the + * path does not exist. + * + * @param path The path for which the bool value should be returned + * @param defaultValue The default value to return if the path does not exist + * @return The bool value of the specified path + */ +- (bool)boolForPath: (OFString*)path + defaultValue: (bool)defaultValue; + +/*! + * @brief Returns the float for the specified path, or the default value if the + * path does not exist. + * + * @param path The path for which the float value should be returned + * @param defaultValue The default value to return if the path does not exist + * @return The float value of the specified path + */ +- (float)floatForPath: (OFString*)path + defaultValue: (float)defaultValue; + +/*! + * @brief Returns the double for the specified path, or the default value if + * the path does not exist. + * + * @param path The path for which the double value should be returned + * @param defaultValue The default value to return if the path does not exist + * @return The double value of the specified path + */ +- (double)doubleForPath: (OFString*)path + defaultValue: (double)defaultValue; + +/*! + * @brief Returns the array of strings for the specified path, or an empty + * array if the path does not exist. + * + * @param path The path for which the array of strings should be returned + * @return The array of strings of the specified path + */ +- (OFArray*)arrayForPath: (OFString*)path; + +/*! + * @brief Removes the value for the specified path. + * + * @param path The path for which the value should be removed + */ +- (void)removeValueForPath: (OFString*)path; + +/*! + * @brief Saves the settings to disk. + * + * @warning Some backends might save the settings instantly, others might not + * save them before calling this method for performance reasons. You + * should always call this method after doing a bunch of changes, no + * matter which backend is used! + */ +- (void)save; +@end ADDED src/OFSettings.m Index: src/OFSettings.m ================================================================== --- src/OFSettings.m +++ src/OFSettings.m @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFSettings.h" +#import "OFSettings_INIFile.h" +#import "OFString.h" + +#import "autorelease.h" +#import "macros.h" + +@implementation OFSettings ++ alloc +{ + if (self == [OFSettings class]) + return [OFSettings_INIFile alloc]; + + return [super alloc]; +} + ++ (instancetype)settingsWithApplicationName: (OFString*)applicationName +{ + return [[[self alloc] + initWithApplicationName: applicationName] autorelease]; +} + +- init +{ + OF_INVALID_INIT_METHOD +} + +- initWithApplicationName: (OFString*)applicationName +{ + self = [super init]; + + @try { + _applicationName = [applicationName copy]; + } @catch (id e) { + @throw e; + [self release]; + } + + return self; +} + +- (void)dealloc +{ + [_applicationName release]; + + [super dealloc]; +} + +- (OFString*)applicationName +{ + OF_GETTER(_applicationName, true) +} + +- (void)setString: (OFString*)string + forPath: (OFString*)path +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (void)setInteger: (intmax_t)integer + forPath: (OFString*)path +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (void)setBool: (bool)bool_ + forPath: (OFString*)path +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (void)setFloat: (float)float_ + forPath: (OFString*)path +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (void)setDouble: (double)double_ + forPath: (OFString*)path +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (void)setArray: (OFArray*)array + forPath: (OFString*)path +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (OFString*)stringForPath: (OFString*)path +{ + return [self stringForPath: path + defaultValue: nil]; +} + +- (OFString*)stringForPath: (OFString*)path + defaultValue: (OFString*)defaultValue +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (intmax_t)integerForPath: (OFString*)path + defaultValue: (intmax_t)defaultValue +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (bool)boolForPath: (OFString*)path + defaultValue: (bool)defaultValue +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (float)floatForPath: (OFString*)path + defaultValue: (float)defaultValue +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (double)doubleForPath: (OFString*)path + defaultValue: (double)defaultValue +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (OFArray*)arrayForPath: (OFString*)path +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (void)removeValueForPath: (OFString*)path +{ + OF_UNRECOGNIZED_SELECTOR +} + +- (void)save +{ + OF_UNRECOGNIZED_SELECTOR +} +@end ADDED src/OFSettings_INIFile.h Index: src/OFSettings_INIFile.h ================================================================== --- src/OFSettings_INIFile.h +++ src/OFSettings_INIFile.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFSettings.h" + +@class OFString; +@class OFINIFile; + +@interface OFSettings_INIFile: OFSettings +{ + OFString *_filePath; + OFINIFile *_INIFile; +} +@end ADDED src/OFSettings_INIFile.m Index: src/OFSettings_INIFile.m ================================================================== --- src/OFSettings_INIFile.m +++ src/OFSettings_INIFile.m @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFSettings_INIFile.h" +#import "OFString.h" +#import "OFINIFile.h" +#import "OFSystemInfo.h" + +#import "autorelease.h" +#import "macros.h" + +@implementation OFSettings_INIFile +- initWithApplicationName: (OFString*)applicationName +{ + self = [super initWithApplicationName: applicationName]; + + @try { + void *pool = objc_autoreleasePoolPush(); + OFString *fileName; + + fileName = [applicationName stringByAppendingString: @".ini"]; + _filePath = [[[OFSystemInfo userConfigPath] + stringByAppendingPathComponent: fileName] copy]; + _INIFile = [[OFINIFile alloc] initWithPath: _filePath]; + + objc_autoreleasePoolPop(pool); + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_filePath release]; + [_INIFile release]; + + [super dealloc]; +} + +- (void)OF_getCategory: (OFString**)category + andKey: (OFString**)key + forPath: (OFString*)path +{ + size_t pos = [path rangeOfString: @"." + options: OF_STRING_SEARCH_BACKWARDS].location; + + if (pos == OF_NOT_FOUND) { + *category = @""; + *key = path; + return; + } + + *category = [path substringWithRange: of_range(0, pos)]; + *key = [path substringWithRange: + of_range(pos + 1, [path length] - pos - 1)]; +} + +- (void)setString: (OFString*)string + forPath: (OFString*)path +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + [[_INIFile categoryForName: category] setString: string + forKey: key]; + + objc_autoreleasePoolPop(pool); +} + +- (void)setInteger: (intmax_t)integer + forPath: (OFString*)path +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + [[_INIFile categoryForName: category] setInteger: integer + forKey: key]; + + objc_autoreleasePoolPop(pool); +} + +- (void)setBool: (bool)bool_ + forPath: (OFString*)path +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + [[_INIFile categoryForName: category] setBool: bool_ + forKey: key]; + + objc_autoreleasePoolPop(pool); +} + +- (void)setFloat: (float)float_ + forPath: (OFString*)path +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + [[_INIFile categoryForName: category] setFloat: float_ + forKey: key]; + + objc_autoreleasePoolPop(pool); +} + +- (void)setDouble: (double)double_ + forPath: (OFString*)path +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + [[_INIFile categoryForName: category] setDouble: double_ + forKey: key]; + + objc_autoreleasePoolPop(pool); +} + +- (void)setArray: (OFArray*)array + forPath: (OFString*)path +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + [[_INIFile categoryForName: category] setArray: array + forKey: key]; + + objc_autoreleasePoolPop(pool); +} + +- (OFString*)stringForPath: (OFString*)path + defaultValue: (OFString*)defaultValue +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key, *ret; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + ret = [[_INIFile categoryForName: category] stringForKey: key + defaultValue: defaultValue]; + + [ret retain]; + objc_autoreleasePoolPop(pool); + return [ret autorelease]; +} + +- (intmax_t)integerForPath: (OFString*)path + defaultValue: (intmax_t)defaultValue +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + intmax_t ret; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + ret = [[_INIFile categoryForName: category] + integerForKey: key + defaultValue: defaultValue]; + + objc_autoreleasePoolPop(pool); + + return ret; +} + +- (bool)boolForPath: (OFString*)path + defaultValue: (bool)defaultValue +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + bool ret; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + ret = [[_INIFile categoryForName: category] boolForKey: key + defaultValue: defaultValue]; + + objc_autoreleasePoolPop(pool); + + return ret; +} + +- (float)floatForPath: (OFString*)path + defaultValue: (float)defaultValue +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + float ret; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + ret = [[_INIFile categoryForName: category] floatForKey: key + defaultValue: defaultValue]; + + objc_autoreleasePoolPop(pool); + + return ret; +} + +- (double)doubleForPath: (OFString*)path + defaultValue: (double)defaultValue +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + double ret; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + ret = [[_INIFile categoryForName: category] doubleForKey: key + defaultValue: defaultValue]; + + objc_autoreleasePoolPop(pool); + + return ret; +} + +- (OFArray*)arrayForPath: (OFString*)path +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + OFArray *ret; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + ret = [[_INIFile categoryForName: category] arrayForKey: key]; + + [ret retain]; + objc_autoreleasePoolPop(pool); + return [ret autorelease]; +} + +- (void)removeValueForPath: (OFString*)path +{ + void *pool = objc_autoreleasePoolPush(); + OFString *category, *key; + + [self OF_getCategory: &category + andKey: &key + forPath: path]; + + [[_INIFile categoryForName: category] removeValueForKey: key]; + + objc_autoreleasePoolPop(pool); +} + +- (void)save +{ + [_INIFile writeToFile: _filePath]; +} +@end Index: src/OFString+URLEncoding.m ================================================================== --- src/OFString+URLEncoding.m +++ src/OFString+URLEncoding.m @@ -96,11 +96,11 @@ else retCString[i++] = *string; break; case 1: case 2:; - uint8_t shift = (state == 1 ? 4 : 0); + uint8_t shift = (state == 1 ? 4 : 0); if (*string >= '0' && *string <= '9') byte += (*string - '0') << shift; else if (*string >= 'A' && *string <= 'F') byte += (*string - 'A' + 10) << shift; Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -48,10 +48,11 @@ #import "OFStdIOStream.h" #import "OFDeflateStream.h" #ifdef OF_HAVE_FILES # import "OFFile.h" # import "OFINIFile.h" +# import "OFSettings.h" # import "OFZIPArchive.h" # import "OFZIPArchiveEntry.h" #endif #ifdef OF_HAVE_SOCKETS # import "OFStreamSocket.h"