Overhaul for new collection class scheme to improve distributed

objects and NeXT-compatibility.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@947 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
mccallum 1996-02-22 15:18:57 +00:00
parent 7853b9d1b0
commit f46b4d9b55
16 changed files with 776 additions and 2171 deletions

View file

@ -6,44 +6,35 @@
#include <objects/Archiver.h>
#include <objects/TextCStream.h>
#include <objects/Set.h>
#include <objects/EltNodeCollector.h>
#include <objects/LinkedList.h>
#include <objects/LinkedListEltNode.h>
#include <objects/Array.h>
#include <objects/Dictionary.h>
#include <objects/NSString.h>
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSValue.h>
int main()
{
id set, ll;
id array, dictionary;
id archiver;
id name;
id arp;
int i;
[NSObject enableDoubleReleaseCheck: YES];
arp = [[NSAutoreleasePool alloc] init];
/* Create a Set of int's
and a LinkedList of float's */
set = [[Set alloc] initWithType:@encode(int)];
ll = [[EltNodeCollector alloc] initWithType:@encode(float)
nodeCollector:[[LinkedList alloc] init]
nodeClass:[LinkedListEltNode class]];
/* Create an Array and Dictionary */
array = [Array new];
dictionary = [Dictionary new];
/* Populate the Set and display it */
[set addElement:1234567];
[set addElement:2345678];
[set addElement:3456789];
[set addElement:4567891];
[set addElement:5678912];
[set printForDebugger];
/* Populate the LinkedList and display it */
[ll addElement:1.2f];
[ll addElement:(float)3.4];
[ll addElement:(float)5.6];
[ll addElement:(float)7.8];
[ll addElement:(float)9.0];
[ll printForDebugger];
for (i = 0; i < 6; i++)
{
[array addObject: [NSNumber numberWithInt: i]];
[dictionary putObject: [NSNumber numberWithInt: i]
atKey: [NSNumber numberWithInt: i*i]];
}
[array printForDebugger];
[dictionary printForDebugger];
/* Write them to a file */
@ -52,12 +43,14 @@ int main()
coding. */
archiver = [[Archiver alloc] initForWritingToFile: @"./textcoding.txt"
withCStreamClass: [TextCStream class]];
[archiver encodeObject:set withName:@"Test Set"];
[archiver encodeObject:ll withName:@"Test EltNodeCollector LinkedList"];
[archiver encodeObject: array
withName:@"Test Array"];
[archiver encodeObject: dictionary
withName:@"Test Dictionary"];
/* Release the objects that were coded */
[set release];
[ll release];
[array release];
[dictionary release];
/* Close the archiver, (and thus flush the stream); then release it.
We must separate the idea of "closing" a stream and
@ -72,21 +65,21 @@ int main()
/* First create the unarchiver */
archiver = [Unarchiver newReadingFromFile: @"./textcoding.txt"];
/* Read in the Set */
[archiver decodeObjectAt:&set withName:&name];
/* Read in the Array */
[archiver decodeObjectAt: &array withName: &name];
printf("got object named %@\n", name);
/* Read in the LinkedList */
[archiver decodeObjectAt:&ll withName:&name];
/* Read in the Dictionary */
[archiver decodeObjectAt: &dictionary withName: &name];
printf("got object named %@\n", name);
/* Display what we read, to make sure it matches what we wrote */
[set printForDebugger];
[ll printForDebugger];
[array printForDebugger];
[dictionary printForDebugger];
/* Relase the objects we read */
[set release];
[ll release];
[array release];
[dictionary release];
/* Release the unarchiver. */
[archiver release];

View file

@ -24,13 +24,61 @@
#include <objects/Array.h>
#include <objects/ArrayPrivate.h>
#include <objects/NSString.h>
#include <objects/OrderedCollection.h>
@implementation ConstantArray
/* This is the designated initializer of this class */
- initWithObjects: (id*)objs count: (unsigned)c
{
_count = c;
OBJC_MALLOC(_contents_array, id, _count);
while (c--)
_contents_array[c] = objs[c];
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
Array *copy = [super emptyCopy];
copy->_count = 0;
OBJC_MALLOC(copy->_contents_array, id, copy->_capacity);
return copy;
}
- (void) _collectionDealloc
{
OBJC_FREE(_contents_array);
[super _collectionDealloc];
}
// GETTING ELEMENTS BY INDEX;
- objectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
return _contents_array[index];
}
// TESTING;
- (unsigned) count
{
return _count;
}
@end
@implementation Array
+ (void) initialize
{
if (self == [Array class])
[self setVersion:0]; /* beta release */
class_add_behavior (self, [OrderedCollection class]);
}
// MANAGING CAPACITY;
@ -47,17 +95,14 @@
{
return DEFAULT_ARRAY_GROW_FACTOR;
}
/* This is the designated initializer of this class */
- initWithType: (const char *)contentEncoding
capacity: (unsigned)aCapacity
/* This is the designated initializer for this class */
- initWithCapacity: (unsigned)aCapacity
{
[super initWithType:contentEncoding];
_comparison_function = elt_get_comparison_function(contentEncoding);
_grow_factor = [[self class] defaultGrowFactor];
_count = 0;
_capacity = (aCapacity < 1) ? 1 : aCapacity;
OBJC_MALLOC(_contents_array, elt, _capacity);
OBJC_MALLOC(_contents_array, id, _capacity);
return self;
}
@ -65,12 +110,7 @@
- (void) _encodeCollectionWithCoder: (id <Encoding>)coder
{
const char *encoding = [self contentType];
[super _encodeCollectionWithCoder:coder];
[coder encodeValueOfCType:@encode(char*)
at:&encoding
withName:@"Array Encoding Type"];
[coder encodeValueOfCType:@encode(unsigned)
at:&_grow_factor
withName:@"Array Grow Factor"];
@ -81,12 +121,7 @@
- _initCollectionWithCoder: (id <Decoding>)coder
{
char *encoding;
[super _initCollectionWithCoder:coder];
[coder decodeValueOfCType:@encode(char*)
at:&encoding
withName:NULL];
_comparison_function = elt_get_comparison_function(encoding);
[coder decodeValueOfCType:@encode(unsigned)
at:&_grow_factor
withName:NULL];
@ -94,76 +129,23 @@
[coder decodeValueOfCType:@encode(unsigned)
at:&_capacity
withName:NULL];
OBJC_MALLOC(_contents_array, elt, _capacity);
OBJC_MALLOC(_contents_array, id, _capacity);
return self;
}
- _writeInit: (TypedStream*)aStream
/* Override superclass' designated initializer to call ours */
- initWithObjects: (id*)objs count: (unsigned)c
{
const char *encoding = [self contentType];
[super _writeInit: aStream];
// This implicitly archives the _comparison_function;
objc_write_type(aStream, @encode(char*), &encoding);
objc_write_type(aStream, @encode(unsigned int), &_grow_factor);
objc_write_type(aStream, @encode(unsigned int), &_capacity);
return self;
}
- _readInit: (TypedStream*)aStream
{
char *encoding;
[super _readInit: aStream];
objc_read_type(aStream, @encode(char*), &encoding);
_comparison_function = elt_get_comparison_function(encoding);
objc_read_type(aStream, @encode(unsigned int), &_grow_factor);
_count = 0;
objc_read_type(aStream, @encode(unsigned int), &_capacity);
OBJC_MALLOC(_contents_array, elt, _capacity);
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
Array *copy = [super emptyCopy];
copy->_count = 0;
OBJC_MALLOC(copy->_contents_array, elt, copy->_capacity);
return copy;
int i;
[self initWithCapacity: c];
for (i = 0; i < c; i++)
[self insertObject: objs[i] atIndex:i]; // xxx this most efficient method?
}
/* This must work without sending any messages to content objects */
- _empty
- (void) _empty
{
_count = 0;
return self;
}
- (void) _collectionDealloc
{
OBJC_FREE(_contents_array);
[super _collectionDealloc];
}
- initWithContentsOf: (id <Collecting>)aCollection
{
[self initWithType:[aCollection contentType]
capacity:[aCollection count]];
[self addContentsOf:aCollection];
return self;
}
- initWithCapacity: (unsigned)aCapacity
{
return [self initWithType:@encode(id) capacity:aCapacity];
}
/* Catch designated initializer for IndexedCollection */
- initWithType: (const char *)contentEncoding
{
return [self initWithType:contentEncoding
capacity:[[self class] defaultCapacity]];
}
// MANAGING CAPACITY;
@ -171,13 +153,12 @@
/* This is the only method that changes the value of the instance
variable _capacity, except for "-initDescription:capacity:" */
- setCapacity: (unsigned)newCapacity
- (void) setCapacity: (unsigned)newCapacity
{
if (newCapacity > _count) {
_capacity = newCapacity;
OBJC_REALLOC(_contents_array, elt, _capacity);
OBJC_REALLOC(_contents_array, id, _capacity);
}
return self;
}
- (unsigned) growFactor
@ -185,109 +166,73 @@
return _grow_factor;
}
- setGrowFactor: (unsigned)aNum;
- (void) setGrowFactor: (unsigned)aNum;
{
_grow_factor = aNum;
return self;
}
// ADDING;
- appendElement: (elt)newElement
- (void) appendObject: newObject
{
incrementCount(self);
RETAIN_ELT(newElement);
_contents_array[_count-1] = newElement;
return self;
[newObject retain];
_contents_array[_count-1] = newObject;
}
- prependElement: (elt)newElement
- (void) prependObject: newObject
{
incrementCount(self);
RETAIN_ELT(newElement);
[newObject retain];
makeHoleAt(self, 0);
_contents_array[0] = newElement;
return self;
_contents_array[0] = newObject;
}
- insertElement: (elt)newElement atIndex: (unsigned)index
- (void) insertObject: newObject atIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count+1);
incrementCount(self);
RETAIN_ELT(newElement);
[newObject retain];
makeHoleAt(self, index);
_contents_array[index] = newElement;
return self;
_contents_array[index] = newObject;
}
// REMOVING, REPLACING AND SWAPPING;
- (elt) removeElementAtIndex: (unsigned)index
- (void) removeObjectAtIndex: (unsigned)index
{
elt ret;
CHECK_INDEX_RANGE_ERROR(index, _count);
ret = _contents_array[index];
[_contents_array[index] release];
fillHoleAt(self, index);
decrementCount(self);
return AUTORELEASE_ELT(ret);
}
/* We could be more efficient if we override these also.
- (elt) removeFirstElement
- (elt) removeLastElement; */
- removeFirstObject
- removeLastObject;
If you do, remember, you will have to implement this methods
in GapArray also! */
- (elt) replaceElementAtIndex: (unsigned)index with: (elt)newElement
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
{
elt ret;
CHECK_INDEX_RANGE_ERROR(index, _count);
RETAIN_ELT(newElement);
ret = _contents_array[index];
_contents_array[index] = newElement;
return AUTORELEASE_ELT(ret);
[newObject retain];
[_contents_array[index] release];
_contents_array[index] = newObject;
}
- swapAtIndeces: (unsigned)index1 : (unsigned)index2
- (void) swapAtIndeces: (unsigned)index1 : (unsigned)index2
{
elt tmp;
id tmp;
CHECK_INDEX_RANGE_ERROR(index1, _count);
CHECK_INDEX_RANGE_ERROR(index2, _count);
tmp = _contents_array[index1];
_contents_array[index1] = _contents_array[index2];
_contents_array[index2] = tmp;
return self;
}
// GETTING ELEMENTS BY INDEX;
- (elt) elementAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
return _contents_array[index];
}
// TESTING;
- (int(*)(elt,elt)) comparisonFunction
{
return _comparison_function;
}
- (const char *) contentType
{
return elt_get_encoding(_comparison_function);
}
- (unsigned) count
{
return _count;
}
@end

