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