Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -4,10 +4,11 @@ LIB_MAJOR = 1 LIB_MINOR = 0 SRCS = OFArray.m \ OFAutoreleasePool.m \ + OFDictionary.m \ OFExceptions.m \ OFHashes.m \ OFFile.m \ OFList.m \ OFNumber.m \ ADDED src/OFDictionary.h Index: src/OFDictionary.h ================================================================== --- src/OFDictionary.h +++ src/OFDictionary.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2008 - 2009 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of libobjfw. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE included in + * the packaging of this file. + */ + +#import "OFObject.h" +#import "OFList.h" + +/** + * The OFDictionary class provides a class for using hash tables. + */ +@interface OFDictionary: OFObject +{ + OFList **data; + size_t size; +} + +/** + * Creates a new OFDictionary, defaulting to a 12 bit hash. + * + * \return A new autoreleased OFDictionary + */ ++ dictionary; + +/* + * Creates a new OFDictionary with a hash of N bits. + * + * \param bits The size of the hash to use + * \return A new autoreleased OFDictionary + */ ++ dictionaryWithHashSize: (int)hashsize; + +/** + * Initializes an already allocated OFDictionary, defaulting to a 12 bit hash. + * + * \return An initialized OFDictionary + */ +- init; + +/* + * Initializes an already allocated OFDictionary with a hash of N bits. + * + * \param bits The size of the hash to use + * \return An initialized OFDictionary + */ +- initWithHashSize: (int)hashsize; + +/* + * Sets a key to an object. A key can be any object. + * + * \param key The key to set + * \param obj The object to set the key to + */ +- set: (OFObject*)key + to: (OFObject*)obj; + +/* + * \param key The key whose object should be returned + * \return The object for the given key + */ +- get: (OFObject*)key; + +/* + * Remove the object with the given key from the dictionary. + * + * \param key The key whose object should be removed + */ +- remove: (OFObject*)key; +@end ADDED src/OFDictionary.m Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2008 - 2009 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of libobjfw. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE included in + * the packaging of this file. + */ + +#import "OFDictionary.h" +#import "OFExceptions.h" + +@implementation OFDictionary ++ dictionary; +{ + return [[[OFDictionary alloc] init] autorelease]; +} + ++ dictionaryWithHashSize: (int)hashsize +{ + return [[[OFDictionary alloc] initWithHashSize: hashsize] autorelease]; +} + +- init +{ + if ((self = [super init])) { + size = 4096; + + @try { + data = [self getMemForNItems: size + ofSize: sizeof(OFList*)]; + } @catch (OFException *e) { + [self free]; + @throw e; + } + memset(data, 0, size); + } + + return self; +} + +- initWithHashSize: (int)hashsize +{ + if ((self = [super init])) { + if (hashsize < 8 || hashsize > 31) { + Class c = [self class]; + [self free]; + @throw [OFInvalidArgumentException + newWithClass: c + andSelector: _cmd]; + } + + size = (size_t)1 << hashsize; + + @try { + data = [self getMemForNItems: size + ofSize: sizeof(OFList*)]; + } @catch (OFException *e) { + [self free]; + @throw e; + } + memset(data, 0, size); + } + + return self; +} + +- free +{ + size_t i; + + for (i = 0; i < size; i++) + if (data[i] != nil) + [data[i] release]; + + return [super free]; +} + +- set: (OFObject*)key + to: (OFObject*)obj +{ + uint32_t hash = [key hash] & (size - 1); + of_list_object_t *iter; + + if (data[hash] == nil) + data[hash] = [OFList new]; + + if (data[hash] == nil) + @throw [OFInitializationFailedException + newWithClass: [OFList class]]; + + for (iter = [data[hash] first]; iter != NULL; iter = iter->next->next) { + if ([iter->object isEqual: key]) { + [iter->next->object release]; + [obj retain]; + iter->next->object = obj; + + return self; + } + } + + [data[hash] append: key]; + [data[hash] append: obj]; + + return self; +} + +- get: (OFObject*)key +{ + uint32_t hash = [key hash] & (size - 1); + of_list_object_t *iter; + + if (data[hash] == nil) + return nil; + + for (iter = [data[hash] first]; iter != NULL; iter = iter->next->next) + if ([iter->object isEqual: key]) + return iter->next->object; + + return nil; +} + +- remove: (OFObject*)key +{ + uint32_t hash = [key hash] & (size - 1); + of_list_object_t *iter; + + if (data[hash] == nil) + return self; // FIXME: Throw exception? + + for (iter = [data[hash] first]; iter != NULL; iter = iter->next->next) { + if ([iter->object isEqual: key]) { + [data[hash] remove: iter->next]; + [data[hash] remove: iter]; + + return self; + } + } + + return self; // FIXME: Throw exception? +} + +/* FIXME: Implement this! */ +/* +- (BOOL)isEqual +{ +} +*/ +@end Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -1,10 +1,11 @@ SUBDIRS = OFObject \ OFAutoreleasePool \ OFArray \ + OFDictionary \ OFHashes \ OFString \ OFTCPSocket \ OFList \ OFXMLFactory include ../buildsys.mk ADDED tests/OFDictionary/Makefile Index: tests/OFDictionary/Makefile ================================================================== --- tests/OFDictionary/Makefile +++ tests/OFDictionary/Makefile @@ -0,0 +1,23 @@ +PROG_NOINST = ofdictionary${PROG_SUFFIX} +SRCS = OFDictionary.m + +include ../../buildsys.mk +include ../../extra.mk + +CPPFLAGS += -I../../src -I../.. +LIBS := -L../../src -lobjfw ${LIBS} + +.PHONY: run + +all: run +run: ${PROG_NOINST} + rm -f libobjfw.so.1 libobjfw.so.1.0 libobjfw.dll libobjfw.dylib + ln -s ../../src/libobjfw.so libobjfw.so.1 + ln -s ../../src/libobjfw.so libobjfw.so.1.0 + ln -s ../../src/libobjfw.dll libobjfw.dll + ln -s ../../src/libobjfw.dylib libobjfw.dylib + LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ + DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ + ${TEST_LAUNCHER} ./${PROG_NOINST}; EXIT=$$?; \ + rm -f libobjfw.so.1 libobjfw.so.1.0 libobjfw.dll libobjfw.dylib; \ + exit $$EXIT ADDED tests/OFDictionary/OFDictionary.m Index: tests/OFDictionary/OFDictionary.m ================================================================== --- tests/OFDictionary/OFDictionary.m +++ tests/OFDictionary/OFDictionary.m @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2008 - 2009 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of libobjfw. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE included in + * the packaging of this file. + */ + +#import "config.h" + +#import + +#import "OFAutoreleasePool.h" +#import "OFDictionary.h" +#import "OFString.h" + +int +main() +{ + OFDictionary *dict = [OFDictionary dictionaryWithHashSize: 16]; + + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + OFString *key1 = [OFString stringWithCString: "key1"]; + OFString *key2 = [OFString stringWithCString: "key2"]; + OFString *value1 = [OFString stringWithCString: "value1"]; + OFString *value2 = [OFString stringWithCString: "value2"]; + + [dict set: key1 + to: value1]; + [dict set: key2 + to: value2]; + [pool release]; + + puts([[dict get: key1] cString]); + puts([[dict get: key2] cString]); + + return 0; +}