View file

@ -1,8 +1,8 @@
/* Implementation for Objective-C Bag collection object
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
Created: May 1993
This file is part of the GNU Objective C Class Library.
@ -24,33 +24,55 @@
#include <objects/Bag.h>
#include <objects/CollectionPrivate.h>
#define DEFAULT_BAG_CAPACITY 32
@implementation Bag
+ (void) initialize
{
if (self == [Bag class])
[self setVersion:0]; /* beta release */
}
// MANAGING CAPACITY;
/* Eventually we will want to have better capacity management,
potentially keep default capacity as a class variable. */
+ (unsigned) defaultCapacity
{
return DEFAULT_BAG_CAPACITY;
}
// INITIALIZING AND FREEING;
/* This is the designated initializer of this class */
/* Override designated initializer of superclass */
- initWithType: (const char *)contentEncoding
capacity: (unsigned)aCapacity
- initWithCapacity: (unsigned)cap
{
[super initWithType:contentEncoding
capacity:aCapacity];
_contents_map = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSIntMapValueCallBacks,
cap);
_count = 0;
return self;
}
/* Override Collection's designated initializer */
- initWithObjects: (id*)objs count: (unsigned)count
{
[self initWithCapacity: count];
while (count--)
[self addObject: objs[count]];
return self;
}
/* Archiving must mimic the above designated initializer */
- _readInit: (TypedStream*)aStream
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: anEncoder
{
[super _readInit:aStream];
_count = 0;
[self notImplemented:_cmd];
}
- initWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
@ -58,94 +80,70 @@
- emptyCopy
{
Bag *copy = [super emptyCopy];
copy->_contents_map = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSIntMapValueCallBacks,
0);
copy->_count = 0;
return copy;
}
/* This must work without sending any messages to content objects */
- _empty
- (void) dealloc
{
coll_hash_empty(_contents_hash);
NSFreeMapTable (_contents_map);
[super _collectionDealloc];
}
/* This must work without sending any messages to content objects */
- (void) _collectionEmpty
{
NSResetMapTable (_contents_map);
_count = 0;
return self;
}
// ADDING;
- addElement: (elt)newElement withOccurrences: (unsigned)count
- (void) addObject: newObject withOccurrences: (unsigned)count
{
coll_node_ptr node =
coll_hash_node_for_key(_contents_hash, newElement);
if (node)
node->value.unsigned_int_u += count;
else
coll_hash_add(&_contents_hash, newElement, count);
unsigned new_count = (unsigned) NSMapGet (_contents_map, newObject);
new_count += count;
NSMapInsert (_contents_map, newObject, (void*)new_count);
_count += count;
while (count--)
RETAIN_ELT(newElement);
return self;
}
- addElement: (elt)newElement
- (void) addObject: newObject
{
return [self addElement:newElement withOccurrences:1];
[self addObject: newObject withOccurrences: 1];
}
// REMOVING AND REPLACING;
- (elt) removeElement:(elt)oldElement occurrences: (unsigned)count
- (void) removeObject: oldObject occurrences: (unsigned)count
{
elt err(arglist_t argFrame)
unsigned c = (unsigned) NSMapGet (_contents_map, oldObject);
if (c)
{
return ELEMENT_NOT_FOUND_ERROR(oldElement);
if (c <= count)
{
NSMapRemove (_contents_map, oldObject);
_count -= c;
}
else
{
NSMapInsert (_contents_map, oldObject, (void*)(c - count));
_count -= count;
}
}
return [self removeElement:oldElement occurrences:count
ifAbsentCall:err];
}
- (elt) removeElement:(elt)oldElement occurrences: (unsigned)count
ifAbsentCall: (elt(*)(arglist_t))excFunc
- (void) removeObject: oldObject
{
coll_node_ptr node =
coll_hash_node_for_key(_contents_hash, oldElement);
if (!node || node->value.unsigned_int_u < count)
{
RETURN_BY_CALLING_EXCEPTION_FUNCTION(excFunc);
}
if (node->value.unsigned_int_u > count)
{
(node->value.unsigned_int_u) -= count;
}
else /* (node->value.unsigned_int_u == count) */
{
coll_hash_remove(_contents_hash, oldElement);
}
_count -= count;
while (count-- > 0)
RELEASE_ELT(oldElement);
return AUTORELEASE_ELT(oldElement);
[self removeObject: oldObject occurrences:1];
}
- (elt) removeElement: (elt)oldElement ifAbsentCall: (elt(*)(arglist_t))excFunc
- (void) uniqueContents
{
return [self removeElement:oldElement occurrences:1 ifAbsentCall:excFunc];
}
- uniqueContents
{
void *state = 0;
coll_node_ptr node = 0;
_count = 0;
while ((node = coll_hash_next(_contents_hash, &state)))
{
while ((node->value.unsigned_int_u)-- > 0)
RELEASE_ELT(node->key);
node->value.unsigned_int_u = 1;
_count++;
}
return self;
[self notImplemented: _cmd];
}
@ -158,18 +156,12 @@
- (unsigned) uniqueCount
{
return _contents_hash->used;
return NSCountMapTable (_contents_map);
}
- (unsigned) occurrencesOfElement: (elt)anElement
- (unsigned) occurrencesOfObject: anObject
{
coll_node_ptr node =
coll_hash_node_for_key(_contents_hash, anElement);
if (node)
return node->value.unsigned_int_u;
else
return 0;
return (unsigned) NSMapGet (_contents_map, anObject);
}
@ -177,34 +169,22 @@
struct BagEnumState
{
void *state;
coll_node_ptr node;
NSMapEnumerator me;
id object;
unsigned count;
};
#define ES ((struct BagEnumState *) *enumState)
- (BOOL) getNextElement:(elt *)anElementPtr withEnumState: (void**)enumState
- nextObjectWithEnumState: (void**)enumState
{
if (!(*enumState))
{
}
else if (ES->count >= ES->node->value.unsigned_int_u)
{
/* time to get the next different element */
ES->node = coll_hash_next(_contents_hash, &(ES->state));
ES->count = 0;
}
if (!(ES->node))
{
/* at end of enumeration */
OBJC_FREE(*enumState);
*enumState = 0;
return NO;
}
*anElementPtr = ES->node->key;
(ES->count)++;
return YES;
if (!(ES->count))
if (!NSNextMapEnumeratorPair (&(ES->me),
(void**) &(ES->object),
(void**) &(ES->count)))
return NO_OBJECT;
ES->count--;
return ES->object;
}
- (void*) newEnumState
@ -213,81 +193,16 @@ struct BagEnumState
void *vp;
void **enumState = &vp;
OBJC_MALLOC(*enumState, struct BagEnumState, 1);
ES->state = 0;
ES->node = coll_hash_next(_contents_hash, &(ES->state));
ES->me = NSEnumerateMapTable (_contents_map);
ES->object = nil;
ES->count = 0;
return vp;
}
- freeEnumState: (void**)enumState
- (void) freeEnumState: (void**)enumState
{
if (*enumState)
OBJC_FREE(*enumState);
return self;
}
- withElementsCall: (void(*)(elt))aFunc whileTrue:(BOOL *)flag
{
int i;
void *state = 0;
coll_node_ptr node;
while ((node = coll_hash_next(_contents_hash, &state)))
{
for (i = 0; i < node->value.unsigned_int_u; i++)
{
if (!(*flag))
return self;
(*aFunc)(node->key);
}
}
return self;
}
- withElementsCall: (void(*)(elt))aFunc
{
int i;
void *state = 0;
coll_node_ptr node;
int test = 0;
while ((node = coll_hash_next(_contents_hash, &state)))
{
test++;
for (i = 0; i < node->value.unsigned_int_u; i++)
{
(*aFunc)(node->key);
}
}
return self;
}
// OBJECT-COMPATIBLE MESSAGE NAMES;
- addObject: newObject withOccurrences: (unsigned)count
{
return [self addElement:newObject withOccurrences:count];
}
- removeObject: oldObject occurrences: (unsigned)count
{
id err(arglist_t argFrame)
{
return ELEMENT_NOT_FOUND_ERROR(oldObject);
}
return [self removeObject:oldObject occurrences:count ifAbsentCall:err];
}
- removeObject: oldObject occurrences: (unsigned)count
ifAbsentCall: (id(*)(arglist_t))excFunc
{
elt elt_exc(arglist_t argFrame)
{
RETURN_BY_CALLING_EXCEPTION_FUNCTION(excFunc);
}
return [self removeElement:oldObject occurrences:count
ifAbsentCall:elt_exc].id_u;
}
@end

