/* * Copyright (c) 2008 - 2009 * Jonathan Schleifer <js@webkeks.org> * * 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. */ #include <string.h> #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