This is KeyedCollection.m in view mode; [Download] [Up]
/* Implementation for Objective-C KeyedCollection 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/KeyedCollection.h>
@implementation KeyedCollection
+ initialize
{
if (self == [KeyedCollection class])
[self setVersion:-1]; /* alpha release */
return self;
}
// NON-OBJECT ELEMENT METHOD NAMES;
// INITIALIZING;
/* This is the designated initializer of this class */
- initDescription: (const char *)contentType
keyDescription: (const char *)keyType
{
[super initDescription:contentType];
if (objc_sizeof_type(keyType) != sizeof(elt))
[self error:
"KeyedCollection can't use keys with size different than (elt)"];
OBJC_MALLOC(_keyDescription, char, strlen(contentType)+1);
strcpy(_keyDescription, keyType);
return self;
}
- initKeyDescription: (const char *)keyType
{
return [self initDescription:"@" keyDescription:keyType];
}
- free
{
OBJC_FREE(_keyDescription);
return [super free];
}
// ADDING OR REPLACING;
- insertElement: (elt)newContentElement atKey: (elt)aKey
{
return [self subclassResponsibility:_cmd];
}
/* The right thing? */
- (elt) replaceElementAtKey: (elt)aKey with: (elt)newContentElement
{
elt ret;
ret = [self removeElementAtKey:aKey];
[self insertElement:newContentElement atKey:aKey];
return ret;
}
// REMOVING;
- (elt) removeElementAtKey: (elt)aKey
{
return [self subclassResponsibility:_cmd];
}
- removeObjectAtKey: (elt)aKey
{
return [self removeElementAtKey:aKey].id_t;
}
// GETTING ELEMENTS AND KEYS;
- (elt) elementAtKey: (elt)aKey
{
return [self subclassResponsibility:_cmd];
}
- (elt) keyElementOfElement: (elt)aContent
{
elt theKey = COLL_NO_KEY;
BOOL notDone = YES;
void doIt(elt key, elt content)
{
if (_compare_func(aContent.void_ptr_t, content.void_ptr_t))
{
theKey = key;
notDone = NO;
}
}
[self withKeysAndContentsCall:doIt whileTrue:¬Done];
if (notDone)
[self warning:"in %s, content not found", sel_get_name(_cmd)];
return theKey;
}
- objectAtKey: (elt)aKey
{
return [self elementAtKey:aKey].id_t;
}
- keyObjectOfObject: aContent
{
return [self keyElementOfElement:aContent].id_t;
}
// TESTING;
- (const char *) keyDescription
{
return _keyDescription;
}
- (BOOL) includesKey: (elt)aKey
{
[self subclassResponsibility:_cmd];
return NO;
}
// COPYING;
- shallowCopyAs: (id <Collecting>)aCollectionClass
{
id (*insertElementAtKeyImp)(id,SEL,elt,elt);
id newColl;
void addKeysAndContents(const elt key, elt content)
{
insertElementAtKeyImp(newColl, @selector(insertElement:atKey:),
content, key);
}
if ([(Object*)aCollectionClass conformsTo:@protocol(KeyedCollecting)])
{
newColl = [self emptyCopyAs:aCollectionClass];
insertElementAtKeyImp = (id(*)(id,SEL,elt,elt))
objc_msg_lookup(newColl, @selector(insertElement:atKey:));
[self withKeysAndContentsCall: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];
}
- withKeysCall: (void(*)(const elt))aFunc
{
void doIt(elt key, elt content)
{
aFunc(key);
}
[self withKeysAndContentsCall:doIt];
return self;
}
- withKeysAndContentsCall: (void(*)(const elt,elt))aFunc
{
BOOL flag = YES;
[self withKeysAndContentsCall:aFunc whileTrue:&flag];
return self;
}
- withKeysAndContentsCall: (void(*)(const elt,elt))aFunc
whileTrue: (BOOL *)flag
{
void *s;
elt key, content;
while ([self getNextKey:&key content:&content withEnumState:&s])
aFunc(key, content);
return self;
}
// ADDING OR REPLACING;
- insertObject: newContentObject atKey: (elt)aKey
{
return [self insertElement:newContentObject atKey:aKey];
}
- replaceObjectAtKey: (elt)aKey with: newContentObject
{
return [self replaceElementAtKey:aKey with:newContentObject].id_t;
}
// 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 withKeysCall:doIt];
return self;
}
- shallowCopyContentsAs: aCollectionClass
{
return [super shallowCopyAs:aCollectionClass];
}
// ENUMERATIONS;
/* All these need error checking to make sure we're sending messages
to objects */
- makeKeysPerform: (SEL)aSel
{
void doIt(elt e)
{
[e.id_t perform:aSel];
}
[self withKeysCall:doIt];
return self;
}
- makeKeysPerform: (SEL)aSel with: argObject
{
void doIt(elt e)
{
[e.id_t perform:aSel with:argObject];
}
[self withKeysCall:doIt];
return self;
}
- withKeysPerform: (SEL)aSel in: selObject
{
id (*aSelImp)(id,SEL,id) = (id(*)(id,SEL,id))
objc_msg_lookup(selObject, aSel);
void doIt(elt e)
{
aSelImp(selObject, aSel, e.id_t);
}
[self withKeysCall:doIt];
return self;
}
- withKeysPerform: (SEL)aSel in: selObject with: argObject
{
id (*aSelImp)(id,SEL,id,id) = (id(*)(id,SEL,id,id))
objc_msg_lookup(selObject, aSel);
void doIt(elt e)
{
aSelImp(selObject, aSel, e.id_t, argObject);
}
[self withElementsCall:doIt];
return self;
}
- withKeysAndContentsPerform: (SEL)aSel in: selObject
{
id (*aSelImp)(id,SEL,id,id) = (id(*)(id,SEL,id,id))
objc_msg_lookup(selObject, aSel);
void doIt(elt key, elt content)
{
aSelImp(selObject, aSel, key.id_t, content.id_t);
}
[self withKeysAndContentsCall:doIt];
return self;
}
- withContentsMakeKeysPerform: (SEL)aSel
{
void doIt(elt key, elt content)
{
[key.id_t perform:aSel with: content.id_t];
}
[self withKeysAndContentsCall:doIt];
return self;
}
- withContentsMakeKeysPerform: (SEL)aSel with: argObject
{
void doIt(elt key, elt content)
{
[key.id_t perform:aSel with: content.id_t with: argObject];
}
[self withKeysAndContentsCall:doIt];
return self;
}
- withKeysMakeContentsPerform: (SEL)aSel
{
void doIt(elt key, elt content)
{
[content.id_t perform:aSel with: key.id_t];
}
[self withKeysAndContentsCall:doIt];
return self;
}
- withKeysMakeContentsPerform: (SEL)aSel with: argObject
{
void doIt(elt key, elt content)
{
[content.id_t perform:aSel with: key.id_t with: argObject];
}
[self withKeysAndContentsCall:doIt];
return self;
}
- printForDebugger
{
void doIt(const elt key, elt content)
{
printf("(");
[[self class] printElement:key description:_keyDescription];
printf(",");
[self printElement:content];
printf(") ");
}
[self withKeysAndContentsCall:doIt];
printf(" :%s\n", [self name]);
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.