1*e3723e1fSApple OSS Distributions /* 2*e3723e1fSApple OSS Distributions * Copyright (c) 2019 Apple Inc. All rights reserved. 3*e3723e1fSApple OSS Distributions * 4*e3723e1fSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*e3723e1fSApple OSS Distributions * 6*e3723e1fSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7*e3723e1fSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8*e3723e1fSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9*e3723e1fSApple OSS Distributions * compliance with the License. The rights granted to you under the License 10*e3723e1fSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11*e3723e1fSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12*e3723e1fSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13*e3723e1fSApple OSS Distributions * terms of an Apple operating system software license agreement. 14*e3723e1fSApple OSS Distributions * 15*e3723e1fSApple OSS Distributions * Please obtain a copy of the License at 16*e3723e1fSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17*e3723e1fSApple OSS Distributions * 18*e3723e1fSApple OSS Distributions * The Original Code and all software distributed under the License are 19*e3723e1fSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*e3723e1fSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*e3723e1fSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*e3723e1fSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*e3723e1fSApple OSS Distributions * Please see the License for the specific language governing rights and 24*e3723e1fSApple OSS Distributions * limitations under the License. 25*e3723e1fSApple OSS Distributions * 26*e3723e1fSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*e3723e1fSApple OSS Distributions */ 28*e3723e1fSApple OSS Distributions /* IOCollectionIterator.h created by gvdl on Fri 1998-10-30 */ 29*e3723e1fSApple OSS Distributions 30*e3723e1fSApple OSS Distributions #ifndef _OS_OSCOLLECTIONITERATOR_H 31*e3723e1fSApple OSS Distributions #define _OS_OSCOLLECTIONITERATOR_H 32*e3723e1fSApple OSS Distributions 33*e3723e1fSApple OSS Distributions #include <libkern/c++/OSIterator.h> 34*e3723e1fSApple OSS Distributions #include <libkern/c++/OSCollection.h> 35*e3723e1fSApple OSS Distributions #include <libkern/c++/OSPtr.h> 36*e3723e1fSApple OSS Distributions 37*e3723e1fSApple OSS Distributions class OSCollectionIterator; 38*e3723e1fSApple OSS Distributions 39*e3723e1fSApple OSS Distributions typedef OSCollectionIterator* OSCollectionIteratorPtr; 40*e3723e1fSApple OSS Distributions 41*e3723e1fSApple OSS Distributions #if XNU_KERNEL_PRIVATE 42*e3723e1fSApple OSS Distributions 43*e3723e1fSApple OSS Distributions __enum_closed_decl(OSCollectionIteratorStorageType, uint8_t, { 44*e3723e1fSApple OSS Distributions OSCollectionIteratorStorageUnallocated = 0, 45*e3723e1fSApple OSS Distributions OSCollectionIteratorStorageInvalid = 1, 46*e3723e1fSApple OSS Distributions OSCollectionIteratorStorageInline = 2, 47*e3723e1fSApple OSS Distributions OSCollectionIteratorStoragePointer = 3, /* two bits set, matches top bits of kernel pointer */ 48*e3723e1fSApple OSS Distributions }); 49*e3723e1fSApple OSS Distributions 50*e3723e1fSApple OSS Distributions #endif /* XNU_KERNEL_PRIVATE */ 51*e3723e1fSApple OSS Distributions 52*e3723e1fSApple OSS Distributions /*! 53*e3723e1fSApple OSS Distributions * @header 54*e3723e1fSApple OSS Distributions * 55*e3723e1fSApple OSS Distributions * @abstract 56*e3723e1fSApple OSS Distributions * This header declares the OSCollectionIterator collection class. 57*e3723e1fSApple OSS Distributions */ 58*e3723e1fSApple OSS Distributions 59*e3723e1fSApple OSS Distributions 60*e3723e1fSApple OSS Distributions /*! 61*e3723e1fSApple OSS Distributions * @class OSCollectionIterator 62*e3723e1fSApple OSS Distributions * 63*e3723e1fSApple OSS Distributions * @discussion 64*e3723e1fSApple OSS Distributions * OSCollectionIterator defines a consistent mechanism to iterate 65*e3723e1fSApple OSS Distributions * through the objects of an OSCollection. 66*e3723e1fSApple OSS Distributions * It expands on the basic interface of 67*e3723e1fSApple OSS Distributions * @link //apple_ref/cpp/class/OSIterator OSIterator@/link 68*e3723e1fSApple OSS Distributions * to allow association of an iterator with a specific collection. 69*e3723e1fSApple OSS Distributions * 70*e3723e1fSApple OSS Distributions * To use an OSCollectionIterator, you create it with the collection 71*e3723e1fSApple OSS Distributions * to be iterated, then call 72*e3723e1fSApple OSS Distributions * @link //apple_ref/cpp/class/OSIterator OSIterator@/link 73*e3723e1fSApple OSS Distributions * as long as it returns an object: 74*e3723e1fSApple OSS Distributions * 75*e3723e1fSApple OSS Distributions * @textblock 76*e3723e1fSApple OSS Distributions * <pre> 77*e3723e1fSApple OSS Distributions * OSPtr <OSCollectionIterator> iterator = 78*e3723e1fSApple OSS Distributions * OSCollectionIterator::withCollection(myCollection); 79*e3723e1fSApple OSS Distributions * OSObject * object; 80*e3723e1fSApple OSS Distributions * while (object = iterator->getNextObject()) { 81*e3723e1fSApple OSS Distributions * // do something with object 82*e3723e1fSApple OSS Distributions * } 83*e3723e1fSApple OSS Distributions * // optional 84*e3723e1fSApple OSS Distributions * if (!iterator->isValid()) { 85*e3723e1fSApple OSS Distributions * // report that collection changed during iteration 86*e3723e1fSApple OSS Distributions * } 87*e3723e1fSApple OSS Distributions * iterator = nullptr; 88*e3723e1fSApple OSS Distributions * </pre> 89*e3723e1fSApple OSS Distributions * @/textblock 90*e3723e1fSApple OSS Distributions * 91*e3723e1fSApple OSS Distributions * Note that when iterating associative collections, 92*e3723e1fSApple OSS Distributions * the objects returned by <code>getNextObject</code> are keys; 93*e3723e1fSApple OSS Distributions * if you want to work with the associated values, 94*e3723e1fSApple OSS Distributions * simply look them up in the collection with the keys. 95*e3723e1fSApple OSS Distributions * 96*e3723e1fSApple OSS Distributions * <b>Use Restrictions</b> 97*e3723e1fSApple OSS Distributions * 98*e3723e1fSApple OSS Distributions * With very few exceptions in the I/O Kit, all Libkern-based C++ 99*e3723e1fSApple OSS Distributions * classes, functions, and macros are <b>unsafe</b> 100*e3723e1fSApple OSS Distributions * to use in a primary interrupt context. 101*e3723e1fSApple OSS Distributions * Consult the I/O Kit documentation related to primary interrupts 102*e3723e1fSApple OSS Distributions * for more information. 103*e3723e1fSApple OSS Distributions * 104*e3723e1fSApple OSS Distributions * OSCollectionIterator provides no concurrency protection. 105*e3723e1fSApple OSS Distributions */ 106*e3723e1fSApple OSS Distributions class OSCollectionIterator : public OSIterator 107*e3723e1fSApple OSS Distributions { 108*e3723e1fSApple OSS Distributions OSDeclareDefaultStructors(OSCollectionIterator); 109*e3723e1fSApple OSS Distributions 110*e3723e1fSApple OSS Distributions protected: 111*e3723e1fSApple OSS Distributions // xx-review: Do we want to document these? 112*e3723e1fSApple OSS Distributions OSPtr<const OSCollection> collection; 113*e3723e1fSApple OSS Distributions #if __LP64__ && XNU_KERNEL_PRIVATE 114*e3723e1fSApple OSS Distributions union { 115*e3723e1fSApple OSS Distributions struct { 116*e3723e1fSApple OSS Distributions uint8_t inlineStorage[4]; 117*e3723e1fSApple OSS Distributions uint8_t __padding[4]; 118*e3723e1fSApple OSS Distributions }; 119*e3723e1fSApple OSS Distributions void * collIterator; 120*e3723e1fSApple OSS Distributions }; 121*e3723e1fSApple OSS Distributions #else 122*e3723e1fSApple OSS Distributions void * collIterator; 123*e3723e1fSApple OSS Distributions #endif /* __LP64__ && XNU_KERNEL_PRIVATE */ 124*e3723e1fSApple OSS Distributions unsigned int initialUpdateStamp; 125*e3723e1fSApple OSS Distributions bool valid; 126*e3723e1fSApple OSS Distributions 127*e3723e1fSApple OSS Distributions #if XNU_KERNEL_PRIVATE 128*e3723e1fSApple OSS Distributions private: 129*e3723e1fSApple OSS Distributions /* 130*e3723e1fSApple OSS Distributions * Returns true if this object is an instance of a OSCollectionIterator subclass 131*e3723e1fSApple OSS Distributions */ 132*e3723e1fSApple OSS Distributions bool isSubclassed(); 133*e3723e1fSApple OSS Distributions 134*e3723e1fSApple OSS Distributions /* 135*e3723e1fSApple OSS Distributions * Initialize iterator storage. 136*e3723e1fSApple OSS Distributions * 137*e3723e1fSApple OSS Distributions * If storage is already initialized, return false. Otherwise, return true. 138*e3723e1fSApple OSS Distributions */ 139*e3723e1fSApple OSS Distributions bool initializeIteratorStorage(); 140*e3723e1fSApple OSS Distributions 141*e3723e1fSApple OSS Distributions /* 142*e3723e1fSApple OSS Distributions * Get the iterator storage. If storage is not initialized, this returns NULL. 143*e3723e1fSApple OSS Distributions */ 144*e3723e1fSApple OSS Distributions void * getIteratorStorage(); 145*e3723e1fSApple OSS Distributions 146*e3723e1fSApple OSS Distributions /* 147*e3723e1fSApple OSS Distributions * Free iterator storage. If storage is not initialized, this has no effect. 148*e3723e1fSApple OSS Distributions */ 149*e3723e1fSApple OSS Distributions void freeIteratorStorage(); 150*e3723e1fSApple OSS Distributions 151*e3723e1fSApple OSS Distributions /* 152*e3723e1fSApple OSS Distributions * Determine if storage is unallocated, allocated, or inline. 153*e3723e1fSApple OSS Distributions */ 154*e3723e1fSApple OSS Distributions OSCollectionIteratorStorageType getStorageType(); 155*e3723e1fSApple OSS Distributions 156*e3723e1fSApple OSS Distributions /* 157*e3723e1fSApple OSS Distributions * Set the storage type. The expectation is that this is called AFTER the conditions 158*e3723e1fSApple OSS Distributions * for the storage type have been set. For example, collIterator must be set to a valid 159*e3723e1fSApple OSS Distributions * pointer before calling setStorageType(OSCollectionIteratorStoragePointer) 160*e3723e1fSApple OSS Distributions */ 161*e3723e1fSApple OSS Distributions void setStorageType(OSCollectionIteratorStorageType storageType); 162*e3723e1fSApple OSS Distributions #endif 163*e3723e1fSApple OSS Distributions 164*e3723e1fSApple OSS Distributions public: 165*e3723e1fSApple OSS Distributions /*! 166*e3723e1fSApple OSS Distributions * @function withCollection 167*e3723e1fSApple OSS Distributions * 168*e3723e1fSApple OSS Distributions * @abstract 169*e3723e1fSApple OSS Distributions * Creates and initializes an OSCollectionIterator 170*e3723e1fSApple OSS Distributions * for the provided collection object. 171*e3723e1fSApple OSS Distributions * 172*e3723e1fSApple OSS Distributions * @param inColl The OSCollection-derived collection object to be iteratated. 173*e3723e1fSApple OSS Distributions * 174*e3723e1fSApple OSS Distributions * @result 175*e3723e1fSApple OSS Distributions * A new instance of OSCollectionIterator, or <code>NULL</code> on failure. 176*e3723e1fSApple OSS Distributions */ 177*e3723e1fSApple OSS Distributions static OSPtr<OSCollectionIterator> withCollection(const OSCollection * inColl); 178*e3723e1fSApple OSS Distributions 179*e3723e1fSApple OSS Distributions 180*e3723e1fSApple OSS Distributions /*! 181*e3723e1fSApple OSS Distributions * @function initWithCollection 182*e3723e1fSApple OSS Distributions * 183*e3723e1fSApple OSS Distributions * @abstract 184*e3723e1fSApple OSS Distributions * Initializes an OSCollectionIterator 185*e3723e1fSApple OSS Distributions * for the provided collection object. 186*e3723e1fSApple OSS Distributions * 187*e3723e1fSApple OSS Distributions * @param inColl The OSCollection-derived collection object to be iteratated. 188*e3723e1fSApple OSS Distributions * @result 189*e3723e1fSApple OSS Distributions * <code>true</code> if the initialization was successful, 190*e3723e1fSApple OSS Distributions * or <code>false</code> on failure. 191*e3723e1fSApple OSS Distributions * 192*e3723e1fSApple OSS Distributions * @discussion 193*e3723e1fSApple OSS Distributions * Not for general use. Use the static instance creation method 194*e3723e1fSApple OSS Distributions * <code>@link withCollection withCollection@/link</code> instead. 195*e3723e1fSApple OSS Distributions */ 196*e3723e1fSApple OSS Distributions virtual bool initWithCollection(const OSCollection * inColl); 197*e3723e1fSApple OSS Distributions 198*e3723e1fSApple OSS Distributions 199*e3723e1fSApple OSS Distributions /*! 200*e3723e1fSApple OSS Distributions * @function free 201*e3723e1fSApple OSS Distributions * 202*e3723e1fSApple OSS Distributions * @abstract 203*e3723e1fSApple OSS Distributions * Releases or deallocates any resources used 204*e3723e1fSApple OSS Distributions * by the OSCollectionIterator object. 205*e3723e1fSApple OSS Distributions * 206*e3723e1fSApple OSS Distributions * @discussion 207*e3723e1fSApple OSS Distributions * This function should not be called directly; 208*e3723e1fSApple OSS Distributions * use 209*e3723e1fSApple OSS Distributions * <code>@link 210*e3723e1fSApple OSS Distributions * //apple_ref/cpp/instm/OSObject/release/virtualvoid/() 211*e3723e1fSApple OSS Distributions * release@/link</code> 212*e3723e1fSApple OSS Distributions * instead. 213*e3723e1fSApple OSS Distributions */ 214*e3723e1fSApple OSS Distributions virtual void free() APPLE_KEXT_OVERRIDE; 215*e3723e1fSApple OSS Distributions 216*e3723e1fSApple OSS Distributions 217*e3723e1fSApple OSS Distributions /*! 218*e3723e1fSApple OSS Distributions * @function reset 219*e3723e1fSApple OSS Distributions * 220*e3723e1fSApple OSS Distributions * @abstract 221*e3723e1fSApple OSS Distributions * Resets the iterator to the beginning of the collection, 222*e3723e1fSApple OSS Distributions * as if it had just been created. 223*e3723e1fSApple OSS Distributions */ 224*e3723e1fSApple OSS Distributions virtual void reset() APPLE_KEXT_OVERRIDE; 225*e3723e1fSApple OSS Distributions 226*e3723e1fSApple OSS Distributions 227*e3723e1fSApple OSS Distributions /*! 228*e3723e1fSApple OSS Distributions * @function isValid 229*e3723e1fSApple OSS Distributions * 230*e3723e1fSApple OSS Distributions * @abstract 231*e3723e1fSApple OSS Distributions * Checks that the collection hasn't been modified during iteration. 232*e3723e1fSApple OSS Distributions * 233*e3723e1fSApple OSS Distributions * @return 234*e3723e1fSApple OSS Distributions * <code>true</code> if the iterator is valid for continued use, 235*e3723e1fSApple OSS Distributions * <code>false</code> otherwise 236*e3723e1fSApple OSS Distributions * (typically because the iteration context has been modified). 237*e3723e1fSApple OSS Distributions */ 238*e3723e1fSApple OSS Distributions virtual bool isValid() APPLE_KEXT_OVERRIDE; 239*e3723e1fSApple OSS Distributions 240*e3723e1fSApple OSS Distributions 241*e3723e1fSApple OSS Distributions /*! 242*e3723e1fSApple OSS Distributions * @function getNextObject 243*e3723e1fSApple OSS Distributions * 244*e3723e1fSApple OSS Distributions * @abstract 245*e3723e1fSApple OSS Distributions * Advances to and returns the next object in the iteration. 246*e3723e1fSApple OSS Distributions * 247*e3723e1fSApple OSS Distributions * @return 248*e3723e1fSApple OSS Distributions * The next object in the iteration context, 249*e3723e1fSApple OSS Distributions * <code>NULL</code> if there is no next object 250*e3723e1fSApple OSS Distributions * or if the iterator is no longer valid. 251*e3723e1fSApple OSS Distributions * 252*e3723e1fSApple OSS Distributions * @discussion 253*e3723e1fSApple OSS Distributions * This function first calls 254*e3723e1fSApple OSS Distributions * <code>@link //apple_ref/cpp/instm/OSCollectionIterator/isValid/virtualbool/() 255*e3723e1fSApple OSS Distributions * isValid@/link</code> 256*e3723e1fSApple OSS Distributions * and returns <code>NULL</code> if that function 257*e3723e1fSApple OSS Distributions * returns <code>false</code>. 258*e3723e1fSApple OSS Distributions * 259*e3723e1fSApple OSS Distributions * Subclasses must implement this pure virtual function 260*e3723e1fSApple OSS Distributions * to check for validity with 261*e3723e1fSApple OSS Distributions * <code>@link 262*e3723e1fSApple OSS Distributions * //apple_ref/cpp/instm/OSCollectionIterator/isValid/virtualbool/() 263*e3723e1fSApple OSS Distributions * isValid@/link</code>, 264*e3723e1fSApple OSS Distributions * and then to advance the iteration context to the next object (if any) 265*e3723e1fSApple OSS Distributions * and return that next object, or <code>NULL</code> if there is none. 266*e3723e1fSApple OSS Distributions */ 267*e3723e1fSApple OSS Distributions virtual OSObject * getNextObject() APPLE_KEXT_OVERRIDE; 268*e3723e1fSApple OSS Distributions }; 269*e3723e1fSApple OSS Distributions 270*e3723e1fSApple OSS Distributions #endif /* !_OS_OSCOLLECTIONITERATOR_H */ 271