This is Dictionary.m in view mode; [Download] [Up]
/* Implementation for Objective-C Dictionary collection object Copyright (C) 1993 R. Andrew McCallum <mccallum@cs.rochester.edu> Dept. of Computer Science, U. of Rochester, Rochester, NY 14627 This file is part of the GNU Objective-C Collection library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <coll/Dictionary.h> #include <coll/CollectionPrivate.h> #include <objc/objc-api.h> #define DEFAULT_DICTIONARY_CAPACITY 32 @implementation Dictionary + initialize { if (self == [Dictionary class]) [self setVersion:-1]; /* alpha release */ return self; } // MANAGING CAPACITY; /* Eventually we will want to have better capacity management, potentially keep default capacity as a class variable. */ + (unsigned) defaultCapacity { return DEFAULT_DICTIONARY_CAPACITY; } // INITIALIZING; /* This is the designated initializer of this class */ - initDescription: (const char *)contentType keyDescription: (const char *)keyType capacity: (unsigned)aCapacity { compare_func_type key_compare_func; hash_func_type key_hash_func; [super initDescription:contentType keyDescription:keyType]; /* Need to make sure that aCapacity is power of 2 */ /* I don't think this is very portable... Change this switch. */ switch (*_keyDescription) { case _C_CHARPTR: case _C_ATOM: key_compare_func = (compare_func_type)coll_compare_strings; key_hash_func = (hash_func_type)coll_hash_string; break; case _C_ID: case _C_CLASS: /* I can send classes isEqual:? */ key_compare_func = (compare_func_type)coll_compare_objects; key_hash_func = (hash_func_type)coll_hash_object; break; case _C_PTR: case _C_SEL: key_compare_func = (compare_func_type)coll_compare_ptrs; key_hash_func = (hash_func_type)coll_hash_ptr; break; case _C_INT: case _C_UINT: case _C_FLT: /* Yipes */ key_compare_func = (compare_func_type)coll_compare_ints; key_hash_func = (hash_func_type)coll_hash_int; break; case _C_LNG: case _C_ULNG: key_compare_func = (compare_func_type)coll_compare_long_ints; key_hash_func = (hash_func_type)coll_hash_int; break; default : [self error:"Element type (%s) not supported.\n", _keyDescription]; } _contents_hash = hash_new(aCapacity, (hash_func_type)key_hash_func, (compare_func_type)key_compare_func); return self; } /* To make sure that former KeyedCollection init'ers go through Dictionary init, we override the designated initializer for KeyedCollection. */ - initDescription: (const char *)contentType keyDescription: (const char *)keyType { return [self initDescription:contentType keyDescription:keyType capacity:[[self class] defaultCapacity]]; } - initDescription: (const char *)type capacity: (unsigned)aCapacity { return [self initDescription:type keyDescription:"@" capacity:aCapacity]; } - initCapacity: (unsigned)aCapacity { return [self initDescription:"@" capacity:aCapacity]; } - free { hash_delete(_contents_hash); return [super free]; } // ADDING OR REPLACING; - addElement: (elt)anElement { return [self shouldNotImplement:_cmd]; /* or should I make up some default behavior here? Base it on object conforming to <Associating> protocol, perhaps */ } - insertElement: (elt)newContentElement atKey: (elt)aKey { node_ptr node = hash_node_for_key(_contents_hash, aKey.void_ptr_t); if (node) /* Casting constant here. trouble? */ (const void*)node->value = newContentElement.void_ptr_t; else hash_add(&_contents_hash, aKey.void_ptr_t, (void*)newContentElement.char_ptr_t); return; } // REMOVING; - (elt) removeElementAtKey: (elt)aKey { node_ptr node = hash_node_for_key(_contents_hash, aKey.void_ptr_t); elt ret; ret.void_ptr_t = 0; if (node) { ret = node->value; hash_remove(_contents_hash, aKey.void_ptr_t); } return ret; } - (elt) removeElement: (elt)oldElement { elt key = [self keyElementOfElement:oldElement]; return [self removeElementAtKey:key]; } // GETTING ELEMENTS; - (elt) elementAtKey: (elt)aKey { return hash_value_for_key(_contents_hash, aKey.void_ptr_t); } // TESTING; - (BOOL) includesKey: (elt)aKey { if (hash_value_for_key(_contents_hash, aKey.void_ptr_t)) return YES; else return NO; } // ENUMERATIONS; - (BOOL) getNextKey: (elt*)aKeyPtr content: (elt*)anElementPtr withEnumState: (void**)enumState { *enumState = hash_next(_contents_hash, *enumState); if (*enumState) { *aKeyPtr = ((node_ptr)(*enumState))->key; *anElementPtr = ((node_ptr)(*enumState))->value; return YES; } return NO; } - withKeysAndContentsCall: (void(*)(const elt,elt))aFunc whileTrue: (BOOL *)flag { node_ptr node = 0; while (flag && (node = hash_next(_contents_hash, node))) aFunc(node->key, node->value); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.