mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-26 10:11:03 +00:00
add NSPointerArray
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@27660 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
8040b6c88a
commit
ed994b6d46
6 changed files with 437 additions and 0 deletions
|
@ -5,6 +5,8 @@
|
|||
are dealing with none-nil values.
|
||||
* Headers/Additions/GNUstepBase/GSIMap.h:
|
||||
Some changes moving towards use of typed memory for gc.
|
||||
* Headers/Foundation/NSPointerArray.h: New class header.
|
||||
* Source/NSPointerArray.m: Skeletal (non-working) implementation
|
||||
|
||||
2009-01-22 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
#import <Foundation/NSNull.h>
|
||||
#import <Foundation/NSNumberFormatter.h>
|
||||
#import <Foundation/NSPathUtilities.h>
|
||||
#import <Foundation/NSPointerArray.h>
|
||||
#import <Foundation/NSPointerFunctions.h>
|
||||
#import <Foundation/NSPortCoder.h>
|
||||
#import <Foundation/NSPortMessage.h>
|
||||
|
|
134
Headers/Foundation/NSPointerArray.h
Normal file
134
Headers/Foundation/NSPointerArray.h
Normal file
|
@ -0,0 +1,134 @@
|
|||
/**Interface for NSPointerArray for GNUStep
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
||||
Date: 2009
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02111 USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __NSPointerArray_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __NSPointerArray_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSPointerFunctions.h>
|
||||
|
||||
#if OS_API_VERSION(100500, GS_API_LATEST)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An NSPointerArray acts like a standard mutable array except that it
|
||||
* can contain nil and even non-object values.<br />
|
||||
* The count can also be set causing the array to shrink (discarding items)
|
||||
* or grow (adding nil/zero items).
|
||||
*/
|
||||
|
||||
@interface NSPointerArray : NSObject <NSCopying, NSCoding>
|
||||
|
||||
/** Allocate an instance, initialise using initWithOptions: and
|
||||
* return it autoreleased.
|
||||
*/
|
||||
+ (id) pointerArrayWithOptions: (NSPointerFunctionsOptions)options;
|
||||
|
||||
/** Allocate an instance, initialise using initWithPointerFunctions: and
|
||||
* return it autoreleased.
|
||||
*/
|
||||
+ (id) pointerArrayWithPointerFunctions: (NSPointerFunctions *)functions;
|
||||
|
||||
/** Removes all nil/zero items from the array.
|
||||
*/
|
||||
- (void) compact; // eliminate NULLs
|
||||
|
||||
/** Returns the number of items in the array.
|
||||
*/
|
||||
- (NSUInteger) count;
|
||||
|
||||
/** Initialises the receiver with the spefieifd options.
|
||||
*/
|
||||
- (id) initWithOptions: (NSPointerFunctionsOptions)options;
|
||||
|
||||
/** Initialises the receiver using the supplied object.
|
||||
*/
|
||||
- (id) initWithPointerFunctions: (NSPointerFunctions*)functions;
|
||||
|
||||
/** Adds an item at the end of the array.
|
||||
*/
|
||||
- (void) addPointer: (void*)pointer;
|
||||
|
||||
/** Inserts an item at the specified index causing all higher indexed
|
||||
* items to be adjusted upwards.
|
||||
*/
|
||||
- (void) insertPointer: (void*)pointer atIndex: (NSUInteger)index;
|
||||
|
||||
/** Returns the item at the given index or raises an exception if index
|
||||
* is out of range.
|
||||
*/
|
||||
- (void*) pointerAtIndex: (NSUInteger)index;
|
||||
|
||||
/** Returns an autorelease NSPointerFunctions instance giving the
|
||||
* functions in use by the receiver.
|
||||
*/
|
||||
- (NSPointerFunctions*) pointerFunctions;
|
||||
|
||||
/** Removes the item at the specified index, adjusting the positions of
|
||||
* all higher indexed items.
|
||||
*/
|
||||
- (void) removePointerAtIndex: (NSUInteger)index;
|
||||
|
||||
/* Replaces the item at the specified index. The index must be less than
|
||||
* the current count or an exception is raised.
|
||||
*/
|
||||
- (void) replacePointerAtIndex: (NSUInteger)index withPointer: (void*)item;
|
||||
|
||||
/** Sets the number of items in the receiver. Adds nil/zero items to pad
|
||||
* the end of the array, or removes extraneous items from the end.
|
||||
*/
|
||||
- (void) setCount: (NSUInteger)count;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSPointerArray (NSArrayConveniences)
|
||||
|
||||
/** Creates an instance configured to hold objects and prevent them from
|
||||
* being garbage collected.
|
||||
*/
|
||||
+ (id) pointerArrayWithStrongObjects;
|
||||
|
||||
/** Creates an instance configured to hold objects, allowing them to be
|
||||
* garbage collected and replaced by nil if/when they are collected.
|
||||
*/
|
||||
+ (id) pointerArrayWithWeakObjects;
|
||||
|
||||
/** Returns an array containing all the non-nil objects from the receiver.
|
||||
*/
|
||||
- (NSArray*) allObjects;
|
||||
|
||||
@end
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -84,6 +84,8 @@ NSNumberFormatter.h \
|
|||
NSObjCRuntime.h \
|
||||
NSObject.h \
|
||||
NSPathUtilities.h \
|
||||
NSPointerFunctions.h \
|
||||
NSPointerArray.h \
|
||||
NSPortCoder.h \
|
||||
NSPort.h \
|
||||
NSPortMessage.h \
|
||||
|
|
|
@ -223,6 +223,7 @@ NSObject+NSComparisonMethods.m \
|
|||
NSPage.m \
|
||||
NSPathUtilities.m \
|
||||
NSPipe.m \
|
||||
NSPointerArray.m \
|
||||
NSPointerFunctions.m \
|
||||
NSPort.m \
|
||||
NSPortCoder.m \
|
||||
|
@ -361,6 +362,7 @@ NSNumberFormatter.h \
|
|||
NSObjCRuntime.h \
|
||||
NSObject.h \
|
||||
NSPathUtilities.h \
|
||||
NSPointerArray.h \
|
||||
NSPointerFunctions.h \
|
||||
NSPortCoder.h \
|
||||
NSPort.h \
|
||||
|
|
296
Source/NSPointerArray.m
Normal file
296
Source/NSPointerArray.m
Normal file
|
@ -0,0 +1,296 @@
|
|||
/**Implementation for NSPointerArray for GNUStep
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
||||
Date: 2009
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02111 USA.
|
||||
|
||||
*/
|
||||
|
||||
#import "config.h"
|
||||
#import "GNUstepBase/preface.h"
|
||||
#import "Foundation/NSPointerArray.h"
|
||||
#import "GNUstepBase/GSObjCRuntime.h"
|
||||
#import "Foundation/NSDictionary.h"
|
||||
#import "Foundation/NSEnumerator.h"
|
||||
#import "Foundation/NSException.h"
|
||||
#import "Foundation/NSDebug.h"
|
||||
#import "Foundation/NSValue.h"
|
||||
#import "Foundation/NSKeyedArchiver.h"
|
||||
|
||||
#import "GSPrivate.h"
|
||||
|
||||
@implementation NSPointerArray
|
||||
|
||||
+ (id) pointerArrayWithOptions: (NSPointerFunctionsOptions)options
|
||||
{
|
||||
return AUTORELEASE([[self alloc] initWithOptions: options]);
|
||||
}
|
||||
|
||||
+ (id) pointerArrayWithPointerFunctions: (NSPointerFunctions *)functions
|
||||
{
|
||||
return AUTORELEASE([[self alloc] initWithPointerFunctions: functions]);
|
||||
}
|
||||
|
||||
- (void) compact
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (id) copyWithZone: (NSZone*)zone
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSUInteger) count
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
return [self initWithOptions: 0];
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id) initWithOptions: (NSPointerFunctionsOptions)options
|
||||
{
|
||||
NSPointerFunctions *functions;
|
||||
|
||||
functions = [NSPointerFunctions pointerFunctionsWithOptions: options];
|
||||
return [self initWithPointerFunctions: functions];
|
||||
}
|
||||
|
||||
- (id) initWithPointerFunctions: (NSPointerFunctions*)functions
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) addPointer: (void*)pointer
|
||||
{
|
||||
[self insertPointer: pointer atIndex: [self count]];
|
||||
}
|
||||
|
||||
- (void) insertPointer: (void*)pointer atIndex: (NSUInteger)index
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void*) pointerAtIndex: (NSUInteger)index
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (NSPointerFunctions*) pointerFunctions
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) removePointerAtIndex: (NSUInteger)index
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) replacePointerAtIndex: (NSUInteger)index withPointer: (void*)item
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) setCount: (NSUInteger)count
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSPointerArray (NSArrayConveniences)
|
||||
|
||||
+ (id) pointerArrayWithStrongObjects
|
||||
{
|
||||
return [self pointerArrayWithOptions: NSPointerFunctionsStrongMemory];
|
||||
}
|
||||
|
||||
+ (id) pointerArrayWithWeakObjects
|
||||
{
|
||||
return [self pointerArrayWithOptions: NSPointerFunctionsZeroingWeakMemory];
|
||||
}
|
||||
|
||||
- (NSArray*) allObjects
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface GSPointerArray : NSPointerArray
|
||||
{
|
||||
NSUInteger _count;
|
||||
void **_contents_array;
|
||||
unsigned _capacity;
|
||||
unsigned _grow_factor;
|
||||
NSPointerFunctions *_functions;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation GSPointerArray
|
||||
|
||||
- (void) _raiseRangeExceptionWithIndex: (NSUInteger)index from: (SEL)sel
|
||||
{
|
||||
NSDictionary *info;
|
||||
NSException *exception;
|
||||
NSString *reason;
|
||||
|
||||
info = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithUnsignedInt: index], @"Index",
|
||||
[NSNumber numberWithUnsignedInt: _count], @"Count",
|
||||
self, @"Array", nil, nil];
|
||||
|
||||
reason = [NSString stringWithFormat:
|
||||
@"Index %d is out of range %d (in '%@')",
|
||||
index, _count, NSStringFromSelector(sel)];
|
||||
|
||||
exception = [NSException exceptionWithName: NSRangeException
|
||||
reason: reason
|
||||
userInfo: info];
|
||||
[exception raise];
|
||||
}
|
||||
|
||||
- (id) copyWithZone: (NSZone*)zone
|
||||
{
|
||||
return RETAIN(self); // FIXME
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self finalize];
|
||||
if (_contents_array != 0)
|
||||
{
|
||||
NSZoneFree([self zone], _contents_array);
|
||||
}
|
||||
[_functions release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
if ([aCoder allowsKeyedCoding])
|
||||
{
|
||||
[super encodeWithCoder: aCoder];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For performace we encode directly ... must exactly match the
|
||||
* superclass implemenation. */
|
||||
[aCoder encodeValueOfObjCType: @encode(unsigned)
|
||||
at: &_count];
|
||||
if (_count > 0)
|
||||
{
|
||||
[aCoder encodeArrayOfObjCType: @encode(id)
|
||||
count: _count
|
||||
at: _contents_array];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
if ([aCoder allowsKeyedCoding])
|
||||
{
|
||||
self = [super initWithCoder: aCoder];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* for performance, we decode directly into memory rather than
|
||||
* using the superclass method. Must exactly match superclass. */
|
||||
[aCoder decodeValueOfObjCType: @encode(unsigned)
|
||||
at: &_count];
|
||||
if (_count > 0)
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
_contents_array = NSAllocateCollectable(sizeof(id) * _count,
|
||||
NSScannedOption);
|
||||
#else
|
||||
_contents_array = NSZoneCalloc([self zone], _count, sizeof(id));
|
||||
#endif
|
||||
if (_contents_array == 0)
|
||||
{
|
||||
[NSException raise: NSMallocException
|
||||
format: @"Unable to make array"];
|
||||
}
|
||||
[aCoder decodeArrayOfObjCType: @encode(id)
|
||||
count: _count
|
||||
at: _contents_array];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (unsigned) count
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
- (unsigned) hash
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
- (void) insertPointer: (void*)pointer atIndex: (NSUInteger)index
|
||||
{
|
||||
if (index > _count)
|
||||
{
|
||||
[self _raiseRangeExceptionWithIndex: index from: _cmd];
|
||||
}
|
||||
if (_count >= _capacity)
|
||||
{
|
||||
void **ptr;
|
||||
size_t size = (_capacity + _grow_factor)*sizeof(void*);
|
||||
|
||||
ptr = (void**)NSZoneRealloc([self zone], _contents_array, size);
|
||||
if (ptr == 0)
|
||||
{
|
||||
[NSException raise: NSMallocException
|
||||
format: @"Unable to grow array"];
|
||||
}
|
||||
_contents_array = ptr;
|
||||
_capacity += _grow_factor;
|
||||
_grow_factor = _capacity/2;
|
||||
}
|
||||
// FIXME ... retain/copy in
|
||||
_contents_array[_count] = pointer;
|
||||
_count++;
|
||||
}
|
||||
@end
|
||||
|
Loading…
Reference in a new issue