View file

@ -1,5 +1,5 @@
/* Implementation for GNU Objective-C ConstantString object
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Copyright (C) 1993,1994, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
@ -29,10 +29,9 @@
// INITIALIZING;
/* This must work without sending any messages to content objects */
- empty
- (void) empty
{
[self shouldNotImplement:_cmd];
return self;
}
// REPLACING;

View file

@ -1,8 +1,8 @@
/* Implementation for Objective-C Dictionary collection object
Copyright (C) 1993,1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
Created: May 1993
This file is part of the GNU Objective C Class Library.
@ -28,12 +28,6 @@
@implementation Dictionary
+ (void) initialize
{
if (self == [Dictionary class])
[self setVersion:0]; /* beta release */
}
// MANAGING CAPACITY;
/* Eventually we will want to have better capacity management,
@ -47,61 +41,35 @@
// INITIALIZING;
/* This is the designated initializer of this class */
- initWithType: (const char *)contentEncoding
keyType: (const char *)keyEncoding
capacity: (unsigned)aCapacity
- initWithCapacity: (unsigned)cap
{
[super initWithType:contentEncoding
keyType:keyEncoding];
_contents_hash =
coll_hash_new(POWER_OF_TWO(aCapacity),
elt_get_hash_function(keyEncoding),
elt_get_comparison_function(keyEncoding));
_comparison_function = elt_get_comparison_function(contentEncoding);
_contents_hash = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
cap);
return self;
}
/* Override the KeyedCollection designated initializer */
- initWithObjects: (id*)objects forKeys: (id*)keys count: (unsigned)c
{
[self initWithCapacity: c];
while (c--)
[self putObject: objects[c] atKey: keys[c]];
return self;
}
- init
{
return [self initWithCapacity: DEFAULT_DICTIONARY_CAPACITY];
}
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: anEncoder
- _initCollectionWithCoder: (id <Decoding>)coder
{
[self notImplemented:_cmd];
}
+ newWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
- _writeInit: (TypedStream*)aStream
{
const char *ce = [self contentType];
const char *ke = [self keyType];
[super _writeInit:aStream];
/* This implicitly archives the key's comparison and hash functions */
objc_write_type(aStream, @encode(char*), &ke);
objc_write_type(aStream, @encode(unsigned int), &(_contents_hash->size));
/* This implicitly archives the content's comparison function */
objc_write_type(aStream, @encode(char*), &ce);
return self;
}
- _readInit: (TypedStream*)aStream
{
char *keyEncoding, *contentEncoding;
unsigned int size;
[super _readInit:aStream];
objc_read_type(aStream, @encode(char*), &keyEncoding);
objc_read_type(aStream, @encode(unsigned int), &size);
_contents_hash =
coll_hash_new(size,
elt_get_hash_function(keyEncoding),
elt_get_comparison_function(keyEncoding));
objc_read_type(aStream, @encode(char*), &contentEncoding);
_comparison_function = elt_get_comparison_function(contentEncoding);
_contents_hash = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
0);
return self;
}
@ -110,181 +78,105 @@
- emptyCopy
{
Dictionary *copy = [super emptyCopy];
copy->_contents_hash =
coll_hash_new(_contents_hash->size,
_contents_hash->hash_func,
_contents_hash->compare_func);
copy->_contents_hash = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
0);
return copy;
}
/* To make sure that former KeyedCollection init'ers go through
Dictionary init, we override the designated initializer for
KeyedCollection. */
- initWithType: (const char *)contentEncoding
keyType: (const char *)keyEncoding
- (void) dealloc
{
return [self initWithType:contentEncoding
keyType:keyEncoding
capacity:[[self class] defaultCapacity]];
}
- initWithType: (const char *)contentEncoding
capacity: (unsigned)aCapacity
{
return [self initWithType:contentEncoding
keyType:@encode(id)
capacity:aCapacity];
}
- initWithCapacity: (unsigned)aCapacity
{
return [self initWithType:@encode(id)
capacity:aCapacity];
}
- (void) _collectionDealloc
{
coll_hash_delete(_contents_hash);
NSFreeMapTable (_contents_hash);
[super _collectionDealloc];
}
/* This must work without sending any messages to content objects */
- _empty
- (void) _collectionEmpty
{
coll_hash_empty(_contents_hash);
return self;
NSResetMapTable (_contents_hash);
}
// ADDING OR REPLACING;
- addElement: (elt)anElement
- (void) addObject: newObject
{
return [self shouldNotImplement:_cmd];
[self shouldNotImplement: _cmd];
/* or should I make up some default behavior here?
Base it on object conforming to <Associating> protocol, perhaps */
}
- putElement: (elt)newContentElement atKey: (elt)aKey
- (void) putObject: newObject atKey: aKey
{
coll_node_ptr node = coll_hash_node_for_key(_contents_hash, aKey);
if (node)
{
RELEASE_ELT(node->value);
node->value = newContentElement;
}
else
coll_hash_add(&_contents_hash, aKey,
newContentElement);
RETAIN_ELT(newContentElement);
return self;
NSMapInsert (_contents_hash, aKey, newObject);
}
// REMOVING;
- (elt) removeElementAtKey: (elt)aKey ifAbsentCall: (elt(*)(arglist_t))excFunc
- (void) removeObjectAtKey: aKey
{
coll_node_ptr node = coll_hash_node_for_key(_contents_hash, aKey);
elt ret;
if (node)
{
ret = node->value;
coll_hash_remove(_contents_hash, aKey);
return AUTORELEASE_ELT(ret);
}
else
RETURN_BY_CALLING_EXCEPTION_FUNCTION(excFunc);
NSMapRemove (_contents_hash, aKey);
}
- (elt) removeElement: (elt)oldElement ifAbsentCall: (elt(*)(arglist_t))excFunc
- (void) removeObject: oldObject
{
elt err(arglist_t argFrame)
{
RETURN_BY_CALLING_EXCEPTION_FUNCTION(excFunc);
}
elt key = [self keyElementOfElement:oldElement ifAbsentCall:err];
return [self removeElementAtKey:key];
[self notImplemented: _cmd];
}
// GETTING ELEMENTS;
- (elt) elementAtKey: (elt)aKey ifAbsentCall: (elt(*)(arglist_t))excFunc
- objectAtKey: aKey
{
coll_node_ptr node = coll_hash_node_for_key(_contents_hash, aKey);
if (node)
return node->value;
else
RETURN_BY_CALLING_EXCEPTION_FUNCTION(excFunc);
return NSMapGet (_contents_hash, aKey);
}
// TESTING;
- (int(*)(elt,elt)) comparisonFunction
- (BOOL) containsKey: aKey
{
return _comparison_function;
}
- (const char *) contentType
{
return elt_get_encoding(_comparison_function);
}
- (const char *) keyType
{
return elt_get_encoding(_contents_hash->compare_func);
}
- (BOOL) includesKey: (elt)aKey
{
if (coll_hash_node_for_key(_contents_hash, aKey))
if (NSMapGet (_contents_hash, aKey))
return YES;
else
return NO;
}
- (unsigned) count
{
return NSCountMapTable (_contents_hash);
}
// ENUMERATIONS;
- (BOOL) getNextKey: (elt*)aKeyPtr content: (elt*)anElementPtr
withEnumState: (void**)enumState
- nextObjectAndKey: (id*)aKeyPtr withEnumState: (void**)enumState
{
coll_node_ptr node = coll_hash_next(_contents_hash, enumState);
if (node)
{
*aKeyPtr = node->key;
*anElementPtr = node->value;
return YES;
}
return NO;
id o;
if (!NSNextMapEnumeratorPair (*enumState, (void**)aKeyPtr, (void**)&o))
return NO_OBJECT;
return o;
}
- (void*) newEnumState
{
return (void*)0;
void *es;
NSMapEnumerator me;
OBJC_MALLOC (es, NSMapEnumerator, 1);
#if 1
*((NSMapEnumerator*)es) = NSEnumerateMapTable (_contents_hash);
#else
me = NSEnumerateMapTable (_contents_hash);
memcpy (es, &me, sizeof (NSMapEnumerator));
#endif
return es;
}
- freeEnumState: (void**)enumState
- (void) freeEnumState: (void**)enumState
{
if (*enumState)
OBJC_FREE(*enumState);
return self;
OBJC_FREE (*enumState);
}
- withKeyElementsAndContentElementsCall: (void(*)(const elt,elt))aFunc
whileTrue: (BOOL *)flag
{
void *state = 0;
coll_node_ptr node = 0;
while (flag && (node = coll_hash_next(_contents_hash, &state)))
(*aFunc)(node->key, node->value);
return self;
}
@end

