mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
initial implementation of NSPointerArray
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@27866 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
5b183e80e8
commit
5407104a7c
3 changed files with 258 additions and 44 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2009-02-15 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/NSPointerArray.m: Initial implementation. Untested.
|
||||||
|
No coding/decoding support.
|
||||||
|
|
||||||
2009-02-14 Richard Frith-Macdonald <rfm@gnu.org>
|
2009-02-14 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/NSPointerFunctions.m: Add some more functions to be set by
|
* Source/NSPointerFunctions.m: Add some more functions to be set by
|
||||||
|
|
|
@ -131,3 +131,21 @@ pointerFunctionsRelinquish(PFInfo *PF, void **itemptr)
|
||||||
*itemptr = 0;
|
*itemptr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
pointerFunctionsReplace(PFInfo *PF, void **dst, void *src)
|
||||||
|
{
|
||||||
|
if (src != *dst)
|
||||||
|
{
|
||||||
|
if (PF->acquireFunction != 0)
|
||||||
|
src = (*PF->acquireFunction)(src, PF->sizeFunction, PF->shouldCopyIn);
|
||||||
|
if (PF->relinquishFunction != 0)
|
||||||
|
(*PF->relinquishFunction)(*dst, PF->sizeFunction);
|
||||||
|
#if GSWITHGC
|
||||||
|
if (PF->usesWeakReadAndWriteBarriers)
|
||||||
|
GSAssignZeroingWeakPointer(dst, src);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
*dst = src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -205,11 +205,11 @@ static Class concreteClass = Nil;
|
||||||
|
|
||||||
@interface NSConcretePointerArray : NSPointerArray
|
@interface NSConcretePointerArray : NSPointerArray
|
||||||
{
|
{
|
||||||
NSUInteger _count;
|
PFInfo _pf;
|
||||||
void **_contents_array;
|
NSUInteger _count;
|
||||||
unsigned _capacity;
|
void **_contents;
|
||||||
unsigned _grow_factor;
|
unsigned _capacity;
|
||||||
NSConcretePointerFunctions *_functions;
|
unsigned _grow_factor;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -236,9 +236,56 @@ static Class concreteClass = Nil;
|
||||||
[exception raise];
|
[exception raise];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) compact
|
||||||
|
{
|
||||||
|
NSUInteger i = _count;
|
||||||
|
|
||||||
|
while (i-- > 0)
|
||||||
|
{
|
||||||
|
if (_contents[i] == 0)
|
||||||
|
{
|
||||||
|
NSUInteger j = i;
|
||||||
|
|
||||||
|
while (j > 0 && _contents[j-1] != 0)
|
||||||
|
{
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
if (i < _count - 1)
|
||||||
|
{
|
||||||
|
memcpy(_contents + j, _contents + i + 1,
|
||||||
|
(_count - i) * sizeof(void*));
|
||||||
|
}
|
||||||
|
_count = i = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (id) copyWithZone: (NSZone*)zone
|
- (id) copyWithZone: (NSZone*)zone
|
||||||
{
|
{
|
||||||
return RETAIN(self); // FIXME
|
NSConcretePointerArray *c;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
c = (NSConcretePointerArray*)NSCopyObject(self, 0, NSDefaultMallocZone());
|
||||||
|
c->_capacity = c->_count;
|
||||||
|
c->_grow_factor = c->_capacity/2;
|
||||||
|
#if GS_WITH_GC
|
||||||
|
if (_pf.usesWeakReadAndWriteBarriers)
|
||||||
|
{
|
||||||
|
c->_contents = NSAllocateCollectable(sizeof(id) * _count, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c->_contents = NSAllocateCollectable(sizeof(id) * _count,
|
||||||
|
NSScannedOption);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
c->_contents = NSZoneCalloc([self zone], _count, sizeof(id));
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < _count; i++)
|
||||||
|
{
|
||||||
|
pointerFunctionsAcquire(&_pf, &c->_contents[i], _contents[i]);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned) count
|
- (unsigned) count
|
||||||
|
@ -249,16 +296,18 @@ static Class concreteClass = Nil;
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
[self finalize];
|
[self finalize];
|
||||||
if (_contents_array != 0)
|
if (_contents != 0)
|
||||||
{
|
{
|
||||||
NSZoneFree([self zone], _contents_array);
|
NSZoneFree([self zone], _contents);
|
||||||
}
|
}
|
||||||
[_functions release];
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||||
{
|
{
|
||||||
|
/* FIXME ... how can we meaningfully encode the pointer functions???
|
||||||
|
*/
|
||||||
|
[self notImplemented: _cmd];
|
||||||
if ([aCoder allowsKeyedCoding])
|
if ([aCoder allowsKeyedCoding])
|
||||||
{
|
{
|
||||||
[super encodeWithCoder: aCoder];
|
[super encodeWithCoder: aCoder];
|
||||||
|
@ -273,7 +322,7 @@ static Class concreteClass = Nil;
|
||||||
{
|
{
|
||||||
[aCoder encodeArrayOfObjCType: @encode(id)
|
[aCoder encodeArrayOfObjCType: @encode(id)
|
||||||
count: _count
|
count: _count
|
||||||
at: _contents_array];
|
at: _contents];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,6 +334,9 @@ static Class concreteClass = Nil;
|
||||||
|
|
||||||
- (id) initWithCoder: (NSCoder*)aCoder
|
- (id) initWithCoder: (NSCoder*)aCoder
|
||||||
{
|
{
|
||||||
|
/* FIXME ... how can we meaningfully encode the pointer functions???
|
||||||
|
*/
|
||||||
|
[self notImplemented: _cmd];
|
||||||
if ([aCoder allowsKeyedCoding])
|
if ([aCoder allowsKeyedCoding])
|
||||||
{
|
{
|
||||||
self = [super initWithCoder: aCoder];
|
self = [super initWithCoder: aCoder];
|
||||||
|
@ -298,19 +350,26 @@ static Class concreteClass = Nil;
|
||||||
if (_count > 0)
|
if (_count > 0)
|
||||||
{
|
{
|
||||||
#if GS_WITH_GC
|
#if GS_WITH_GC
|
||||||
_contents_array = NSAllocateCollectable(sizeof(id) * _count,
|
if (_pf.usesWeakReadAndWriteBarriers)
|
||||||
NSScannedOption);
|
{
|
||||||
|
_contents = NSAllocateCollectable(sizeof(id) * _count, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_contents = NSAllocateCollectable(sizeof(id) * _count,
|
||||||
|
NSScannedOption);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
_contents_array = NSZoneCalloc([self zone], _count, sizeof(id));
|
_contents = NSZoneCalloc([self zone], _count, sizeof(id));
|
||||||
#endif
|
#endif
|
||||||
if (_contents_array == 0)
|
if (_contents == 0)
|
||||||
{
|
{
|
||||||
[NSException raise: NSMallocException
|
[NSException raise: NSMallocException
|
||||||
format: @"Unable to make array"];
|
format: @"Unable to make array"];
|
||||||
}
|
}
|
||||||
[aCoder decodeArrayOfObjCType: @encode(id)
|
[aCoder decodeArrayOfObjCType: @encode(id)
|
||||||
count: _count
|
count: _count
|
||||||
at: _contents_array];
|
at: _contents];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
@ -318,7 +377,11 @@ static Class concreteClass = Nil;
|
||||||
|
|
||||||
- (id) initWithOptions: (NSPointerFunctionsOptions)options
|
- (id) initWithOptions: (NSPointerFunctionsOptions)options
|
||||||
{
|
{
|
||||||
_functions = [[NSConcretePointerFunctions alloc] initWithOptions: options];
|
NSConcretePointerFunctions *f;
|
||||||
|
|
||||||
|
f = [[NSConcretePointerFunctions alloc] initWithOptions: options];
|
||||||
|
self = [self initWithPointerFunctions: f];
|
||||||
|
[f release];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,49 +389,177 @@ static Class concreteClass = Nil;
|
||||||
{
|
{
|
||||||
if ([functions class] == [NSConcretePointerFunctions class])
|
if ([functions class] == [NSConcretePointerFunctions class])
|
||||||
{
|
{
|
||||||
_functions = [functions copy];
|
memcpy(&_pf, &((NSConcretePointerFunctions*)functions)->_x, sizeof(_pf));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_functions = [NSConcretePointerFunctions new];
|
_pf.acquireFunction = [functions acquireFunction];
|
||||||
[_functions setAcquireFunction: [functions acquireFunction]];
|
_pf.descriptionFunction = [functions descriptionFunction];
|
||||||
[_functions setDescriptionFunction: [functions descriptionFunction]];
|
_pf.hashFunction = [functions hashFunction];
|
||||||
[_functions setHashFunction: [functions hashFunction]];
|
_pf.isEqualFunction = [functions isEqualFunction];
|
||||||
[_functions setIsEqualFunction: [functions isEqualFunction]];
|
_pf.relinquishFunction = [functions relinquishFunction];
|
||||||
[_functions setRelinquishFunction: [functions relinquishFunction]];
|
_pf.sizeFunction = [functions sizeFunction];
|
||||||
[_functions setSizeFunction: [functions sizeFunction]];
|
_pf.usesStrongWriteBarrier
|
||||||
[_functions setUsesStrongWriteBarrier:
|
= [functions usesStrongWriteBarrier];
|
||||||
[functions usesStrongWriteBarrier]];
|
_pf.usesWeakReadAndWriteBarriers
|
||||||
[_functions setUsesWeakReadAndWriteBarriers:
|
= [functions usesWeakReadAndWriteBarriers];
|
||||||
[functions usesWeakReadAndWriteBarriers]];
|
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) insertPointer: (void*)pointer atIndex: (NSUInteger)index
|
- (void) insertPointer: (void*)pointer atIndex: (NSUInteger)index
|
||||||
{
|
{
|
||||||
|
NSUInteger i;
|
||||||
|
|
||||||
if (index > _count)
|
if (index > _count)
|
||||||
{
|
{
|
||||||
[self _raiseRangeExceptionWithIndex: index from: _cmd];
|
[self _raiseRangeExceptionWithIndex: index from: _cmd];
|
||||||
}
|
}
|
||||||
if (_count >= _capacity)
|
i = _count;
|
||||||
|
[self setCount: _count + 1];
|
||||||
|
while (i > index)
|
||||||
{
|
{
|
||||||
void **ptr;
|
_contents[i] = _contents[i-1];
|
||||||
size_t size = (_capacity + _grow_factor)*sizeof(void*);
|
}
|
||||||
|
pointerFunctionsAcquire(&_pf, &_contents[index], pointer);
|
||||||
ptr = (void**)NSZoneRealloc([self zone], _contents_array, size);
|
}
|
||||||
if (ptr == 0)
|
|
||||||
{
|
- (BOOL) isEqual: (id)other
|
||||||
[NSException raise: NSMallocException
|
{
|
||||||
format: @"Unable to grow array"];
|
NSUInteger count;
|
||||||
}
|
|
||||||
_contents_array = ptr;
|
if (other == self)
|
||||||
_capacity += _grow_factor;
|
{
|
||||||
_grow_factor = _capacity/2;
|
return YES;
|
||||||
|
}
|
||||||
|
if ([other isKindOfClass: abstractClass] == NO)
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
if ([other hash] != [self hash])
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
count = [self count];
|
||||||
|
while (count-- > 0)
|
||||||
|
{
|
||||||
|
if (pointerFunctionsEqual(&_pf, _contents[count],
|
||||||
|
[other pointerAtIndex: count]) == NO)
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void*) pointerAtIndex: (NSUInteger)index
|
||||||
|
{
|
||||||
|
if (index >= _count)
|
||||||
|
{
|
||||||
|
[self _raiseRangeExceptionWithIndex: index from: _cmd];
|
||||||
|
}
|
||||||
|
return _contents[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSPointerFunctions*) pointerFunctions
|
||||||
|
{
|
||||||
|
NSConcretePointerFunctions *pf = [NSConcretePointerFunctions new];
|
||||||
|
|
||||||
|
pf->_x = _pf;
|
||||||
|
return [pf autorelease];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) removePointerAtIndex: (NSUInteger)index
|
||||||
|
{
|
||||||
|
if (index >= _count)
|
||||||
|
{
|
||||||
|
[self _raiseRangeExceptionWithIndex: index from: _cmd];
|
||||||
|
}
|
||||||
|
pointerFunctionsRelinquish(&_pf, &_contents[index]);
|
||||||
|
while (++index < _count)
|
||||||
|
{
|
||||||
|
_contents[index-1] = _contents[index];
|
||||||
|
}
|
||||||
|
[self setCount: _count - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) replacePointerAtIndex: (NSUInteger)index withPointer: (void*)item
|
||||||
|
{
|
||||||
|
if (index >= _count)
|
||||||
|
{
|
||||||
|
[self _raiseRangeExceptionWithIndex: index from: _cmd];
|
||||||
|
}
|
||||||
|
pointerFunctionsReplace(&_pf, &_contents[index], item);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setCount: (NSUInteger)count
|
||||||
|
{
|
||||||
|
if (count > _count)
|
||||||
|
{
|
||||||
|
_count = count;
|
||||||
|
if (_count >= _capacity)
|
||||||
|
{
|
||||||
|
void **ptr;
|
||||||
|
size_t size;
|
||||||
|
size_t new_cap = _capacity;
|
||||||
|
size_t new_gf = _grow_factor;
|
||||||
|
|
||||||
|
while (new_cap + new_gf < _count)
|
||||||
|
{
|
||||||
|
new_cap += new_gf;
|
||||||
|
new_gf = new_cap/2;
|
||||||
|
}
|
||||||
|
size = (new_cap + new_gf)*sizeof(void*);
|
||||||
|
new_cap += new_gf;
|
||||||
|
new_gf = new_cap / 2;
|
||||||
|
if (_contents == 0)
|
||||||
|
{
|
||||||
|
#if GS_WITH_GC
|
||||||
|
ptr = (void**)NSZoneMalloc([self zone], size);
|
||||||
|
#else
|
||||||
|
if (_pf.usesWeakReadAndWriteBarriers)
|
||||||
|
{
|
||||||
|
ptr = (void**)NSAllocateCollectable(size, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr = (void**)NSAllocateCollectable(size, NSScannedOption);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if GS_WITH_GC
|
||||||
|
ptr = (void**)NSZoneRealloc([self zone], _contents, size);
|
||||||
|
#else
|
||||||
|
if (_pf.usesWeakReadAndWriteBarriers)
|
||||||
|
{
|
||||||
|
ptr = (void**)NSReallocateCollectable(
|
||||||
|
_contents, size, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr = (void**)NSReallocateCollectable(
|
||||||
|
_contents, size, NSScannedOption);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (ptr == 0)
|
||||||
|
{
|
||||||
|
[NSException raise: NSMallocException
|
||||||
|
format: @"Unable to grow array"];
|
||||||
|
}
|
||||||
|
_contents = ptr;
|
||||||
|
_capacity = new_cap;
|
||||||
|
_grow_factor = new_gf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (count < _count)
|
||||||
|
{
|
||||||
|
_count--;
|
||||||
|
pointerFunctionsRelinquish(&_pf, &_contents[_count]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// FIXME ... retain/copy in
|
|
||||||
_contents_array[_count] = pointer;
|
|
||||||
_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue