2006-02-12 19:02:58 +00:00
|
|
|
/** Implementation for NSIndexPath for GNUStep
|
|
|
|
Copyright (C) 2006 Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
|
|
|
Created: Feb 2006
|
|
|
|
|
|
|
|
This file is part of the GNUstep Base Library.
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
2007-09-14 11:36:11 +00:00
|
|
|
modify it under the terms of the GNU Lesser General Public
|
2006-02-12 19:02:58 +00:00
|
|
|
License as published by the Free Software Foundation; either
|
2008-06-08 10:38:33 +00:00
|
|
|
version 2 of the License, or (at your option) any later version.
|
2006-02-12 19:02:58 +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
|
2019-12-09 23:36:00 +00:00
|
|
|
Lesser General Public License for more details.
|
2006-02-12 19:02:58 +00:00
|
|
|
|
2007-09-14 11:36:11 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
2006-02-12 19:02:58 +00:00
|
|
|
License along with this library; if not, write to the Free
|
2006-10-20 10:56:27 +00:00
|
|
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
2019-12-09 23:36:00 +00:00
|
|
|
Boston, MA 02110 USA.
|
2006-02-12 19:02:58 +00:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
2010-02-19 08:12:46 +00:00
|
|
|
#import "common.h"
|
2010-02-14 10:48:10 +00:00
|
|
|
#define EXPOSE_NSIndexPath_IVARS 1
|
|
|
|
#import "Foundation/NSByteOrder.h"
|
|
|
|
#import "Foundation/NSData.h"
|
|
|
|
#import "Foundation/NSException.h"
|
|
|
|
#import "Foundation/NSHashTable.h"
|
|
|
|
#import "Foundation/NSIndexPath.h"
|
|
|
|
#import "Foundation/NSKeyedArchiver.h"
|
|
|
|
#import "Foundation/NSLock.h"
|
2006-02-12 19:02:58 +00:00
|
|
|
|
2018-04-10 13:59:35 +00:00
|
|
|
static NSRecursiveLock *lock = nil;
|
2006-02-12 19:02:58 +00:00
|
|
|
static NSHashTable *shared = 0;
|
|
|
|
static Class myClass = 0;
|
|
|
|
static NSIndexPath *empty = nil;
|
|
|
|
static NSIndexPath *dummy = nil;
|
|
|
|
|
|
|
|
@implementation NSIndexPath
|
|
|
|
|
|
|
|
+ (id) allocWithZone: (NSZone*)aZone
|
|
|
|
{
|
|
|
|
if (self == myClass)
|
|
|
|
{
|
|
|
|
return empty;
|
|
|
|
}
|
|
|
|
return [super allocWithZone: aZone];
|
|
|
|
}
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
+ (id) indexPathWithIndex: (NSUInteger)anIndex
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
|
|
|
return [self indexPathWithIndexes: &anIndex length: 1];
|
|
|
|
}
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
+ (id) indexPathWithIndexes: (NSUInteger*)indexes length: (NSUInteger)length
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
|
|
|
id o = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
|
|
|
o = [o initWithIndexes: indexes length: length];
|
2009-01-12 12:48:46 +00:00
|
|
|
return AUTORELEASE(o);
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
|
|
|
|
2023-09-20 22:53:52 +00:00
|
|
|
+ (NSIndexPath *) indexPathForItem: (NSInteger)item inSection: (NSInteger)section
|
2022-03-03 07:26:33 +00:00
|
|
|
{
|
2022-03-07 01:59:27 +00:00
|
|
|
NSUInteger idxs[2];
|
2022-03-03 07:26:33 +00:00
|
|
|
|
2022-03-07 01:59:27 +00:00
|
|
|
idxs[0] = (NSUInteger)section;
|
|
|
|
idxs[1] = (NSUInteger)item;
|
|
|
|
|
|
|
|
return [self indexPathWithIndexes: idxs length: 2];
|
2022-03-03 07:26:33 +00:00
|
|
|
}
|
|
|
|
|
2023-09-20 22:53:52 +00:00
|
|
|
+ (NSIndexPath *) indexPathForRow: (NSInteger)row inSection: (NSInteger)section
|
2022-03-07 12:35:12 +00:00
|
|
|
{
|
|
|
|
NSUInteger idxs[2];
|
|
|
|
|
|
|
|
idxs[0] = (NSUInteger)section;
|
|
|
|
idxs[1] = (NSUInteger)row;
|
|
|
|
|
|
|
|
return [self indexPathWithIndexes: idxs length: 2];
|
|
|
|
}
|
|
|
|
|
2006-02-12 19:02:58 +00:00
|
|
|
+ (void) initialize
|
|
|
|
{
|
|
|
|
if (empty == nil)
|
|
|
|
{
|
|
|
|
myClass = self;
|
|
|
|
empty = (NSIndexPath*)NSAllocateObject(self, 0, NSDefaultMallocZone());
|
2013-08-22 15:44:54 +00:00
|
|
|
[[NSObject leakAt: &empty] release];
|
2006-02-12 19:02:58 +00:00
|
|
|
dummy = (NSIndexPath*)NSAllocateObject(self, 0, NSDefaultMallocZone());
|
2013-08-22 15:44:54 +00:00
|
|
|
[[NSObject leakAt: &dummy] release];
|
2006-02-12 19:02:58 +00:00
|
|
|
shared = NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 1024);
|
2013-08-22 15:44:54 +00:00
|
|
|
[[NSObject leakAt: &shared] release];
|
2006-02-12 19:02:58 +00:00
|
|
|
NSHashInsert(shared, empty);
|
2018-04-10 13:59:35 +00:00
|
|
|
lock = [NSRecursiveLock new];
|
2013-08-22 15:44:54 +00:00
|
|
|
[[NSObject leakAt: &lock] release];
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSComparisonResult) compare: (NSIndexPath*)other
|
|
|
|
{
|
2006-08-13 09:17:53 +00:00
|
|
|
if (other != self)
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
NSUInteger olength = other->_length;
|
|
|
|
NSUInteger *oindexes = other->_indexes;
|
|
|
|
NSUInteger end = (_length > olength) ? _length : olength;
|
|
|
|
NSUInteger pos;
|
2006-02-12 19:02:58 +00:00
|
|
|
|
2006-08-13 09:17:53 +00:00
|
|
|
for (pos = 0; pos < end; pos++)
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
2006-08-13 09:17:53 +00:00
|
|
|
if (pos >= _length)
|
|
|
|
{
|
|
|
|
return NSOrderedDescending;
|
|
|
|
}
|
|
|
|
else if (pos >= olength)
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
|
|
|
return NSOrderedAscending;
|
|
|
|
}
|
2006-08-13 09:17:53 +00:00
|
|
|
if (oindexes[pos] < _indexes[pos])
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
|
|
|
return NSOrderedDescending;
|
|
|
|
}
|
2006-08-13 09:17:53 +00:00
|
|
|
if (oindexes[pos] > _indexes[pos])
|
|
|
|
{
|
|
|
|
return NSOrderedAscending;
|
|
|
|
}
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
2006-08-13 09:17:53 +00:00
|
|
|
/*
|
|
|
|
* Should never get here.
|
|
|
|
*/
|
|
|
|
NSLog(@"Argh ... two identical index paths exist!");
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
2006-08-13 09:17:53 +00:00
|
|
|
return NSOrderedSame;
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (id) copyWithZone: (NSZone*)aZone
|
|
|
|
{
|
|
|
|
return RETAIN(self);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
{
|
|
|
|
if (self != empty)
|
|
|
|
{
|
|
|
|
[lock lock];
|
2013-08-22 19:55:03 +00:00
|
|
|
if (shared != nil)
|
|
|
|
{
|
|
|
|
NSHashRemove(shared, self);
|
|
|
|
}
|
2006-02-12 19:02:58 +00:00
|
|
|
[lock unlock];
|
2013-08-22 19:55:03 +00:00
|
|
|
if (_indexes != 0)
|
|
|
|
{
|
|
|
|
NSZoneFree(NSDefaultMallocZone(), _indexes);
|
|
|
|
}
|
2009-10-10 08:16:17 +00:00
|
|
|
[super dealloc];
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
2006-06-04 06:42:10 +00:00
|
|
|
GSNOSUPERDEALLOC;
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
|
|
|
|
2006-09-10 13:30:05 +00:00
|
|
|
- (NSString*) description
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
|
|
|
NSMutableString *m = [[super description] mutableCopy];
|
2009-02-23 20:42:32 +00:00
|
|
|
NSUInteger i;
|
2006-02-12 19:02:58 +00:00
|
|
|
|
2013-07-03 06:46:41 +00:00
|
|
|
[m appendFormat: @"%"PRIuPTR" indexes [", _length];
|
2006-02-12 19:02:58 +00:00
|
|
|
for (i = 0; i < _length; i++)
|
|
|
|
{
|
|
|
|
if (i > 0)
|
|
|
|
{
|
|
|
|
[m appendString: @", "];
|
|
|
|
}
|
2013-07-03 06:46:41 +00:00
|
|
|
[m appendFormat: @"%"PRIuPTR, _indexes[i]];
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
|
|
|
[m appendString: @"]"];
|
|
|
|
return AUTORELEASE(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
|
|
|
{
|
|
|
|
if ([aCoder allowsKeyedCoding] == YES)
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
[aCoder encodeInt: (NSInteger)_length forKey: @"NSIndexPathLength"];
|
2006-02-12 19:02:58 +00:00
|
|
|
if (_length == 1)
|
|
|
|
{
|
2013-08-22 19:55:03 +00:00
|
|
|
[aCoder encodeInt: (NSInteger)_indexes[0]
|
|
|
|
forKey: @"NSIndexPathValue"];
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
|
|
|
else if (_length > 1)
|
|
|
|
{
|
|
|
|
NSMutableData *m;
|
2009-02-23 20:42:32 +00:00
|
|
|
NSUInteger *buf;
|
|
|
|
NSUInteger i;
|
2006-02-12 19:02:58 +00:00
|
|
|
|
|
|
|
m = [NSMutableData new];
|
2009-02-23 20:42:32 +00:00
|
|
|
[m setLength: _length * sizeof(NSUInteger)];
|
2006-02-12 19:02:58 +00:00
|
|
|
buf = [m mutableBytes];
|
|
|
|
for (i = 0; i < _length; i++)
|
|
|
|
{
|
|
|
|
buf[i] = NSSwapHostIntToBig(_indexes[i]);
|
|
|
|
}
|
|
|
|
[aCoder encodeObject: m forKey: @"NSIndexPathData"];
|
|
|
|
RELEASE(m);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
[aCoder encodeValueOfObjCType: @encode(NSUInteger) at: &_length];
|
2006-02-12 19:02:58 +00:00
|
|
|
if (_length > 0)
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
[aCoder encodeArrayOfObjCType: @encode(NSUInteger)
|
2006-02-12 19:02:58 +00:00
|
|
|
count: _length
|
|
|
|
at: _indexes];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-07 12:35:12 +00:00
|
|
|
- (NSInteger) row
|
|
|
|
{
|
|
|
|
return (NSInteger)[self indexAtPosition: 1];
|
|
|
|
}
|
|
|
|
|
2022-03-03 07:26:33 +00:00
|
|
|
- (NSInteger) item
|
|
|
|
{
|
2022-03-07 01:59:27 +00:00
|
|
|
return (NSInteger)[self indexAtPosition: 1];
|
2022-03-03 07:26:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSInteger) section
|
|
|
|
{
|
2022-03-07 01:59:27 +00:00
|
|
|
return (NSInteger)[self indexAtPosition: 0];
|
2022-03-03 07:26:33 +00:00
|
|
|
}
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
- (void) getIndexes: (NSUInteger*)aBuffer
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
memcpy(aBuffer, _indexes, _length * sizeof(NSUInteger));
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
- (NSUInteger) hash
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
|
|
|
return _hash;
|
|
|
|
}
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
- (NSUInteger) indexAtPosition: (NSUInteger)position
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
|
|
|
if (position >= _length)
|
2006-08-13 08:14:47 +00:00
|
|
|
{
|
|
|
|
return NSNotFound;
|
|
|
|
}
|
2006-02-12 19:02:58 +00:00
|
|
|
return _indexes[position];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return path formed by adding the index to the receiver.
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
- (NSIndexPath *) indexPathByAddingIndex: (NSUInteger)anIndex
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
NSUInteger buffer[_length + 1];
|
2006-02-12 19:02:58 +00:00
|
|
|
|
|
|
|
[self getIndexes: buffer];
|
|
|
|
buffer[_length] = anIndex;
|
|
|
|
return [[self class] indexPathWithIndexes: buffer length: _length + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSIndexPath *) indexPathByRemovingLastIndex
|
|
|
|
{
|
|
|
|
if (_length <= 1)
|
|
|
|
{
|
|
|
|
return empty;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return [[self class] indexPathWithIndexes: _indexes length: _length - 1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithCoder: (NSCoder*)aCoder
|
|
|
|
{
|
|
|
|
if ([aCoder allowsKeyedCoding] == YES)
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
NSUInteger length;
|
|
|
|
NSUInteger index;
|
2006-02-12 19:02:58 +00:00
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
length = [aCoder decodeIntegerForKey: @"NSIndexPathLength"];
|
2006-02-12 19:02:58 +00:00
|
|
|
if (length == 1)
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
index = [aCoder decodeIntegerForKey: @"NSIndexPathValue"];
|
2006-02-12 19:02:58 +00:00
|
|
|
self = [self initWithIndex: index];
|
|
|
|
}
|
|
|
|
else if (length > 1)
|
|
|
|
{
|
|
|
|
// FIXME ... not MacOS-X
|
|
|
|
NSMutableData *d = [aCoder decodeObjectForKey: @"NSIndexPathData"];
|
2009-02-23 20:42:32 +00:00
|
|
|
NSUInteger l = [d length];
|
|
|
|
NSUInteger s = l / length;
|
|
|
|
NSUInteger i;
|
|
|
|
void *src = [d mutableBytes];
|
|
|
|
NSUInteger *dst;
|
2006-02-12 19:02:58 +00:00
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
if (s == sizeof(NSUInteger))
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
dst = (NSUInteger*)src;
|
|
|
|
}
|
2006-02-12 19:02:58 +00:00
|
|
|
else
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
dst = (NSUInteger*)NSZoneMalloc(NSDefaultMallocZone(),
|
|
|
|
length * sizeof(NSUInteger));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s == sizeof(long))
|
|
|
|
{
|
|
|
|
long *ptr = (long*)src;
|
|
|
|
|
|
|
|
for (i = 0; i < _length; i++)
|
|
|
|
{
|
|
|
|
dst[i] = (NSUInteger)NSSwapBigLongToHost(ptr[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (s == sizeof(short))
|
|
|
|
{
|
|
|
|
short *ptr = (short*)src;
|
|
|
|
|
|
|
|
for (i = 0; i < _length; i++)
|
|
|
|
{
|
|
|
|
dst[i] = (NSUInteger)NSSwapBigShortToHost(ptr[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (s == sizeof(long long))
|
|
|
|
{
|
|
|
|
long long *ptr = (long long*)src;
|
|
|
|
|
|
|
|
for (i = 0; i < _length; i++)
|
|
|
|
{
|
|
|
|
dst[i] = (NSUInteger)NSSwapBigLongLongToHost(ptr[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((void*)dst != src)
|
|
|
|
{
|
|
|
|
NSZoneFree(NSDefaultMallocZone(), dst);
|
|
|
|
}
|
|
|
|
[NSException raise: NSGenericException format:
|
2013-07-02 15:46:26 +00:00
|
|
|
@"Unable to decode unsigned integers of size %"PRIuPTR, s];
|
2009-02-23 20:42:32 +00:00
|
|
|
}
|
|
|
|
self = [self initWithIndexes: dst length: length];
|
|
|
|
if ((void*)dst != src)
|
|
|
|
{
|
|
|
|
NSZoneFree(NSDefaultMallocZone(), dst);
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
NSUInteger length;
|
2006-02-12 19:02:58 +00:00
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
[aCoder decodeValueOfObjCType: @encode(NSUInteger) at: &length];
|
2006-02-12 19:02:58 +00:00
|
|
|
if (length == 0)
|
|
|
|
{
|
2013-08-22 19:55:03 +00:00
|
|
|
ASSIGN(self, empty);
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
NSUInteger buf[16];
|
|
|
|
NSUInteger *indexes = buf;
|
2006-02-12 19:02:58 +00:00
|
|
|
|
|
|
|
if (length > 16)
|
|
|
|
{
|
|
|
|
indexes = NSZoneMalloc(NSDefaultMallocZone(),
|
2009-02-23 20:42:32 +00:00
|
|
|
length * sizeof(NSUInteger));
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
2009-02-23 20:42:32 +00:00
|
|
|
[aCoder decodeArrayOfObjCType: @encode(NSUInteger)
|
2006-02-12 19:02:58 +00:00
|
|
|
count: length
|
|
|
|
at: indexes];
|
|
|
|
self = [self initWithIndexes: indexes length: length];
|
|
|
|
if (indexes != buf)
|
|
|
|
{
|
|
|
|
NSZoneFree(NSDefaultMallocZone(), indexes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
- (id) initWithIndex: (NSUInteger)anIndex
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
|
|
|
return [self initWithIndexes: &anIndex length: 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
/** <init />
|
|
|
|
* Initialise the receiver to contain the specified indexes.<br />
|
|
|
|
* May return an existing index path.
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
- (id) initWithIndexes: (NSUInteger*)indexes length: (NSUInteger)length
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
|
|
|
NSIndexPath *found;
|
2009-02-23 20:42:32 +00:00
|
|
|
NSUInteger h = 0;
|
|
|
|
NSUInteger i;
|
2006-02-12 19:02:58 +00:00
|
|
|
|
|
|
|
if (_length != 0)
|
|
|
|
{
|
|
|
|
[NSException raise: NSGenericException
|
|
|
|
format: @"Attempt to re-initialize NSIndexPath"];
|
|
|
|
}
|
|
|
|
// FIXME ... need better hash function?
|
|
|
|
for (i = 0; i < length; i++)
|
|
|
|
{
|
|
|
|
h = (h << 5) ^ indexes[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
[lock lock];
|
|
|
|
dummy->_hash = h;
|
|
|
|
dummy->_length = length;
|
|
|
|
dummy->_indexes = indexes;
|
|
|
|
found = NSHashGet(shared, dummy);
|
|
|
|
if (found == nil)
|
|
|
|
{
|
|
|
|
if (self == empty)
|
|
|
|
{
|
2013-08-22 19:55:03 +00:00
|
|
|
RELEASE(self);
|
2006-02-12 19:02:58 +00:00
|
|
|
self = (NSIndexPath*)NSAllocateObject([self class],
|
|
|
|
0, NSDefaultMallocZone());
|
|
|
|
}
|
|
|
|
_hash = dummy->_hash;
|
|
|
|
_length = dummy->_length;
|
|
|
|
_indexes = NSZoneMalloc(NSDefaultMallocZone(),
|
2009-02-23 20:42:32 +00:00
|
|
|
_length * sizeof(NSUInteger));
|
|
|
|
memcpy(_indexes, dummy->_indexes, _length * sizeof(NSUInteger));
|
2006-02-12 19:02:58 +00:00
|
|
|
NSHashInsert(shared, self);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-08-22 19:55:03 +00:00
|
|
|
ASSIGN(self, found);
|
2006-02-12 19:02:58 +00:00
|
|
|
}
|
2013-08-22 19:55:03 +00:00
|
|
|
dummy->_indexes = 0; // Don't want static indexes deallocated atExit
|
2006-02-12 19:02:58 +00:00
|
|
|
[lock unlock];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) isEqual: (id)other
|
|
|
|
{
|
|
|
|
if (other == self)
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
2010-02-22 10:13:20 +00:00
|
|
|
if (other == nil || GSObjCIsKindOf(object_getClass(other), myClass) == NO)
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
if (((NSIndexPath*)other)->_length != _length)
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
NSUInteger *oindexes = ((NSIndexPath*)other)->_indexes;
|
|
|
|
NSUInteger pos = _length;
|
2006-02-12 19:02:58 +00:00
|
|
|
|
|
|
|
while (pos-- > 0)
|
|
|
|
{
|
|
|
|
if (_indexes[pos] != oindexes[pos])
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
- (NSUInteger) length
|
2006-02-12 19:02:58 +00:00
|
|
|
{
|
|
|
|
return _length;
|
|
|
|
}
|
|
|
|
|
2011-07-31 15:31:39 +00:00
|
|
|
- (oneway void) release
|
2006-09-10 13:30:05 +00:00
|
|
|
{
|
|
|
|
if (self != empty)
|
|
|
|
{
|
|
|
|
/* We lock the table while checking, to prevent
|
|
|
|
* another thread from grabbing this object while we are
|
|
|
|
* checking it.
|
|
|
|
* If we are going to deallocate the object, we first remove
|
|
|
|
* it from the table so that no other thread will find it
|
|
|
|
* and try to use it while it is being deallocated.
|
|
|
|
*/
|
|
|
|
[lock lock];
|
|
|
|
if (NSDecrementExtraRefCountWasZero(self))
|
|
|
|
{
|
|
|
|
[self dealloc];
|
|
|
|
}
|
|
|
|
[lock unlock];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-02-12 19:02:58 +00:00
|
|
|
@end
|
|
|
|
|