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