1 /* 2 * Copyright (c) 2000-2019 Apple 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 /* IOData.h created by rsulack on Wed 17-Sep-1997 */ 29 /* IOData.h converted to C++ by gvdl on Fri 1998-10-30 */ 30 31 #ifndef _OS_OSDATA_H 32 #define _OS_OSDATA_H 33 34 #include <libkern/c++/OSObject.h> 35 #include <libkern/c++/OSPtr.h> 36 #include <os/base.h> 37 38 #if KERNEL_PRIVATE 39 #include <kern/kalloc.h> 40 #endif 41 42 class OSData; 43 class OSString; 44 45 typedef OSData* OSDataPtr; 46 typedef OSData const* OSDataConstPtr; 47 48 /*! 49 * @header 50 * 51 * @abstract 52 * This header declares the OSData container class. 53 */ 54 55 56 /*! 57 * @class OSData 58 * 59 * @abstract 60 * OSData wraps an array of bytes in a C++ object 61 * for use in Libkern collections. 62 * 63 * @discussion 64 * OSData represents an array of bytes as a Libkern C++ object. 65 * OSData objects are mutable: 66 * You can add bytes to them and 67 * overwrite portions of the byte array. 68 * 69 * <b>Use Restrictions</b> 70 * 71 * With very few exceptions in the I/O Kit, all Libkern-based C++ 72 * classes, functions, and macros are <b>unsafe</b> 73 * to use in a primary interrupt context. 74 * Consult the I/O Kit documentation related to primary interrupts 75 * for more information. 76 * 77 * OSData provides no concurrency protection; 78 * it's up to the usage context to provide any protection necessary. 79 * Some portions of the I/O Kit, such as 80 * @link //apple_ref/doc/class/IORegistryEntry IORegistryEntry@/link, 81 * handle synchronization via defined member functions for setting 82 * properties. 83 */ 84 class OSData : public OSObject 85 { 86 friend class OSSerialize; 87 88 OSDeclareDefaultStructors(OSData); 89 90 #if APPLE_KEXT_ALIGN_CONTAINERS 91 92 protected: 93 unsigned int length; 94 unsigned int capacity; 95 unsigned int capacityIncrement; 96 void * OS_PTRAUTH_SIGNED_PTR("OSData.data") data; 97 98 #else /* APPLE_KEXT_ALIGN_CONTAINERS */ 99 100 protected: 101 void * OS_PTRAUTH_SIGNED_PTR("OSData.data") data; 102 unsigned int length; 103 unsigned int capacity; 104 unsigned int capacityIncrement; 105 106 #endif /* APPLE_KEXT_ALIGN_CONTAINERS */ 107 108 #ifdef XNU_KERNEL_PRIVATE 109 /* Available within xnu source only */ 110 public: 111 typedef void (*DeallocFunction)(void * ptr, unsigned int length); 112 protected: 113 struct ExpansionData { 114 DeallocFunction deallocFunction; 115 bool disableSerialization; 116 }; 117 #else /* XNU_KERNEL_PRIVATE */ 118 private: 119 typedef void (*DeallocFunction)(void * ptr, unsigned int length); 120 protected: 121 struct ExpansionData; 122 #endif /* XNU_KERNEL_PRIVATE */ 123 124 /* Reserved for future use. (Internal use only) */ 125 ExpansionData * reserved; 126 127 public: 128 129 /*! 130 * @function withCapacity 131 * 132 * @abstract 133 * Creates and initializes an empty instance of OSData. 134 * 135 * @param capacity The initial capacity of the OSData object in bytes. 136 * 137 * @result 138 * An instance of OSData with a reference count of 1; 139 * <code>NULL</code> on failure. 140 * 141 * @discussion 142 * <code>capacity</code> may be zero. 143 * The OSData object will allocate a buffer internally 144 * when necessary, and will grow as needed to accommodate more bytes 145 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 146 * for which a nonzero initial capacity is a hard limit). 147 */ 148 static OSPtr<OSData> withCapacity(unsigned int capacity); 149 150 151 /*! 152 * @function withBytes 153 * 154 * @abstract 155 * Creates and initializes an instance of OSData 156 * with a copy of the provided data buffer. 157 * 158 * @param bytes The buffer of data to copy. 159 * @param numBytes The length of <code>bytes</code>. 160 * 161 * @result 162 * An instance of OSData containing a copy of the provided byte array, 163 * with a reference count of 1; 164 * <code>NULL</code> on failure. 165 * 166 * @discussion 167 * The new OSData object will grow as needed to accommodate more bytes 168 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 169 * for which a nonzero initial capacity is a hard limit). 170 */ 171 static OSPtr<OSData> withBytes( 172 const void * bytes, 173 unsigned int numBytes); 174 175 176 #if KERNEL_PRIVATE 177 /*! 178 * @function withValue 179 * 180 * @abstract 181 * Creates and initializes an instance of OSData 182 * with a copy of the provided value of a concrete type. 183 * 184 * @param value The instance of a value to copy. 185 * 186 * @result 187 * An instance of OSData containing a copy of the provided value's data, 188 * with a reference count of 1; 189 * <code>NULL</code> on failure. 190 * 191 * @discussion 192 * The new OSData object will grow as needed to accommodate more bytes 193 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 194 * for which a nonzero initial capacity is a hard limit). 195 */ 196 template <typename T> 197 static OSPtr<OSData> withValue(const T & value)198 withValue(const T& value) 199 { 200 validateValueType<T, kValueCopy>(); 201 return withBytes(&value, sizeof(T)); 202 } 203 #endif // KERNEL_PRIVATE 204 205 206 /*! 207 * @function withBytesNoCopy 208 * 209 * @abstract 210 * Creates and initializes an instance of OSData 211 * that shares the provided data buffer. 212 * 213 * @param bytes The buffer of data to represent. 214 * @param numBytes The length of <code>bytes</code>. 215 * 216 * @result 217 * A instance of OSData that shares the provided byte array, 218 * with a reference count of 1; 219 * <code>NULL</code> on failure. 220 * 221 * @discussion 222 * An OSData object created with this function 223 * does not claim ownership 224 * of the data buffer, but shares it with the caller. 225 * When the caller determines that the OSData object has actually been freed, 226 * it can safely dispose of the data buffer. 227 * Conversely, if it frees the shared data buffer, 228 * it must not attempt to use the OSData object and should release it. 229 * 230 * An OSData object created with shared external data cannot append bytes, 231 * but you can get the byte pointer and 232 * modify bytes within the shared buffer. 233 */ 234 static OSPtr<OSData> withBytesNoCopy( 235 void * bytes, 236 unsigned int numBytes); 237 238 239 #if KERNEL_PRIVATE 240 /*! 241 * @function withValueNoCopy 242 * 243 * @abstract 244 * Creates and initializes an instance of OSData 245 * that shares the provided value of a concrete type. 246 * 247 * @param value The instance of a value to represent. 248 * 249 * @result 250 * A instance of OSData that shares the provided value's data, 251 * with a reference count of 1; 252 * <code>NULL</code> on failure. 253 * 254 * @discussion 255 * An OSData object created with this function does not claim ownership 256 * of the data of the value, but shares it with the caller. 257 * When the caller determines that the OSData object has actually been freed, 258 * it can safely dispose of the data buffer. 259 * Conversely, if the lifetime of the data's shared value instance ends, 260 * it must not attempt to use the OSData object and should release it. 261 * 262 * An OSData object created with shared external data cannot append bytes, 263 * but you can get the byte pointer and 264 * modify bytes within the shared buffer. 265 */ 266 template <typename T> 267 static OSPtr<OSData> withValueNoCopy(T & value)268 withValueNoCopy(T& value) 269 { 270 validateValueType<T, kValueNoCopy>(); 271 return withBytesNoCopy(&value, sizeof(T)); 272 } 273 274 #if __cplusplus >= 201103L 275 /* rvalue overload is deleted for the NoCopy variation to 276 * disallow holding a dangling pointer to a temporary value */ 277 template <typename T> 278 static OSPtr<OSData> withValueNoCopy(T&& value) = delete; 279 #endif 280 #endif // KERNEL_PRIVATE 281 282 283 /*! 284 * @function withData 285 * 286 * @abstract 287 * Creates and initializes an instance of OSData 288 * with contents copied from another OSData object. 289 * 290 * @param inData An OSData object that provides the initial data. 291 * 292 * @result 293 * An instance of OSData containing a copy of the data in <code>inData</code>, 294 * with a reference count of 1; 295 * <code>NULL</code> on failure. 296 * 297 * @discussion 298 * The new OSData object will grow as needed to accommodate more bytes 299 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 300 * for which a nonzero initial capacity is a hard limit). 301 */ 302 static OSPtr<OSData> withData(const OSData * inData); 303 304 305 /*! 306 * @function withData 307 * 308 * @abstract 309 * Creates and initializes an instance of OSData 310 * with contents copied from a range within another OSData object. 311 * 312 * @param inData An OSData object that provides the initial data. 313 * @param start The starting index from which bytes will be copied. 314 * @param numBytes The number of bytes to be copied from <code>start</code>. 315 * 316 * @result 317 * An instance of OSData containing a copy 318 * of the specified data range from <code>inData</code>, 319 * with a reference count of 1; 320 * <code>NULL</code> on failure. 321 * 322 * @discussion 323 * The new OSData object will grow as needed to accommodate more bytes 324 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 325 * for which a nonzero initial capacity is a hard limit). 326 */ 327 static OSPtr<OSData> withData( 328 const OSData * inData, 329 unsigned int start, 330 unsigned int numBytes); 331 332 333 /*! 334 * @function initWithCapacity 335 * 336 * @abstract 337 * Initializes an instance of OSData. 338 * 339 * @param capacity The initial capacity of the OSData object in bytes. 340 * 341 * @result 342 * <code>true</code> on success, <code>false</code> on failure. 343 * 344 * @discussion 345 * Not for general use. Use the static instance creation method 346 * <code>@link 347 * //apple_ref/cpp/clm/OSData/withCapacity/staticOSData*\/(unsignedint) 348 * withCapacity@/link</code> instead. 349 * 350 * <code>capacity</code> may be zero. 351 * The OSData object will allocate a buffer internally 352 * when necessary, and will grow as needed to accommodate more bytes 353 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 354 * for which a nonzero initial capacity is a hard limit). 355 */ 356 virtual bool initWithCapacity(unsigned int capacity); 357 358 359 /*! 360 * @function initWithBytes 361 * 362 * @abstract 363 * Initializes an instance of OSData 364 * with a copy of the provided data buffer. 365 * 366 * @param bytes The buffer of data to copy. 367 * @param numBytes The length of <code>bytes</code>. 368 * 369 * @result 370 * <code>true</code> on success, <code>false</code> on failure. 371 * 372 * @discussion 373 * Not for general use. Use the static instance creation method 374 * <code>@link withBytes withBytes@/link</code> instead. 375 * 376 * The new OSData object will grow as needed to accommodate more bytes 377 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 378 * for which a nonzero initial capacity is a hard limit). 379 */ 380 virtual bool initWithBytes( 381 const void * bytes, 382 unsigned int numBytes); 383 384 385 #if KERNEL_PRIVATE 386 /*! 387 * @function initWithValue 388 * 389 * @abstract 390 * Initializes an instance of OSData 391 * with a copy of the provided value of a concrete type. 392 * 393 * @param value The instance of a value to copy. 394 * 395 * @result 396 * <code>true</code> on success, <code>false</code> on failure. 397 * 398 * @discussion 399 * Not for general use. Use the static instance creation method 400 * <code>@link withValue withValue@/link</code> instead. 401 * 402 * The new OSData object will grow as needed to accommodate more bytes 403 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 404 * for which a nonzero initial capacity is a hard limit). 405 */ 406 template <typename T> 407 bool initWithValue(const T & value)408 initWithValue(const T& value) 409 { 410 validateValueType<T, kValueCopy>(); 411 return initWithBytes(&value, sizeof(T)); 412 } 413 #endif // KERNEL_PRIVATE 414 415 416 /*! 417 * @function initWithBytesNoCopy 418 * 419 * @abstract 420 * Initializes an instance of OSData 421 * to share the provided data buffer. 422 * 423 * @param bytes The buffer of data to represent. 424 * @param numBytes The length of <code>bytes</code>. 425 * 426 * @result 427 * <code>true</code> on success, <code>false</code> on failure. 428 * 429 * @discussion 430 * Not for general use. Use the static instance creation method 431 * <code>@link withBytesNoCopy withBytesNoCopy@/link</code> instead. 432 * 433 * An OSData object initialized with this function 434 * does not claim ownership 435 * of the data buffer, but merely shares it with the caller. 436 * 437 * An OSData object created with shared external data cannot append bytes, 438 * but you can get the byte pointer and 439 * modify bytes within the shared buffer. 440 */ 441 virtual bool initWithBytesNoCopy( 442 void * bytes, 443 unsigned int numBytes); 444 445 446 #if KERNEL_PRIVATE 447 /*! 448 * @function initWithValueNoCopy 449 * 450 * @abstract 451 * Initializes an instance of OSData 452 * to share the provided value of a concrete type. 453 * 454 * @param value The instance of a value to represent. 455 * 456 * @result 457 * <code>true</code> on success, <code>false</code> on failure. 458 * 459 * @discussion 460 * Not for general use. Use the static instance creation method 461 * <code>@link withValueNoCopy withValueNoCopy@/link</code> instead. 462 * 463 * An OSData object initialized with this function does not claim ownership 464 * of the data of the value, but merely shares it with the caller. 465 * 466 * An OSData object created with shared external data cannot append bytes, 467 * but you can get the byte pointer and 468 * modify bytes within the shared buffer. 469 */ 470 template <typename T> 471 bool initWithValueNoCopy(T & value)472 initWithValueNoCopy(T& value) 473 { 474 validateValueType<T, kValueNoCopy>(); 475 return initWithBytesNoCopy(&value, sizeof(T)); 476 } 477 478 #if __cplusplus >= 201103L 479 /* rvalue overload is deleted for the NoCopy variation to 480 * disallow holding a dangling pointer to a temporary value */ 481 template <typename T> 482 bool initWithValueNoCopy(T&& value) = delete; 483 #endif 484 #endif // KERNEL_PRIVATE 485 486 487 /*! 488 * @function initWithData 489 * 490 * @abstract 491 * Creates and initializes an instance of OSData 492 * with contents copied from another OSData object. 493 * 494 * @param inData An OSData object that provides the initial data. 495 * 496 * @result 497 * <code>true</code> on success, <code>false</code> on failure. 498 * 499 * @discussion 500 * Not for general use. Use the static instance creation method 501 * <code>@link 502 * //apple_ref/cpp/clm/OSData/withData/staticOSData*\/(constOSData*) 503 * withData(OSData *)@/link</code> 504 * instead. 505 * 506 * The new OSData object will grow as needed to accommodate more bytes 507 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 508 * for which a nonzero initial capacity is a hard limit). 509 */ 510 virtual bool initWithData(const OSData * inData); 511 512 513 /*! 514 * @function initWithData 515 * 516 * @abstract 517 * Initializes an instance of OSData 518 * with contents copied from a range within another OSData object. 519 * 520 * @param inData An OSData object that provides the initial data. 521 * @param start The starting index from which bytes will be copied. 522 * @param numBytes The number of bytes to be copied from <code>start</code>. 523 * 524 * @result 525 * Returns <code>true</code> on success, <code>false</code> on failure. 526 * 527 * @discussion 528 * Not for general use. Use the static instance creation method 529 * <code>@link 530 * //apple_ref/cpp/clm/OSData/withData/staticOSData*\/(constOSData*,unsignedint,unsignedint) 531 * withData(OSData *, unsigned int, unsigned int)@/link</code> 532 * instead. 533 * 534 * The new OSData object will grow as needed to accommodate more bytes 535 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 536 * for which a nonzero initial capacity is a hard limit). 537 */ 538 virtual bool initWithData( 539 const OSData * inData, 540 unsigned int start, 541 unsigned int numBytes); 542 543 544 /*! 545 * @function free 546 * 547 * @abstract 548 * Deallocates or releases any resources 549 * used by the OSData instance. 550 * 551 * @discussion 552 * This function should not be called directly; 553 * use 554 * <code>@link 555 * //apple_ref/cpp/instm/OSObject/release/virtualvoid/() 556 * release@/link</code> 557 * instead. 558 */ 559 virtual void free() APPLE_KEXT_OVERRIDE; 560 561 562 /*! 563 * @function getLength 564 * 565 * @abstract 566 * Returns the number of bytes in or referenced by the OSData object. 567 * 568 * @result 569 * The number of bytes in or referenced by the OSData object. 570 */ 571 virtual unsigned int getLength() const; 572 573 574 /*! 575 * @function getCapacity 576 * 577 * @abstract 578 * Returns the total number of bytes the OSData can store without reallocating. 579 * 580 * @result 581 * The total number bytes the OSData can store without reallocating. 582 * 583 * @discussion 584 * OSData objects grow when full to accommodate additional bytes. 585 * See 586 * <code>@link 587 * //apple_ref/cpp/instm/OSData/getCapacityIncrement/virtualunsignedint/() 588 * getCapacityIncrement@/link</code> 589 * and 590 * <code>@link 591 * //apple_ref/cpp/instm/OSData/ensureCapacity/virtualunsignedint/(unsignedint) 592 * ensureCapacity@/link</code>. 593 * 594 * OSData objects created or initialized to use a shared buffer 595 * do not make use of this attribute, and return -1 from this function. 596 */ 597 virtual unsigned int getCapacity() const; 598 599 600 /*! 601 * @function getCapacityIncrement 602 * 603 * @abstract 604 * Returns the storage increment of the OSData object. 605 * 606 * @result 607 * The storage increment of the OSData object. 608 * 609 * @discussion 610 * An OSData object allocates storage for bytes in multiples 611 * of the capacity increment. 612 * 613 * OSData objects created or initialized to use a shared buffer 614 * do not make use of this attribute. 615 */ 616 virtual unsigned int getCapacityIncrement() const; 617 618 619 /*! 620 * @function setCapacityIncrement 621 * 622 * @abstract 623 * Sets the storage increment of the array. 624 * 625 * @result 626 * The original storage increment of the array. 627 * 628 * @discussion 629 * An OSArray allocates storage for objects in multiples 630 * of the capacity increment. 631 * 632 * OSData objects created or initialized to use a shared buffer 633 * do not make use of this attribute. 634 */ 635 virtual unsigned int setCapacityIncrement(unsigned increment); 636 637 638 // xx-review: does not check for capacity == EXTERNAL 639 640 /*! 641 * @function ensureCapacity 642 * 643 * @abstract 644 * Ensures the array has enough space 645 * to store the requested number of bytes. 646 * 647 * @param newCapacity The total number of bytes the OSData object 648 * should be able to store. 649 * 650 * @result 651 * Returns the new capacity of the OSData object, 652 * which may be different from the number requested 653 * (if smaller, reallocation of storage failed). 654 * 655 * @discussion 656 * This function immediately resizes the OSData's buffer, if necessary, 657 * to accommodate at least <code>newCapacity</code> bytes. 658 * If <code>newCapacity</code> is not greater than the current capacity, 659 * or if an allocation error occurs, the original capacity is returned. 660 * 661 * There is no way to reduce the capacity of an OSData. 662 * 663 * An OSData object created "NoCopy" does not allow resizing. 664 */ 665 virtual unsigned int ensureCapacity(unsigned int newCapacity); 666 667 668 /*! 669 * @function appendBytes 670 * 671 * @abstract 672 * Appends a buffer of bytes to the OSData object's internal data buffer. 673 * 674 * @param bytes A pointer to the data to append. 675 * If <code>bytes</code> is <code>NULL</code> 676 * then a zero-filled buffer of length <code>numBytes</code> 677 * is appended. 678 * @param numBytes The number of bytes from <code>bytes</code> to append. 679 * 680 * @result 681 * <code>true</code> if the new data was successfully added, 682 * <code>false</code> on failure. 683 * 684 * @discussion 685 * This function immediately resizes the OSData's buffer, if necessary, 686 * to accommodate the new total size. 687 * 688 * An OSData object created "NoCopy" does not allow bytes 689 * to be appended. 690 */ 691 virtual bool appendBytes( 692 const void * bytes, 693 unsigned int numBytes); 694 695 696 #if KERNEL_PRIVATE 697 /*! 698 * @function appendValue 699 * 700 * @abstract 701 * Appends a copy of the provided value of a concrete type to the 702 * OSData object's internal data buffer. 703 * 704 * @param value The instance of a value to copy. 705 * 706 * @result 707 * <code>true</code> if the new data was successfully added, 708 * <code>false</code> on failure. 709 * 710 * @discussion 711 * This function immediately resizes the OSData's buffer, if necessary, 712 * to accommodate the new total size. 713 * 714 * An OSData object created "NoCopy" does not allow bytes 715 * to be appended. 716 */ 717 template <typename T> 718 bool appendValue(const T & value)719 appendValue(const T& value) 720 { 721 validateValueType<T, kValueCopy>(); 722 return appendBytes(&value, sizeof(T)); 723 } 724 #endif // KERNEL_PRIVATE 725 726 727 /*! 728 * @function appendBytes 729 * 730 * @abstract 731 * Appends the data contained in another OSData object. 732 * 733 * @param aDataObj The OSData object whose contents will be appended. 734 * 735 * @result 736 * <code>true</code> if the new data was successfully added, 737 * <code>false</code> on failure. 738 * 739 * @discussion 740 * This function immediately resizes the OSData's buffer, if necessary, 741 * to accommodate the new total size. 742 * 743 * An OSData object created "NoCopy" does not allow bytes 744 * to be appended. 745 */ 746 virtual bool appendBytes(const OSData * aDataObj); 747 748 749 /*! 750 * @function getBytesNoCopy 751 * 752 * @abstract 753 * Returns a pointer to the OSData object's internal data buffer. 754 * 755 * @result 756 * A pointer to the OSData object's internal data buffer. 757 * 758 * @discussion 759 * You can modify the existing contents of an OSData object 760 * via this function. 761 * It works with OSData objects that have their own data buffers 762 * as well as with OSData objects that have shared buffers. 763 * 764 * If you append bytes or characters to an OSData object, 765 * it may have to reallocate its internal storage, 766 * rendering invalid an extrated pointer to that storage. 767 */ 768 virtual const void * getBytesNoCopy() const; 769 770 771 /*! 772 * @function getBytesNoCopy 773 * 774 * @abstract 775 * Returns a pointer into the OSData object's internal data buffer 776 * with a given offset and length. 777 * 778 * @param start The offset from the base of the internal data buffer. 779 * @param numBytes The length of the window. 780 * 781 * @result 782 * A pointer to the bytes in the specified range 783 * within the OSData object, 784 * or 0 if that range does not lie completely 785 * within the object's buffer. 786 * 787 * @discussion 788 * You can modify the existing contents of an OSData object 789 * via this function. 790 * It works with OSData objects that have their own data buffers 791 * as well as with OSData objects that have shared buffers. 792 * 793 * If you append bytes or characters to an OSData object, 794 * it may have to reallocate its internal storage, 795 * rendering invalid an extrated pointer to that storage. 796 */ 797 virtual const void * getBytesNoCopy( 798 unsigned int start, 799 unsigned int numBytes) const; 800 801 802 /*! 803 * @function isEqualTo 804 * 805 * @abstract 806 * Tests the equality of two OSData objects. 807 * 808 * @param aDataObj The OSData object being compared against the receiver. 809 * 810 * @result 811 * <code>true</code> if the two OSData objects are equivalent, 812 * <code>false</code> otherwise. 813 * 814 * @discussion 815 * Two OSData objects are considered equal 816 * if they have same length and if their 817 * byte buffers hold the same contents. 818 */ 819 virtual bool isEqualTo(const OSData * aDataObj) const; 820 821 822 /*! 823 * @function isEqualTo 824 * 825 * @abstract 826 * Tests the equality of an OSData object's contents 827 * to a C array of bytes. 828 * 829 * @param bytes A pointer to the bytes to compare. 830 * @param numBytes The number of bytes to compare. 831 * 832 * @result 833 * <code>true</code> if the data buffers are equal 834 * over the given length, 835 * <code>false</code> otherwise. 836 */ 837 virtual bool isEqualTo( 838 const void * bytes, 839 unsigned int numBytes) const; 840 841 842 /*! 843 * @function isEqualTo 844 * 845 * @abstract 846 * Tests the equality of an OSData object to an arbitrary object. 847 * 848 * @param anObject The object to be compared against the receiver. 849 * 850 * @result 851 * <code>true</code> if the two objects are equivalent, 852 * <code>false</code> otherwise. 853 * 854 * @discussion 855 * An OSData is considered equal to another object 856 * if that object is derived from OSData 857 * and contains the equivalent bytes of the same length. 858 */ 859 virtual bool isEqualTo(const OSMetaClassBase * anObject) const APPLE_KEXT_OVERRIDE; 860 861 862 /*! 863 * @function isEqualTo 864 * 865 * @abstract 866 * Tests the equality of an OSData object to an OSString. 867 * 868 * @param aString The string object to be compared against the receiver. 869 * 870 * @result 871 * <code>true</code> if the two objects are equivalent, 872 * <code>false</code> otherwise. 873 * 874 * @discussion 875 * This function compares the bytes of the OSData object 876 * against those of the OSString, 877 * accounting for the possibility that an OSData 878 * might explicitly include a nul 879 * character as part of its total length. 880 * Thus, for example, an OSData object containing 881 * either the bytes <'u', 's', 'b', '\0'> 882 * or <'u', 's', 'b'> 883 * will compare as equal to the OSString containing "usb". 884 */ 885 virtual bool isEqualTo(const OSString * aString) const; 886 887 888 /*! 889 * @function serialize 890 * 891 * @abstract 892 * Archives the receiver into the provided 893 * @link //apple_ref/doc/class/IORegistryEntry OSSerialize@/link object. 894 * 895 * @param serializer The OSSerialize object. 896 * 897 * @result 898 * <code>true</code> if serialization succeeds, <code>false</code> if not. 899 */ 900 virtual bool serialize(OSSerialize * serializer) const APPLE_KEXT_OVERRIDE; 901 902 903 /*! 904 * @function appendByte 905 * 906 * @abstract 907 * Appends a single byte value 908 * to the OSData object's internal data buffer 909 * a specified number of times. 910 * 911 * @param byte The byte value to append. 912 * @param numBytes The number of copies of <code>byte</code> to append. 913 * 914 * @result 915 * <code>true</code> if the new data was successfully added, 916 * <code>false</code> if not. 917 * 918 * @discussion 919 * This function immediately resizes the OSData's buffer, if necessary, 920 * to accommodate the new total size. 921 * 922 * An OSData object created "NoCopy" does not allow bytes 923 * to be appended. 924 */ 925 virtual bool appendByte( 926 unsigned char byte, 927 unsigned int numBytes); 928 929 930 void setSerializable(bool serializable); 931 932 #ifdef XNU_KERNEL_PRIVATE 933 /* Available within xnu source only */ 934 public: 935 #else 936 private: 937 #endif 938 virtual void setDeallocFunction(DeallocFunction func); 939 bool isSerializable(void); 940 941 private: 942 enum ValueAcquisition { 943 kValueCopy, 944 kValueNoCopy 945 }; 946 947 #if KERNEL_PRIVATE 948 #if __cplusplus >= 201103L 949 template <typename T, ValueAcquisition acquisition> 950 static constexpr int validateValueType()951 validateValueType() 952 { 953 static_assert(sizeof(T) <= size_t(UINT32_MAX), "value type's size is too large"); 954 static_assert(__is_trivially_copyable(T) && __is_standard_layout(T), 955 "only trivially copyable types can be contained"); 956 static_assert(!__is_pointer(T) || (acquisition == kValueNoCopy), 957 "pointers cannot be contained"); 958 static_assert(KALLOC_TYPE_IS_DATA_ONLY(T) || (acquisition == kValueNoCopy), 959 "only plain data types can be contained (consider using OSValueObject)"); 960 return 0; // C++11 does not support void-returning constexpr functions 961 } 962 #else 963 template <typename T, ValueAcquisition> 964 static void validateValueType()965 validateValueType() 966 { 967 } 968 #endif 969 #endif // KERNEL_PRIVATE 970 971 private: 972 OSMetaClassDeclareReservedUsedX86(OSData, 0); 973 OSMetaClassDeclareReservedUnused(OSData, 1); 974 OSMetaClassDeclareReservedUnused(OSData, 2); 975 OSMetaClassDeclareReservedUnused(OSData, 3); 976 OSMetaClassDeclareReservedUnused(OSData, 4); 977 OSMetaClassDeclareReservedUnused(OSData, 5); 978 OSMetaClassDeclareReservedUnused(OSData, 6); 979 OSMetaClassDeclareReservedUnused(OSData, 7); 980 }; 981 982 #endif /* !_OS_OSDATA_H */ 983