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() APPLE_KEXT_OVERRIDE;
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 * @function iterateObjects
453 *
454 * @abstract
455 * Invoke a callback for each member of the collection.
456 *
457 * @param refcon A reference constant for the callback.
458 * @param callback The callback function,
459 * called with the refcon and each member object
460 * of the collection in turn, on the callers thread.
461 * The callback should return true to early terminate
462 * the iteration, false otherwise.
463 *
464 * @result
465 * False if the collection iteration was made invalid
466 * (see OSCollectionIterator::isValid()) otherwise true.
467 */
468 bool iterateObjects(void * refcon, bool (*callback)(void * refcon, OSObject * object));
469
470#ifdef __BLOCKS__
471
472 /*!
473 * @function iterateObjects
474 *
475 * @abstract
476 * Invoke a block for each member of the collection.
477 *
478 * @param block The block,
479 * called with the refcon and each member object
480 * of the collection in turn, on the callers thread.
481 * The block should return true to early terminate
482 * the iteration, false otherwise.
483 *
484 * @result
485 * False if the collection iteration was made invalid
486 * (see OSCollectionIterator::isValid()) otherwise true.
487 */
488 bool iterateObjects(bool (^block)(OSObject * object));
489
490#endif /* __BLOCKS__ */
491
492 OSMetaClassDeclareReservedUnused(OSCollection, 2);
493 OSMetaClassDeclareReservedUnused(OSCollection, 3);
494 OSMetaClassDeclareReservedUnused(OSCollection, 4);
495 OSMetaClassDeclareReservedUnused(OSCollection, 5);
496 OSMetaClassDeclareReservedUnused(OSCollection, 6);
497 OSMetaClassDeclareReservedUnused(OSCollection, 7);
498};
499
500#endif /* !_OS_OSCOLLECTION_H */
501
502
503