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