View file

@ -1,9 +1,11 @@
/* Implementation for Objective-C GapArray collection object
Copyright (C) 1993,1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Kresten Krab Thorup <krab@iesd.auc.dk>
Dept. of Mathematics and Computer Science, Aalborg U., Denmark
Overhauled by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
@ -27,19 +29,11 @@
@implementation GapArray
+ (void) initialize
{
if (self == [GapArray class])
[self setVersion:0]; /* beta release */
}
/* This is the designated initializer of this class */
/* Override designated initializer of superclass */
- initWithType: (const char *)contentEncoding
capacity: (unsigned)aCapacity
- initWithCapacity: (unsigned)aCapacity
{
[super initWithType:contentEncoding
capacity:aCapacity];
[super initWithCapacity: aCapacity];
_gap_start = 0;
_gap_size = aCapacity;
return self;
@ -58,14 +52,6 @@
return self;
}
- _readInit: (TypedStream*)aStream
{
[super _readInit: aStream];
_gap_start = 0;
_gap_size = _capacity;
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
@ -76,15 +62,14 @@
return copy;
}
- _empty
- (void) _collectionEmpty
{
[super _empty];
[super _collectionEmpty];
_gap_start = 0;
_gap_size = _capacity;
return self;
}
- setCapacity: (unsigned)newCapacity
- (void) setCapacity: (unsigned)newCapacity
{
if (newCapacity > _count)
{
@ -92,80 +77,58 @@
[super setCapacity: newCapacity]; /* resize */
_gap_size = _capacity - _gap_start;
}
return self;
}
- (elt) removeElementAtIndex: (unsigned)index
- (void) removeObjectAtIndex: (unsigned)index
{
elt res;
CHECK_INDEX_RANGE_ERROR(index, _count);
res = _contents_array[GAP_TO_BASIC (index)];
[_contents_array[GAP_TO_BASIC (index)] release];
gapFillHoleAt (self, index);
decrementCount(self);
return AUTORELEASE_ELT(res);
}
- (elt) removeFirstElement
{
elt res = _contents_array[GAP_TO_BASIC (0)];
gapFillHoleAt (self, 0);
decrementCount(self);
return AUTORELEASE_ELT(res);
}
- (elt) removeLastElement
{
return [self removeElementAtIndex: _count-1];
}
- (elt) elementAtIndex: (unsigned)index
- objectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
return _contents_array[GAP_TO_BASIC(index)];
}
- appendElement: (elt)newElement
- (void) appendObject: newObject
{
incrementCount(self);
RETAIN_ELT(newElement);
[newObject retain];
gapMakeHoleAt (self, _count-1);
_contents_array[_count-1] = newElement;
return self;
_contents_array[_count-1] = newObject;
}
- prependElement: (elt)newElement
- (void) prependObject: newObject
{
incrementCount(self);
[newObject retain];
gapMakeHoleAt (self, 0);
_contents_array[0] = newElement;
return self;
_contents_array[0] = newObject;
}
- insertElement: (elt)newElement atIndex: (unsigned)index
- (void) insertObject: newObject atIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count+1);
incrementCount(self);
RETAIN_ELT(newElement);
[newObject retain];
gapMakeHoleAt (self, index);
_contents_array[index] = newElement;
return self;
_contents_array[index] = newObject;
}
- (elt) replaceElementAtIndex: (unsigned)index with: (elt)newElement
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
{
elt ret;
CHECK_INDEX_RANGE_ERROR(index, _count);
RETAIN_ELT(newElement);
ret = _contents_array[GAP_TO_BASIC(index)];
_contents_array[GAP_TO_BASIC(index)] = newElement;
return AUTORELEASE_ELT(ret);
[newObject retain];
[_contents_array[GAP_TO_BASIC(index)] release];
_contents_array[GAP_TO_BASIC(index)] = newObject;
}
- swapAtIndeces: (unsigned)index1 : (unsigned)index2
- (void) swapAtIndeces: (unsigned)index1 : (unsigned)index2
{
elt tmp;
id tmp;
CHECK_INDEX_RANGE_ERROR(index1, _count);
CHECK_INDEX_RANGE_ERROR(index2, _count);
@ -174,7 +137,6 @@
tmp = _contents_array[index1];
_contents_array[index1] = _contents_array[index2];
_contents_array[index2] = tmp;
return self;
}
@end

