2001-12-17 14:31:42 +00:00
|
|
|
/** NSHashTable implementation for GNUStep.
|
2002-01-30 13:05:35 +00:00
|
|
|
* Copyright (C) 1994, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
|
1996-02-13 02:31:48 +00:00
|
|
|
*
|
|
|
|
* Author: Albin L. Jones <Albin.L.Jones@Dartmouth.EDU>
|
|
|
|
* Created: Mon Dec 12 23:54:09 EST 1994
|
1996-03-22 00:36:13 +00:00
|
|
|
* Updated: Mon Mar 11 01:48:31 EST 1996
|
|
|
|
* Serial: 96.03.11.06
|
2002-01-30 13:05:35 +00:00
|
|
|
* Rewrite by: Richard Frith-Macdonald <rfm@gnu.org>
|
1996-02-13 02:31:48 +00:00
|
|
|
*
|
1996-05-12 00:56:10 +00:00
|
|
|
* This file is part of the GNUstep Base Library.
|
1996-02-13 02:31:48 +00:00
|
|
|
*
|
|
|
|
* 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
|
2001-12-18 16:54:15 +00:00
|
|
|
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
2002-01-30 13:05:35 +00:00
|
|
|
*
|
|
|
|
* <title>NSHashTable class reference</title>
|
|
|
|
* $Date$ $Revision$
|
2001-12-18 16:54:15 +00:00
|
|
|
*/
|
1996-02-13 02:31:48 +00:00
|
|
|
|
|
|
|
/**** Included Headers *******************************************************/
|
|
|
|
|
1997-11-06 00:51:23 +00:00
|
|
|
#include <config.h>
|
1996-03-22 00:36:13 +00:00
|
|
|
#include <Foundation/NSZone.h>
|
1996-02-13 02:31:48 +00:00
|
|
|
#include <Foundation/NSString.h>
|
|
|
|
#include <Foundation/NSArray.h>
|
|
|
|
#include <Foundation/NSException.h>
|
|
|
|
#include <Foundation/NSHashTable.h>
|
2002-01-31 19:31:15 +00:00
|
|
|
#include <Foundation/NSDebug.h>
|
1996-03-22 00:36:13 +00:00
|
|
|
#include "NSCallBacks.h"
|
1996-02-13 02:31:48 +00:00
|
|
|
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/*
|
|
|
|
* The 'Fastmap' stuff provides an inline implementation of a hash
|
|
|
|
* table - for maximum performance.
|
|
|
|
*/
|
|
|
|
#define GSI_MAP_HAS_VALUE 0
|
|
|
|
#define GSI_MAP_EXTRA NSHashTableCallBacks
|
|
|
|
#define GSI_MAP_KTYPES GSUNION_PTR
|
|
|
|
#define GSI_MAP_HASH(M, X)\
|
|
|
|
(M->extra.hash)((NSHashTable*)M, X.ptr)
|
|
|
|
#define GSI_MAP_EQUAL(M, X, Y)\
|
|
|
|
(M->extra.isEqual)((NSHashTable*)M, X.ptr, Y.ptr)
|
|
|
|
#define GSI_MAP_RELEASE_KEY(M, X)\
|
|
|
|
(M->extra.release)((NSHashTable*)M, X.ptr)
|
|
|
|
#define GSI_MAP_RETAIN_KEY(M, X)\
|
|
|
|
(M->extra.retain)((NSHashTable*)M, X.ptr)
|
|
|
|
#define GSI_MAP_ENUMERATOR NSHashEnumerator
|
|
|
|
|
|
|
|
#include <base/GSIMap.h>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an array of all the objects in the table.
|
|
|
|
* NB. The table <em>must</em> contain objects, not pointers or integers.
|
|
|
|
*/
|
|
|
|
NSArray *
|
|
|
|
NSAllHashTableObjects(NSHashTable *table)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-30 13:05:35 +00:00
|
|
|
NSMutableArray *array;
|
|
|
|
NSHashEnumerator enumerator;
|
|
|
|
id element;
|
1996-03-22 00:36:13 +00:00
|
|
|
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul table argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
array = [NSMutableArray arrayWithCapacity: NSCountHashTable(table)];
|
1996-02-13 02:31:48 +00:00
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/* Get an enumerator for TABLE. */
|
|
|
|
enumerator = NSEnumerateHashTable(table);
|
1996-02-13 02:31:48 +00:00
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
while ((element = NSNextHashEnumeratorItem(&enumerator)) != 0)
|
|
|
|
{
|
|
|
|
[array addObject: element];
|
|
|
|
}
|
|
|
|
return array;
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Compares the two hash tables for equality.
|
|
|
|
* If the tables are different sizes, returns NO.
|
|
|
|
* Otherwise, compares the values in the two tables
|
|
|
|
* and returns NO if they differ.<br />
|
|
|
|
* The GNUstep implementation enumerates the values in table1
|
|
|
|
* and uses the hash and isEqual functions of table2 for comparison.
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
NSCompareHashTables(NSHashTable *table1, NSHashTable *table2)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-30 13:05:35 +00:00
|
|
|
GSIMapTable t1 = (GSIMapTable)table1;
|
|
|
|
GSIMapTable t2 = (GSIMapTable)table2;
|
1996-02-13 02:31:48 +00:00
|
|
|
|
2002-01-31 19:31:15 +00:00
|
|
|
if (t1 == t2)
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
if (t1 == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul first argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
if (t2 == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul second argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
if (t1->nodeCount != t2->nodeCount)
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-05-28 05:23:36 +00:00
|
|
|
NSHashEnumerator enumerator = GSIMapEnumeratorForMap((GSIMapTable)t1);
|
|
|
|
GSIMapNode n;
|
|
|
|
while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0)
|
|
|
|
{
|
2002-01-30 13:05:35 +00:00
|
|
|
if (GSIMapNodeForKey(t2, n->key) == 0)
|
|
|
|
{
|
2002-05-28 11:30:15 +00:00
|
|
|
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
|
2002-01-30 13:05:35 +00:00
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
}
|
2002-05-28 11:30:15 +00:00
|
|
|
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
|
2002-01-30 13:05:35 +00:00
|
|
|
return YES;
|
|
|
|
}
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Copy the supplied map table creating the new table in the specified zone.
|
|
|
|
*/
|
|
|
|
NSHashTable *
|
|
|
|
NSCopyHashTableWithZone(NSHashTable *table, NSZone *zone)
|
1996-03-22 00:36:13 +00:00
|
|
|
{
|
2002-01-30 13:05:35 +00:00
|
|
|
GSIMapTable t;
|
|
|
|
GSIMapNode n;
|
2002-05-28 05:23:36 +00:00
|
|
|
NSHashEnumerator enumerator;
|
|
|
|
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul table argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
t = (GSIMapTable)NSZoneMalloc(zone, sizeof(GSIMapTable_t));
|
|
|
|
GSIMapInitWithZoneAndCapacity(t, zone, ((GSIMapTable)table)->nodeCount);
|
|
|
|
t->extra = ((GSIMapTable)table)->extra;
|
2002-05-28 05:23:36 +00:00
|
|
|
enumerator = GSIMapEnumeratorForMap((GSIMapTable)table);
|
|
|
|
while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0)
|
2002-01-30 13:05:35 +00:00
|
|
|
{
|
|
|
|
GSIMapAddKey(t, n->key);
|
|
|
|
}
|
2002-05-28 11:30:15 +00:00
|
|
|
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
|
2002-01-30 13:05:35 +00:00
|
|
|
|
|
|
|
return (NSHashTable*)t;
|
1996-03-22 00:36:13 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Returns the number of objects in the table.
|
|
|
|
*/
|
|
|
|
unsigned int
|
|
|
|
NSCountHashTable(NSHashTable *table)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul table argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2002-01-30 13:05:35 +00:00
|
|
|
return ((GSIMapTable)table)->nodeCount;
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Create a new hash table by calling NSCreateHashTableWithZone() using
|
|
|
|
* NSDefaultMallocZone().
|
|
|
|
*/
|
1996-02-13 02:31:48 +00:00
|
|
|
NSHashTable *
|
2002-01-30 13:05:35 +00:00
|
|
|
NSCreateHashTable(
|
|
|
|
NSHashTableCallBacks callBacks,
|
|
|
|
unsigned int capacity)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
1997-01-06 21:35:01 +00:00
|
|
|
return NSCreateHashTableWithZone(callBacks, capacity, NSDefaultMallocZone());
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Create a new hash table using the supplied callbacks structure.
|
|
|
|
* If any functions in the callback structure is null the default
|
|
|
|
* values are used ... as for non-owned pointers.
|
|
|
|
* The table will be created with the specified capacity ... ie ready
|
|
|
|
* to hold at lest that many items.
|
|
|
|
*/
|
1996-02-13 02:31:48 +00:00
|
|
|
NSHashTable *
|
2002-01-30 13:05:35 +00:00
|
|
|
NSCreateHashTableWithZone(
|
|
|
|
NSHashTableCallBacks callBacks,
|
|
|
|
unsigned int capacity,
|
|
|
|
NSZone *zone)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-30 13:05:35 +00:00
|
|
|
GSIMapTable table;
|
|
|
|
|
|
|
|
table = (GSIMapTable)NSZoneMalloc(zone, sizeof(GSIMapTable_t));
|
|
|
|
GSIMapInitWithZoneAndCapacity(table, zone, capacity);
|
|
|
|
table->extra = callBacks;
|
|
|
|
|
|
|
|
if (table->extra.hash == 0)
|
|
|
|
table->extra.hash = NSNonOwnedPointerHashCallBacks.hash;
|
|
|
|
if (table->extra.isEqual == 0)
|
|
|
|
table->extra.isEqual = NSNonOwnedPointerHashCallBacks.isEqual;
|
|
|
|
if (table->extra.retain == 0)
|
|
|
|
table->extra.retain = NSNonOwnedPointerHashCallBacks.retain;
|
|
|
|
if (table->extra.release == 0)
|
|
|
|
table->extra.release = NSNonOwnedPointerHashCallBacks.release;
|
|
|
|
if (table->extra.describe == 0)
|
|
|
|
table->extra.describe = NSNonOwnedPointerHashCallBacks.describe;
|
|
|
|
|
|
|
|
return (NSHashTable*)table;
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Function to be called when finished with the enumerator.
|
2002-05-28 05:23:36 +00:00
|
|
|
* This permits memory used by the enumerator to be released.
|
2002-01-30 13:05:35 +00:00
|
|
|
*/
|
1996-02-13 02:31:48 +00:00
|
|
|
void
|
2002-01-30 13:05:35 +00:00
|
|
|
NSEndHashTableEnumeration(NSHashEnumerator *enumerator)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-31 19:31:15 +00:00
|
|
|
if (enumerator == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul enumerator argument supplied");
|
2002-05-28 05:23:36 +00:00
|
|
|
return;
|
2002-01-31 19:31:15 +00:00
|
|
|
}
|
2002-05-28 11:30:15 +00:00
|
|
|
GSIMapEndEnumerator((GSIMapEnumerator)enumerator);
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Return an enumerator for stepping through a map table using the
|
|
|
|
* NSNextHashEnumeratorPair() function.
|
|
|
|
*/
|
|
|
|
NSHashEnumerator
|
|
|
|
NSEnumerateHashTable(NSHashTable *table)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
2002-05-28 05:23:36 +00:00
|
|
|
NSHashEnumerator v = { 0, 0, 0 };
|
2002-01-31 19:31:15 +00:00
|
|
|
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul table argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return GSIMapEnumeratorForMap((GSIMapTable)table);
|
|
|
|
}
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Destroy the hash table and relase its contents.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
NSFreeHashTable(NSHashTable *table)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul table argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NSZone *z = ((GSIMapTable)table)->zone;
|
1996-02-13 02:31:48 +00:00
|
|
|
|
2002-01-31 19:31:15 +00:00
|
|
|
GSIMapEmptyMap((GSIMapTable)table);
|
|
|
|
NSZoneFree(z, table);
|
|
|
|
}
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Returns the value for the specified element, or a nul pointer if the
|
|
|
|
* element is not found in the table.
|
|
|
|
*/
|
1996-02-13 02:31:48 +00:00
|
|
|
void *
|
2002-01-30 13:05:35 +00:00
|
|
|
NSHashGet(NSHashTable *table, const void *element)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-31 19:31:15 +00:00
|
|
|
GSIMapNode n;
|
1996-02-13 02:31:48 +00:00
|
|
|
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul table argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
n = GSIMapNodeForKey((GSIMapTable)table, (GSIMapKey)element);
|
2002-01-30 13:05:35 +00:00
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return n->key.ptr;
|
|
|
|
}
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Adds the element to table.<br />
|
|
|
|
* If an equal element is already in table, replaces it with the new one.<br />
|
|
|
|
* If element is nul raises an NSInvalidArgumentException.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
NSHashInsert(NSHashTable *table, const void *element)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-30 13:05:35 +00:00
|
|
|
GSIMapTable t = (GSIMapTable)table;
|
2002-03-08 07:11:10 +00:00
|
|
|
GSIMapNode n;
|
2002-01-30 13:05:35 +00:00
|
|
|
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"Attempt to place value in nul hash table"];
|
|
|
|
}
|
2002-01-30 13:05:35 +00:00
|
|
|
if (element == 0)
|
|
|
|
{
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"Attempt to place nul in hash table"];
|
|
|
|
}
|
2002-03-08 07:11:10 +00:00
|
|
|
n = GSIMapNodeForKey(t, (GSIMapKey)element);
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
GSIMapAddKey(t, (GSIMapKey)element);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSIMapKey tmp = n->key;
|
|
|
|
|
|
|
|
n->key = (GSIMapKey)element;
|
|
|
|
GSI_MAP_RETAIN_KEY(t, n->key);
|
|
|
|
GSI_MAP_RELEASE_KEY(t, tmp);
|
|
|
|
}
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Adds the element to table and returns nul.<br />
|
|
|
|
* If an equal element is already in table, returns the old element
|
|
|
|
* instead of adding the new one.<br />
|
|
|
|
* If element is nul, raises an NSInvalidArgumentException.
|
|
|
|
*/
|
1996-02-13 02:31:48 +00:00
|
|
|
void *
|
2002-01-30 13:05:35 +00:00
|
|
|
NSHashInsertIfAbsent(NSHashTable *table, const void *element)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-30 13:05:35 +00:00
|
|
|
GSIMapTable t = (GSIMapTable)table;
|
|
|
|
GSIMapNode n;
|
|
|
|
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"Attempt to place value in nul hash table"];
|
|
|
|
}
|
2002-01-30 13:05:35 +00:00
|
|
|
if (element == 0)
|
|
|
|
{
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"Attempt to place nul in hash table"];
|
|
|
|
}
|
|
|
|
n = GSIMapNodeForKey(t, (GSIMapKey)element);
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
GSIMapAddKey(t, (GSIMapKey)element);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return n->key.ptr;
|
|
|
|
}
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Adds the element to table and returns nul.<br />
|
|
|
|
* If an equal element is already present, raises NSInvalidArgumentException.
|
|
|
|
* <br />If element is nul raises an NSInvalidArgumentException.
|
|
|
|
*/
|
1996-02-13 02:31:48 +00:00
|
|
|
void
|
2002-01-30 13:05:35 +00:00
|
|
|
NSHashInsertKnownAbsent(NSHashTable *table, const void *element)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-30 13:05:35 +00:00
|
|
|
GSIMapTable t = (GSIMapTable)table;
|
|
|
|
GSIMapNode n;
|
|
|
|
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"Attempt to place value in nul hash table"];
|
|
|
|
}
|
2002-01-30 13:05:35 +00:00
|
|
|
if (element == 0)
|
|
|
|
{
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"Attempt to place nul in hash table"];
|
|
|
|
}
|
|
|
|
n = GSIMapNodeForKey(t, (GSIMapKey)element);
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
GSIMapAddKey(t, (GSIMapKey)element);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"NSHashInsertKnownAbsent ... element not absent"];
|
|
|
|
}
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Remove the specified element from the table.
|
|
|
|
*/
|
1996-02-13 02:31:48 +00:00
|
|
|
void
|
2002-01-30 13:05:35 +00:00
|
|
|
NSHashRemove(NSHashTable *table, const void *element)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul table argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSIMapRemoveKey((GSIMapTable)table, (GSIMapKey)element);
|
|
|
|
}
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Step through the hash table ... return the next item or
|
|
|
|
* return nulif we hit the of the table.
|
|
|
|
*/
|
1996-02-13 02:31:48 +00:00
|
|
|
void *
|
2002-01-30 13:05:35 +00:00
|
|
|
NSNextHashEnumeratorItem(NSHashEnumerator *enumerator)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-02-01 10:00:54 +00:00
|
|
|
GSIMapNode n;
|
2002-01-30 13:05:35 +00:00
|
|
|
|
2002-01-31 19:31:15 +00:00
|
|
|
if (enumerator == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul enumerator argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
n = GSIMapEnumeratorNextNode((GSIMapEnumerator)enumerator);
|
2002-01-30 13:05:35 +00:00
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return n->key.ptr;
|
|
|
|
}
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Empty the hash table, but preserve its capacity.
|
|
|
|
*/
|
1996-02-13 02:31:48 +00:00
|
|
|
void
|
2002-01-30 13:05:35 +00:00
|
|
|
NSResetHashTable(NSHashTable *table)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul table argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSIMapCleanMap((GSIMapTable)table);
|
|
|
|
}
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
|
|
|
|
2002-01-30 13:05:35 +00:00
|
|
|
/**
|
|
|
|
* Returns a string describing the table contents.<br />
|
|
|
|
* For each item, a string of the form "value;\n"
|
|
|
|
* is appended. The appropriate describe function is used to generate
|
|
|
|
* the strings for each item.
|
|
|
|
*/
|
1996-02-13 02:31:48 +00:00
|
|
|
NSString *
|
1996-03-22 00:36:13 +00:00
|
|
|
NSStringFromHashTable(NSHashTable *table)
|
1996-02-13 02:31:48 +00:00
|
|
|
{
|
2002-01-30 13:05:35 +00:00
|
|
|
GSIMapTable t = (GSIMapTable)table;
|
|
|
|
NSMutableString *string;
|
|
|
|
NSHashEnumerator enumerator;
|
|
|
|
const void *element;
|
1996-02-13 02:31:48 +00:00
|
|
|
|
2002-01-31 19:31:15 +00:00
|
|
|
if (table == 0)
|
|
|
|
{
|
2002-02-02 07:40:35 +00:00
|
|
|
NSWarnFLog(@"Nul table argument supplied");
|
2002-01-31 19:31:15 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
1996-02-13 02:31:48 +00:00
|
|
|
/* This will be our string. */
|
2002-01-30 13:05:35 +00:00
|
|
|
string = [NSMutableString stringWithCapacity: 0];
|
1996-02-13 02:31:48 +00:00
|
|
|
|
|
|
|
/* Get an enumerator for TABLE. */
|
|
|
|
enumerator = NSEnumerateHashTable(table);
|
|
|
|
|
|
|
|
/* Iterate over the elements of TABLE, appending the description of
|
|
|
|
* each to the mutable string STRING. */
|
2002-01-30 13:05:35 +00:00
|
|
|
while ((element = NSNextHashEnumeratorItem(&enumerator)) != 0)
|
|
|
|
{
|
|
|
|
[string appendFormat: @"%@;\n", (t->extra.describe)(table, element)];
|
|
|
|
}
|
|
|
|
return string;
|
1996-02-13 02:31:48 +00:00
|
|
|
}
|
2002-01-30 13:05:35 +00:00
|
|
|
|