1
1
/** NSArray - Array object to hold other objects.
2
2
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
4
4
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
5
5
From skeleton by: Adam Fedor <fedor@boulder.colorado.edu>
8
8
Rewrite by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
9
January 1998 - new methods and changes as documented for Rhapsody plus
9
January 1998 - new methods and changes as documented for Rhapsody plus
10
10
changes of array indices to type unsigned, plus major efficiency hacks.
12
12
This file is part of the GNUstep Base Library.
14
14
This library is free software; you can redistribute it and/or
15
15
modify it under the terms of the GNU Library General Public
16
16
License as published by the Free Software Foundation; either
17
17
version 2 of the License, or (at your option) any later version.
19
19
This library is distributed in the hope that it will be useful,
20
20
but WITHOUT ANY WARRANTY; without even the implied warranty of
21
21
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22
22
Library General Public License for more details.
24
24
You should have received a copy of the GNU Library General Public
25
25
License along with this library; if not, write to the Free
26
26
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
28
28
<title>NSArray class reference</title>
29
$Date: 2002/03/13 09:58:43 $ $Revision: 1.107 $
29
$Date: 2005/02/22 11:22:43 $ $Revision: 1.144 $
33
#include <base/behavior.h>
34
#include <Foundation/NSArray.h>
35
#include <Foundation/NSCoder.h>
36
#include <Foundation/NSString.h>
37
#include <Foundation/NSRange.h>
33
#include "Foundation/NSArray.h"
34
#include "Foundation/NSCoder.h"
35
#include "Foundation/NSData.h"
36
#include "Foundation/NSString.h"
37
#include "Foundation/NSRange.h"
38
38
#include <limits.h>
39
#include <Foundation/NSUtilities.h>
40
#include <Foundation/NSException.h>
41
#include <Foundation/NSAutoreleasePool.h>
42
#include <Foundation/NSThread.h>
43
#include <Foundation/NSMapTable.h>
44
#include <Foundation/NSLock.h>
45
#include <Foundation/NSDebug.h>
39
#include "Foundation/NSUtilities.h"
40
#include "Foundation/NSException.h"
41
#include "Foundation/NSAutoreleasePool.h"
42
#include "Foundation/NSThread.h"
43
#include "Foundation/NSMapTable.h"
44
#include "Foundation/NSLock.h"
45
#include "Foundation/NSDebug.h"
46
#include "Foundation/NSValue.h"
47
#include "Foundation/NSNull.h"
48
// For private method _decodeArrayOfObjectsForKey:
49
#include "Foundation/NSKeyedArchiver.h"
50
#include "GNUstepBase/GSCategories.h"
46
51
#include "GSPrivate.h"
53
extern BOOL GSMacOSXCompatiblePropertyLists(void);
54
extern void GSPropertyListMake(id,NSDictionary*,BOOL,BOOL,unsigned,id*);
48
56
@class NSArrayEnumerator;
49
57
@class NSArrayEnumeratorReverse;
194
233
return AUTORELEASE(o);
237
* Returns an autoreleased array containing the list
238
* of objects, preserving order.
197
240
+ (id) arrayWithObjects: firstObject, ...
200
va_start(ap, firstObject);
201
self = [[self allocWithZone: NSDefaultMallocZone()]
202
_initWithObjects: firstObject rest: ap];
204
return AUTORELEASE(self);
242
id a = [self allocWithZone: NSDefaultMallocZone()];
244
GS_USEIDLIST(firstObject,
245
a = [a initWithObjects: __objects count: __count]);
246
return AUTORELEASE(a);
250
* Returns an autoreleased array containing the specified
251
* objects, preserving order.
207
253
+ (id) arrayWithObjects: (id*)objects count: (unsigned)count
209
255
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
210
256
initWithObjects: objects count: count]);
260
* Returns an autoreleased array formed from the contents of
261
* the receiver and adding anObject as the last item.
213
263
- (NSArray*) arrayByAddingObject: (id)anObject
216
266
unsigned c = [self count];
218
268
if (anObject == nil)
219
269
[NSException raise: NSInvalidArgumentException
220
270
format: @"Attempt to add nil to an array"];
222
na = [[GSArrayClass allocWithZone: NSDefaultMallocZone()]
223
initWithObjects: &anObject count: 1];
273
na = [[GSArrayClass allocWithZone: NSDefaultMallocZone()]
274
initWithObjects: &anObject count: 1];
278
GS_BEGINIDBUF(objects, c+1);
228
280
[self getObjects: objects];
229
281
objects[c] = anObject;
230
282
na = [[GSArrayClass allocWithZone: NSDefaultMallocZone()]
231
283
initWithObjects: objects count: c+1];
233
287
return AUTORELEASE(na);
291
* Returns a new array which is the concatenation of self and
292
* otherArray (in this precise order).
236
294
- (NSArray*) arrayByAddingObjectsFromArray: (NSArray*)anotherArray
241
299
c = [self count];
242
300
l = [anotherArray count];
303
GS_BEGINIDBUF(objects, c+l);
246
305
[self getObjects: objects];
247
306
[anotherArray getObjects: &objects[c]];
248
307
na = [NSArrayClass arrayWithObjects: objects count: c+l];
316
* Returns the abstract class ... arrays are coded as abstract arrays.
253
318
- (Class) classForCoder
255
320
return NSArrayClass;
258
- (BOOL) containsObject: anObject
324
* Returns YES if anObject belongs to self. No otherwise.<br />
325
* The -isEqual: method of anObject is used to test for equality.
327
- (BOOL) containsObject: (id)anObject
260
329
return ([self indexOfObject: anObject] != NSNotFound);
333
* Returns a new copy of the receiver.<br />
334
* The default abstract implementation of a copy is to use the
335
* -initWithArray:copyItems: method with the flag set to YES.<br />
336
* Immutable subclasses generally simply retain and return the receiver.
263
338
- (id) copyWithZone: (NSZone*)zone
340
NSArray *copy = [NSArrayClass allocWithZone: zone];
342
return [copy initWithArray: self copyItems: YES];
345
/** <override-subclass />
346
* Returns the number of elements contained in the receiver.
268
348
- (unsigned) count
270
350
[self subclassResponsibility: _cmd];
355
* Encodes the receiver for storing to archive or sending over an
274
358
- (void) encodeWithCoder: (NSCoder*)aCoder
276
360
unsigned count = [self count];
278
[aCoder encodeValueOfObjCType: @encode(unsigned)
285
[self getObjects: a];
286
[aCoder encodeArrayOfObjCType: @encode(id)
362
if ([aCoder allowsKeyedCoding])
364
/* HACK ... MacOS-X seems to code differently if the coder is an
365
* actual instance of NSKeyedArchiver
367
if ([aCoder class] == [NSKeyedArchiver class])
369
[(NSKeyedArchiver*)aCoder _encodeArrayOfObjects: self
370
forKey: @"NS.objects"];
376
for (i = 0; i < count; i++)
380
key = [NSString stringWithFormat: @"NS.object.%u", i];
381
[(NSKeyedArchiver*)aCoder encodeObject: [self objectAtIndex: i]
388
[aCoder encodeValueOfObjCType: @encode(unsigned)
393
GS_BEGINIDBUF(a, count);
395
[self getObjects: a];
396
[aCoder encodeArrayOfObjCType: @encode(id)
405
* Copies the objects from the receiver to aBuffer, which must be
406
* an area of memory large enough to hold them.
292
408
- (void) getObjects: (id*)aBuffer
294
410
unsigned i, c = [self count];
380
519
return NSNotFound;
523
* <p>In MacOS-X class clusters do not have designated initialisers,
524
* and there is a general rule that -init is treated as the designated
525
* initialiser of the class cluster, but that other intitialisers
526
* may not work s expected an would need to be individually overridden
529
* <p>GNUstep tries to make it easier to subclass a class cluster,
530
* by making class clusters follow the same convention as normal
531
* classes, so the designated initialiser is the <em>richest</em>
532
* initialiser. This means that all other initialisers call the
533
* documented designated initialiser (which calls -init only for
534
* MacOS-X compatibility), and anyone writing a subclass only needs
535
* to override that one initialiser in order to have all the other
538
* <p>For MacOS-X compatibility, you may also need to override various
539
* other initialisers. Exactly which ones, you will need to determine
540
* by trial on a MacOS-X system ... and may vary between releases of
541
* MacOS-X. So to be safe, on MacOS-X you probably need to re-implement
542
* <em>all</em> the class cluster initialisers you might use in conjunction
543
* with your subclass.
385
return [self initWithObjects: (id*)0 count: 0];
553
* Initialize the receiver with the contents of array.
554
* The order of array is preserved.<br />
555
* If shouldCopy is YES then the objects are copied
556
* rather than simply retained.<br />
557
* Invokes -initWithObjects:count:
559
- (id) initWithArray: (NSArray*)array copyItems: (BOOL)shouldCopy
561
unsigned c = [array count];
562
GS_BEGINIDBUF(objects, c);
564
[array getObjects: objects];
565
if (shouldCopy == YES)
569
for (i = 0; i < c; i++)
571
objects[i] = [objects[i] copy];
573
self = [self initWithObjects: objects count: c];
577
[objects[--i] release];
583
self = [self initWithObjects: objects count: c];
590
* Initialize the receiver with the contents of array.
591
* The order of array is preserved.<br />
592
* Invokes -initWithObjects:count:
388
594
- (id) initWithArray: (NSArray*)array
396
[array getObjects: objects];
397
self = [self initWithObjects: objects count: c];
596
unsigned c = [array count];
597
GS_BEGINIDBUF(objects, c);
599
[array getObjects: objects];
600
self = [self initWithObjects: objects count: c];
606
* Initialize the array by decoding from an archive.<br />
607
* Invokes -initWithObjects:count:
402
609
- (id) initWithCoder: (NSCoder*)aCoder
406
[aCoder decodeValueOfObjCType: @encode(unsigned)
611
if ([aCoder allowsKeyedCoding])
412
[aCoder decodeArrayOfObjCType: @encode(id)
415
return [self initWithObjects: contents count: count];
615
array = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
623
array = [NSMutableArray arrayWithCapacity: 2];
624
key = [NSString stringWithFormat: @"NS.object.%u", i];
625
val = [(NSKeyedUnarchiver*)aCoder decodeObjectForKey: key];
629
[array addObject: val];
631
key = [NSString stringWithFormat: @"NS.object.%u", i];
632
val = [(NSKeyedUnarchiver*)aCoder decodeObjectForKey: key];
636
self = [self initWithArray: array];
418
return [self initWithObjects: 0 count: 0];
642
[aCoder decodeValueOfObjCType: @encode(unsigned)
646
GS_BEGINIDBUF(contents, count);
648
[aCoder decodeArrayOfObjCType: @encode(id)
651
self = [self initWithObjects: contents count: count];
655
[contents[count] release];
662
self = [self initWithObjects: 0 count: 0];
669
* <p>Initialises the array with the contents of the specified file,
670
* which must contain an array in property-list format.
672
* <p>In GNUstep, the property-list format may be either the OpenStep
673
* format (ASCII data), or the MacOS-X format (UTF-8 XML data) ... this
674
* method will recognise which it is.
676
* <p>If there is a failure to load the file for any reason, the receiver
677
* will be released, the method will return nil, and a warning may be logged.
679
* <p>Works by invoking [NSString-initWithContentsOfFile:] and
680
* [NSString-propertyList] then checking that the result is an array.
421
683
- (id) initWithContentsOfFile: (NSString*)file
423
685
NSString *myString;
425
687
myString = [[NSString allocWithZone: NSDefaultMallocZone()]
426
688
initWithContentsOfFile: file];
433
result = [myString propertyList];
441
if ([result isKindOfClass: NSArrayClass])
443
self = [self initWithArray: result];
447
NSWarnMLog(@"Contents of file '%@' does not contain an array", file);
452
/* This is the designated initializer for NSArray. */
699
result = [myString propertyList];
707
if ([result isKindOfClass: NSArrayClass])
709
self = [self initWithArray: result];
713
NSWarnMLog(@"Contents of file '%@' does not contain an array", file);
721
* <p>Initialises the array with the contents of the specified URL,
722
* which must contain an array in property-list format.
724
* <p>In GNUstep, the property-list format may be either the OpenStep
725
* format (ASCII data), or the MacOS-X format (URF8 XML data) ... this
726
* method will recognise which it is.
728
* <p>If there is a failure to load the URL for any reason, the receiver
729
* will be released, the method will return nil, and a warning may be logged.
731
* <p>Works by invoking [NSString-initWithContentsOfURL:] and
732
* [NSString-propertyList] then checking that the result is an array.
735
- (id) initWithContentsOfURL: (NSURL*)aURL
739
myString = [[NSString allocWithZone: NSDefaultMallocZone()]
740
initWithContentsOfURL: aURL];
751
result = [myString propertyList];
759
if ([result isKindOfClass: NSArrayClass])
761
self = [self initWithArray: result];
765
NSWarnMLog(@"Contents of URL '%@' does not contain an array", aURL);
772
/** <init /> <override-subclass />
773
* This should initialize the array with count (may be zero) objects.<br />
774
* Retains each object placed in the array.<br />
775
* Calls -init (which does nothing but maintain MacOS-X compatibility),
776
* and needs to be re-implemented in subclasses in order to have all
777
* other initialisers work.
453
779
- (id) initWithObjects: (id*)objects count: (unsigned)count
455
[self subclassResponsibility: _cmd];
459
- (id) _initWithObjects: firstObject rest: (va_list) ap
462
register unsigned curSize;
463
auto unsigned prevSize;
464
auto unsigned newSize;
468
/* Do initial allocation. */
471
objsArray = (id*)NSZoneMalloc(NSDefaultMallocZone(), sizeof(id) * curSize);
474
/* Loop through adding objects to array until a nil is
477
for (i = 0; tmpId != nil; i++)
479
/* Put id into array. */
480
objsArray[i] = tmpId;
482
/* If the index equals the current size, increase size. */
483
if (i == curSize - 1)
485
/* Fibonacci series. Supposedly, for this application,
486
* the fibonacci series will be more memory efficient.
488
newSize = prevSize + curSize;
492
/* Reallocate object array. */
493
objsArray = (id*)NSZoneRealloc(NSDefaultMallocZone(), objsArray,
494
sizeof(id) * curSize);
496
tmpId = va_arg(ap, id);
500
/* Put object ids into NSArray. */
501
self = [self initWithObjects: objsArray count: i];
502
NSZoneFree(NSDefaultMallocZone(), objsArray);
786
* Initialize the array the list of objects.
787
* <br />May change the value of self before returning it.
506
789
- (id) initWithObjects: firstObject, ...
509
va_start(ap, firstObject);
510
self = [self _initWithObjects: firstObject rest: ap];
791
GS_USEIDLIST(firstObject,
792
self = [self initWithObjects: __objects count: __count]);
797
* Returns an NSMutableArray instance containing the same objects as
798
* the receiver.<br />
799
* The default implementation does this by calling the
800
* -initWithArray:copyItems: method on a newly created object,
801
* and passing it NO to tell it just to retain the items.
515
803
- (id) mutableCopyWithZone: (NSZone*)zone
517
return [[GSMutableArrayClass allocWithZone: zone]
518
initWithArray: self];
805
NSMutableArray *copy = [NSMutableArrayClass allocWithZone: zone];
807
return [copy initWithArray: self copyItems: NO];
810
/** <override-subclass />
811
* Returns the object at the specified index.
812
* Raises an exception of the index is beyond the array.
521
814
- (id) objectAtIndex: (unsigned)index
523
816
[self subclassResponsibility: _cmd];
562
861
return [self objectAtIndex: count-1];
865
* Makes each object in the array perform aSelector.<br />
866
* This is done sequentially from the first to the last object.
565
868
- (void) makeObjectsPerformSelector: (SEL)aSelector
567
unsigned i = [self count];
870
unsigned c = [self count];
571
874
IMP get = [self methodForSelector: oaiSel];
574
[(*get)(self, oaiSel, i) performSelector: aSelector];
879
[(*get)(self, oaiSel, i++) performSelector: aSelector];
885
* Obsolete version of -makeObjectsPerformSelector:
578
887
- (void) makeObjectsPerform: (SEL)aSelector
580
889
[self makeObjectsPerformSelector: aSelector];
583
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: (id) arg
893
* Makes each object in the array perform aSelector with arg.<br />
894
* This is done sequentially from the first to the last object.
896
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: (id)arg
585
unsigned i = [self count];
898
unsigned c = [self count];
589
902
IMP get = [self methodForSelector: oaiSel];
592
[(*get)(self, oaiSel, i) performSelector: aSelector withObject: arg];
907
[(*get)(self, oaiSel, i++) performSelector: aSelector
914
* Obsolete version of -makeObjectsPerformSelector:withObject:
596
916
- (void) makeObjectsPerform: (SEL)aSelector withObject: (id)argument
598
918
[self makeObjectsPerformSelector: aSelector withObject: argument];
601
static int compare(id elem1, id elem2, void* context)
921
static NSComparisonResult
922
compare(id elem1, id elem2, void* context)
603
return (int)[elem1 performSelector: (SEL)context withObject: elem2];
924
NSComparisonResult (*imp)(id, SEL, id);
928
[NSException raise: NSInvalidArgumentException
929
format: @"compare null selector given"];
932
imp = (NSComparisonResult (*)(id, SEL, id))
933
[elem1 methodForSelector: context];
937
[NSException raise: NSGenericException
938
format: @"invalid selector passed to compare"];
941
return (*imp)(elem1, context, elem2);
945
* Returns an autoreleased array in which the objects are ordered
946
* according to a sort with comparator.
606
948
- (NSArray*) sortedArrayUsingSelector: (SEL)comparator
608
950
return [self sortedArrayUsingFunction: compare context: (void *)comparator];
611
- (NSArray*) sortedArrayUsingFunction: (int(*)(id,id,void*))comparator
954
* Returns an autoreleased array in which the objects are ordered
955
* according to a sort with comparator. This invokes
956
* -sortedArrayUsingFunction:context:hint: with a nil hint.
958
- (NSArray*) sortedArrayUsingFunction: (NSComparisonResult(*)(id,id,void*))comparator
612
959
context: (void*)context
614
961
return [self sortedArrayUsingFunction: comparator context: context hint: nil];
965
* Subclasses may provide a hint for sorting ... The default GNUstep
966
* implementation just returns nil.
617
968
- (NSData*) sortedArrayHint
622
- (NSArray*) sortedArrayUsingFunction: (int(*)(id,id,void*))comparator
974
* Returns an autoreleased array in which the objects are ordered
975
* according to a sort with comparator, where the comparator function
976
* is passed two objects to compare, and the context as the third
977
* argument. The hint argument is currently ignored, and may be nil.
979
- (NSArray*) sortedArrayUsingFunction: (NSComparisonResult(*)(id,id,void*))comparator
623
980
context: (void*)context
624
981
hint: (NSData*)hint
626
983
NSMutableArray *sortedArray;
629
985
sortedArray = [[NSMutableArrayClass allocWithZone:
630
NSDefaultMallocZone()] initWithArray: self];
986
NSDefaultMallocZone()] initWithArray: self copyItems: NO];
631
987
[sortedArray sortUsingFunction: comparator context: context];
632
result = [NSArrayClass arrayWithArray: sortedArray];
633
RELEASE(sortedArray);
989
return AUTORELEASE([sortedArray makeImmutableCopyOnFail: NO]);
993
* Returns a string formed by concatenating the objects in the receiver,
994
* with the specified separator string inserted between each part.
637
996
- (NSString*) componentsJoinedByString: (NSString*)separator
639
unsigned i, c = [self count];
640
id s = [NSMutableString stringWithCapacity: 2]; /* arbitrary capacity */
644
[s appendString: [[self objectAtIndex: 0] description]];
645
for (i = 1; i < c; i++)
998
unsigned int c = [self count];
999
NSMutableString *s = [[NSMutableString alloc] initWithCapacity: c];
647
[s appendString: separator];
648
[s appendString: [[self objectAtIndex: i] description]];
1003
unsigned l = [separator length];
1006
[s appendString: [[self objectAtIndex: 0] description]];
1007
for (i = 1; i < c; i++)
1011
[s appendString: separator];
1013
[s appendString: [[self objectAtIndex: i] description]];
1016
return AUTORELEASE([s makeImmutableCopyOnFail: NO]);
1020
* Assumes that the receiver is an array of paths, and returns an
1021
* array formed by selecting the subset of those patch matching
1022
* the specified array of extensions.
653
1024
- (NSArray*) pathsMatchingExtensions: (NSArray*)extensions
655
1026
unsigned i, c = [self count];
656
NSMutableArray *a = [NSMutableArray arrayWithCapacity: 1];
1027
NSMutableArray *a = [[NSMutableArray alloc] initWithCapacity: 1];
657
1028
Class cls = [NSString class];
658
1029
IMP get = [self methodForSelector: oaiSel];
659
1030
IMP add = [a methodForSelector: addSel];
718
1120
return AUTORELEASE(e);
1124
* Returns the result of invoking -descriptionWithLocale:indent: with a nil
1125
* locale and zero indent.
721
1127
- (NSString*) description
723
1129
return [self descriptionWithLocale: nil];
1133
* Returns the result of invoking -descriptionWithLocale:indent:
1134
* with a zero indent.
726
1136
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
728
1138
return [self descriptionWithLocale: locale indent: 0];
1142
* Returns the receiver as a text property list in the traditional format.<br />
1143
* See [NSString-propertyList] for details.<br />
1144
* If locale is nil, no formatting is done, otherwise entries are formatted
1145
* according to the locale, and indented according to level.<br />
1146
* Unless locale is nil, a level of zero indents items by four spaces,
1147
* while a level of one indents them by a tab.<br />
1148
* The items in the property list string appear in the same order as
1149
* they appear in the receiver.
731
1151
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
732
1152
indent: (unsigned int)level
734
NSMutableString *result;
736
result = [[NSMutableString alloc] initWithCapacity: 20*[self count]];
737
result = AUTORELEASE(result);
738
[self descriptionWithLocale: locale
740
to: (id<GNUDescriptionDestination>)result];
744
static NSString *indentStrings[] = {
760
- (void) descriptionWithLocale: (NSDictionary*)locale
761
indent: (unsigned int)level
762
to: (id<GNUDescriptionDestination>)result
764
unsigned count = [self count];
765
unsigned last = count - 1;
766
NSString *plists[count];
770
appImp = [(NSObject*)result methodForSelector: appSel];
772
[self getObjects: plists];
776
(*appImp)(result, appSel, @"(");
777
for (i = 0; i < count; i++)
781
[item descriptionWithLocale: nil indent: 0 to: result];
784
(*appImp)(result, appSel, @", ");
787
(*appImp)(result, appSel, @")");
791
NSString *iBaseString;
792
NSString *iSizeString;
794
if (level < sizeof(indentStrings)/sizeof(id))
796
iBaseString = indentStrings[level];
800
iBaseString = indentStrings[sizeof(indentStrings)/sizeof(id)-1];
803
if (level < sizeof(indentStrings)/sizeof(id))
805
iSizeString = indentStrings[level];
809
iSizeString = indentStrings[sizeof(indentStrings)/sizeof(id)-1];
812
(*appImp)(result, appSel, @"(\n");
813
for (i = 0; i < count; i++)
817
(*appImp)(result, appSel, iSizeString);
819
[item descriptionWithLocale: locale indent: level to: result];
822
(*appImp)(result, appSel, @"\n");
826
(*appImp)(result, appSel, @",\n");
829
(*appImp)(result, appSel, iBaseString);
830
(*appImp)(result, appSel, @")");
834
- (BOOL) writeToFile: (NSString *)path atomically: (BOOL)useAuxilliaryFile
836
extern BOOL GSMacOSXCompatiblePropertyLists();
840
loc = GSUserDefaultsDictionaryRepresentation();
842
if (GSMacOSXCompatiblePropertyLists() == YES)
844
extern NSString *GSXMLPlMake(id obj, NSDictionary *loc);
846
desc = GSXMLPlMake(self, loc);
850
NSMutableString *result;
852
result = [[NSMutableString alloc] initWithCapacity: 20*[self count]];
853
result = AUTORELEASE(result);
854
[self descriptionWithLocale: loc
856
to: (id<GNUDescriptionDestination>)result];
860
return [desc writeToFile: path atomically: useAuxilliaryFile];
863
- (BOOL) writeToURL: (NSURL *)url atomically: (BOOL)useAuxilliaryFile
865
extern BOOL GSMacOSXCompatiblePropertyLists();
869
loc = GSUserDefaultsDictionaryRepresentation();
871
if (GSMacOSXCompatiblePropertyLists() == YES)
873
extern NSString *GSXMLPlMake(id obj, NSDictionary *loc);
875
desc = GSXMLPlMake(self, loc);
879
NSMutableString *result;
881
result = [[NSMutableString alloc] initWithCapacity: 20*[self count]];
882
result = AUTORELEASE(result);
883
[self descriptionWithLocale: loc
885
to: (id<GNUDescriptionDestination>)result];
889
return [desc writeToURL: url atomically: useAuxilliaryFile];
1154
NSString *result = nil;
1156
GSPropertyListMake(self, locale, NO, YES, level == 1 ? 3 : 2, &result);
1162
* <p>Writes the contents of the array to the file specified by path.
1163
* The file contents will be in property-list format ... under GNUstep
1164
* this is either OpenStep style (ASCII characters using \U hexadecimal
1165
* escape sequences for unicode), or MacOS-X style (XML in the UTF8
1168
* <p>If the useAuxiliaryFile flag is YES, the file write operation is
1169
* atomic ... the data is written to a temporary file, which is then
1170
* renamed to the actual file name.
1172
* <p>If the conversion of data into the correct property-list format fails
1173
* or the write operation fails, the method returns NO, otherwise it
1176
* <p>NB. The fact that the file is in property-list format does not
1177
* necessarily mean that it can be used to reconstruct the array using
1178
* the -initWithContentsOfFile: method. If the original array contains
1179
* non-property-list objects, the descriptions of those objects will
1180
* have been written, and reading in the file as a property-list will
1181
* result in a new array containing the string descriptions.
1184
- (BOOL) writeToFile: (NSString *)path atomically: (BOOL)useAuxiliaryFile
1186
NSDictionary *loc = GSUserDefaultsDictionaryRepresentation();
1187
NSString *desc = nil;
1190
if (GSMacOSXCompatiblePropertyLists() == YES)
1192
GSPropertyListMake(self, loc, YES, NO, 2, &desc);
1193
data = [desc dataUsingEncoding: NSUTF8StringEncoding];
1197
GSPropertyListMake(self, loc, NO, NO, 2, &desc);
1198
data = [desc dataUsingEncoding: NSASCIIStringEncoding];
1201
return [data writeToFile: path atomically: useAuxiliaryFile];
1205
* <p>Writes the contents of the array to the specified url.
1206
* This functions just like -writeToFile:atomically: except that the
1207
* output may be written to any URL, not just a local file.
1210
- (BOOL) writeToURL: (NSURL *)url atomically: (BOOL)useAuxiliaryFile
1212
NSDictionary *loc = GSUserDefaultsDictionaryRepresentation();
1213
NSString *desc = nil;
1216
if (GSMacOSXCompatiblePropertyLists() == YES)
1218
GSPropertyListMake(self, loc, YES, NO, 2, &desc);
1219
data = [desc dataUsingEncoding: NSUTF8StringEncoding];
1223
GSPropertyListMake(self, loc, NO, NO, 2, &desc);
1224
data = [desc dataUsingEncoding: NSASCIIStringEncoding];
1227
return [data writeToURL: url atomically: useAuxiliaryFile];
1231
* This overrides NSObjects implementation of this method.
1232
* This method returns an array of objects returned by
1233
* invoking -valueForKey: for each item in the receiver,
1234
* substituting NSNull for nil.
1235
* A special case: the key "count" is not forwarded to each object
1236
* of the receiver but returns the number of objects of the receiver.<br/>
1238
- (id) valueForKey: (NSString*)key
1242
if ([key isEqualToString: @"count"] == YES)
1244
result = [NSNumber numberWithUnsignedInt: [self count]];
1248
NSMutableArray *results = nil;
1249
static NSNull *null = nil;
1251
unsigned count = [self count];
1252
volatile id object = nil;
1254
results = [NSMutableArray array];
1256
for (i = 0; i < count; i++)
1260
object = [self objectAtIndex: i];
1261
result = [object valueForKey: key];
1266
null = RETAIN([NSNull null]);
1271
[results addObject: result];
1283
* <code>NSMutableArray</code> is the mutable version of [NSArray]. It
1284
* provides methods for altering the contents of the array.
895
1286
@implementation NSMutableArray
897
1288
+ (void) initialize
926
1317
return NSMutableArrayClass;
929
/* The NSCopying Protocol */
931
- (id) copyWithZone: (NSZone*)zone
934
unsigned count = [self count];
939
[self getObjects: objects];
940
for (i = 0; i < count; i++)
941
objects[i] = [objects[i] copyWithZone: zone];
942
newArray = [[GSArrayClass allocWithZone: zone]
943
initWithObjects: objects count: count];
945
RELEASE(objects[--i]);
949
/* This is the desgnated initializer for NSMutableArray */
1320
/** <init /> <override-subclass />
1321
* Initialise the array with the specified capacity ... this
1322
* should ensure that the array can have numItems added efficiently.<br />
1323
* Calls -init (which does nothing but maintain MacOS-X compatibility),
1324
* and needs to be re-implemented in subclasses in order to have all
1325
* other initialisers work.
950
1327
- (id) initWithCapacity: (unsigned)numItems
952
[self subclassResponsibility: _cmd];
956
- (void) addObject: anObject
958
[self subclassResponsibility: _cmd];
961
- (void) replaceObjectAtIndex: (unsigned)index withObject: anObject
963
[self subclassResponsibility: _cmd];
1333
/** <override-subclass />
1334
* Adds anObject at the end of the array, thus increasing the size of
1335
* the array. The object is retained upon addition.
1337
- (void) addObject: (id)anObject
1339
[self subclassResponsibility: _cmd];
1343
* Swaps the positions of two objects in the array. Raises an exception
1344
* if either array index is out of bounds.
1346
- (void) exchangeObjectAtIndex: (unsigned int)i1
1347
withObjectAtIndex: (unsigned int)i2
1349
id tmp = [self objectAtIndex: i1];
1352
[self replaceObjectAtIndex: i1 withObject: [self objectAtIndex: i2]];
1353
[self replaceObjectAtIndex: i2 withObject: tmp];
1357
/** <override-subclass />
1358
* Places an object into the receiver at the specified location.<br />
1359
* Raises an exception if given an array index which is too large.<br />
1360
* The object is retained by the array.
1362
- (void) replaceObjectAtIndex: (unsigned)index withObject: (id)anObject
1364
[self subclassResponsibility: _cmd];
1368
* Replaces objects in the receiver with those from anArray.<br />
1369
* Raises an exception if given a range extending beyond the array.<br />
966
1371
- (void) replaceObjectsInRange: (NSRange)aRange
967
1372
withObjectsFromArray: (NSArray*)anArray