2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* IOArray.m created by rsulack on Fri 12-Sep-1997 */
23 /* IOArray.cpp converted to C++ by gvdl on Fri 1998-10-30 */
26 #include <libkern/c++/OSArray.h>
27 #include <libkern/c++/OSSerialize.h>
28 #include <libkern/c++/OSLib.h>
30 #define super OSCollection
32 OSDefineMetaClassAndStructors(OSArray
, OSCollection
)
33 OSMetaClassDefineReservedUnused(OSArray
, 0);
34 OSMetaClassDefineReservedUnused(OSArray
, 1);
35 OSMetaClassDefineReservedUnused(OSArray
, 2);
36 OSMetaClassDefineReservedUnused(OSArray
, 3);
37 OSMetaClassDefineReservedUnused(OSArray
, 4);
38 OSMetaClassDefineReservedUnused(OSArray
, 5);
39 OSMetaClassDefineReservedUnused(OSArray
, 6);
40 OSMetaClassDefineReservedUnused(OSArray
, 7);
44 extern int debug_container_malloc_size
;
46 #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0)
51 bool OSArray::initWithCapacity(unsigned int inCapacity
)
58 size
= sizeof(const OSMetaClassBase
*) * inCapacity
;
59 array
= (const OSMetaClassBase
**) kalloc(size
);
64 capacity
= inCapacity
;
65 capacityIncrement
= (inCapacity
)? inCapacity
: 16;
73 bool OSArray::initWithObjects(const OSObject
*objects
[],
74 unsigned int theCount
,
75 unsigned int theCapacity
= 0)
77 unsigned int capacity
;
81 else if (theCount
> theCapacity
)
84 capacity
= theCapacity
;
86 if (!objects
|| !initWithCapacity(capacity
))
89 for ( unsigned int i
= 0; i
< theCount
; i
++ ) {
90 const OSMetaClassBase
*newObject
= *objects
++;
95 array
[count
++] = newObject
;
96 newObject
->taggedRetain(OSTypeID(OSCollection
));
102 bool OSArray::initWithArray(const OSArray
*anArray
,
103 unsigned int theCapacity
= 0)
108 return initWithObjects((const OSObject
**) anArray
->array
,
109 anArray
->count
, theCapacity
);
112 OSArray
*OSArray::withCapacity(unsigned int capacity
)
114 OSArray
*me
= new OSArray
;
116 if (me
&& !me
->initWithCapacity(capacity
)) {
124 OSArray
*OSArray::withObjects(const OSObject
*objects
[],
126 unsigned int capacity
= 0)
128 OSArray
*me
= new OSArray
;
130 if (me
&& !me
->initWithObjects(objects
, count
, capacity
)) {
138 OSArray
*OSArray::withArray(const OSArray
*array
,
139 unsigned int capacity
= 0)
141 OSArray
*me
= new OSArray
;
143 if (me
&& !me
->initWithArray(array
, capacity
)) {
156 kfree((vm_offset_t
)array
, sizeof(const OSMetaClassBase
*) * capacity
);
157 ACCUMSIZE( -(sizeof(const OSMetaClassBase
*) * capacity
) );
164 unsigned int OSArray::getCount() const { return count
; }
165 unsigned int OSArray::getCapacity() const { return capacity
; }
166 unsigned int OSArray::getCapacityIncrement() const { return capacityIncrement
; }
167 unsigned int OSArray::setCapacityIncrement(unsigned int increment
)
169 capacityIncrement
= (increment
)? increment
: 16;
171 return capacityIncrement
;
174 unsigned int OSArray::ensureCapacity(unsigned int newCapacity
)
176 const OSMetaClassBase
**newArray
;
177 int oldSize
, newSize
;
179 if (newCapacity
<= capacity
)
183 newCapacity
= (((newCapacity
- 1) / capacityIncrement
) + 1)
185 newSize
= sizeof(const OSMetaClassBase
*) * newCapacity
;
187 newArray
= (const OSMetaClassBase
**) kalloc(newSize
);
189 oldSize
= sizeof(const OSMetaClassBase
*) * capacity
;
191 ACCUMSIZE(newSize
- oldSize
);
193 bcopy(array
, newArray
, oldSize
);
194 bzero(&newArray
[capacity
], newSize
- oldSize
);
195 kfree((vm_offset_t
)array
, oldSize
);
197 capacity
= newCapacity
;
203 void OSArray::flushCollection()
208 for (i
= 0; i
< count
; i
++)
209 array
[i
]->taggedRelease(OSTypeID(OSCollection
));
213 bool OSArray::setObject(const OSMetaClassBase
*anObject
)
215 return setObject(count
, anObject
);
218 bool OSArray::setObject(unsigned int index
, const OSMetaClassBase
*anObject
)
221 unsigned int newCount
= count
+ 1;
223 if ((index
> count
) || !anObject
)
226 // do we need more space?
227 if (newCount
> capacity
&& newCount
> ensureCapacity(newCount
))
231 if (index
!= count
) {
232 for (i
= count
; i
> index
; i
--)
233 array
[i
] = array
[i
-1];
235 array
[index
] = anObject
;
236 anObject
->taggedRetain(OSTypeID(OSCollection
));
242 bool OSArray::merge(const OSArray
* otherArray
)
244 unsigned int otherCount
= otherArray
->getCount();
245 unsigned int newCount
= count
+ otherCount
;
250 // do we need more space?
251 if (newCount
> capacity
&& newCount
> ensureCapacity(newCount
))
255 for (unsigned int i
= 0; i
< otherCount
; i
++) {
256 const OSMetaClassBase
*newObject
= otherArray
->getObject(i
);
258 array
[count
++] = newObject
;
259 newObject
->taggedRetain(OSTypeID(OSCollection
));
266 replaceObject(unsigned int index
, const OSMetaClassBase
*anObject
)
268 const OSMetaClassBase
*oldObject
;
270 if ((index
>= count
) || !anObject
)
274 oldObject
= array
[index
];
275 array
[index
] = anObject
;
276 anObject
->taggedRetain(OSTypeID(OSCollection
));
278 oldObject
->taggedRelease(OSTypeID(OSCollection
));
281 void OSArray::removeObject(unsigned int index
)
284 const OSMetaClassBase
*oldObject
;
290 oldObject
= array
[index
];
293 for (i
= index
; i
< count
; i
++)
294 array
[i
] = array
[i
+1];
296 oldObject
->taggedRelease(OSTypeID(OSCollection
));
299 bool OSArray::isEqualTo(const OSArray
*anArray
) const
303 if ( this == anArray
)
306 if ( count
!= anArray
->getCount() )
309 for ( i
= 0; i
< count
; i
++ ) {
310 if ( !array
[i
]->isEqualTo(anArray
->getObject(i
)) )
317 bool OSArray::isEqualTo(const OSMetaClassBase
*anObject
) const
321 otherArray
= OSDynamicCast(OSArray
, anObject
);
323 return isEqualTo(otherArray
);
328 OSObject
*OSArray::getObject(unsigned int index
) const
333 return (OSObject
*) array
[index
];
336 OSObject
*OSArray::getLastObject() const
341 return (OSObject
*) array
[count
- 1];
344 unsigned int OSArray::getNextIndexOfObject(const OSMetaClassBase
* anObject
,
345 unsigned int index
) const
347 while ((index
< count
) && (array
[index
] != anObject
))
350 index
= (unsigned int)-1;
354 unsigned int OSArray::iteratorSize() const
356 return sizeof(unsigned int);
359 bool OSArray::initIterator(void *inIterator
) const
361 unsigned int *iteratorP
= (unsigned int *) inIterator
;
367 bool OSArray::getNextObjectForIterator(void *inIterator
, OSObject
**ret
) const
369 unsigned int *iteratorP
= (unsigned int *) inIterator
;
370 unsigned int index
= (*iteratorP
)++;
373 *ret
= (OSObject
*) array
[index
];
382 bool OSArray::serialize(OSSerialize
*s
) const
384 if (s
->previouslySerialized(this)) return true;
386 if (!s
->addXMLStartTag(this, "array")) return false;
388 for (unsigned i
= 0; i
< count
; i
++) {
389 if (!array
[i
]->serialize(s
)) return false;
392 return s
->addXMLEndTag("array");