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/* IOCollection.h created by gvdl on Thu 1998-10-22 */
29
30#ifndef _OS_OSCOLLECTION_H
31#define _OS_OSCOLLECTION_H
32
33#include <libkern/c++/OSObject.h>
34
35class OSDictionary;
36
37
38/*!
39 * @header
40 *
41 * @abstract
42 * This header declares the OSDictionary collection class.
43 */
44
45
46/*!
47 * @class OSCollection
48 *
49 * @abstract
50 * The abstract superclass for Libkern collections.
51 *
52 * @discussion
53 * OSCollection is the abstract superclass
54 * for all Libkern C++ object collections.
55 * It defines the necessary interfaces for managing storage space
56 * and iterating through an arbitrary collection
57 * (see the
58 * @link //apple_ref/cpp/class/OSIterator OSIterator@/link
59 * and
60 * @link //apple_ref/cpp/class/OSCollectionIterator OSCollectionIterator@/link
61 * classes).
62 * It is up to concrete subclasses
63 * to define their specific content management functions.
64 *
65 * <b>Use Restrictions</b>
66 *
67 * With very few exceptions in the I/O Kit, all Libkern-based C++
68 * classes, functions, and macros are <b>unsafe</b>
69 * to use in a primary interrupt context.
70 * Consult the I/O Kit documentation related to primary interrupts
71 * for more information.
72 *
73 * OSCollection provides no concurrency protection;
74 * it's up to the usage context to provide any protection necessary.
75 * Some portions of the I/O Kit, such as
76 * @link //apple_ref/doc/class/IORegistryEntry IORegistryEntry@/link,
77 * handle synchronization via defined member functions for setting
78 * properties.
79 */
80class OSCollection : public OSObject
81{
82    friend class OSCollectionIterator;
83
84    OSDeclareAbstractStructors(OSCollection);
85
86    struct ExpansionData { };
87
88protected:
89   /* Not to be included in headerdoc.
90    *
91    * @var updateStamp
92    *
93    * @abstract
94    * A counter for changes to the collection object.
95    *
96    * @discussion
97    * The update stamp is used primarily to track validity
98    * of iteration contexts.
99    * See @link //apple_ref/cpp/class/OSIterator OSIterator@/link and
100    * @link //apple_ref/cpp/class/OSCollectionIterator OSCollectionIterator@/link
101    * for more information.
102    */
103    unsigned int updateStamp;
104
105#ifdef XNU_KERNEL_PRIVATE
106protected:
107#else
108private:
109#endif /* XNU_KERNEL_PRIVATE */
110    /* Reserved for future use.  (Internal use only)  */
111    // ExpansionData * reserved;
112    unsigned int fOptions;
113
114protected:
115    // Member functions used by the OSCollectionIterator class.
116
117
118   /*!
119    * @function iteratorSize
120    *
121    * @abstract
122    * Returns the size in bytes of a subclass's iteration context.
123    *
124    * @result
125    * The size in bytes of the iteration context
126    * needed by the subclass of OSCollection.
127    *
128    * @discussion
129    * This pure virtual member function, which subclasses must implement,
130    * is called by an
131    * @link //apple_ref/doc/class/OSCollectionIterator OSCollectionIterator@/link
132    * object so that it can allocate the storage needed
133    * for the iteration context.
134    * An iteration context contains the data necessary
135    * to iterate through the collection.
136    */
137    virtual unsigned int iteratorSize() const = 0;
138
139
140   /*!
141    * @function initIterator
142    *
143    * @abstract
144    * Initializes the iteration context for a collection subclass.
145    *
146    * @param iterationContext  The iteration context to initialize.
147    *
148    * @result
149    * <code>true</code> if initialization was successful,
150    * <code>false</code> otherwise.
151    *
152    * @discussion
153    * This pure virtual member function, which subclasses must implement,
154    * is called by an
155    * @link //apple_ref/doc/class/OSCollectionIterator OSCollectionIterator@/link
156    * object to initialize an iteration context for a collection.
157    * The collection object should interpret <code>iterationContext</code> appropriately
158    * and initialize its contents to begin an iteration.
159    *
160    * This function can be called repeatedly for a given context,
161    * whenever the iterator is reset via the
162    * @link //apple_ref/cpp/instm/OSCollectionIterator/reset/virtualvoid/()
163    * OSCollectionIterator::reset@/link
164    * function.
165    */
166    virtual bool initIterator(void * iterationContext) const = 0;
167
168
169   /*!
170    * @function getNextObjectForIterator
171    *
172    * @abstract
173    * Returns the next member of a collection.
174    *
175    * @param iterationContext  The iteration context.
176    * @param nextObject        The object returned by reference to the caller.
177    *
178    * @result
179    * <code>true</code> if an object was found, <code>false</code> otherwise.
180    *
181    * @discussion
182    * This pure virtual member function, which subclasses must implement,
183    * is called by an
184    * @link //apple_ref/doc/class/OSCollectionIterator OSCollectionIterator@/link
185    * to get the next object for a given iteration context.
186    * The collection object should interpret
187    * <code>iterationContext</code> appropriately,
188    * advance the context from its current object
189    * to the next object (if it exists),
190    * return that object by reference in <code>nextObject</code>,
191    * and return <code>true</code> for the function call.
192    * If there is no next object, the collection object must return <code>false</code>.
193    *
194    * For associative collections, the object returned should be the key
195    * used to access its associated value, and not the value itself.
196    */
197    virtual bool getNextObjectForIterator(
198        void      * iterationContext,
199        OSObject ** nextObject) const = 0;
200
201
202   /*!
203    * @function init
204    *
205    * @abstract
206    * Initializes the OSCollection object.
207    *
208    * @result
209    * <code>true</code> on success, <code>false</code> otherwise.
210    *
211    * @discussion
212    * This function is used to initialize state
213    * within a newly created OSCollection object.
214    */
215    virtual bool init();
216
217public:
218
219   /*!
220    * @typedef _OSCollectionFlags
221    *
222    * @const kImmutable
223    * @discussion
224    * Used with <code>@link setOptions setOptions@/link</code>
225    * to indicate the collection's contents should
226    * or should not change.
227    *
228    * An @link //apple_ref/doc/class/IORegistryEntry IORegistryEntry@/link
229    * object marks collections immutable when set
230    * as properties of a registry entry that's attached to a plane.
231    * This is generally an advisory flag, used for debugging;
232    * setting it does not mean a collection will in fact
233    * disallow modifications.
234    */
235    typedef enum {
236        kImmutable  = 0x00000001,
237        kSort       = 0x00000002,
238        kMASK       = (unsigned) -1
239    } _OSCollectionFlags;
240
241// xx-review: should be protected, not public
242
243   /*!
244    * @function haveUpdated
245    *
246    * @abstract
247    * Tracks updates to the collection.
248    *
249    * @discussion
250    * Subclasses call this function <i>before</i>
251    * making any change to their contents (not after, as the name implies).
252    * Update tracking is used for collection iterators,
253    * and to enforce certain protections in the IORegistry.
254    */
255    void haveUpdated();
256
257
258   /*!
259    * @function getCount
260    *
261    * @abstract
262    * Returns the number of objects in the collection.
263    *
264    * @result
265    * The number of objects in the collection.
266    *
267    * @discussion
268    * Subclasses must implement this pure virtual member function.
269    */
270    virtual unsigned int getCount() const = 0;
271
272
273   /*!
274    * @function getCapacity
275    *
276    * @abstract
277    * Returns the number of objects the collection
278    * can store without reallocating.
279    *
280    * @result
281    * The number objects the collection
282    * can store without reallocating.
283    *
284    * @discussion
285    * Subclasses must implement this pure virtual member function.
286    */
287    virtual unsigned int getCapacity() const = 0;
288
289
290   /*!
291    * @function getCapacityIncrement
292    *
293    * @abstract
294    * Returns the storage increment of the collection.
295    *
296    * @result
297    * The storage increment of the collection.
298    *
299    * @discussion
300    * Subclasses must implement this pure virtual member function.
301    * Most collection subclasses allocate their storage
302    * in multiples of the capacity increment.
303    *
304    * See
305    * <code>@link
306    * //apple_ref/cpp/instm/OSCollection/ensureCapacity/virtualunsignedint/(unsignedint)
307    * ensureCapacity@/link</code>
308    * for how the capacity increment is used.
309    */
310    virtual unsigned int getCapacityIncrement() const = 0;
311
312
313   /*!
314    * @function setCapacityIncrement
315    *
316    * @abstract
317    * Sets the storage increment of the collection.
318    *
319    * @result
320    * The new storage increment of the collection,
321    * which may be different from the number requested.
322    *
323    * @discussion
324    * Subclasses must implement this pure virtual member function.
325    * Most collection subclasses allocate their storage
326    * in multiples of the capacity increment.
327    *
328    * Collection subclasses should gracefully handle
329    * an <code>increment</code> of zero
330    * by applying (and returning) a positive minimum capacity.
331    *
332    * Setting the capacity increment does not trigger an immediate adjustment
333    * of a collection's storage.
334    *
335    * See
336    * @link
337    * //apple_ref/cpp/instm/OSCollection/ensureCapacity/virtualunsignedint/(unsignedint)
338    * ensureCapacity@/link
339    * for how the capacity increment is used.
340    */
341    virtual unsigned int setCapacityIncrement(unsigned increment) = 0;
342
343
344   /*!
345    * @function ensureCapacity
346    *
347    * @abstract
348    * Ensures the collection has enough space to store
349    * the requested number of objects.
350    *
351    * @param newCapacity  The total number of objects the collection
352    *                     should be able to store.
353    *
354    * @result
355    * The new capacity of the collection,
356    * which may be different from the number requested
357    * (if smaller, reallocation of storage failed).
358    *
359    * @discussion
360    * Subclasses implement this pure virtual member function
361    * to adjust their storage so that they can hold
362    * at least <code>newCapacity</code> objects.
363    * Libkern collections generally allocate storage
364    * in multiples of their capacity increment.
365    *
366    * Subclass methods that add objects to the collection
367    * should call this function before adding any object,
368    * and should check the return value for success.
369    *
370    * Collection subclasses may reduce their storage
371    * when the number of contained objects falls below some threshold,
372    * but no Libkern collections currently do.
373    */
374    virtual unsigned int ensureCapacity(unsigned int newCapacity) = 0;
375
376
377   /*!
378    * @function flushCollection
379    *
380    * @abstract
381    * Empties the collection, releasing any objects retained.
382    *
383    * @discussion
384    * Subclasses implement this pure virtual member function
385    * to remove their entire contents.
386    * This must not release the collection itself.
387    */
388    virtual void flushCollection() = 0;
389
390
391   /*!
392    * @function setOptions
393    *
394    * @abstract
395    * Recursively sets option bits in this collection
396    * and all child collections.
397    *
398    * @param options  A bitfield whose values turn the options on (1) or off (0).
399    * @param mask     A mask indicating which bits
400    *                 in <code>options</code> to change.
401    *                 Pass 0 to get the whole current options bitfield
402    *                 without changing any settings.
403    * @param context  Unused.
404    *
405    * @result
406    * The options bitfield as it was before the set operation.
407    *
408    * @discussion
409    * Kernel extensions should not call this function.
410    *
411    * The only option currently in use is
412    * <code>@link //apple_ref/doc/title:econst/OSCollectionFlags/kImmutable
413    * kImmutable@/link</code>.
414    *
415    * Subclasses should override this function to recursively apply
416    * the options to their contents if the options actually change.
417    */
418    virtual unsigned setOptions(
419        unsigned   options,
420        unsigned   mask,
421        void     * context = 0);
422    OSMetaClassDeclareReservedUsed(OSCollection, 0);
423
424   /*!
425    * @function copyCollection
426    *
427    * @abstract
428    * Creates a deep copy of a collection.
429    *
430    * @param cycleDict  A dictionary of all of the collections
431    *                   that have been copied so far,
432    *                   to start the copy at the top level
433    *                   pass <code>NULL</code> for <code>cycleDict</code>.
434    *
435    * @result
436    * The newly copied collecton,
437    * <code>NULL</code> on failure.
438    *
439    * @discussion
440    * This function copies the collection
441    * and all of the contained collections recursively.
442    * Objects that are not derived from OSCollection are retained
443    * rather than copied.
444    *
445    * Subclasses of OSCollection must override this function
446    * to properly support deep copies.
447    */
448    virtual OSCollection *copyCollection(OSDictionary * cycleDict = 0);
449    OSMetaClassDeclareReservedUsed(OSCollection, 1);
450
451
452    OSMetaClassDeclareReservedUnused(OSCollection, 2);
453    OSMetaClassDeclareReservedUnused(OSCollection, 3);
454    OSMetaClassDeclareReservedUnused(OSCollection, 4);
455    OSMetaClassDeclareReservedUnused(OSCollection, 5);
456    OSMetaClassDeclareReservedUnused(OSCollection, 6);
457    OSMetaClassDeclareReservedUnused(OSCollection, 7);
458};
459
460#endif /* !_OS_OSCOLLECTION_H */
461