View file

@ -1,8 +1,8 @@
/* Implementation for Objective-C Heap object
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
Created: May 1993
This file is part of the GNU Objective C Class Library.
@ -21,6 +21,9 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* This class could be improved by somehow making is a subclass of
IndexedCollection, but not OrderedCollection. */
#include <objects/Heap.h>
#include <objects/ArrayPrivate.h>
@ -31,20 +34,20 @@
@implementation Heap
/* We could take out the recursive call to make it a little more efficient */
- heapifyFromIndex: (unsigned)index
- (void) heapifyFromIndex: (unsigned)index
{
unsigned right, left, largest;
elt tmp;
id tmp;
right = HEAP_RIGHT(index);
left = HEAP_LEFT(index);
if (left <= _count
&& COMPARE_ELEMENTS(_contents_array[left],_contents_array[index]) > 0)
&& [_contents_array[left] compare: _contents_array[index]] > 0)
largest = left;
else
largest = index;
if (right <= _count
&& COMPARE_ELEMENTS(_contents_array[right],_contents_array[largest]) > 0)
&& [_contents_array[right] compare: _contents_array[largest]] > 0)
largest = right;
if (largest != index)
{
@ -53,47 +56,41 @@
_contents_array[largest] = tmp;
[self heapifyFromIndex:largest];
}
return self;
}
- heapify
- (void) heapify
{
int i;
// could use objc_msg_lookup here;
for (i = _count / 2; i >= 1; i--)
[self heapifyFromIndex:i];
return self;
}
- (elt) removeFirstElement
- (void) removeFirstObject
{
elt ret;
if (_count == 0)
NO_ELEMENT_FOUND_ERROR();
ret = _contents_array[0];
return;
[_contents_array[0] release];
_contents_array[0] = _contents_array[_count-1];
decrementCount(self);
[self heapifyFromIndex:0];
return AUTORELEASE_ELT(ret);
}
- addElement: (elt)newElement
- (void) addObject: newObject
{
int i;
incrementCount(self);
RETAIN_ELT(newElement);
[newObject retain];
for (i = _count-1;
i > 0
&& COMPARE_ELEMENTS(_contents_array[HEAP_PARENT(i)], newElement) < 0;
&& [_contents_array[HEAP_PARENT(i)] compare: newObject] < 0;
i = HEAP_PARENT(i))
{
_contents_array[i] = _contents_array[HEAP_PARENT(i)];
}
_contents_array[i] = newElement;
return self;
_contents_array[i] = newObject;
}
@end

File diff suppressed because it is too large Load diff

View file

