1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/* IOArray.h created by rsulack on Thu 11-Sep-1997 */
29/* IOArray.h converted to C++ by gvdl on Fri 1998-10-30 */
30
31#ifndef _OS_OSARRAY_H
32#define _OS_OSARRAY_H
33
34#include <libkern/c++/OSCollection.h>
35
36class OSSerialize;
37
38/*!
39 * @header
40 *
41 * @abstract
42 * This header declares the OSArray collection class.
43 */
44
45
46/*!
47 * @class OSArray
48 *
49 * @abstract
50 * OSArray provides an indexed store of objects.
51 *
52 * @discussion
53 * OSArray is a container for Libkern C++ objects
54 * (those derived from
55 * @link //apple_ref/doc/class/OSMetaClassBase OSMetaClassBase@/link,
56 * in particular
57 * @link //apple_ref/doc/class/OSObject OSObject@/link).
58 * Storage and access are by array index.
59 *
60 * You must generally cast retrieved objects from
61 * @link //apple_ref/cpp/cl/OSObject OSObject@/link
62 * to the desired class using
63 * <code>@link //apple_ref/cpp/macro/OSDynamicCast OSDynamicCast@/link</code>.
64 * This macro returns the object cast to the desired class,
65 * or <code>NULL</code> if the object isn't derived from that class.
66 *
67 * As with all Libkern collection classes,
68 * OSArray retains objects added to it,
69 * and releases objects removed from it (or replaced).
70 * An OSArray also grows as necessary to accommodate new objects,
71 * <i>unlike</i> Core Foundation collections (it does not, however, shrink).
72 *
73 * <b>Use Restrictions</b>
74 *
75 * With very few exceptions in the I/O Kit, all Libkern-based C++
76 * classes, functions, and macros are <b>unsafe</b>
77 * to use in a primary interrupt context.
78 * Consult the I/O Kit documentation related to primary interrupts
79 * for more information.
80 *
81 * OSArray provides no concurrency protection;
82 * it's up to the usage context to provide any protection necessary.
83 * Some portions of the I/O Kit, such as
84 * @link //apple_ref/doc/class/IORegistryEntry IORegistryEntry@/link,
85 * handle synchronization via defined member functions for setting
86 * properties.
87 */
88class OSArray : public OSCollection
89{
90 friend class OSSet;
91 friend class OSSerialize;
92
93 OSDeclareDefaultStructors(OSArray)
94
95#if APPLE_KEXT_ALIGN_CONTAINERS
96
97protected:
98 unsigned int count;
99 unsigned int capacity;
100 unsigned int capacityIncrement;
101 const OSMetaClassBase ** array;
102
103#else /* APPLE_KEXT_ALIGN_CONTAINERS */
104
105protected:
106 const OSMetaClassBase ** array;
107 unsigned int count;
108 unsigned int capacity;
109 unsigned int capacityIncrement;
110
111 struct ExpansionData { };
112
113 /* Reserved for future use. (Internal use only) */
114 ExpansionData * reserved;
115
116#endif /* APPLE_KEXT_ALIGN_CONTAINERS */
117
118 /* OSCollectionIterator interfaces. */
119 virtual unsigned int iteratorSize() const APPLE_KEXT_OVERRIDE;
120 virtual bool initIterator(void * iterator) const APPLE_KEXT_OVERRIDE;
121 virtual bool getNextObjectForIterator(void * iterator, OSObject ** ret) const APPLE_KEXT_OVERRIDE;
122
123public:
124
125 /*!
126 * @function withCapacity
127 *
128 * @abstract
129 * Creates and initializes an empty OSArray.
130 *
131 * @param capacity The initial storage capacity of the array object.
132 *
133 * @result
134 * An empty instance of OSArray with a retain count of 1;
135 * <code>NULL</code> on failure.
136 *
137 * @discussion
138 * <code>capacity</code> must be nonzero.
139 * The new array will grow as needed to accommodate more objects
140 * (<i>unlike</i> @link //apple_ref/doc/uid/20001502 CFMutableArray@/link,
141 * for which the initial capacity is a hard limit).
142 */
143 static OSArray * withCapacity(unsigned int capacity);
144
145
146 /*!
147 * @function withObjects
148 *
149 * @abstract
150 * Creates and initializes an OSArray populated with objects provided.
151 *
152 * @param objects A C array of OSObject-derived instances.
153 * @param count The number of objects to be placed into the array.
154 * @param capacity The initial storage capacity of the array object.
155 * If 0, <code>count</code> is used; otherwise this value
156 * must be greater than or equal to <code>count</code>.
157 *
158 * @result
159 * An instance of OSArray containing the objects provided,
160 * with a retain count of 1;
161 * <code>NULL</code> on failure.
162 *
163 * @discussion
164 * <code>objects</code> must be non-<code>NULL</code>, and <code>count</code> must be nonzero.
165 * If <code>capacity</code> is nonzero,
166 * it must be greater than or equal to <code>count</code>.
167 * The new array will grow as needed to accommodate more objects
168 * (<i>unlike</i> @link //apple_ref/doc/uid/20001502 CFMutableArray@/link,
169 * for which the initial capacity is a hard limit).
170 */
171 static OSArray * withObjects(
172 const OSObject * objects[],
173 unsigned int count,
174 unsigned int capacity = 0);
175
176
177 /*!
178 * @function withArray
179 *
180 * @abstract
181 * Creates and initializes an OSArray populated with the contents of another array.
182 *
183 * @param array An OSArray whose contents will be stored
184 * in the new instance.
185 * @param capacity The initial storage capacity of the array object.
186 * If 0, the capacity is set to the number of objects
187 * in <code>array</code>;
188 * otherwise <code>capacity</code> must be
189 * greater than or equal to the number of objects
190 * in <code>array</code>.
191 *
192 * @result
193 * An instance of OSArray containing the objects of <code>array</code>,
194 * with a retain count of 1;
195 * <code>NULL</code> on failure.
196 *
197 * @discussion
198 * <code>array</code> must be non-<code>NULL</code>.
199 * If <code>capacity</code> is nonzero,
200 * it must be greater than or equal to <code>count</code>.
201 * The new array will grow as needed to accommodate more objects
202 * (<i>unlike</i> @link //apple_ref/doc/uid/20001502 CFMutableArray@/link,
203 * for which the initial capacity is a hard limit).
204 *
205 * The objects in <code>array</code> are retained
206 * for storage in the new OSArray,
207 * not copied.
208 */
209 static OSArray * withArray(
210 const OSArray * array,
211 unsigned int capacity = 0);
212
213
214 /*!
215 * @function initWithCapacity
216 *
217 * @abstract
218 * Initializes a new instance of OSArray.
219 *
220 * @param capacity The initial storage capacity of the array object.
221 *
222 * @result
223 * <code>true</code> on success, <code>false</code> on failure.
224 *
225 * @discussion
226 * Not for general use. Use the static instance creation method
227 * <code>@link //apple_ref/cpp/clm/OSArray/withCapacity/staticOSArray*\/(unsignedint)
228 * withCapacity@/link</code>
229 * instead.
230 *
231 * <code>capacity</code> must be nonzero.
232 * The new array will grow as needed to accommodate more objects
233 * (<i>unlike</i> @link //apple_ref/doc/uid/20001502 CFMutableArray@/link,
234 * for which the initial capacity is a hard limit).
235 */
236 virtual bool initWithCapacity(unsigned int capacity);
237
238
239 /*!
240 * @function initWithObjects
241 *
242 * @abstract
243 * Initializes a new OSArray populated with objects provided.
244 *
245 * @param objects A C array of OSObject-derived objects.
246 * @param count The number of objects to be placed into the array.
247 * @param capacity The initial storage capacity of the array object.
248 * If 0, <code>count</code> is used; otherwise this value
249 * must be greater than or equal to <code>count</code>.
250 *
251 * @result
252 * <code>true</code> on success, <code>false</code> on failure.
253 *
254 * @discussion
255 * Not for general use. Use the static instance creation method
256 * <code>@link
257 * //apple_ref/cpp/clm/OSArray/withObjects/staticOSArray*\/(constOSObject*,unsignedint,unsignedint)
258 * withObjects@/link</code>
259 * instead.
260 *
261 * <code>objects</code> must be non-<code>NULL</code>,
262 * and <code>count</code> must be nonzero.
263 * If <code>capacity</code> is nonzero,
264 * it must be greater than or equal to <code>count</code>.
265 * The new array will grow as needed to accommodate more objects
266 * (<i>unlike</i> @link //apple_ref/doc/uid/20001502 CFMutableArray@/link,
267 * for which the initial capacity is a hard limit).
268 */
269 virtual bool initWithObjects(
270 const OSObject * objects[],
271 unsigned int count,
272 unsigned int capacity = 0);
273
274 /*!
275 * @function initWithArray
276 *
277 * @abstract
278 * Initializes a new OSArray populated with the contents of another array.
279 *
280 * @param anArray The array whose contents will be placed
281 * in the new instance.
282 * @param capacity The initial storage capacity of the array object.
283 * If 0, the capacity is set to the number of objects
284 * in <code>array</code>;
285 * otherwise <code>capacity</code> must be
286 * greater than or equal to the number of objects
287 * in <code>array</code>.
288 *
289 * @result
290 * <code>true</code> on success, <code>false</code> on failure.
291 *
292 * @discussion
293 * Not for general use. Use the static instance creation method
294 * <code>@link //apple_ref/cpp/clm/OSArray/withArray/staticOSArray*\/(constOSArray*,unsignedint)
295 * withArray@/link</code> instead.
296 *
297 * <code>array</code> must be non-<code>NULL</code>.
298 * If <code>capacity</code> is nonzero,
299 * it must be greater than or equal to <code>count</code>.
300 * The new array will grow as needed to accommodate more objects
301 * (<i>unlike</i> @link //apple_ref/doc/uid/20001502 CFMutableArray@/link,
302 * for which the initial capacity is a hard limit).
303 *
304 * The objects in <code>array</code> are retained for storage in the new OSArray,
305 * not copied.
306 */
307 virtual bool initWithArray(
308 const OSArray * anArray,
309 unsigned int capacity = 0);
310
311
312 /*!
313 * @function free
314 *
315 * @abstract
316 * Deallocates or releases any resources
317 * used by the OSArray instance.
318 *
319 * @discussion
320 * This function should not be called directly;
321 * use
322 * <code>@link
323 * //apple_ref/cpp/instm/OSObject/release/virtualvoid/()
324 * release@/link</code>
325 * instead.
326 */
327 virtual void free() APPLE_KEXT_OVERRIDE;
328
329
330 /*!
331 * @function getCount
332 *
333 * @abstract
334 * Returns the current number of objects within the array.
335 *
336 * @result
337 * The current number of objects within the array.
338 */
339 virtual unsigned int getCount() const APPLE_KEXT_OVERRIDE;
340
341
342 /*!
343 * @function getCapacity
344 *
345 * @abstract
346 * Returns the number of objects the array can store
347 * without reallocating.
348 *
349 * @result
350 * The number objects the array can store
351 * without reallocating.
352 *
353 * @discussion
354 * OSArray objects grow when full to accommodate additional objects.
355 * See
356 * <code>@link
357 * //apple_ref/cpp/instm/OSArray/getCapacity/virtualunsignedint/()
358 * getCapacityIncrement@/link</code>
359 * and
360 * @link
361 * //apple_ref/cpp/instm/OSArray/ensureCapacity/virtualunsignedint/(unsignedint)
362 * <code>ensureCapacity</code>.@/link
363 */
364 virtual unsigned int getCapacity() const APPLE_KEXT_OVERRIDE;
365
366
367 /*!
368 * @function getCapacityIncrement
369 *
370 * @abstract
371 * Returns the storage increment of the array.
372 *
373 * @result
374 * The storage increment of the array.
375 *
376 * @discussion
377 * An OSArray allocates storage for objects in multiples
378 * of the capacity increment.
379 */
380 virtual unsigned int getCapacityIncrement() const APPLE_KEXT_OVERRIDE;
381
382
383 /*!
384 * @function setCapacityIncrement
385 *
386 * @abstract
387 * Sets the storage increment of the array.
388 *
389 * @result
390 * The new storage increment of the array,
391 * which may be different from the number requested.
392 *
393 * @discussion
394 * An OSArray allocates storage for objects in multiples
395 * of the capacity increment.
396 * Calling this function does not immediately reallocate storage.
397 */
398 virtual unsigned int setCapacityIncrement(unsigned increment) APPLE_KEXT_OVERRIDE;
399
400
401 /*!
402 * @function ensureCapacity
403 *
404 * @abstract
405 * Ensures the array has enough space
406 * to store the requested number of objects.
407 *
408 * @param newCapacity The total number of objects the array
409 * should be able to store.
410 *
411 * @result
412 * The new capacity of the array,
413 * which may be different from the number requested
414 * (if smaller, reallocation of storage failed).
415 *
416 * @discussion
417 * This function immediately resizes the array, if necessary,
418 * to accommodate at least <code>newCapacity</code> objects.
419 * If <code>newCapacity</code> is not greater than the current capacity,
420 * or if an allocation error occurs, the original capacity is returned.
421 *
422 * There is no way to reduce the capacity of an OSArray.
423 */
424 virtual unsigned int ensureCapacity(unsigned int newCapacity) APPLE_KEXT_OVERRIDE;
425
426
427 /*!
428 * @function flushCollection
429 *
430 * @abstract
431 * Removes and releases all objects within the array.
432 *
433 * @discussion
434 * The array's capacity (and therefore direct memory consumption)
435 * is not reduced by this function.
436 */
437 virtual void flushCollection() APPLE_KEXT_OVERRIDE;
438
439
440 /*!
441 * @function setObject
442 *
443 * @abstract
444 * Appends an object onto the end of the array,
445 * increasing storage if necessary.
446 *
447 * @param anObject The object to add to the OSArray instance.
448 *
449 * @result
450 * <code>true</code> if the addition of <code>anObject</code> was successful,
451 * <code>false</code> if not.
452 *
453 * @discussion
454 * The array adds storage to accomodate the new object, if necessary.
455 * If successfully added, the object is retained.
456 */
457 virtual bool setObject(const OSMetaClassBase * anObject);
458
459
460 /*!
461 * @function setObject
462 *
463 * @abstract
464 * Inserts or appends an object into the array
465 * at a particular index.
466 *
467 * @param index The index in the array at which to insert the object.
468 * Must be less than or equal to the array's count.
469 * @param anObject The object to add to the array.
470 *
471 * @result
472 * <code>true</code> if the addition of <code>anObject</code>
473 * was successful, <code>false</code> if not.
474 *
475 * @discussion
476 * This function moves existing objects from <code>index</code> on,
477 * in order to accommodate the new object;
478 * it does not replace an existing object at <code>index</code>. See
479 * <code>@link
480 * //apple_ref/cpp/instm/OSArray/replaceObject/virtualvoid/(unsignedint,constOSMetaClassBase*)
481 * replaceObject@/link</code>.
482 * If successfully added, the object is retained.
483 *
484 * The array adds storage to accomodate the new object, if necessary.
485 * Note, however, that this function does not allow for arbirtrary growth
486 * of an array by specifying an index larger than the current count.
487 * If you need to immediately grow an array by an arbitrary amount,
488 * use
489 * <code>@link
490 * //apple_ref/cpp/instm/OSArray/ensureCapacity/virtualunsignedint/(unsignedint)
491 * ensureCapacity@/link</code>.
492 */
493 virtual bool setObject(
494 unsigned int index,
495 const OSMetaClassBase * anObject);
496
497
498 /*!
499 * @function merge
500 *
501 * @abstract
502 * Appends the contents of an array onto the receiving array.
503 *
504 * @param otherArray The array whose contents will be appended
505 * to the receiving array.
506 * @result
507 * <code>true</code> if merging was successful, <code>false</code> otherwise.
508 *
509 * @discussion
510 * This function merely appends one array onto another.
511 * Duplicates are not avoided and no sorting is performed.
512 * Objects successfully added to the receiver are retained.
513 */
514 virtual bool merge(const OSArray * otherArray);
515
516
517 /*!
518 * @function replaceObject
519 *
520 * @abstract
521 * Replaces an object in an array at a given index.
522 *
523 * @param index The index of the object to be replaced.
524 * Must be less than the array's count.
525 * @param anObject The object to be placed into the array.
526 *
527 * @discussion
528 * The original object is released and the new object is retained.
529 */
530 virtual void replaceObject(
531 unsigned int index,
532 const OSMetaClassBase * anObject);
533
534
535 /*!
536 * @function removeObject
537 *
538 * @abstract
539 * Removes an object from the array.
540 *
541 * @param index The index of the object to be removed.
542 *
543 * @discussion
544 * This function moves existing objects to fill the vacated index
545 * so that there are no gaps.
546 * The object removed is released.
547 */
548 virtual void removeObject(unsigned int index);
549
550
551 /*!
552 * @function isEqualTo
553 *
554 * @abstract
555 * Tests the equality of two OSArray objects.
556 *
557 * @param anArray The array object being compared against the receiver.
558 *
559 * @result
560 * <code>true</code> if the two arrays are equivalent,
561 *<code>false</code> otherwise.
562 *
563 * @discussion
564 * Two OSArray objects are considered equal if they have same count
565 * and if the objects at corresponding indices compare as equal using
566 * <code>@link
567 * //apple_ref/cpp/instm/OSMetaClassBase/isEqualTo/virtualbool/(constOSMetaClassBase*)
568 * isEqualTo@/link</code>.
569 */
570 virtual bool isEqualTo(const OSArray * anArray) const;
571
572
573 /*!
574 * @function isEqualTo
575 *
576 * @abstract
577 * Tests the equality of an OSArray to an arbitrary object.
578 *
579 * @param anObject The object to be compared against the receiver.
580 *
581 * @result
582 * <code>true</code> if the two objects are equivalent,
583 * <code>false</code> otherwise.
584 *
585 * @discussion
586 * An OSArray is considered equal to another object
587 * if that object is derived from OSArray
588 * and contains the same or equivalent objects.
589 */
590 virtual bool isEqualTo(const OSMetaClassBase * anObject) const APPLE_KEXT_OVERRIDE;
591
592
593 /*!
594 * @function getObject
595 *
596 * @abstract
597 * Return the object stored at a given index.
598 *
599 * @param index The index of the object to be returned to caller.
600 *
601 * @result
602 * The object stored at <code>index</code>,
603 * or <code>NULL</code> if <code>index</code> lies past the end of the array.
604 *
605 * @discussion
606 * The returned object will be released if removed from the array;
607 * if you plan to store the reference, you should call
608 * <code>@link
609 * //apple_ref/cpp/instm/OSObject/retain/virtualvoid/()
610 * retain@/link</code>
611 * on that object.
612 */
613 virtual OSObject * getObject(unsigned int index) const;
614
615
616 /*!
617 * @function getLastObject
618 *
619 * @abstract
620 * Returns the last object in the array.
621 *
622 * @result
623 * The last object in the array,
624 * or <code>NULL</code> if the array is empty.
625 *
626 * @discussion
627 * The returned object will be released if removed from the array;
628 * if you plan to store the reference, you should call
629 * <code>@link
630 * //apple_ref/cpp/instm/OSObject/retain/virtualvoid/()
631 * retain@/link</code>
632 * on that object.
633 */
634 virtual OSObject * getLastObject() const;
635
636
637 /*!
638 * @function getNextIndexOfObject
639 *
640 * @abstract
641 * Scans the array for the next instance of a specific object
642 * at or beyond a given index.
643 *
644 * @param anObject The object to scan for.
645 * @param index The index at which to begin the scan.
646 *
647 * @result
648 * The next index of <code>anObject</code> in the array or (-1)
649 * if none is found.
650 *
651 * @discussion
652 * This function uses pointer equivalence, and does not use
653 * <code>@link
654 * //apple_ref/cpp/instm/OSMetaClassBase/isEqualTo/virtualbool/(constOSMetaClassBase*)
655 * isEqualTo@/link</code>.
656 */
657 virtual unsigned int getNextIndexOfObject(
658 const OSMetaClassBase * anObject,
659 unsigned int index) const;
660
661 /*!
662 * @function serialize
663 *
664 * @abstract
665 * Archives the receiver into the provided
666 * @link //apple_ref/doc/class/OSSerialize OSSerialize@/link object.
667 *
668 * @param serializer The OSSerialize object.
669 * @result
670 * <code>true</code> if serialization succeeds, <code>false</code> if not.
671 */
672 virtual bool serialize(OSSerialize * serializer) const APPLE_KEXT_OVERRIDE;
673
674
675 /*!
676 * @function setOptions
677 *
678 * @abstract
679 * Recursively sets option bits in an array
680 * and all child collections.
681 *
682 * @param options A bitfield whose values turn the options on (1) or off (0).
683 * @param mask A mask indicating which bits
684 * in <code>options</code> to change.
685 * Pass 0 to get the whole current options bitfield
686 * without changing any settings.
687 * @param context Unused.
688 *
689 * @result
690 * The options bitfield as it was before the set operation.
691 *
692 * @discussion
693 * Kernel extensions should not call this function.
694 *
695 * Child collections' options are changed only if the receiving array's
696 * options actually change.
697 */
698 virtual unsigned setOptions(
699 unsigned options,
700 unsigned mask,
701 void * context = 0) APPLE_KEXT_OVERRIDE;
702
703
704 /*!
705 * @function copyCollection
706 *
707 * @abstract
708 * Creates a deep copy of an array and its child collections.
709 *
710 * @param cycleDict A dictionary of all of the collections
711 * that have been copied so far,
712 * which is used to track circular references.
713 * To start the copy at the top level,
714 * pass <code>NULL</code>.
715 *
716 * @result
717 * The newly copied array, with a retain count of 1,
718 * or <code>NULL</code> if there is insufficient memory to do the copy.
719 *
720 * @discussion
721 * The receiving array, and any collections it contains,
722 * recursively, are copied.
723 * Objects that are not derived from OSCollection are retained
724 * rather than copied.
725 */
726 OSCollection * copyCollection(OSDictionary * cycleDict = 0) APPLE_KEXT_OVERRIDE;
727
728 OSMetaClassDeclareReservedUnused(OSArray, 0);
729 OSMetaClassDeclareReservedUnused(OSArray, 1);
730 OSMetaClassDeclareReservedUnused(OSArray, 2);
731 OSMetaClassDeclareReservedUnused(OSArray, 3);
732 OSMetaClassDeclareReservedUnused(OSArray, 4);
733 OSMetaClassDeclareReservedUnused(OSArray, 5);
734 OSMetaClassDeclareReservedUnused(OSArray, 6);
735 OSMetaClassDeclareReservedUnused(OSArray, 7);
736};
737
738#endif /* !_OS_OSARRAY_H */
739