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