@ -27,517 +27,236 @@
#include <objects/Array.h>
#include <objects/NSString.h>
@implementation KeyedCollection
@implementation KeyEnumerator
+ (void) initialize
{
if (self == [KeyedCollection class])
[self setVersion:0]; /* beta release */
}
/* xxx What should be here? */
@end
// NON-OBJECT ELEMENT METHOD NAMES;
@implementation ConstantKeyedCollection
// INITIALIZING;
/* This is the designated initializer of this class */
- initWithType: (const char *)contentEncoding
keyType: (const char *)keyEncoding
/* This is the designated initializer */
- initWithObjects: (id*)objects forKeys: (id*)keys count: (unsigned)c
{
[super initWithType:contentEncoding];
if (!elt_get_comparison_function(contentEncoding))
[self error:"There is no elt comparison function for type encoding %s",
keyEncoding];
return self;
[self subclassResponsibility: _cmd];
}
- initKeyType: (const char *)keyEncoding
{
// default contents are objects;
return [self initWithType:@encode(id) keyType:keyEncoding];
}
/* Override designated initializer of superclass */
- initWithType: (const char *)contentEncoding
{
// default keys are objects;
return [self initWithType:contentEncoding
keyType:@encode(id)];
}
// ADDING OR REPLACING;
- putElement: (elt)newContentElement atKey: (elt)aKey
{
return [self subclassResponsibility:_cmd];
}
- addContentsOf: (id <KeyedCollecting>)aKeyedCollection
{
id (*putElementAtKeyImp)(id,SEL,elt,elt) = (id(*)(id,SEL,elt,elt))
objc_msg_lookup(self, @selector(putElement:atKey:));
void doIt(elt k, elt c)
{
(*putElementAtKeyImp)(self, @selector(putElement:atKey:),
c, k);
}
[aKeyedCollection withKeyElementsAndContentElementsCall:doIt];
return self;
}
/* The right thing? Or should this be subclass responsibility? */
- (elt) replaceElementAtKey: (elt)aKey with: (elt)newContentElement
{
elt err(arglist_t argFrame)
{
return ELEMENT_NOT_FOUND_ERROR(aKey);
}
return [self replaceElementAtKey:aKey with:newContentElement
ifAbsentCall:err];
}
- (elt) replaceElementAtKey: (elt)aKey with: (elt)newContentElement
ifAbsentCall: (elt(*)(arglist_t))excFunc;
{
elt err(arglist_t argFrame)
{
RETURN_BY_CALLING_EXCEPTION_FUNCTION(excFunc);
}
elt ret;
ret = [self removeElementAtKey:aKey ifAbsentCall:err];
[self putElement:newContentElement atKey:aKey];
return ret;
}
- swapAtKeys: (elt)key1 : (elt)key2
{
/* Use two tmp's so that when we add reference counting, the count will
stay correct. */
elt tmp1 = [self removeElementAtKey:key1];
elt tmp2 = [self removeElementAtKey:key2];
[self putElement:tmp2 atKey:key1];
[self putElement:tmp1 atKey:key2];
return self;
}
// REMOVING;
- (elt) removeElementAtKey: (elt)aKey
{
elt err(arglist_t argFrame)
{
return ELEMENT_NOT_FOUND_ERROR(aKey);
}
return [self removeElementAtKey:aKey ifAbsentCall:err];
}
- (elt) removeElementAtKey: (elt)aKey
ifAbsentCall: (elt(*)(arglist_t))excFunc
{
return [self subclassResponsibility:_cmd];
}
- removeObjectAtKey: (elt)aKey
{
CHECK_CONTAINS_OBJECTS_ERROR();
return [self removeElementAtKey:aKey].id_u;
}
// GETTING ELEMENTS AND KEYS;
- (elt) elementAtKey: (elt)aKey
- objectAtKey: aKey
{
elt err(arglist_t argFrame)
{
return ELEMENT_NOT_FOUND_ERROR(aKey);
}
return [self elementAtKey:aKey ifAbsentCall:err];
[self subclassResponsibility: _cmd];
}
- (elt) elementAtKey: (elt)aKey ifAbsentCall: (elt(*)(arglist_t))excFunc
- keyOfObject: aContentObject
{
return [self subclassResponsibility:_cmd];
[self subclassResponsibility: _cmd];
}
- (elt) keyElementOfElement: (elt)aContent
{
elt err(arglist_t argFrame)
{
return ELEMENT_NOT_FOUND_ERROR(aContent);
}
return [self keyElementOfElement:aContent ifAbsentCall:err];
}
- (elt) keyElementOfElement: (elt)aContent
ifAbsentCall: (elt(*)(arglist_t))excFunc
{
elt theKey;
BOOL notDone = YES;
int (*cf)(elt,elt) = [self comparisonFunction];
void doIt(elt key, elt content)
{
if (!((*cf)(aContent, content)))
{
theKey = key;
notDone = NO;
}
}
[self withKeyElementsAndContentElementsCall:doIt whileTrue:&notDone];
if (notDone)
RETURN_BY_CALLING_EXCEPTION_FUNCTION(excFunc);
return theKey;
}
- objectAtKey: (elt)aKey
{
CHECK_CONTAINS_OBJECTS_ERROR();
return [self elementAtKey:aKey].id_u;
}
- keyObjectOfObject: aContent
{
CHECK_CONTAINS_OBJECTS_ERROR();
return [self keyElementOfElement:aContent].id_u;
}
// TESTING;
- (const char *) keyType
- (BOOL) containsKey: aKey
{
[self subclassResponsibility:_cmd];
return "";
if ([self objectAtKey: aKey] == NO_OBJECT)
return NO;
return YES;
}
- (BOOL) includesKey: (elt)aKey
{
[self subclassResponsibility:_cmd];
return NO;
}
// COPYING;
- shallowCopyAs: (Class)aCollectionClass
{
id (*putElementAtKeyImp)(id,SEL,elt,elt);
id newColl;
void addKeysAndContents(const elt key, elt content)
{
putElementAtKeyImp(newColl, @selector(putElement:atKey:),
content, key);
}
if ([(id)aCollectionClass conformsToProtocol:@protocol(KeyedCollecting)])
{
newColl = [self emptyCopyAs:aCollectionClass];
putElementAtKeyImp = (id(*)(id,SEL,elt,elt))
objc_msg_lookup(newColl, @selector(putElement:atKey:));
[self withKeyElementsAndContentElementsCall:addKeysAndContents];
return newColl;
}
else
return [super shallowCopyAs:aCollectionClass];
}
// ENUMERATING;
- (BOOL) getNextKey: (elt*)aKeyPtr content: (elt*)anElementPtr
withEnumState: (void**)enumState;
{
[self subclassResponsibility:_cmd];
return NO;
}
- (BOOL) getNextElement:(elt *)anElementPtr withEnumState: (void**)enumState
{
elt key;
return [self getNextKey:&key content:anElementPtr
withEnumState:enumState];
}
- withKeyElementsCall: (void(*)(const elt))aFunc
{
void doIt(elt key, elt content)
{
(*aFunc)(key);
}
[self withKeyElementsAndContentElementsCall:doIt];
return self;
}
- safeWithKeyElementsCall: (void(*)(const elt))aFunc
{
id tmpColl = [[Array alloc] initWithType:[self keyType]
capacity:[self count]];
void addKey(elt k, elt c)
{
[tmpColl addElement:k];
}
[self withKeyElementsAndContentElementsCall:addKey];
[tmpColl withElementsCall:aFunc];
[tmpColl release];
return self;
}
- withKeyObjectsCall: (void(*)(id))aFunc
{
void doIt(elt key, elt content)
{
(*aFunc)(key.id_u);
}
CHECK_CONTAINS_OBJECTS_ERROR();
[self withKeyElementsAndContentElementsCall:doIt];
return self;
}
- safeWithKeyObjectsCall: (void(*)(id))aFunc
{
void doIt(elt key)
{
(*aFunc)(key.id_u);
}
CHECK_CONTAINS_OBJECTS_ERROR();
[self safeWithKeyElementsCall:doIt];
return self;
}
- withKeyElementsAndContentElementsCall: (void(*)(const elt,elt))aFunc
{
BOOL flag = YES;
[self withKeyElementsAndContentElementsCall:aFunc whileTrue:&flag];
return self;
}
- safeWithKeyElementsAndContentElementsCall: (void(*)(const elt,elt))aFunc
{
BOOL flag = YES;
[self safeWithKeyElementsAndContentElementsCall:aFunc whileTrue:&flag];
return self;
}
- withKeyObjectsAndContentObjectsCall: (void(*)(id,id))aFunc
{
BOOL flag = YES;
void doIt(elt k, elt c)
{
(*aFunc)(k.id_u, c.id_u);
}
CHECK_CONTAINS_OBJECTS_ERROR();
[self withKeyElementsAndContentElementsCall:doIt whileTrue:&flag];
return self;
}
- safeWithKeyObjectsAndContentObjectsCall: (void(*)(id,id))aFunc
{
BOOL flag = YES;
void doIt(elt k, elt c)
{
(*aFunc)(k.id_u, c.id_u);
}
CHECK_CONTAINS_OBJECTS_ERROR();
[self safeWithKeyElementsAndContentElementsCall:doIt whileTrue:&flag];
return self;
}
- withKeyElementsAndContentElementsCall: (void(*)(const elt,elt))aFunc
whileTrue: (BOOL *)flag
{
void *s = [self newEnumState];
elt key, content;
while (*flag && [self getNextKey:&key content:&content withEnumState:&s])
(*aFunc)(key, content);
[self freeEnumState:&s];
return self;
}
- withKeyObjectsAndContentObjectsCall: (void(*)(id,id))aFunc
whileTrue: (BOOL *)flag
{
void doIt(elt k, elt c)
{
(*aFunc)(k.id_u, c.id_u);
}
CHECK_CONTAINS_OBJECTS_ERROR();
[self withKeyElementsAndContentElementsCall:doIt whileTrue:flag];
return self;
}
- safeWithKeyObjectsAndContentObjectsCall: (void(*)(id,id))aFunc
whileTrue: (BOOL *)flag
{
void doIt(elt k, elt c)
{
(*aFunc)(k.id_u, c.id_u);
}
CHECK_CONTAINS_OBJECTS_ERROR();
[self safeWithKeyElementsAndContentElementsCall:doIt whileTrue:flag];
return self;
}
- safeWithKeyElementsAndContentElementsCall: (void(*)(elt,elt))aFunc
whileTrue: (BOOL *)flag
{
int i, count = [self count];
id keyTmpColl = [[Array alloc] initWithType:[self keyType]
capacity:count];
id contentTmpColl = [[Array alloc] initWithType:[self contentType]
capacity:count];
void appendKeyAndContent(elt k, elt c)
{
[keyTmpColl appendElement:k];
[contentTmpColl appendElement:c];
}
[self withKeyElementsAndContentElementsCall:appendKeyAndContent];
for (i = 0; *flag && i < count; i++)
(*aFunc)([keyTmpColl elementAtIndex:i], [contentTmpColl elementAtIndex:i]);
[keyTmpColl release];
[contentTmpColl release];
return self;
}
// ADDING OR REPLACING;
- putObject: newContentObject atKey: (elt)aKey
{
CHECK_CONTAINS_OBJECTS_ERROR();
return [self putElement:newContentObject atKey:aKey];
}
- replaceObjectAtKey: (elt)aKey with: newContentObject
{
CHECK_CONTAINS_OBJECTS_ERROR();
return [self replaceElementAtKey:aKey with:newContentObject].id_u;
}
// GETTING COLLECTIONS OF CONTENTS SEPARATELY;
- shallowCopyKeysAs: aCollectionClass;
{
id newColl = [self emptyCopyAs:aCollectionClass];
id(*addElementImp)(id,SEL,elt) = (id(*)(id,SEL,elt))
objc_msg_lookup(newColl, @selector(addElement:));
void doIt(elt e)
{
addElementImp(newColl, @selector(addElement:), e);
}
[self withKeyElementsCall:doIt];
return self;
}
- shallowCopyContentsAs: aCollectionClass
{
return [super shallowCopyAs:aCollectionClass];
}
// ENUMERATIONS;
- printForDebugger
- (id <Enumerating>) keyEnumerator
{
const char *kd = [self keyType];
const char *cd = [self contentType];
void doIt(const elt key, elt content)
{
printf("(");
elt_fprintf_elt(stdout, kd, key);
printf(",");
elt_fprintf_elt(stdout, cd, content);
printf(") ");
}
[self withKeyElementsAndContentElementsCall:doIt];
printf(" :%s\n", [self name]);
return self;
return [[[KeyEnumerator alloc] initWithCollection: self]
autorelease];
}
- withKeysInvoke: (id <Invoking>)anInvocation
{
id o, k;
FOR_KEYED_COLLECTION(self, o, k)
{
[anInvocation invokeWithObject: k];
}
END_FOR_KEYED_COLLECTION(self);
}
- withKeysInvoke: (id <Invoking>)anInvocation
whileTrue: (BOOL *)flag
{
id o, k;
FOR_KEYED_COLLECTION_WHILE_TRUE(self, o, k, *flag)
{
[anInvocation invokeWithObject: k];
}
END_FOR_KEYED_COLLECTION(self);
}
/* Override this Collection method */
- nextObjectWithEnumState: (void**)enumState
{
id k;
return [self nextObjectAndKey: &k withEnumState: enumState];
}
// LOW-LEVEL ENUMERATING;
- nextObjectAndKey: (id*)keyPtr withEnumState: (void**)enumState
{
[self subclassResponsibility: _cmd];
}
// COPYING;
- shallowCopyValuesAs: (Class)aConstantCollectingClass
{
int count = [self count];
id contents[count];
id k;
int i = 0;
id o;
FOR_KEYED_COLLECTION(self, o, k)
{
contents[i++] = o;
}
END_FOR_KEYED_COLLECTION(self);
return [[aConstantCollectingClass alloc]
initWithObjects: contents count: count];
}
- shallowCopyKeysAs: (Class)aCollectingClass;
{
int count = [self count];
id contents[count];
id k;
int i = 0;
id o;
FOR_KEYED_COLLECTION(self, o, k)
{
contents[i++] = k;
}
END_FOR_KEYED_COLLECTION(self);
return [[aCollectingClass alloc]
initWithObjects: contents count: count];
}
- copyValuesAs: (Class)aCollectingClass
{
[self notImplemented: _cmd];
}
- copyKeysAs: (Class)aCollectingClass;
{
[self notImplemented: _cmd];
}
// ARCHIVING
- (void) _encodeContentsWithCoder: (id <Encoding>)aCoder
{
unsigned int count = [self count];
const char *ce = [self contentType];
const char *ke = [self keyType];
void archiveKeyAndContent(elt key, elt content)
{
[aCoder encodeValueOfObjCType:ke
at:elt_get_ptr_to_member(ke, &key)
withName:@"KeyedCollection key element"];
[aCoder encodeValueOfObjCType:ce
at:elt_get_ptr_to_member(ce, &content)
withName:@"KeyedCollection content element"];
}
id o, k;
[aCoder encodeValueOfCType:@encode(unsigned)
at:&count
withName:@"Collection element count"];
[self withKeyElementsAndContentElementsCall:archiveKeyAndContent];
[aCoder encodeValueOfCType: @encode(unsigned)
at: &count
withName: @"Collection content count"];
FOR_KEYED_COLLECTION(self, o, k)
{
[aCoder encodeObject: k
withName: @"KeyedCollection key"];
[aCoder encodeObject: o
withName:@"KeyedCollection content"];
}
END_FOR_KEYED_COLLECTION(self);
}
- (void) _decodeContentsWithCoder: (id <Decoding>)aCoder
{
unsigned int count, i;
elt newKey, newContent;
const char *ce = [self contentType];
const char *ke = [self keyType];
id *objs, *keys;
[aCoder decodeValueOfCType:@encode(unsigned)
at:&count
withName:NULL];
OBJC_MALLOC(objs, id, count);
OBJC_MALLOC(keys, id, count);
for (i = 0; i < count; i++)
{
[aCoder decodeValueOfObjCType:ke
at:elt_get_ptr_to_member(ke, &newKey)
withName:NULL];
[aCoder decodeValueOfObjCType:ce
at:elt_get_ptr_to_member(ce, &newContent)
withName:NULL];
[self putElement:newContent atKey:newKey];
[aCoder decodeObjectAt: &(objs[i])
withName: NULL];
[aCoder decodeObjectAt: &(keys[i])
withName: NULL];
}
[self initWithObjects: objs forKeys: keys count: count];
OBJC_FREE(objs);
OBJC_FREE(keys);
}
- _writeContents: (TypedStream*)aStream
- (id <String>) description
{
unsigned int count = [self count];
const char *ce = [self contentType];
const char *ke = [self keyType];
void archiveKeyAndContent(elt key, elt content)
id s = [NSMutableString new];
id o, k;
FOR_KEYED_COLLECTION(self, o, k)
{
objc_write_types(aStream, ke,
elt_get_ptr_to_member(ke, &key));
objc_write_types(aStream, ce,
elt_get_ptr_to_member(ce, &content));
[s appendFormat: @"(%@,%@) ", [k description], [o description]];
}
objc_write_type(aStream, @encode(unsigned int), &count);
[self withKeyElementsAndContentElementsCall:archiveKeyAndContent];
return self;
}
- _readContents: (TypedStream*)aStream
{
unsigned int count, i;
elt newKey, newContent;
const char *ce = [self contentType];
const char *ke = [self keyType];
objc_read_type(aStream, @encode(unsigned int), &count);
for (i = 0; i < count; i++)
{
objc_read_types(aStream, ke,
elt_get_ptr_to_member(ke, &newKey));
objc_read_types(aStream, ce,
elt_get_ptr_to_member(ce, &newContent));
[self putElement:newContent atKey:newKey];
}
return self;
END_FOR_KEYED_COLLECTION(self);
[s appendFormat: @" :%s\n", [self name]];
return [s autorelease];
}
@end
@implementation KeyedCollection
+ (void) initialize
{
if (self == [KeyedCollection class])
class_add_behavior(self, [Collection class]);
}
// ADDING;
- (void) putObject: newContentObject atKey: aKey
{
[self subclassResponsibility: _cmd];
}
// REPLACING AND SWAPPING;
- (void) replaceObjectAtKey: aKey with: newContentObject
{
[self subclassResponsibility: _cmd];
}
- (void) swapObjectsAtKeys: key1 : key2
{
[self subclassResponsibility: _cmd];
}
// REMOVING;
- (void) removeObjectAtKey: aKey
{
[self subclassResponsibility: _cmd];
}
@end

