2001-12-17 14:31:42 +00:00
|
|
|
|
/** NSArray - Array object to hold other objects.
|
1998-10-08 13:46:53 +00:00
|
|
|
|
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1996-04-17 20:17:45 +00:00
|
|
|
|
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
From skeleton by: Adam Fedor <fedor@boulder.colorado.edu>
|
1996-04-16 23:22:08 +00:00
|
|
|
|
Created: March 1995
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1998-02-03 14:20:00 +00:00
|
|
|
|
Rewrite by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
2005-02-22 11:22:44 +00:00
|
|
|
|
January 1998 - new methods and changes as documented for Rhapsody plus
|
1998-02-03 14:20:00 +00:00
|
|
|
|
changes of array indices to type unsigned, plus major efficiency hacks.
|
|
|
|
|
|
1996-05-12 00:56:10 +00:00
|
|
|
|
This file is part of the GNUstep Base Library.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1995-04-03 22:59:20 +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.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1995-04-03 22:59:20 +00:00
|
|
|
|
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.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1995-04-03 22:59:20 +00:00
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
|
|
|
License along with this library; if not, write to the Free
|
2005-05-22 03:32:16 +00:00
|
|
|
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
|
2001-12-18 16:54:15 +00:00
|
|
|
|
|
|
|
|
|
<title>NSArray class reference</title>
|
|
|
|
|
$Date$ $Revision$
|
1995-04-04 16:01:04 +00:00
|
|
|
|
*/
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
2003-06-07 01:24:41 +00:00
|
|
|
|
#include "config.h"
|
|
|
|
|
#include "Foundation/NSArray.h"
|
|
|
|
|
#include "Foundation/NSCoder.h"
|
|
|
|
|
#include "Foundation/NSData.h"
|
|
|
|
|
#include "Foundation/NSString.h"
|
|
|
|
|
#include "Foundation/NSRange.h"
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
#include <limits.h>
|
2003-06-07 01:24:41 +00:00
|
|
|
|
#include "Foundation/NSUtilities.h"
|
|
|
|
|
#include "Foundation/NSException.h"
|
|
|
|
|
#include "Foundation/NSAutoreleasePool.h"
|
|
|
|
|
#include "Foundation/NSThread.h"
|
|
|
|
|
#include "Foundation/NSMapTable.h"
|
|
|
|
|
#include "Foundation/NSLock.h"
|
|
|
|
|
#include "Foundation/NSDebug.h"
|
2004-01-06 19:43:29 +00:00
|
|
|
|
#include "Foundation/NSValue.h"
|
|
|
|
|
#include "Foundation/NSNull.h"
|
2004-01-27 21:51:33 +00:00
|
|
|
|
// For private method _decodeArrayOfObjectsForKey:
|
|
|
|
|
#include "Foundation/NSKeyedArchiver.h"
|
2003-07-31 23:49:32 +00:00
|
|
|
|
#include "GNUstepBase/GSCategories.h"
|
2002-03-13 09:58:43 +00:00
|
|
|
|
#include "GSPrivate.h"
|
1995-07-01 18:38:03 +00:00
|
|
|
|
|
2002-11-09 06:45:31 +00:00
|
|
|
|
extern BOOL GSMacOSXCompatiblePropertyLists(void);
|
2002-11-27 13:56:00 +00:00
|
|
|
|
extern void GSPropertyListMake(id,NSDictionary*,BOOL,BOOL,unsigned,id*);
|
2002-11-09 06:45:31 +00:00
|
|
|
|
|
2005-07-08 11:48:37 +00:00
|
|
|
|
@interface NSArrayEnumerator : NSEnumerator
|
|
|
|
|
{
|
|
|
|
|
NSArray *array;
|
|
|
|
|
unsigned pos;
|
|
|
|
|
IMP get;
|
|
|
|
|
unsigned (*cnt)(NSArray*, SEL);
|
|
|
|
|
}
|
|
|
|
|
- (id) initWithArray: (NSArray*)anArray;
|
|
|
|
|
@end
|
|
|
|
|
@interface NSArrayEnumeratorReverse : NSArrayEnumerator
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
1995-07-01 18:38:03 +00:00
|
|
|
|
|
2001-01-08 16:45:36 +00:00
|
|
|
|
@class GSArray;
|
2005-07-08 11:48:37 +00:00
|
|
|
|
@interface GSArray : NSObject // Help the compiler
|
|
|
|
|
@end
|
2001-01-08 16:45:36 +00:00
|
|
|
|
@class GSInlineArray;
|
2005-07-08 11:48:37 +00:00
|
|
|
|
@interface GSInlineArray : NSObject // Help the compiler
|
|
|
|
|
@end
|
2001-01-08 16:45:36 +00:00
|
|
|
|
@class GSMutableArray;
|
2005-07-08 11:48:37 +00:00
|
|
|
|
@interface GSMutableArray : NSObject // Help the compiler
|
|
|
|
|
@end
|
2001-01-08 16:45:36 +00:00
|
|
|
|
@class GSPlaceholderArray;
|
2005-07-08 11:48:37 +00:00
|
|
|
|
@interface GSPlaceholderArray : NSObject // Help the compiler
|
|
|
|
|
@end
|
2001-01-08 16:45:36 +00:00
|
|
|
|
|
|
|
|
|
static Class NSArrayClass;
|
|
|
|
|
static Class GSArrayClass;
|
|
|
|
|
static Class GSInlineArrayClass;
|
|
|
|
|
static Class NSMutableArrayClass;
|
|
|
|
|
static Class GSMutableArrayClass;
|
|
|
|
|
static Class GSPlaceholderArrayClass;
|
1995-07-01 18:38:03 +00:00
|
|
|
|
|
2001-01-08 16:45:36 +00:00
|
|
|
|
static GSPlaceholderArray *defaultPlaceholderArray;
|
|
|
|
|
static NSMapTable *placeholderMap;
|
|
|
|
|
static NSLock *placeholderLock;
|
2000-10-30 18:00:27 +00:00
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2003-04-06 17:20:04 +00:00
|
|
|
|
* A simple, low overhead, ordered container for objects. All the objects
|
|
|
|
|
* in the container are retained by it. The container may not contain nil
|
|
|
|
|
* (though it may contain [NSNull+null]).
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
1996-03-31 22:23:37 +00:00
|
|
|
|
@implementation NSArray
|
1995-07-01 18:38:03 +00:00
|
|
|
|
|
2000-10-30 18:00:27 +00:00
|
|
|
|
static SEL addSel;
|
|
|
|
|
static SEL appSel;
|
|
|
|
|
static SEL countSel;
|
|
|
|
|
static SEL eqSel;
|
|
|
|
|
static SEL oaiSel;
|
|
|
|
|
static SEL remSel;
|
|
|
|
|
static SEL rlSel;
|
|
|
|
|
|
1996-03-31 22:23:37 +00:00
|
|
|
|
+ (void) initialize
|
1995-07-01 18:38:03 +00:00
|
|
|
|
{
|
1996-03-31 22:23:37 +00:00
|
|
|
|
if (self == [NSArray class])
|
|
|
|
|
{
|
2000-10-30 18:00:27 +00:00
|
|
|
|
[self setVersion: 1];
|
|
|
|
|
|
|
|
|
|
addSel = @selector(addObject:);
|
|
|
|
|
appSel = @selector(appendString:);
|
|
|
|
|
countSel = @selector(count);
|
|
|
|
|
eqSel = @selector(isEqual:);
|
|
|
|
|
oaiSel = @selector(objectAtIndex:);
|
|
|
|
|
remSel = @selector(removeObjectAtIndex:);
|
|
|
|
|
rlSel = @selector(removeLastObject);
|
|
|
|
|
|
2001-01-08 16:45:36 +00:00
|
|
|
|
NSArrayClass = [NSArray class];
|
|
|
|
|
NSMutableArrayClass = [NSMutableArray class];
|
|
|
|
|
GSArrayClass = [GSArray class];
|
|
|
|
|
GSInlineArrayClass = [GSInlineArray class];
|
|
|
|
|
GSMutableArrayClass = [GSMutableArray class];
|
|
|
|
|
GSPlaceholderArrayClass = [GSPlaceholderArray class];
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Set up infrastructure for placeholder arrays.
|
|
|
|
|
*/
|
|
|
|
|
defaultPlaceholderArray = (GSPlaceholderArray*)
|
|
|
|
|
NSAllocateObject(GSPlaceholderArrayClass, 0, NSDefaultMallocZone());
|
|
|
|
|
placeholderMap = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
|
|
|
|
|
NSNonRetainedObjectMapValueCallBacks, 0);
|
|
|
|
|
placeholderLock = [NSLock new];
|
1996-03-31 22:23:37 +00:00
|
|
|
|
}
|
1995-07-01 18:38:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
+ (id) allocWithZone: (NSZone*)z
|
1995-06-30 13:45:13 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
if (self == NSArrayClass)
|
2000-08-07 22:00:31 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
/*
|
|
|
|
|
* For a constant array, we return a placeholder object that can
|
|
|
|
|
* be converted to a real object when its initialisation method
|
|
|
|
|
* is called.
|
|
|
|
|
*/
|
|
|
|
|
if (z == NSDefaultMallocZone() || z == 0)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* As a special case, we can return a placeholder for an array
|
|
|
|
|
* in the default malloc zone extremely efficiently.
|
|
|
|
|
*/
|
|
|
|
|
return defaultPlaceholderArray;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
id obj;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* For anything other than the default zone, we need to
|
|
|
|
|
* locate the correct placeholder in the (lock protected)
|
|
|
|
|
* table of placeholders.
|
|
|
|
|
*/
|
|
|
|
|
[placeholderLock lock];
|
|
|
|
|
obj = (id)NSMapGet(placeholderMap, (void*)z);
|
|
|
|
|
if (obj == nil)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* There is no placeholder object for this zone, so we
|
|
|
|
|
* create a new one and use that.
|
|
|
|
|
*/
|
|
|
|
|
obj = (id)NSAllocateObject(GSPlaceholderArrayClass, 0, z);
|
|
|
|
|
NSMapInsert(placeholderMap, (void*)z, (void*)obj);
|
|
|
|
|
}
|
|
|
|
|
[placeholderLock unlock];
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
2000-08-07 22:00:31 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return NSAllocateObject(self, 0, z);
|
|
|
|
|
}
|
1995-06-30 13:45:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an empty autoreleased array.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
+ (id) array
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
o = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
o = [o initWithObjects: (id*)0 count: 0];
|
|
|
|
|
return AUTORELEASE(o);
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a new autoreleased NSArray instance containing all the objects from
|
|
|
|
|
* array, in the same order as the original.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
+ (id) arrayWithArray: (NSArray*)array
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
o = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
o = [o initWithArray: array];
|
|
|
|
|
return AUTORELEASE(o);
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* Returns an autoreleased array based upon the file. The new array is
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* created using [NSObject+allocWithZone:] and initialised using the
|
|
|
|
|
* [NSArray-initWithContentsOfFile:] method. See the documentation for those
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* methods for more detail.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
+ (id) arrayWithContentsOfFile: (NSString*)file
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
o = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
o = [o initWithContentsOfFile: file];
|
|
|
|
|
return AUTORELEASE(o);
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-15 16:35:11 +00:00
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* Returns an autoreleased array from the contents of aURL. The new array is
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* created using [NSObject+allocWithZone:] and initialised using the
|
2003-07-15 16:35:11 +00:00
|
|
|
|
* -initWithContentsOfURL: method. See the documentation for those
|
|
|
|
|
* methods for more detail.
|
|
|
|
|
*/
|
|
|
|
|
+ (id) arrayWithContentsOfURL: (NSURL*)aURL
|
|
|
|
|
{
|
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
o = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
o = [o initWithContentsOfURL: aURL];
|
|
|
|
|
return AUTORELEASE(o);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array containing anObject.
|
|
|
|
|
*/
|
2000-10-30 18:00:27 +00:00
|
|
|
|
+ (id) arrayWithObject: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2000-10-30 18:00:27 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
2001-01-08 16:45:36 +00:00
|
|
|
|
o = [self allocWithZone: NSDefaultMallocZone()];
|
2000-10-30 18:00:27 +00:00
|
|
|
|
o = [o initWithObjects: &anObject count: 1];
|
|
|
|
|
return AUTORELEASE(o);
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array containing the list
|
|
|
|
|
* of objects, preserving order.
|
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
+ (id) arrayWithObjects: firstObject, ...
|
1998-08-01 21:34:58 +00:00
|
|
|
|
{
|
2003-04-06 17:20:04 +00:00
|
|
|
|
id a = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
|
|
|
|
|
GS_USEIDLIST(firstObject,
|
2005-02-22 11:22:44 +00:00
|
|
|
|
a = [a initWithObjects: __objects count: __count]);
|
2003-04-06 17:20:04 +00:00
|
|
|
|
return AUTORELEASE(a);
|
1998-08-01 21:34:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array containing the specified
|
|
|
|
|
* objects, preserving order.
|
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
+ (id) arrayWithObjects: (id*)objects count: (unsigned)count
|
1998-08-01 21:34:58 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
|
initWithObjects: objects count: count]);
|
1998-08-01 21:34:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array formed from the contents of
|
|
|
|
|
* the receiver and adding anObject as the last item.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (NSArray*) arrayByAddingObject: (id)anObject
|
1996-03-30 19:14:43 +00:00
|
|
|
|
{
|
|
|
|
|
id na;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
unsigned c = [self count];
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (anObject == nil)
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"Attempt to add nil to an array"];
|
|
|
|
|
if (c == 0)
|
2003-10-14 09:00:42 +00:00
|
|
|
|
{
|
|
|
|
|
na = [[GSArrayClass allocWithZone: NSDefaultMallocZone()]
|
|
|
|
|
initWithObjects: &anObject count: 1];
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINIDBUF(objects, c+1);
|
1998-10-08 13:46:53 +00:00
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
[self getObjects: objects];
|
|
|
|
|
objects[c] = anObject;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
na = [[GSArrayClass allocWithZone: NSDefaultMallocZone()]
|
1999-09-14 19:24:58 +00:00
|
|
|
|
initWithObjects: objects count: c+1];
|
2003-10-14 09:00:42 +00:00
|
|
|
|
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1999-06-30 21:13:19 +00:00
|
|
|
|
return AUTORELEASE(na);
|
1996-03-30 19:14:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a new array which is the concatenation of self and
|
|
|
|
|
* otherArray (in this precise order).
|
|
|
|
|
*/
|
1996-03-30 19:14:43 +00:00
|
|
|
|
- (NSArray*) arrayByAddingObjectsFromArray: (NSArray*)anotherArray
|
|
|
|
|
{
|
1999-06-04 16:05:45 +00:00
|
|
|
|
id na;
|
|
|
|
|
unsigned c, l;
|
1998-10-08 13:46:53 +00:00
|
|
|
|
|
1999-06-04 16:05:45 +00:00
|
|
|
|
c = [self count];
|
|
|
|
|
l = [anotherArray count];
|
|
|
|
|
|
2004-09-10 15:10:54 +00:00
|
|
|
|
{
|
|
|
|
|
GS_BEGINIDBUF(objects, c+l);
|
2003-10-14 09:00:42 +00:00
|
|
|
|
|
2004-09-10 15:10:54 +00:00
|
|
|
|
[self getObjects: objects];
|
|
|
|
|
[anotherArray getObjects: &objects[c]];
|
|
|
|
|
na = [NSArrayClass arrayWithObjects: objects count: c+l];
|
2003-10-14 09:00:42 +00:00
|
|
|
|
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
|
|
|
|
}
|
2003-10-14 09:00:42 +00:00
|
|
|
|
|
1999-06-04 16:05:45 +00:00
|
|
|
|
return na;
|
1996-03-30 19:14:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* Returns the abstract class ... arrays are coded as abstract arrays.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (Class) classForCoder
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return NSArrayClass;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns YES if anObject belongs to self. No otherwise.<br />
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* The [NSObject-isEqual:] method of anObject is used to test for equality.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
|
|
|
|
- (BOOL) containsObject: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return ([self indexOfObject: anObject] != NSNotFound);
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2003-01-20 17:18:06 +00:00
|
|
|
|
* Returns a new copy of the receiver.<br />
|
|
|
|
|
* The default abstract implementation of a copy is to use the
|
|
|
|
|
* -initWithArray:copyItems: method with the flag set to YES.<br />
|
|
|
|
|
* Immutable subclasses generally simply retain and return the receiver.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) copyWithZone: (NSZone*)zone
|
1998-05-13 19:25:38 +00:00
|
|
|
|
{
|
2003-01-20 17:18:06 +00:00
|
|
|
|
NSArray *copy = [NSArrayClass allocWithZone: zone];
|
|
|
|
|
|
|
|
|
|
return [copy initWithArray: self copyItems: YES];
|
1998-05-13 19:25:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/** <override-subclass />
|
|
|
|
|
* Returns the number of elements contained in the receiver.
|
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (unsigned) count
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
|
|
|
|
return 0;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Encodes the receiver for storing to archive or sending over an
|
|
|
|
|
* [NSConnection].
|
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
unsigned count = [self count];
|
1998-01-19 15:20:15 +00:00
|
|
|
|
|
2004-01-28 07:33:20 +00:00
|
|
|
|
if ([aCoder allowsKeyedCoding])
|
|
|
|
|
{
|
|
|
|
|
/* HACK ... MacOS-X seems to code differently if the coder is an
|
|
|
|
|
* actual instance of NSKeyedArchiver
|
|
|
|
|
*/
|
|
|
|
|
if ([aCoder class] == [NSKeyedArchiver class])
|
|
|
|
|
{
|
|
|
|
|
[(NSKeyedArchiver*)aCoder _encodeArrayOfObjects: self
|
|
|
|
|
forKey: @"NS.objects"];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
unsigned i;
|
1998-10-08 13:46:53 +00:00
|
|
|
|
|
2004-01-28 07:33:20 +00:00
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
{
|
|
|
|
|
NSString *key;
|
|
|
|
|
|
|
|
|
|
key = [NSString stringWithFormat: @"NS.object.%u", i];
|
|
|
|
|
[(NSKeyedArchiver*)aCoder encodeObject: [self objectAtIndex: i]
|
|
|
|
|
forKey: key];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2001-01-08 16:45:36 +00:00
|
|
|
|
{
|
2004-01-28 07:33:20 +00:00
|
|
|
|
[aCoder encodeValueOfObjCType: @encode(unsigned)
|
|
|
|
|
at: &count];
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
2004-01-28 07:33:20 +00:00
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINIDBUF(a, count);
|
2004-01-28 07:33:20 +00:00
|
|
|
|
|
|
|
|
|
[self getObjects: a];
|
|
|
|
|
[aCoder encodeArrayOfObjCType: @encode(id)
|
|
|
|
|
count: count
|
|
|
|
|
at: a];
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
2004-01-28 07:33:20 +00:00
|
|
|
|
}
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Copies the objects from the receiver to aBuffer, which must be
|
|
|
|
|
* an area of memory large enough to hold them.
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (void) getObjects: (id*)aBuffer
|
|
|
|
|
{
|
1998-02-03 14:20:00 +00:00
|
|
|
|
unsigned i, c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
for (i = 0; i < c; i++)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
aBuffer[i] = (*get)(self, oaiSel, i);
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Copies the objects from the range aRange of the receiver to aBuffer,
|
|
|
|
|
* which must be an area of memory large enough to hold them.
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (void) getObjects: (id*)aBuffer range: (NSRange)aRange
|
|
|
|
|
{
|
1998-02-03 14:20:00 +00:00
|
|
|
|
unsigned i, j = 0, c = [self count], e = aRange.location + aRange.length;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1999-06-21 08:30:26 +00:00
|
|
|
|
GS_RANGE_CHECK(aRange, c);
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1999-05-11 13:05:24 +00:00
|
|
|
|
for (i = aRange.location; i < e; i++)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
aBuffer[j++] = (*get)(self, oaiSel, i);
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* Returns the same value as -count
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
1998-10-27 08:12:49 +00:00
|
|
|
|
- (unsigned) hash
|
|
|
|
|
{
|
1999-06-04 16:05:45 +00:00
|
|
|
|
return [self count];
|
1998-10-27 08:12:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the index of the specified object in the receiver, or
|
|
|
|
|
* NSNotFound if the object is not present.
|
|
|
|
|
*/
|
|
|
|
|
- (unsigned) indexOfObjectIdenticalTo: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
unsigned c = [self count];
|
|
|
|
|
|
|
|
|
|
if (c > 0)
|
|
|
|
|
{
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
if (anObject == (*get)(self, oaiSel, i))
|
|
|
|
|
return i;
|
|
|
|
|
}
|
1995-09-21 17:42:46 +00:00
|
|
|
|
return NSNotFound;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the index of the specified object in the range of the receiver,
|
|
|
|
|
* or NSNotFound if the object is not present.
|
|
|
|
|
*/
|
1999-04-08 12:17:15 +00:00
|
|
|
|
- (unsigned) indexOfObjectIdenticalTo: anObject inRange: (NSRange)aRange
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1998-02-03 14:20:00 +00:00
|
|
|
|
unsigned i, e = aRange.location + aRange.length, c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1999-06-21 08:30:26 +00:00
|
|
|
|
GS_RANGE_CHECK(aRange, c);
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
for (i = aRange.location; i < e; i++)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (anObject == (*get)(self, oaiSel, i))
|
1998-01-19 15:20:15 +00:00
|
|
|
|
return i;
|
|
|
|
|
return NSNotFound;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the index of the first object found in the receiver
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* which is equal to anObject (using anObject's [NSObject-isEqual:] method).
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* Returns NSNotFound on failure.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (unsigned) indexOfObject: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
unsigned c = [self count];
|
|
|
|
|
|
|
|
|
|
if (c > 0 && anObject != nil)
|
|
|
|
|
{
|
|
|
|
|
unsigned i;
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
BOOL (*eq)(id, SEL, id)
|
|
|
|
|
= (BOOL (*)(id, SEL, id))[anObject methodForSelector: eqSel];
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
if ((*eq)(anObject, eqSel, (*get)(self, oaiSel, i)) == YES)
|
|
|
|
|
return i;
|
|
|
|
|
}
|
1995-09-21 17:42:46 +00:00
|
|
|
|
return NSNotFound;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the index of the first object found in aRange of receiver
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* which is equal to anObject (using anObject's [NSObject-isEqual:] method).
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* Returns NSNotFound on failure.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (unsigned) indexOfObject: (id)anObject inRange: (NSRange)aRange
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1998-02-03 14:20:00 +00:00
|
|
|
|
unsigned i, e = aRange.location + aRange.length, c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
BOOL (*eq)(id, SEL, id)
|
|
|
|
|
= (BOOL (*)(id, SEL, id))[anObject methodForSelector: eqSel];
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1999-06-21 08:30:26 +00:00
|
|
|
|
GS_RANGE_CHECK(aRange, c);
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
for (i = aRange.location; i < e; i++)
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if ((*eq)(anObject, eqSel, (*get)(self, oaiSel, i)) == YES)
|
1998-01-19 15:20:15 +00:00
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
return NSNotFound;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-07 05:43:20 +00:00
|
|
|
|
/**
|
|
|
|
|
* <p>In MacOS-X class clusters do not have designated initialisers,
|
|
|
|
|
* and there is a general rule that -init is treated as the designated
|
|
|
|
|
* initialiser of the class cluster, but that other intitialisers
|
|
|
|
|
* may not work s expected an would need to be individually overridden
|
|
|
|
|
* in any subclass.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>GNUstep tries to make it easier to subclass a class cluster,
|
|
|
|
|
* by making class clusters follow the same convention as normal
|
|
|
|
|
* classes, so the designated initialiser is the <em>richest</em>
|
|
|
|
|
* initialiser. This means that all other initialisers call the
|
|
|
|
|
* documented designated initialiser (which calls -init only for
|
|
|
|
|
* MacOS-X compatibility), and anyone writing a subclass only needs
|
|
|
|
|
* to override that one initialiser in order to have all the other
|
|
|
|
|
* ones work.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>For MacOS-X compatibility, you may also need to override various
|
|
|
|
|
* other initialisers. Exactly which ones, you will need to determine
|
|
|
|
|
* by trial on a MacOS-X system ... and may vary between releases of
|
|
|
|
|
* MacOS-X. So to be safe, on MacOS-X you probably need to re-implement
|
|
|
|
|
* <em>all</em> the class cluster initialisers you might use in conjunction
|
|
|
|
|
* with your subclass.
|
|
|
|
|
* </p>
|
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) init
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2004-09-07 05:43:20 +00:00
|
|
|
|
self = [super init];
|
|
|
|
|
return self;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2002-08-27 09:37:58 +00:00
|
|
|
|
* Initialize the receiver with the contents of array.
|
|
|
|
|
* The order of array is preserved.<br />
|
|
|
|
|
* If shouldCopy is YES then the objects are copied
|
|
|
|
|
* rather than simply retained.<br />
|
|
|
|
|
* Invokes -initWithObjects:count:
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2002-08-27 09:37:58 +00:00
|
|
|
|
- (id) initWithArray: (NSArray*)array copyItems: (BOOL)shouldCopy
|
2001-01-08 16:45:36 +00:00
|
|
|
|
{
|
2002-08-27 09:37:58 +00:00
|
|
|
|
unsigned c = [array count];
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINIDBUF(objects, c);
|
2001-01-08 16:45:36 +00:00
|
|
|
|
|
2002-08-27 09:37:58 +00:00
|
|
|
|
[array getObjects: objects];
|
|
|
|
|
if (shouldCopy == YES)
|
|
|
|
|
{
|
|
|
|
|
unsigned i;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
|
2002-08-27 09:37:58 +00:00
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
{
|
|
|
|
|
objects[i] = [objects[i] copy];
|
|
|
|
|
}
|
|
|
|
|
self = [self initWithObjects: objects count: c];
|
|
|
|
|
#if GS_WITH_GC == 0
|
|
|
|
|
while (i > 0)
|
|
|
|
|
{
|
|
|
|
|
[objects[--i] release];
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
self = [self initWithObjects: objects count: c];
|
|
|
|
|
}
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
2002-08-27 09:37:58 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialize the receiver with the contents of array.
|
|
|
|
|
* The order of array is preserved.<br />
|
|
|
|
|
* Invokes -initWithObjects:count:
|
|
|
|
|
*/
|
|
|
|
|
- (id) initWithArray: (NSArray*)array
|
|
|
|
|
{
|
|
|
|
|
unsigned c = [array count];
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINIDBUF(objects, c);
|
2002-08-27 09:37:58 +00:00
|
|
|
|
|
|
|
|
|
[array getObjects: objects];
|
|
|
|
|
self = [self initWithObjects: objects count: c];
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2002-08-27 09:37:58 +00:00
|
|
|
|
* Initialize the array by decoding from an archive.<br />
|
|
|
|
|
* Invokes -initWithObjects:count:
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) initWithCoder: (NSCoder*)aCoder
|
|
|
|
|
{
|
2004-01-27 21:51:33 +00:00
|
|
|
|
if ([aCoder allowsKeyedCoding])
|
2001-01-08 16:45:36 +00:00
|
|
|
|
{
|
2004-01-28 07:33:20 +00:00
|
|
|
|
id array;
|
|
|
|
|
|
2005-02-22 11:22:44 +00:00
|
|
|
|
array = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
|
2004-01-27 21:51:33 +00:00
|
|
|
|
@"NS.objects"];
|
2004-01-28 07:33:20 +00:00
|
|
|
|
if (array == nil)
|
|
|
|
|
{
|
|
|
|
|
unsigned i = 0;
|
|
|
|
|
NSString *key;
|
|
|
|
|
id val;
|
|
|
|
|
|
|
|
|
|
array = [NSMutableArray arrayWithCapacity: 2];
|
|
|
|
|
key = [NSString stringWithFormat: @"NS.object.%u", i];
|
|
|
|
|
val = [(NSKeyedUnarchiver*)aCoder decodeObjectForKey: key];
|
|
|
|
|
|
|
|
|
|
while (val != nil)
|
|
|
|
|
{
|
|
|
|
|
[array addObject: val];
|
|
|
|
|
i++;
|
|
|
|
|
key = [NSString stringWithFormat: @"NS.object.%u", i];
|
|
|
|
|
val = [(NSKeyedUnarchiver*)aCoder decodeObjectForKey: key];
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-08 16:45:36 +00:00
|
|
|
|
|
2004-01-28 07:33:20 +00:00
|
|
|
|
self = [self initWithArray: array];
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2002-08-27 09:37:58 +00:00
|
|
|
|
{
|
2004-01-27 21:51:33 +00:00
|
|
|
|
unsigned count;
|
|
|
|
|
|
|
|
|
|
[aCoder decodeValueOfObjCType: @encode(unsigned)
|
|
|
|
|
at: &count];
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINIDBUF(contents, count);
|
2004-01-27 21:51:33 +00:00
|
|
|
|
|
2004-09-10 15:10:54 +00:00
|
|
|
|
[aCoder decodeArrayOfObjCType: @encode(id)
|
|
|
|
|
count: count
|
|
|
|
|
at: contents];
|
2004-01-27 21:51:33 +00:00
|
|
|
|
self = [self initWithObjects: contents count: count];
|
|
|
|
|
#if GS_WITH_GC == 0
|
|
|
|
|
while (count-- > 0)
|
|
|
|
|
{
|
|
|
|
|
[contents[count] release];
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
2004-01-27 21:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
self = [self initWithObjects: 0 count: 0];
|
|
|
|
|
}
|
2002-08-27 09:37:58 +00:00
|
|
|
|
}
|
2003-10-08 15:03:58 +00:00
|
|
|
|
return self;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-21 09:45:30 +00:00
|
|
|
|
/**
|
|
|
|
|
* <p>Initialises the array with the contents of the specified file,
|
|
|
|
|
* which must contain an array in property-list format.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>In GNUstep, the property-list format may be either the OpenStep
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* format (ASCII data), or the MacOS-X format (UTF-8 XML data) ... this
|
2002-03-21 09:45:30 +00:00
|
|
|
|
* method will recognise which it is.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>If there is a failure to load the file for any reason, the receiver
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* will be released, the method will return nil, and a warning may be logged.
|
2002-03-21 09:45:30 +00:00
|
|
|
|
* </p>
|
2002-10-04 09:08:09 +00:00
|
|
|
|
* <p>Works by invoking [NSString-initWithContentsOfFile:] and
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* [NSString-propertyList] then checking that the result is an array.
|
2002-10-04 09:08:09 +00:00
|
|
|
|
* </p>
|
2002-03-21 09:45:30 +00:00
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) initWithContentsOfFile: (NSString*)file
|
|
|
|
|
{
|
|
|
|
|
NSString *myString;
|
|
|
|
|
|
2002-03-21 09:45:30 +00:00
|
|
|
|
myString = [[NSString allocWithZone: NSDefaultMallocZone()]
|
2002-10-04 09:08:09 +00:00
|
|
|
|
initWithContentsOfFile: file];
|
|
|
|
|
if (myString == nil)
|
|
|
|
|
{
|
|
|
|
|
DESTROY(self);
|
|
|
|
|
}
|
|
|
|
|
else
|
2001-01-08 16:45:36 +00:00
|
|
|
|
{
|
|
|
|
|
id result;
|
|
|
|
|
|
|
|
|
|
NS_DURING
|
|
|
|
|
{
|
|
|
|
|
result = [myString propertyList];
|
|
|
|
|
}
|
|
|
|
|
NS_HANDLER
|
|
|
|
|
{
|
|
|
|
|
result = nil;
|
|
|
|
|
}
|
|
|
|
|
NS_ENDHANDLER
|
|
|
|
|
RELEASE(myString);
|
|
|
|
|
if ([result isKindOfClass: NSArrayClass])
|
|
|
|
|
{
|
2001-01-26 12:09:35 +00:00
|
|
|
|
self = [self initWithArray: result];
|
2002-10-04 09:08:09 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NSWarnMLog(@"Contents of file '%@' does not contain an array", file);
|
|
|
|
|
DESTROY(self);
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-04 09:08:09 +00:00
|
|
|
|
return self;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-15 16:35:11 +00:00
|
|
|
|
/**
|
|
|
|
|
* <p>Initialises the array with the contents of the specified URL,
|
|
|
|
|
* which must contain an array in property-list format.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>In GNUstep, the property-list format may be either the OpenStep
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* format (ASCII data), or the MacOS-X format (UTF8 XML data) ... this
|
2003-07-15 16:35:11 +00:00
|
|
|
|
* method will recognise which it is.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>If there is a failure to load the URL for any reason, the receiver
|
|
|
|
|
* will be released, the method will return nil, and a warning may be logged.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>Works by invoking [NSString-initWithContentsOfURL:] and
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* [NSString-propertyList] then checking that the result is an array.
|
2003-07-15 16:35:11 +00:00
|
|
|
|
* </p>
|
|
|
|
|
*/
|
|
|
|
|
- (id) initWithContentsOfURL: (NSURL*)aURL
|
|
|
|
|
{
|
|
|
|
|
NSString *myString;
|
|
|
|
|
|
|
|
|
|
myString = [[NSString allocWithZone: NSDefaultMallocZone()]
|
|
|
|
|
initWithContentsOfURL: aURL];
|
|
|
|
|
if (myString == nil)
|
|
|
|
|
{
|
|
|
|
|
DESTROY(self);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
id result;
|
|
|
|
|
|
|
|
|
|
NS_DURING
|
|
|
|
|
{
|
|
|
|
|
result = [myString propertyList];
|
|
|
|
|
}
|
|
|
|
|
NS_HANDLER
|
|
|
|
|
{
|
|
|
|
|
result = nil;
|
|
|
|
|
}
|
|
|
|
|
NS_ENDHANDLER
|
|
|
|
|
RELEASE(myString);
|
|
|
|
|
if ([result isKindOfClass: NSArrayClass])
|
|
|
|
|
{
|
|
|
|
|
self = [self initWithArray: result];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NSWarnMLog(@"Contents of URL '%@' does not contain an array", aURL);
|
|
|
|
|
DESTROY(self);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-07 05:43:20 +00:00
|
|
|
|
/** <init /> <override-subclass />
|
|
|
|
|
* This should initialize the array with count (may be zero) objects.<br />
|
2002-08-27 09:37:58 +00:00
|
|
|
|
* Retains each object placed in the array.<br />
|
2004-09-07 05:43:20 +00:00
|
|
|
|
* Calls -init (which does nothing but maintain MacOS-X compatibility),
|
|
|
|
|
* and needs to be re-implemented in subclasses in order to have all
|
|
|
|
|
* other initialisers work.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) initWithObjects: (id*)objects count: (unsigned)count
|
|
|
|
|
{
|
2004-09-07 05:43:20 +00:00
|
|
|
|
self = [self init];
|
|
|
|
|
return self;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Initialize the array the list of objects.
|
|
|
|
|
* <br />May change the value of self before returning it.
|
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) initWithObjects: firstObject, ...
|
|
|
|
|
{
|
2003-04-06 17:20:04 +00:00
|
|
|
|
GS_USEIDLIST(firstObject,
|
2005-02-22 11:22:44 +00:00
|
|
|
|
self = [self initWithObjects: __objects count: __count]);
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an NSMutableArray instance containing the same objects as
|
2003-01-20 17:18:06 +00:00
|
|
|
|
* the receiver.<br />
|
|
|
|
|
* The default implementation does this by calling the
|
|
|
|
|
* -initWithArray:copyItems: method on a newly created object,
|
|
|
|
|
* and passing it NO to tell it just to retain the items.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) mutableCopyWithZone: (NSZone*)zone
|
|
|
|
|
{
|
2003-01-20 17:18:06 +00:00
|
|
|
|
NSMutableArray *copy = [NSMutableArrayClass allocWithZone: zone];
|
|
|
|
|
|
|
|
|
|
return [copy initWithArray: self copyItems: NO];
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/** <override-subclass />
|
|
|
|
|
* Returns the object at the specified index.
|
|
|
|
|
* Raises an exception of the index is beyond the array.
|
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) objectAtIndex: (unsigned)index
|
|
|
|
|
{
|
|
|
|
|
[self subclassResponsibility: _cmd];
|
|
|
|
|
return nil;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (BOOL) isEqual: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (self == anObject)
|
|
|
|
|
return YES;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
if ([anObject isKindOfClass: NSArrayClass])
|
1999-04-08 12:17:15 +00:00
|
|
|
|
return [self isEqualToArray: anObject];
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns YES if the receiver is equal to otherArray, NO otherwise.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (BOOL) isEqualToArray: (NSArray*)otherArray
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
unsigned i, c;
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (self == (id)otherArray)
|
|
|
|
|
return YES;
|
|
|
|
|
c = [self count];
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
if (c != [otherArray count])
|
1995-04-04 16:01:04 +00:00
|
|
|
|
return NO;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (c > 0)
|
|
|
|
|
{
|
|
|
|
|
IMP get0 = [self methodForSelector: oaiSel];
|
|
|
|
|
IMP get1 = [otherArray methodForSelector: oaiSel];
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
if (![(*get0)(self, oaiSel, i) isEqual: (*get1)(otherArray, oaiSel, i)])
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
1995-04-04 16:01:04 +00:00
|
|
|
|
return YES;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the last object in the receiver, or nil if the receiver is empty.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (id) lastObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1998-02-03 14:20:00 +00:00
|
|
|
|
unsigned count = [self count];
|
1996-03-30 23:00:27 +00:00
|
|
|
|
if (count == 0)
|
|
|
|
|
return nil;
|
|
|
|
|
return [self objectAtIndex: count-1];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Makes each object in the array perform aSelector.<br />
|
2004-09-16 14:33:54 +00:00
|
|
|
|
* This is done sequentially from the first to the last object.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
1998-11-14 03:48:55 +00:00
|
|
|
|
- (void) makeObjectsPerformSelector: (SEL)aSelector
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2004-09-16 14:33:54 +00:00
|
|
|
|
unsigned c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
2004-09-16 14:33:54 +00:00
|
|
|
|
if (c > 0)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
{
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
2004-09-16 14:33:54 +00:00
|
|
|
|
unsigned i = 0;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
2004-09-16 14:33:54 +00:00
|
|
|
|
while (i < c)
|
|
|
|
|
{
|
|
|
|
|
[(*get)(self, oaiSel, i++) performSelector: aSelector];
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Obsolete version of -makeObjectsPerformSelector:
|
|
|
|
|
*/
|
1998-11-14 03:48:55 +00:00
|
|
|
|
- (void) makeObjectsPerform: (SEL)aSelector
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1998-11-14 03:48:55 +00:00
|
|
|
|
[self makeObjectsPerformSelector: aSelector];
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Makes each object in the array perform aSelector with arg.<br />
|
2004-09-16 14:33:54 +00:00
|
|
|
|
* This is done sequentially from the first to the last object.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
|
|
|
|
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: (id)arg
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2004-09-16 14:33:54 +00:00
|
|
|
|
unsigned c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
2004-09-16 14:33:54 +00:00
|
|
|
|
if (c > 0)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
{
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
2004-09-16 14:33:54 +00:00
|
|
|
|
unsigned i = 0;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
2004-09-16 14:33:54 +00:00
|
|
|
|
while (i < c)
|
|
|
|
|
{
|
|
|
|
|
[(*get)(self, oaiSel, i++) performSelector: aSelector
|
|
|
|
|
withObject: arg];
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Obsolete version of -makeObjectsPerformSelector:withObject:
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (void) makeObjectsPerform: (SEL)aSelector withObject: (id)argument
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[self makeObjectsPerformSelector: aSelector withObject: argument];
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-02-19 17:48:54 +00:00
|
|
|
|
static NSComparisonResult
|
|
|
|
|
compare(id elem1, id elem2, void* context)
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2003-02-19 17:48:54 +00:00
|
|
|
|
NSComparisonResult (*imp)(id, SEL, id);
|
|
|
|
|
|
2003-02-19 20:48:03 +00:00
|
|
|
|
if (context == 0)
|
2003-02-19 21:09:00 +00:00
|
|
|
|
{
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"compare null selector given"];
|
|
|
|
|
}
|
2003-02-19 20:48:03 +00:00
|
|
|
|
|
2003-02-19 17:48:54 +00:00
|
|
|
|
imp = (NSComparisonResult (*)(id, SEL, id))
|
|
|
|
|
[elem1 methodForSelector: context];
|
|
|
|
|
|
2003-02-19 20:48:03 +00:00
|
|
|
|
if (imp == NULL)
|
|
|
|
|
{
|
|
|
|
|
[NSException raise: NSGenericException
|
|
|
|
|
format: @"invalid selector passed to compare"];
|
|
|
|
|
}
|
|
|
|
|
|
2003-02-19 17:48:54 +00:00
|
|
|
|
return (*imp)(elem1, context, elem2);
|
2001-09-05 21:31:42 +00:00
|
|
|
|
}
|
1997-01-09 16:24:07 +00:00
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array in which the objects are ordered
|
|
|
|
|
* according to a sort with comparator.
|
|
|
|
|
*/
|
2001-09-05 21:31:42 +00:00
|
|
|
|
- (NSArray*) sortedArrayUsingSelector: (SEL)comparator
|
|
|
|
|
{
|
|
|
|
|
return [self sortedArrayUsingFunction: compare context: (void *)comparator];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array in which the objects are ordered
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* according to a sort with comparator. This invokes
|
|
|
|
|
* -sortedArrayUsingFunction:context:hint: with a nil hint.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2005-02-22 11:22:44 +00:00
|
|
|
|
- (NSArray*) sortedArrayUsingFunction: (NSComparisonResult(*)(id,id,void*))comparator
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
context: (void*)context
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1998-01-19 15:20:15 +00:00
|
|
|
|
return [self sortedArrayUsingFunction: comparator context: context hint: nil];
|
|
|
|
|
}
|
1997-01-09 16:24:07 +00:00
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Subclasses may provide a hint for sorting ... The default GNUstep
|
|
|
|
|
* implementation just returns nil.
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (NSData*) sortedArrayHint
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
return nil;
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array in which the objects are ordered
|
|
|
|
|
* according to a sort with comparator, where the comparator function
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* is passed two objects to compare, and the context as the third
|
|
|
|
|
* argument. The hint argument is currently ignored, and may be nil.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
*/
|
2005-02-22 11:22:44 +00:00
|
|
|
|
- (NSArray*) sortedArrayUsingFunction: (NSComparisonResult(*)(id,id,void*))comparator
|
1998-01-19 15:20:15 +00:00
|
|
|
|
context: (void*)context
|
|
|
|
|
hint: (NSData*)hint
|
|
|
|
|
{
|
|
|
|
|
NSMutableArray *sortedArray;
|
|
|
|
|
|
2001-01-08 16:45:36 +00:00
|
|
|
|
sortedArray = [[NSMutableArrayClass allocWithZone:
|
2003-01-20 17:18:06 +00:00
|
|
|
|
NSDefaultMallocZone()] initWithArray: self copyItems: NO];
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[sortedArray sortUsingFunction: comparator context: context];
|
2002-11-04 08:06:48 +00:00
|
|
|
|
|
|
|
|
|
return AUTORELEASE([sortedArray makeImmutableCopyOnFail: NO]);
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a string formed by concatenating the objects in the receiver,
|
|
|
|
|
* with the specified separator string inserted between each part.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (NSString*) componentsJoinedByString: (NSString*)separator
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2002-11-04 08:06:48 +00:00
|
|
|
|
unsigned int c = [self count];
|
|
|
|
|
NSMutableString *s = [[NSMutableString alloc] initWithCapacity: c];
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
if (c > 0)
|
1995-04-07 21:01:59 +00:00
|
|
|
|
{
|
2002-11-04 08:06:48 +00:00
|
|
|
|
unsigned l = [separator length];
|
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
|
|
[s appendString: [[self objectAtIndex: 0] description]];
|
|
|
|
|
for (i = 1; i < c; i++)
|
|
|
|
|
{
|
|
|
|
|
if (l > 0)
|
|
|
|
|
{
|
|
|
|
|
[s appendString: separator];
|
|
|
|
|
}
|
|
|
|
|
[s appendString: [[self objectAtIndex: i] description]];
|
|
|
|
|
}
|
1995-04-07 21:01:59 +00:00
|
|
|
|
}
|
2002-11-04 08:06:48 +00:00
|
|
|
|
return AUTORELEASE([s makeImmutableCopyOnFail: NO]);
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Assumes that the receiver is an array of paths, and returns an
|
|
|
|
|
* array formed by selecting the subset of those patch matching
|
|
|
|
|
* the specified array of extensions.
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (NSArray*) pathsMatchingExtensions: (NSArray*)extensions
|
|
|
|
|
{
|
1998-02-03 14:20:00 +00:00
|
|
|
|
unsigned i, c = [self count];
|
2002-11-04 08:06:48 +00:00
|
|
|
|
NSMutableArray *a = [[NSMutableArray alloc] initWithCapacity: 1];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
Class cls = [NSString class];
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
IMP add = [a methodForSelector: addSel];
|
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
id o = (*get)(self, oaiSel, i);
|
|
|
|
|
|
|
|
|
|
if ([o isKindOfClass: cls])
|
2002-11-04 08:06:48 +00:00
|
|
|
|
{
|
|
|
|
|
if ([extensions containsObject: [o pathExtension]])
|
|
|
|
|
{
|
|
|
|
|
(*add)(a, addSel, o);
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
2002-11-04 08:06:48 +00:00
|
|
|
|
return AUTORELEASE([a makeImmutableCopyOnFail: NO]);
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the first object found in the receiver (starting at index 0)
|
|
|
|
|
* which is present in the otherArray as determined by using the
|
|
|
|
|
* -containsObject: method.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (id) firstObjectCommonWithArray: (NSArray*)otherArray
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1998-02-03 14:20:00 +00:00
|
|
|
|
unsigned i, c = [self count];
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
id o;
|
2002-11-04 08:06:48 +00:00
|
|
|
|
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
for (i = 0; i < c; i++)
|
2002-11-04 08:06:48 +00:00
|
|
|
|
{
|
|
|
|
|
if ([otherArray containsObject: (o = [self objectAtIndex: i])])
|
|
|
|
|
{
|
|
|
|
|
return o;
|
|
|
|
|
}
|
|
|
|
|
}
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
return nil;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a subarray of the receiver containing the objects found in
|
|
|
|
|
* the specified range aRange.
|
|
|
|
|
*/
|
1999-06-04 16:05:45 +00:00
|
|
|
|
- (NSArray*) subarrayWithRange: (NSRange)aRange
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1996-03-30 19:14:43 +00:00
|
|
|
|
id na;
|
|
|
|
|
unsigned c = [self count];
|
|
|
|
|
|
1999-06-21 08:30:26 +00:00
|
|
|
|
GS_RANGE_CHECK(aRange, c);
|
1996-03-30 19:14:43 +00:00
|
|
|
|
|
1999-06-04 16:05:45 +00:00
|
|
|
|
if (aRange.length == 0)
|
2000-03-17 13:13:08 +00:00
|
|
|
|
{
|
|
|
|
|
na = [NSArray array];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINIDBUF(objects, aRange.length);
|
1996-03-30 19:14:43 +00:00
|
|
|
|
|
2000-03-17 13:13:08 +00:00
|
|
|
|
[self getObjects: objects range: aRange];
|
|
|
|
|
na = [NSArray arrayWithObjects: objects count: aRange.length];
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
2000-03-17 13:13:08 +00:00
|
|
|
|
}
|
1998-10-08 13:46:53 +00:00
|
|
|
|
return na;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* Returns an enumerator describing the array sequentially
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* from the first to the last element.<br/>
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* If you use a mutable subclass of NSArray,
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* you should not modify the array during enumeration.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (NSEnumerator*) objectEnumerator
|
|
|
|
|
{
|
2000-03-17 13:13:08 +00:00
|
|
|
|
id e;
|
|
|
|
|
|
|
|
|
|
e = [NSArrayEnumerator allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
e = [e initWithArray: self];
|
|
|
|
|
return AUTORELEASE(e);
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* Returns an enumerator describing the array sequentially
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* from the last to the first element.<br/>
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* If you use a mutable subclass of NSArray,
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* you should not modify the array during enumeration.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (NSEnumerator*) reverseObjectEnumerator
|
|
|
|
|
{
|
2000-03-17 13:13:08 +00:00
|
|
|
|
id e;
|
|
|
|
|
|
|
|
|
|
e = [NSArrayEnumeratorReverse allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
e = [e initWithArray: self];
|
|
|
|
|
return AUTORELEASE(e);
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
2002-11-11 11:34:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the result of invoking -descriptionWithLocale:indent: with a nil
|
|
|
|
|
* locale and zero indent.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (NSString*) description
|
1997-11-07 18:46:30 +00:00
|
|
|
|
{
|
1998-01-19 15:20:15 +00:00
|
|
|
|
return [self descriptionWithLocale: nil];
|
1997-11-07 18:46:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-11 11:34:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the result of invoking -descriptionWithLocale:indent:
|
|
|
|
|
* with a zero indent.
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1998-01-19 15:20:15 +00:00
|
|
|
|
return [self descriptionWithLocale: locale indent: 0];
|
|
|
|
|
}
|
1998-01-21 14:56:24 +00:00
|
|
|
|
|
2002-11-11 11:34:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the receiver as a text property list in the traditional format.<br />
|
|
|
|
|
* See [NSString-propertyList] for details.<br />
|
|
|
|
|
* If locale is nil, no formatting is done, otherwise entries are formatted
|
|
|
|
|
* according to the locale, and indented according to level.<br />
|
|
|
|
|
* Unless locale is nil, a level of zero indents items by four spaces,
|
|
|
|
|
* while a level of one indents them by a tab.<br />
|
|
|
|
|
* The items in the property list string appear in the same order as
|
|
|
|
|
* they appear in the receiver.
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
|
|
|
|
|
indent: (unsigned int)level
|
|
|
|
|
{
|
2002-11-10 09:29:45 +00:00
|
|
|
|
NSString *result = nil;
|
1997-10-31 16:26:44 +00:00
|
|
|
|
|
2002-11-27 13:56:00 +00:00
|
|
|
|
GSPropertyListMake(self, locale, NO, YES, level == 1 ? 3 : 2, &result);
|
2000-03-17 13:13:08 +00:00
|
|
|
|
|
2002-11-10 09:29:45 +00:00
|
|
|
|
return result;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-21 09:45:30 +00:00
|
|
|
|
/**
|
|
|
|
|
* <p>Writes the contents of the array to the file specified by path.
|
|
|
|
|
* The file contents will be in property-list format ... under GNUstep
|
|
|
|
|
* this is either OpenStep style (ASCII characters using \U hexadecimal
|
|
|
|
|
* escape sequences for unicode), or MacOS-X style (XML in the UTF8
|
|
|
|
|
* character set).
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>If the useAuxiliaryFile flag is YES, the file write operation is
|
|
|
|
|
* atomic ... the data is written to a temporary file, which is then
|
|
|
|
|
* renamed to the actual file name.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>If the conversion of data into the correct property-list format fails
|
|
|
|
|
* or the write operation fails, the method returns NO, otherwise it
|
|
|
|
|
* returns YES.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>NB. The fact that the file is in property-list format does not
|
|
|
|
|
* necessarily mean that it can be used to reconstruct the array using
|
|
|
|
|
* the -initWithContentsOfFile: method. If the original array contains
|
|
|
|
|
* non-property-list objects, the descriptions of those objects will
|
|
|
|
|
* have been written, and reading in the file as a property-list will
|
|
|
|
|
* result in a new array containing the string descriptions.
|
|
|
|
|
* </p>
|
|
|
|
|
*/
|
|
|
|
|
- (BOOL) writeToFile: (NSString *)path atomically: (BOOL)useAuxiliaryFile
|
2000-02-19 00:40:47 +00:00
|
|
|
|
{
|
2002-11-10 09:29:45 +00:00
|
|
|
|
NSDictionary *loc = GSUserDefaultsDictionaryRepresentation();
|
|
|
|
|
NSString *desc = nil;
|
2002-11-27 16:39:17 +00:00
|
|
|
|
NSData *data;
|
2001-09-08 05:11:58 +00:00
|
|
|
|
|
|
|
|
|
if (GSMacOSXCompatiblePropertyLists() == YES)
|
|
|
|
|
{
|
2002-11-27 13:56:00 +00:00
|
|
|
|
GSPropertyListMake(self, loc, YES, NO, 2, &desc);
|
2002-11-27 16:39:17 +00:00
|
|
|
|
data = [desc dataUsingEncoding: NSUTF8StringEncoding];
|
2001-09-08 05:11:58 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2002-11-27 13:56:00 +00:00
|
|
|
|
GSPropertyListMake(self, loc, NO, NO, 2, &desc);
|
2002-11-27 16:39:17 +00:00
|
|
|
|
data = [desc dataUsingEncoding: NSASCIIStringEncoding];
|
2001-09-08 05:11:58 +00:00
|
|
|
|
}
|
2000-03-17 13:13:08 +00:00
|
|
|
|
|
2002-11-27 16:39:17 +00:00
|
|
|
|
return [data writeToFile: path atomically: useAuxiliaryFile];
|
2000-02-19 00:40:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-21 09:45:30 +00:00
|
|
|
|
/**
|
|
|
|
|
* <p>Writes the contents of the array to the specified url.
|
|
|
|
|
* This functions just like -writeToFile:atomically: except that the
|
|
|
|
|
* output may be written to any URL, not just a local file.
|
|
|
|
|
* </p>
|
|
|
|
|
*/
|
|
|
|
|
- (BOOL) writeToURL: (NSURL *)url atomically: (BOOL)useAuxiliaryFile
|
2001-07-16 07:08:47 +00:00
|
|
|
|
{
|
2002-11-10 09:29:45 +00:00
|
|
|
|
NSDictionary *loc = GSUserDefaultsDictionaryRepresentation();
|
|
|
|
|
NSString *desc = nil;
|
2002-11-27 16:39:17 +00:00
|
|
|
|
NSData *data;
|
2001-09-08 05:15:19 +00:00
|
|
|
|
|
|
|
|
|
if (GSMacOSXCompatiblePropertyLists() == YES)
|
|
|
|
|
{
|
2002-11-27 13:56:00 +00:00
|
|
|
|
GSPropertyListMake(self, loc, YES, NO, 2, &desc);
|
2002-11-27 16:39:17 +00:00
|
|
|
|
data = [desc dataUsingEncoding: NSUTF8StringEncoding];
|
2001-09-08 05:15:19 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2002-11-27 13:56:00 +00:00
|
|
|
|
GSPropertyListMake(self, loc, NO, NO, 2, &desc);
|
2002-11-27 16:39:17 +00:00
|
|
|
|
data = [desc dataUsingEncoding: NSASCIIStringEncoding];
|
2001-09-08 05:15:19 +00:00
|
|
|
|
}
|
2001-07-16 07:08:47 +00:00
|
|
|
|
|
2002-11-27 16:39:17 +00:00
|
|
|
|
return [data writeToURL: url atomically: useAuxiliaryFile];
|
2001-07-16 07:08:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-01-06 19:43:29 +00:00
|
|
|
|
/**
|
|
|
|
|
* This overrides NSObjects implementation of this method.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* This method returns an array of objects returned by
|
|
|
|
|
* invoking -valueForKey: for each item in the receiver,
|
2004-01-06 19:43:29 +00:00
|
|
|
|
* substituting NSNull for nil.
|
|
|
|
|
* A special case: the key "count" is not forwarded to each object
|
|
|
|
|
* of the receiver but returns the number of objects of the receiver.<br/>
|
|
|
|
|
*/
|
|
|
|
|
- (id) valueForKey: (NSString*)key
|
|
|
|
|
{
|
2004-01-08 08:07:29 +00:00
|
|
|
|
id result = nil;
|
2004-01-06 19:43:29 +00:00
|
|
|
|
|
|
|
|
|
if ([key isEqualToString: @"count"] == YES)
|
|
|
|
|
{
|
|
|
|
|
result = [NSNumber numberWithUnsignedInt: [self count]];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2004-01-08 08:07:29 +00:00
|
|
|
|
NSMutableArray *results = nil;
|
|
|
|
|
static NSNull *null = nil;
|
|
|
|
|
unsigned i;
|
|
|
|
|
unsigned count = [self count];
|
|
|
|
|
volatile id object = nil;
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2005-03-02 11:46:21 +00:00
|
|
|
|
results = [NSMutableArray arrayWithCapacity: count];
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2004-01-08 08:07:29 +00:00
|
|
|
|
for (i = 0; i < count; i++)
|
2004-01-06 19:43:29 +00:00
|
|
|
|
{
|
2004-01-08 08:07:29 +00:00
|
|
|
|
id result;
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2004-01-06 19:43:29 +00:00
|
|
|
|
object = [self objectAtIndex: i];
|
|
|
|
|
result = [object valueForKey: key];
|
2004-01-08 08:07:29 +00:00
|
|
|
|
if (result == nil)
|
2004-01-06 19:43:29 +00:00
|
|
|
|
{
|
2004-01-08 08:07:29 +00:00
|
|
|
|
if (null == nil)
|
|
|
|
|
{
|
|
|
|
|
null = RETAIN([NSNull null]);
|
|
|
|
|
}
|
2004-01-06 19:43:29 +00:00
|
|
|
|
result = null;
|
|
|
|
|
}
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2004-01-06 19:43:29 +00:00
|
|
|
|
[results addObject: result];
|
|
|
|
|
}
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2004-01-08 08:07:29 +00:00
|
|
|
|
result = results;
|
2004-01-06 19:43:29 +00:00
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
1995-04-03 22:59:20 +00:00
|
|
|
|
@end
|
|
|
|
|
|
1996-03-31 22:23:37 +00:00
|
|
|
|
|
2004-06-22 22:40:40 +00:00
|
|
|
|
/**
|
|
|
|
|
* <code>NSMutableArray</code> is the mutable version of [NSArray]. It
|
|
|
|
|
* provides methods for altering the contents of the array.
|
|
|
|
|
*/
|
1996-03-31 22:23:37 +00:00
|
|
|
|
@implementation NSMutableArray
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
1996-03-31 22:23:37 +00:00
|
|
|
|
+ (void) initialize
|
1995-05-05 15:50:26 +00:00
|
|
|
|
{
|
1996-03-31 22:23:37 +00:00
|
|
|
|
if (self == [NSMutableArray class])
|
1996-05-06 19:57:29 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
1995-05-05 15:50:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
+ (id) allocWithZone: (NSZone*)z
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
if (self == NSMutableArrayClass)
|
2000-08-07 22:00:31 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return NSAllocateObject(GSMutableArrayClass, 0, z);
|
2000-08-07 22:00:31 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return NSAllocateObject(self, 0, z);
|
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-10-30 18:00:27 +00:00
|
|
|
|
+ (id) arrayWithObject: (id)anObject
|
|
|
|
|
{
|
|
|
|
|
NSMutableArray *obj = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
|
|
|
|
|
obj = [obj initWithObjects: &anObject count: 1];
|
2000-11-12 13:58:52 +00:00
|
|
|
|
return AUTORELEASE(obj);
|
2000-10-30 18:00:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-10-16 12:35:42 +00:00
|
|
|
|
- (Class) classForCoder
|
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return NSMutableArrayClass;
|
2000-10-16 12:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-07 05:43:20 +00:00
|
|
|
|
/** <init /> <override-subclass />
|
2002-08-27 11:09:12 +00:00
|
|
|
|
* Initialise the array with the specified capacity ... this
|
2004-09-07 05:43:20 +00:00
|
|
|
|
* should ensure that the array can have numItems added efficiently.<br />
|
|
|
|
|
* Calls -init (which does nothing but maintain MacOS-X compatibility),
|
|
|
|
|
* and needs to be re-implemented in subclasses in order to have all
|
|
|
|
|
* other initialisers work.
|
2002-08-27 11:09:12 +00:00
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (id) initWithCapacity: (unsigned)numItems
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2004-09-07 05:43:20 +00:00
|
|
|
|
self = [self init];
|
|
|
|
|
return self;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 11:09:12 +00:00
|
|
|
|
/** <override-subclass />
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* Adds anObject at the end of the array, thus increasing the size of
|
|
|
|
|
* the array. The object is retained upon addition.
|
2002-08-27 11:09:12 +00:00
|
|
|
|
*/
|
|
|
|
|
- (void) addObject: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1997-09-01 21:59:51 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 11:09:12 +00:00
|
|
|
|
/**
|
|
|
|
|
* Swaps the positions of two objects in the array. Raises an exception
|
|
|
|
|
* if either array index is out of bounds.
|
|
|
|
|
*/
|
2005-02-22 11:22:44 +00:00
|
|
|
|
- (void) exchangeObjectAtIndex: (unsigned int)i1
|
2002-08-27 11:09:12 +00:00
|
|
|
|
withObjectAtIndex: (unsigned int)i2
|
|
|
|
|
{
|
|
|
|
|
id tmp = [self objectAtIndex: i1];
|
|
|
|
|
|
|
|
|
|
RETAIN(tmp);
|
|
|
|
|
[self replaceObjectAtIndex: i1 withObject: [self objectAtIndex: i2]];
|
|
|
|
|
[self replaceObjectAtIndex: i2 withObject: tmp];
|
|
|
|
|
RELEASE(tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** <override-subclass />
|
|
|
|
|
* Places an object into the receiver at the specified location.<br />
|
|
|
|
|
* Raises an exception if given an array index which is too large.<br />
|
|
|
|
|
* The object is retained by the array.
|
|
|
|
|
*/
|
|
|
|
|
- (void) replaceObjectAtIndex: (unsigned)index withObject: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 11:09:12 +00:00
|
|
|
|
/**
|
|
|
|
|
* Replaces objects in the receiver with those from anArray.<br />
|
|
|
|
|
* Raises an exception if given a range extending beyond the array.<br />
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (void) replaceObjectsInRange: (NSRange)aRange
|
|
|
|
|
withObjectsFromArray: (NSArray*)anArray
|
|
|
|
|
{
|
1998-04-06 02:09:44 +00:00
|
|
|
|
id e, o;
|
1998-01-19 15:20:15 +00:00
|
|
|
|
|
1998-04-06 02:09:44 +00:00
|
|
|
|
if ([self count] < (aRange.location + aRange.length))
|
1998-01-19 15:20:15 +00:00
|
|
|
|
[NSException raise: NSRangeException
|
|
|
|
|
format: @"Replacing objects beyond end of array."];
|
|
|
|
|
[self removeObjectsInRange: aRange];
|
1998-04-06 02:09:44 +00:00
|
|
|
|
e = [anArray reverseObjectEnumerator];
|
|
|
|
|
while ((o = [e nextObject]))
|
|
|
|
|
[self insertObject: o atIndex: aRange.location];
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 11:09:12 +00:00
|
|
|
|
/**
|
|
|
|
|
* Replaces objects in the receiver with some of those from anArray.<br />
|
|
|
|
|
* Raises an exception if given a range extending beyond the array.<br />
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (void) replaceObjectsInRange: (NSRange)aRange
|
|
|
|
|
withObjectsFromArray: (NSArray*)anArray
|
|
|
|
|
range: (NSRange)anotherRange
|
|
|
|
|
{
|
|
|
|
|
[self replaceObjectsInRange: aRange
|
|
|
|
|
withObjectsFromArray: [anArray subarrayWithRange: anotherRange]];
|
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 11:09:12 +00:00
|
|
|
|
/** <override-subclass />
|
|
|
|
|
* Inserts an object into the receiver at the specified location.<br />
|
|
|
|
|
* Raises an exception if given an array index which is too large.<br />
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* The size of the array increases by one.<br />
|
2002-08-27 11:09:12 +00:00
|
|
|
|
* The object is retained by the array.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (void) insertObject: anObject atIndex: (unsigned)index
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 11:09:12 +00:00
|
|
|
|
/** <override-subclass />
|
|
|
|
|
* Removes an object from the receiver at the specified location.<br />
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* The size of the array decreases by one.<br />
|
2002-08-27 11:09:12 +00:00
|
|
|
|
* Raises an exception if given an array index which is too large.<br />
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (void) removeObjectAtIndex: (unsigned)index
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* Creates an autoreleased mutable array able to store at least numItems.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* See the -initWithCapacity: method.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
+ (id) arrayWithCapacity: (unsigned)numItems
|
1996-03-31 22:23:37 +00:00
|
|
|
|
{
|
1999-06-30 21:13:19 +00:00
|
|
|
|
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
|
initWithCapacity: numItems]);
|
1996-03-31 22:23:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-07 05:43:20 +00:00
|
|
|
|
/**
|
|
|
|
|
* Override our superclass's designated initializer to go our's
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (id) initWithObjects: (id*)objects count: (unsigned)count
|
1996-03-31 22:23:37 +00:00
|
|
|
|
{
|
|
|
|
|
self = [self initWithCapacity: count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
unsigned i;
|
|
|
|
|
IMP add = [self methodForSelector: addSel];
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
(*add)(self, addSel, objects[i]);
|
|
|
|
|
}
|
1996-03-31 22:23:37 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Removes the last object in the array. Raises an exception if the array
|
|
|
|
|
* is already empty.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (void) removeLastObject
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
unsigned count = [self count];
|
|
|
|
|
|
1996-03-30 23:00:27 +00:00
|
|
|
|
if (count == 0)
|
|
|
|
|
[NSException raise: NSRangeException
|
|
|
|
|
format: @"Trying to remove from an empty array."];
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[self removeObjectAtIndex: count-1];
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* Removes all occurrences of anObject (found by pointer equality)
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* from the receiver.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (void) removeObjectIdenticalTo: (id)anObject
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
1999-11-04 10:42:20 +00:00
|
|
|
|
unsigned i;
|
1996-04-30 14:25:22 +00:00
|
|
|
|
|
1999-11-04 10:42:20 +00:00
|
|
|
|
if (anObject == nil)
|
|
|
|
|
{
|
2001-05-22 09:30:07 +00:00
|
|
|
|
NSWarnMLog(@"attempt to remove nil object");
|
1999-11-04 10:42:20 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
i = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (i > 0)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP rem = 0;
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
|
|
|
|
|
while (i-- > 0)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
id o = (*get)(self, oaiSel, i);
|
|
|
|
|
|
|
|
|
|
if (o == anObject)
|
|
|
|
|
{
|
|
|
|
|
if (rem == 0)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
rem = [self methodForSelector: remSel];
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
(*rem)(self, remSel, i);
|
|
|
|
|
}
|
1998-02-03 14:20:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* Removes all occurrences of anObject (found by the [NSObject-isEqual:] method
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* of anObject) aRange in the receiver.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (void) removeObject: (id)anObject inRange: (NSRange)aRange
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1999-11-04 10:42:20 +00:00
|
|
|
|
unsigned c;
|
|
|
|
|
unsigned s;
|
|
|
|
|
unsigned i;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
1999-11-04 10:42:20 +00:00
|
|
|
|
if (anObject == nil)
|
|
|
|
|
{
|
2001-05-22 09:30:07 +00:00
|
|
|
|
NSWarnMLog(@"attempt to remove nil object");
|
1999-11-04 10:42:20 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
c = [self count];
|
|
|
|
|
s = aRange.location;
|
|
|
|
|
i = aRange.location + aRange.length;
|
1998-01-19 15:20:15 +00:00
|
|
|
|
if (i > c)
|
1999-11-04 10:42:20 +00:00
|
|
|
|
{
|
|
|
|
|
i = c;
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (i > s)
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP rem = 0;
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
BOOL (*eq)(id, SEL, id)
|
|
|
|
|
= (BOOL (*)(id, SEL, id))[anObject methodForSelector: eqSel];
|
|
|
|
|
|
|
|
|
|
while (i-- > s)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
id o = (*get)(self, oaiSel, i);
|
|
|
|
|
|
|
|
|
|
if (o == anObject || (*eq)(anObject, eqSel, o) == YES)
|
|
|
|
|
{
|
|
|
|
|
if (rem == 0)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
rem = [self methodForSelector: remSel];
|
|
|
|
|
/*
|
|
|
|
|
* We need to retain the object so that when we remove the
|
|
|
|
|
* first equal object we don't get left with a bad object
|
|
|
|
|
* pointer for later comparisons.
|
|
|
|
|
*/
|
|
|
|
|
RETAIN(anObject);
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
(*rem)(self, remSel, i);
|
|
|
|
|
}
|
1998-02-03 14:20:00 +00:00
|
|
|
|
}
|
2002-05-10 09:17:12 +00:00
|
|
|
|
#if GS_WITH_GC == 0
|
1999-12-13 12:14:01 +00:00
|
|
|
|
if (rem != 0)
|
|
|
|
|
{
|
|
|
|
|
RELEASE(anObject);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* Removes all occurrences of anObject (found by pointer equality)
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* from aRange in the receiver.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (void) removeObjectIdenticalTo: (id)anObject inRange: (NSRange)aRange
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1999-11-04 10:42:20 +00:00
|
|
|
|
unsigned c;
|
|
|
|
|
unsigned s;
|
|
|
|
|
unsigned i;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
1999-11-04 10:42:20 +00:00
|
|
|
|
if (anObject == nil)
|
|
|
|
|
{
|
2001-05-22 09:30:07 +00:00
|
|
|
|
NSWarnMLog(@"attempt to remove nil object");
|
1999-11-04 10:42:20 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
c = [self count];
|
|
|
|
|
s = aRange.location;
|
|
|
|
|
i = aRange.location + aRange.length;
|
1998-01-19 15:20:15 +00:00
|
|
|
|
if (i > c)
|
1999-11-04 10:42:20 +00:00
|
|
|
|
{
|
|
|
|
|
i = c;
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (i > s)
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP rem = 0;
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
|
|
|
|
|
while (i-- > s)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
id o = (*get)(self, oaiSel, i);
|
|
|
|
|
|
|
|
|
|
if (o == anObject)
|
|
|
|
|
{
|
|
|
|
|
if (rem == 0)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
rem = [self methodForSelector: remSel];
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
(*rem)(self, remSel, i);
|
|
|
|
|
}
|
1998-02-03 14:20:00 +00:00
|
|
|
|
}
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* Removes all occurrences of anObject (found by anObject's
|
|
|
|
|
* [NSObject-isEqual:] method) from the receiver.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (void) removeObject: (id)anObject
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
1999-11-04 10:42:20 +00:00
|
|
|
|
unsigned i;
|
1996-04-30 14:25:22 +00:00
|
|
|
|
|
1999-11-04 10:42:20 +00:00
|
|
|
|
if (anObject == nil)
|
|
|
|
|
{
|
2001-05-22 09:30:07 +00:00
|
|
|
|
NSWarnMLog(@"attempt to remove nil object");
|
1999-11-04 10:42:20 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
i = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (i > 0)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP rem = 0;
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
BOOL (*eq)(id, SEL, id)
|
|
|
|
|
= (BOOL (*)(id, SEL, id))[anObject methodForSelector: eqSel];
|
|
|
|
|
|
|
|
|
|
while (i-- > 0)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
id o = (*get)(self, oaiSel, i);
|
|
|
|
|
|
|
|
|
|
if (o == anObject || (*eq)(anObject, eqSel, o) == YES)
|
|
|
|
|
{
|
|
|
|
|
if (rem == 0)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
rem = [self methodForSelector: remSel];
|
|
|
|
|
/*
|
|
|
|
|
* We need to retain the object so that when we remove the
|
|
|
|
|
* first equal object we don't get left with a bad object
|
|
|
|
|
* pointer for later comparisons.
|
|
|
|
|
*/
|
|
|
|
|
RETAIN(anObject);
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
(*rem)(self, remSel, i);
|
|
|
|
|
}
|
1998-02-03 14:20:00 +00:00
|
|
|
|
}
|
2005-05-21 05:16:19 +00:00
|
|
|
|
#if GS_WITH_GC == 0
|
1999-12-13 12:14:01 +00:00
|
|
|
|
if (rem != 0)
|
|
|
|
|
{
|
|
|
|
|
RELEASE(anObject);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
1998-02-03 14:20:00 +00:00
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Removes all objects from the receiver, leaving an empty array.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (void) removeAllObjects
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
unsigned c = [self count];
|
|
|
|
|
|
|
|
|
|
if (c > 0)
|
|
|
|
|
{
|
|
|
|
|
IMP remLast = [self methodForSelector: rlSel];
|
|
|
|
|
|
|
|
|
|
while (c--)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
(*remLast)(self, rlSel);
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Adds each object from otherArray to the receiver, in first to last order.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (void) addObjectsFromArray: (NSArray*)otherArray
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
unsigned c = [otherArray count];
|
|
|
|
|
|
|
|
|
|
if (c > 0)
|
|
|
|
|
{
|
|
|
|
|
unsigned i;
|
|
|
|
|
IMP get = [otherArray methodForSelector: oaiSel];
|
|
|
|
|
IMP add = [self methodForSelector: addSel];
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
(*add)(self, addSel, (*get)(otherArray, oaiSel, i));
|
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sets the contents of the receiver to be identical to the contents
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* of otherArray.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
*/
|
1999-04-08 12:17:15 +00:00
|
|
|
|
- (void) setArray: (NSArray *)otherArray
|
1996-03-30 19:14:43 +00:00
|
|
|
|
{
|
|
|
|
|
[self removeAllObjects];
|
1996-03-31 22:23:37 +00:00
|
|
|
|
[self addObjectsFromArray: otherArray];
|
1996-03-30 19:14:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Supplied with a C array of indices containing count values, this method
|
|
|
|
|
* removes all corresponding objects from the receiver. The objects are
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* removed in such a way that the removal is <em>safe</em> irrespective
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* of the order in which they are specified in the indices array.
|
|
|
|
|
*/
|
2005-02-22 11:22:44 +00:00
|
|
|
|
- (void) removeObjectsFromIndices: (unsigned*)indices
|
1996-03-31 22:23:37 +00:00
|
|
|
|
numIndices: (unsigned)count
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
1999-02-16 16:08:59 +00:00
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
unsigned to = 0;
|
|
|
|
|
unsigned from = 0;
|
|
|
|
|
unsigned i;
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINITEMBUF(sorted, count, unsigned int);
|
1999-02-16 16:08:59 +00:00
|
|
|
|
|
|
|
|
|
while (from < count)
|
|
|
|
|
{
|
|
|
|
|
unsigned val = indices[from++];
|
|
|
|
|
|
|
|
|
|
i = to;
|
2002-12-10 05:44:56 +00:00
|
|
|
|
while (i > 0 && sorted[i-1] > val)
|
1999-02-16 16:08:59 +00:00
|
|
|
|
{
|
|
|
|
|
i--;
|
|
|
|
|
}
|
|
|
|
|
if (i == to)
|
|
|
|
|
{
|
|
|
|
|
sorted[to++] = val;
|
|
|
|
|
}
|
1999-02-16 16:18:26 +00:00
|
|
|
|
else if (sorted[i] != val)
|
1999-02-16 16:08:59 +00:00
|
|
|
|
{
|
|
|
|
|
unsigned j = to++;
|
|
|
|
|
|
1999-02-16 16:18:26 +00:00
|
|
|
|
if (sorted[i] < val)
|
|
|
|
|
{
|
|
|
|
|
i++;
|
|
|
|
|
}
|
1999-02-16 16:08:59 +00:00
|
|
|
|
while (j > i)
|
|
|
|
|
{
|
|
|
|
|
sorted[j] = sorted[j-1];
|
|
|
|
|
j--;
|
|
|
|
|
}
|
|
|
|
|
sorted[i] = val;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (to > 0)
|
1999-02-16 16:08:59 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP rem = [self methodForSelector: remSel];
|
|
|
|
|
|
|
|
|
|
while (to--)
|
|
|
|
|
{
|
|
|
|
|
(*rem)(self, remSel, sorted[to]);
|
|
|
|
|
}
|
1999-02-16 16:08:59 +00:00
|
|
|
|
}
|
2004-09-07 14:27:14 +00:00
|
|
|
|
GS_ENDITEMBUF();
|
1999-02-16 16:08:59 +00:00
|
|
|
|
}
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Removes from the receiver, all the objects present in otherArray,
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* as determined by using the [NSObject-isEqual:] method.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (void) removeObjectsInArray: (NSArray*)otherArray
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
unsigned c = [otherArray count];
|
|
|
|
|
|
|
|
|
|
if (c > 0)
|
|
|
|
|
{
|
|
|
|
|
unsigned i;
|
|
|
|
|
IMP get = [otherArray methodForSelector: oaiSel];
|
|
|
|
|
IMP rem = [self methodForSelector: @selector(removeObject:)];
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
(*rem)(self, @selector(removeObject:), (*get)(otherArray, oaiSel, i));
|
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Removes all the objects in aRange from the receiver.
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (void) removeObjectsInRange: (NSRange)aRange
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
unsigned i;
|
|
|
|
|
unsigned s = aRange.location;
|
|
|
|
|
unsigned c = [self count];
|
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
i = aRange.location + aRange.length;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
if (c < i)
|
|
|
|
|
i = c;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
|
|
|
|
if (i > s)
|
|
|
|
|
{
|
|
|
|
|
IMP rem = [self methodForSelector: remSel];
|
|
|
|
|
|
|
|
|
|
while (i-- > s)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
(*rem)(self, remSel, i);
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sorts the array according to the supplied comparator.
|
|
|
|
|
*/
|
1997-09-01 21:59:51 +00:00
|
|
|
|
- (void) sortUsingSelector: (SEL)comparator
|
|
|
|
|
{
|
2001-09-05 21:31:42 +00:00
|
|
|
|
[self sortUsingFunction: compare context: (void *)comparator];
|
1997-09-01 21:59:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sorts the array according to the supplied compare function
|
|
|
|
|
* with the context information.
|
|
|
|
|
*/
|
2005-02-22 11:22:44 +00:00
|
|
|
|
- (void) sortUsingFunction: (NSComparisonResult (*)(id,id,void*))compare
|
1999-12-01 19:36:20 +00:00
|
|
|
|
context: (void*)context
|
1995-04-03 03:18:43 +00:00
|
|
|
|
{
|
1997-01-09 16:24:07 +00:00
|
|
|
|
/* Shell sort algorithm taken from SortingInAction - a NeXT example */
|
|
|
|
|
#define STRIDE_FACTOR 3 // good value for stride factor is not well-understood
|
|
|
|
|
// 3 is a fairly good choice (Sedgewick)
|
2003-01-03 20:14:47 +00:00
|
|
|
|
unsigned int c;
|
|
|
|
|
unsigned int d;
|
|
|
|
|
unsigned int stride = 1;
|
1999-12-01 19:36:20 +00:00
|
|
|
|
BOOL found;
|
2003-01-03 20:14:47 +00:00
|
|
|
|
unsigned int count = [self count];
|
1999-12-01 19:36:20 +00:00
|
|
|
|
#ifdef GSWARN
|
|
|
|
|
BOOL badComparison = NO;
|
|
|
|
|
#endif
|
1997-01-09 16:24:07 +00:00
|
|
|
|
|
|
|
|
|
while (stride <= count)
|
1999-12-01 19:36:20 +00:00
|
|
|
|
{
|
|
|
|
|
stride = stride * STRIDE_FACTOR + 1;
|
|
|
|
|
}
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
while (stride > (STRIDE_FACTOR - 1))
|
1999-09-14 19:24:58 +00:00
|
|
|
|
{
|
|
|
|
|
// loop to sort for each value of stride
|
|
|
|
|
stride = stride / STRIDE_FACTOR;
|
|
|
|
|
for (c = stride; c < count; c++)
|
|
|
|
|
{
|
|
|
|
|
found = NO;
|
|
|
|
|
if (stride > c)
|
1999-12-01 19:36:20 +00:00
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
d = c - stride;
|
1999-12-01 19:36:20 +00:00
|
|
|
|
while (!found) /* move to left until correct place */
|
1999-09-14 19:24:58 +00:00
|
|
|
|
{
|
1999-12-01 19:36:20 +00:00
|
|
|
|
id a = [self objectAtIndex: d + stride];
|
|
|
|
|
id b = [self objectAtIndex: d];
|
|
|
|
|
NSComparisonResult r;
|
|
|
|
|
|
|
|
|
|
r = (*compare)(a, b, context);
|
|
|
|
|
if (r < 0)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
{
|
1999-12-01 19:36:20 +00:00
|
|
|
|
#ifdef GSWARN
|
|
|
|
|
if (r != NSOrderedAscending)
|
|
|
|
|
{
|
|
|
|
|
badComparison = YES;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
1999-09-28 19:35:09 +00:00
|
|
|
|
IF_NO_GC(RETAIN(a));
|
1999-09-14 19:24:58 +00:00
|
|
|
|
[self replaceObjectAtIndex: d + stride withObject: b];
|
|
|
|
|
[self replaceObjectAtIndex: d withObject: a];
|
|
|
|
|
RELEASE(a);
|
|
|
|
|
if (stride > d)
|
1999-12-01 19:36:20 +00:00
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
d -= stride; // jump by stride factor
|
|
|
|
|
}
|
1999-12-01 19:36:20 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#ifdef GSWARN
|
|
|
|
|
if (r != NSOrderedDescending && r != NSOrderedSame)
|
|
|
|
|
{
|
|
|
|
|
badComparison = YES;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
found = YES;
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1997-01-09 16:24:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-12-01 19:36:20 +00:00
|
|
|
|
#ifdef GSWARN
|
|
|
|
|
if (badComparison == YES)
|
|
|
|
|
{
|
2001-05-22 09:30:07 +00:00
|
|
|
|
NSWarnMLog(@"Detected bad return value from comparison");
|
1999-12-01 19:36:20 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
1995-04-03 03:18:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-01-06 19:43:29 +00:00
|
|
|
|
/**
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* Call setValue:forKey: on each of the receiver's items
|
2004-01-06 19:43:29 +00:00
|
|
|
|
* with the value and key.
|
|
|
|
|
*/
|
|
|
|
|
- (void) setValue: (id)value forKey: (NSString*)key
|
|
|
|
|
{
|
2004-01-08 08:07:29 +00:00
|
|
|
|
unsigned i;
|
|
|
|
|
unsigned count = [self count];
|
|
|
|
|
volatile id object = nil;
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2004-01-08 08:07:29 +00:00
|
|
|
|
for (i = 0; i < count; i++)
|
2004-01-06 19:43:29 +00:00
|
|
|
|
{
|
|
|
|
|
object = [self objectAtIndex: i];
|
|
|
|
|
[object setValue: value
|
2004-01-08 08:07:29 +00:00
|
|
|
|
forKey: key];
|
2004-01-06 19:43:29 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
@end
|
1996-03-31 22:23:37 +00:00
|
|
|
|
|
|
|
|
|
@implementation NSArrayEnumerator
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (id) initWithArray: (NSArray*)anArray
|
1996-03-31 22:23:37 +00:00
|
|
|
|
{
|
2003-10-14 09:00:42 +00:00
|
|
|
|
self = [super init];
|
|
|
|
|
if (self != nil)
|
|
|
|
|
{
|
|
|
|
|
array = anArray;
|
|
|
|
|
IF_NO_GC(RETAIN(array));
|
|
|
|
|
pos = 0;
|
|
|
|
|
get = [array methodForSelector: oaiSel];
|
|
|
|
|
cnt = (unsigned (*)(NSArray*, SEL))[array methodForSelector: countSel];
|
|
|
|
|
}
|
1996-03-31 22:23:37 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the next object in the enumeration or nil if there are no more
|
|
|
|
|
* objects.<br />
|
|
|
|
|
* NB. modifying a mutable array during an enumeration can break things ...
|
|
|
|
|
* don't do it.
|
|
|
|
|
*/
|
1996-03-31 22:23:37 +00:00
|
|
|
|
- (id) nextObject
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (pos >= (*cnt)(array, countSel))
|
1996-03-31 22:23:37 +00:00
|
|
|
|
return nil;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
return (*get)(array, oaiSel, pos++);
|
1996-03-31 22:23:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
|
{
|
1999-06-30 21:13:19 +00:00
|
|
|
|
RELEASE(array);
|
1996-03-31 22:23:37 +00:00
|
|
|
|
[super dealloc];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@implementation NSArrayEnumeratorReverse
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (id) initWithArray: (NSArray*)anArray
|
1996-03-31 22:23:37 +00:00
|
|
|
|
{
|
2003-10-14 09:00:42 +00:00
|
|
|
|
self = [super initWithArray: anArray];
|
|
|
|
|
if (self != nil)
|
|
|
|
|
{
|
|
|
|
|
pos = (*cnt)(array, countSel);
|
|
|
|
|
}
|
1996-03-31 22:23:37 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the next object in the enumeration or nil if there are no more
|
|
|
|
|
* objects.<br />
|
|
|
|
|
* NB. modifying a mutable array during an enumeration can break things ...
|
|
|
|
|
* don't do it.
|
|
|
|
|
*/
|
1996-03-31 22:23:37 +00:00
|
|
|
|
- (id) nextObject
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (pos == 0)
|
1996-03-31 22:23:37 +00:00
|
|
|
|
return nil;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
return (*get)(array, oaiSel, --pos);
|
1996-03-31 22:23:37 +00:00
|
|
|
|
}
|
1999-02-20 19:59:45 +00:00
|
|
|
|
@end
|
2000-08-07 22:00:31 +00:00
|
|
|
|
|