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