View file

@ -1,8 +1,8 @@
/* Implementation for GNU Objective-C MutableCString object
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: January 1995
Created: January 1995
This file is part of the GNU Objective C Class Library.
@ -71,7 +71,6 @@ stringDecrementCountAndFillHoleAt(MutableCStringStruct *self,
/* This is the designated initializer for this class */
- initWithCapacity: (unsigned)capacity
{
[super initWithType:@encode(char)];
_count = 0;
_capacity = capacity;
OBJC_MALLOC(_contents_chars, char, _capacity+1);
@ -89,11 +88,10 @@ stringDecrementCountAndFillHoleAt(MutableCStringStruct *self,
/* xxx This should be made to return void, but we need to change
IndexedCollecting and its conformers */
- removeRange: (IndexRange)range
- (void) removeRange: (IndexRange)range
{
stringDecrementCountAndFillHoleAt((MutableCStringStruct*)self,
range.location, range.length);
return self;
}
- (void) insertString: (String*)string atIndex: (unsigned)index
@ -166,6 +164,7 @@ stringDecrementCountAndFillHoleAt(MutableCStringStruct *self,
return _contents_chars[index];
}
#if 0
/* For IndexedCollecting protocol */
- insertElement: (elt)newElement atIndex: (unsigned)index
@ -202,4 +201,6 @@ stringDecrementCountAndFillHoleAt(MutableCStringStruct *self,
return ret_elt;
}
#endif
@end

View file

@ -43,10 +43,9 @@
/* Subclasses need to implemented the next two methods */
- removeRange: (IndexRange)range
- (void) removeRange: (IndexRange)range
{
[self subclassResponsibility:_cmd];
return self;
}
- (void) insertString: (String*)string atIndex: (unsigned)index

View file

@ -52,7 +52,7 @@
if (objects[i] == nil)
[NSException raise:NSInvalidArgumentException
format:@"Tried to add nil"];
[self initWithType: @encode(id) capacity: count];
[self initWithCapacity: count];
while (count--)
[self addObject: [objects[count] retain]];
return self;
@ -69,7 +69,7 @@
if (index >= self->_count)
[NSException raise: NSRangeException
format: @"Index out of bounds"];
return self->_contents_array[index].id_u;
return self->_contents_array[index];
}
@ -88,12 +88,8 @@
}
}
- initWithCapacity: (unsigned)numItems
{
return [self initWithType: @encode(id) capacity: numItems];
}
/* Comes in from Array behavior
- initWithCapacity:
- (void) addObject: anObject
- (void) insertObject: anObject atIndex: (unsigned)index
*/

