2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* IOArray.m created by rsulack on Fri 12-Sep-1997 */
26 /* IOArray.cpp converted to C++ by gvdl on Fri 1998-10-30 */
29 #include <libkern/c++/OSArray.h>
30 #include <libkern/c++/OSSerialize.h>
31 #include <libkern/c++/OSLib.h>
33 #define super OSCollection
35 OSDefineMetaClassAndStructors(OSArray
, OSCollection
)
36 OSMetaClassDefineReservedUnused(OSArray
, 0);
37 OSMetaClassDefineReservedUnused(OSArray
, 1);
38 OSMetaClassDefineReservedUnused(OSArray
, 2);
39 OSMetaClassDefineReservedUnused(OSArray
, 3);
40 OSMetaClassDefineReservedUnused(OSArray
, 4);
41 OSMetaClassDefineReservedUnused(OSArray
, 5);
42 OSMetaClassDefineReservedUnused(OSArray
, 6);
43 OSMetaClassDefineReservedUnused(OSArray
, 7);
47 extern int debug_container_malloc_size
;
49 #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0)
54 bool OSArray::initWithCapacity(unsigned int inCapacity
)
61 size
= sizeof(const OSMetaClassBase
*) * inCapacity
;
62 array
= (const OSMetaClassBase
**) kalloc(size
);
67 capacity
= inCapacity
;
68 capacityIncrement
= (inCapacity
)? inCapacity
: 16;
76 bool OSArray::initWithObjects(const OSObject
*objects
[],
77 unsigned int theCount
,
78 unsigned int theCapacity
)
80 unsigned int capacity
;
84 else if (theCount
> theCapacity
)
87 capacity
= theCapacity
;
89 if (!objects
|| !initWithCapacity(capacity
))
92 for ( unsigned int i
= 0; i
< theCount
; i
++ ) {
93 const OSMetaClassBase
*newObject
= *objects
++;
98 array
[count
++] = newObject
;
99 newObject
->taggedRetain(OSTypeID(OSCollection
));
105 bool OSArray::initWithArray(const OSArray
*anArray
,
106 unsigned int theCapacity
)
111 return initWithObjects((const OSObject
**) anArray
->array
,
112 anArray
->count
, theCapacity
);
115 OSArray
*OSArray::withCapacity(unsigned int capacity
)
117 OSArray
*me
= new OSArray
;
119 if (me
&& !me
->initWithCapacity(capacity
)) {
127 OSArray
*OSArray::withObjects(const OSObject
*objects
[],
129 unsigned int capacity
)
131 OSArray
*me
= new OSArray
;
133 if (me
&& !me
->initWithObjects(objects
, count
, capacity
)) {
141 OSArray
*OSArray::withArray(const OSArray
*array
,
142 unsigned int capacity
)
144 OSArray
*me
= new OSArray
;
146 if (me
&& !me
->initWithArray(array
, capacity
)) {
159 kfree((vm_offset_t
)array
, sizeof(const OSMetaClassBase
*) * capacity
);
160 ACCUMSIZE( -(sizeof(const OSMetaClassBase
*) * capacity
) );
167 unsigned int OSArray::getCount() const { return count
; }
168 unsigned int OSArray::getCapacity() const { return capacity
; }
169 unsigned int OSArray::getCapacityIncrement() const { return capacityIncrement
; }
170 unsigned int OSArray::setCapacityIncrement(unsigned int increment
)
172 capacityIncrement
= (increment
)? increment
: 16;
174 return capacityIncrement
;
177 unsigned int OSArray::ensureCapacity(unsigned int newCapacity
)
179 const OSMetaClassBase
**newArray
;
180 int oldSize
, newSize
;
182 if (newCapacity
<= capacity
)
186 newCapacity
= (((newCapacity
- 1) / capacityIncrement
) + 1)
188 newSize
= sizeof(const OSMetaClassBase
*) * newCapacity
;
190 newArray
= (const OSMetaClassBase
**) kalloc(newSize
);
192 oldSize
= sizeof(const OSMetaClassBase
*) * capacity
;
194 ACCUMSIZE(newSize
- oldSize
);
196 bcopy(array
, newArray
, oldSize
);
197 bzero(&newArray
[capacity
], newSize
- oldSize
);
198 kfree((vm_offset_t
)array
, oldSize
);
200 capacity
= newCapacity
;
206 void OSArray::flushCollection()
211 for (i
= 0; i
< count
; i
++)
212 array
[i
]->taggedRelease(OSTypeID(OSCollection
));
216 bool OSArray::setObject(const OSMetaClassBase
*anObject
)
218 return setObject(count
, anObject
);
221 bool OSArray::setObject(unsigned int index
, const OSMetaClassBase
*anObject
)
224 unsigned int newCount
= count
+ 1;
226 if ((index
> count
) || !anObject
)
229 // do we need more space?
230 if (newCount
> capacity
&& newCount
> ensureCapacity(newCount
))
234 if (index
!= count
) {
235 for (i
= count
; i
> index
; i
--)
236 array
[i
] = array
[i
-1];
238 array
[index
] = anObject
;
239 anObject
->taggedRetain(OSTypeID(OSCollection
));
245 bool OSArray::merge(const OSArray
* otherArray
)
247 unsigned int otherCount
= otherArray
->getCount();
248 unsigned int newCount
= count
+ otherCount
;
253 // do we need more space?
254 if (newCount
> capacity
&& newCount
> ensureCapacity(newCount
))
258 for (unsigned int i
= 0; i
< otherCount
; i
++) {
259 const OSMetaClassBase
*newObject
= otherArray
->getObject(i
);
261 array
[count
++] = newObject
;
262 newObject
->taggedRetain(OSTypeID(OSCollection
));
269 replaceObject(unsigned int index
, const OSMetaClassBase
*anObject
)
271 const OSMetaClassBase
*oldObject
;
273 if ((index
>= count
) || !anObject
)
277 oldObject
= array
[index
];
278 array
[index
] = anObject
;
279 anObject
->taggedRetain(OSTypeID(OSCollection
));
281 oldObject
->taggedRelease(OSTypeID(OSCollection
));
284 void OSArray::removeObject(unsigned int index
)
287 const OSMetaClassBase
*oldObject
;
293 oldObject
= array
[index
];
296 for (i
= index
; i
< count
; i
++)
297 array
[i
] = array
[i
+1];
299 oldObject
->taggedRelease(OSTypeID(OSCollection
));
302 bool OSArray::isEqualTo(const OSArray
*anArray
) const
306 if ( this == anArray
)
309 if ( count
!= anArray
->getCount() )
312 for ( i
= 0; i
< count
; i
++ ) {
313 if ( !array
[i
]->isEqualTo(anArray
->getObject(i
)) )
320 bool OSArray::isEqualTo(const OSMetaClassBase
*anObject
) const
324 otherArray
= OSDynamicCast(OSArray
, anObject
);
326 return isEqualTo(otherArray
);
331 OSObject
*OSArray::getObject(unsigned int index
) const
336 return (OSObject
*) array
[index
];
339 OSObject
*OSArray::getLastObject() const
344 return (OSObject
*) array
[count
- 1];
347 unsigned int OSArray::getNextIndexOfObject(const OSMetaClassBase
* anObject
,
348 unsigned int index
) const
350 while ((index
< count
) && (array
[index
] != anObject
))
353 index
= (unsigned int)-1;
357 unsigned int OSArray::iteratorSize() const
359 return sizeof(unsigned int);
362 bool OSArray::initIterator(void *inIterator
) const
364 unsigned int *iteratorP
= (unsigned int *) inIterator
;
370 bool OSArray::getNextObjectForIterator(void *inIterator
, OSObject
**ret
) const
372 unsigned int *iteratorP
= (unsigned int *) inIterator
;
373 unsigned int index
= (*iteratorP
)++;
376 *ret
= (OSObject
*) array
[index
];
385 bool OSArray::serialize(OSSerialize
*s
) const
387 if (s
->previouslySerialized(this)) return true;
389 if (!s
->addXMLStartTag(this, "array")) return false;
391 for (unsigned i
= 0; i
< count
; i
++) {
392 if (!array
[i
]->serialize(s
)) return false;
395 return s
->addXMLEndTag("array");