ObjFW  Artifact [065f154d58]

Artifact 065f154d58eb11c9b1a091ce4d5ea1f864b6b489236576f031c9b43c4ce27574:

  • File src/OFDictionary.m — part of check-in [cbdd534337] at 2009-04-12 14:51:00 on branch trunk — Get rid of the dependency on Object.

    This allows libobjfw to run on ObjC2-only runtimes like the one on the
    iPhone. However, it's still relying on objc_msgSendv for plugins, which
    is unavailable in ObjC2-only runtimes, thus OFPlugins are unavailable
    on the iPhone until I write a replacement for objc_msgSendv. (user: js, size: 2751) [annotate] [blame] [check-ins using]


/*
 * 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.
 */

#import "config.h"

#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