View file

@ -1,5 +1,5 @@
/* Concrete implementation of NSCountedSet based on GNU Bag class
Copyright (C) 1995 Free Software Foundation, Inc.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Created: Sep 1995
@ -49,11 +49,7 @@
- nextObject
{
elt e;
if ([bag getNextElement:&e withEnumState:&enum_state])
return e.id_u;
else
return nil;
return [bag nextObjectWithEnumState: &enum_state];
}
- (void) dealloc
@ -90,19 +86,9 @@
autorelease];
}
- (void) addObject: anObject
{
[self addElement:anObject];
}
- (void) removeObject: anObject
{
[self removeElement:anObject];
}
- (unsigned int) countForObject: anObject
{
return [self occurrencesOfElement:anObject];
return [self occurrencesOfObject: anObject];
}
/* To deal with behavior over-enthusiasm. Will be fixed later. */

View file

@ -1,8 +1,8 @@
/* Concrete implementation of NSDictionary based on GNU Dictionary class
Copyright (C) 1995 Free Software Foundation, Inc.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: April 1995
Created: April 1995
This file is part of the GNU Objective C Class Library.
@ -49,11 +49,8 @@
- nextObject
{
elt k, c;
if ([dictionary getNextKey:&k content:&c withEnumState:&enum_state])
return k.id_u;
else
return nil;
id k;
return [dictionary nextObjectAndKey: &k withEnumState: &enum_state];
}
- (void) dealloc
@ -71,11 +68,9 @@
- nextObject
{
elt k, c;
if ([dictionary getNextKey:&k content:&c withEnumState:&enum_state])
return c.id_u;
else
return nil;
id k;
[dictionary nextObjectAndKey: &k withEnumState: &enum_state];
return k;
}
@end
@ -85,63 +80,21 @@
+ (void) initialize
{
static int done = 0;
if (!done)
{
done = 1;
class_add_behavior([NSGDictionary class], [Dictionary class]);
}
}
/* This is the designated initializer */
- initWithObjects: (id*)objects
forKeys: (NSString**)keys
count: (unsigned)count
{
char * content_encoding = @encode(id);
char * key_encoding = @encode(id);
CALL_METHOD_IN_CLASS([KeyedCollection class], initWithType:keyType:,
content_encoding, key_encoding);
_contents_hash =
coll_hash_new(POWER_OF_TWO(count),
elt_get_hash_function(key_encoding),
elt_get_comparison_function(key_encoding));
_comparison_function = elt_get_comparison_function(content_encoding);
while (count--)
{
[keys[count] retain];
[objects[count] retain];
coll_hash_add(&_contents_hash, keys[count], objects[count]);
}
return self;
if (self == [NSGDictionary class])
class_add_behavior([NSGDictionary class], [Dictionary class]);
}
/*
Comes from Dictionary.m
- initWithObjects: (id*)objects
forKeys: (NSString**)keys
count: (unsigned)count
- (unsigned) count
- objectForKey: (NSString*)aKey
- (NSEnumerator*) keyEnumerator
- (NSEnumerator*) objectEnumerator
*/
- objectForKey: (NSString*)aKey
{
elt ret_nil(arglist_t a)
{
return nil;
}
return [self elementAtKey:aKey ifAbsentCall:ret_nil].id_u;
}
- (NSEnumerator*) keyEnumerator
{
return [[[NSGDictionaryKeyEnumerator alloc] initWithDictionary:self]
autorelease];
}
- (NSEnumerator*) objectEnumerator
{
return [[[NSGDictionaryObjectEnumerator alloc] initWithDictionary:self]
autorelease];
}
@end
@implementation NSGMutableDictionary
@ -163,16 +116,12 @@
- (void) setObject:anObject forKey:(NSString *)aKey
{
[self putElement:anObject atKey:aKey];
[self putObject: anObject atKey: aKey];
}
- (void) removeObjectForKey:(NSString *)aKey
{
elt do_nothing (arglist_t a)
{
return 0;
}
[self removeElementAtKey:aKey ifAbsentCall:do_nothing];
[self removeObjectAtKey: aKey];
}
@end

View file

@ -1,8 +1,8 @@
/* Concrete implementation of NSSet based on GNU Set class
Copyright (C) 1995 Free Software Foundation, Inc.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Created: Sep 1995
Created: September 1995
This file is part of the GNU Objective C Class Library.
@ -43,17 +43,13 @@
[super init];
set = d;
[set retain];
enum_state = 0;
enum_state = [set newEnumState];
return self;
}
- nextObject
{
elt e;
if ([set getNextElement:&e withEnumState:&enum_state])
return e.id_u;
else
return nil;
return [set nextObjectWithEnumState: &enum_state];
}
- (void) dealloc
@ -79,20 +75,14 @@
}
/* This is the designated initializer */
- initWithObjects: (id*)objects
count: (unsigned)count
{
[self initWithType:@encode(id)
capacity:count];
while (count--)
[self addObject:objects[count]];
return self;
}
/* This is the designated initializer
- initWithObjects: (id*)objects
count: (unsigned)count
Implemented by behavior. */
- member: anObject
{
return coll_hash_value_for_key(_contents_hash, anObject).id_u;
[self containsObject: anObject];
}
- (NSEnumerator*) objectEnumerator
@ -121,28 +111,20 @@
}
}
/* This is the designated initializer */
- initWithCapacity: (unsigned)numItems
{
return [self initWithType:@encode(id)
capacity:numItems];
}
/* This is the designated initializer
- initWithCapacity: (unsigned)numItems
implemented by behavior. */
- (void) addObject: anObject
{
[self addElement:anObject];
}
/* Implemented by behavior:
- (void) addObject: newObject;
- (void) removeObject: anObject
*/
- (void) removeAllObjects
{
[self empty];
}
- (void) removeObject: anObject
{
[self removeElement:anObject];
}
/* To deal with behavior over-enthusiasm. Will be fixed later. */
- (BOOL) isEqual: other
{

View file

@ -37,6 +37,7 @@
#include <Foundation/NSString.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSCharacterSet.h>
#include <Foundation/NSValue.h>
#include <objects/IndexedCollection.h>
#include <objects/IndexedCollectionPrivate.h>
#include <objects/String.h>
@ -953,12 +954,10 @@ handle_printf_atsign (FILE *stream,
@implementation NSString (GNU)
- (elt) elementAtIndex: (unsigned)index
- objectAtIndex: (unsigned)index
{
elt ret_elt;
CHECK_INDEX_RANGE_ERROR(index, [self cStringLength]);
ret_elt.char_u = [self _cStringContents][index];
return ret_elt;
return [NSNumber numberWithChar: [self _cStringContents][index]];
}
/* The rest are handled by the class_add_behavior() call in +initialize. */