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 __xnu_data_size); 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 __xnu_data_size); 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 __xnu_data_size); 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 __xnu_data_size); 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 #ifdef XNU_KERNEL_PRIVATE 668 /*! 669 * @function clipForCopyout 670 * 671 * @abstract 672 * Clips the backing store of an atomic OSData in order 673 * to make it usable with copyoutkdata(). 674 */ 675 bool clipForCopyout(); 676 #endif /* XNU_KERNEL_PRIVATE */ 677 678 /*! 679 * @function appendBytes 680 * 681 * @abstract 682 * Appends a buffer of bytes to the OSData object's internal data buffer. 683 * 684 * @param bytes A pointer to the data to append. 685 * If <code>bytes</code> is <code>NULL</code> 686 * then a zero-filled buffer of length <code>numBytes</code> 687 * is appended. 688 * @param numBytes The number of bytes from <code>bytes</code> to append. 689 * 690 * @result 691 * <code>true</code> if the new data was successfully added, 692 * <code>false</code> on failure. 693 * 694 * @discussion 695 * This function immediately resizes the OSData's buffer, if necessary, 696 * to accommodate the new total size. 697 * 698 * An OSData object created "NoCopy" does not allow bytes 699 * to be appended. 700 */ 701 virtual bool appendBytes( 702 const void * bytes, 703 unsigned int numBytes __xnu_data_size); 704 705 706 #if KERNEL_PRIVATE 707 /*! 708 * @function appendValue 709 * 710 * @abstract 711 * Appends a copy of the provided value of a concrete type to the 712 * OSData object's internal data buffer. 713 * 714 * @param value The instance of a value to copy. 715 * 716 * @result 717 * <code>true</code> if the new data was successfully added, 718 * <code>false</code> on failure. 719 * 720 * @discussion 721 * This function immediately resizes the OSData's buffer, if necessary, 722 * to accommodate the new total size. 723 * 724 * An OSData object created "NoCopy" does not allow bytes 725 * to be appended. 726 */ 727 template <typename T> 728 bool appendValue(const T & value)729 appendValue(const T& value) 730 { 731 validateValueType<T, kValueCopy>(); 732 return appendBytes(&value, sizeof(T)); 733 } 734 #endif // KERNEL_PRIVATE 735 736 737 /*! 738 * @function appendBytes 739 * 740 * @abstract 741 * Appends the data contained in another OSData object. 742 * 743 * @param aDataObj The OSData object whose contents will be appended. 744 * 745 * @result 746 * <code>true</code> if the new data was successfully added, 747 * <code>false</code> on failure. 748 * 749 * @discussion 750 * This function immediately resizes the OSData's buffer, if necessary, 751 * to accommodate the new total size. 752 * 753 * An OSData object created "NoCopy" does not allow bytes 754 * to be appended. 755 */ 756 virtual bool appendBytes(const OSData * aDataObj); 757 758 759 /*! 760 * @function getBytesNoCopy 761 * 762 * @abstract 763 * Returns a pointer to the OSData object's internal data buffer. 764 * 765 * @result 766 * A pointer to the OSData object's internal data buffer. 767 * 768 * @discussion 769 * You can modify the existing contents of an OSData object 770 * via this function. 771 * It works with OSData objects that have their own data buffers 772 * as well as with OSData objects that have shared buffers. 773 * 774 * If you append bytes or characters to an OSData object, 775 * it may have to reallocate its internal storage, 776 * rendering invalid an extrated pointer to that storage. 777 */ 778 __xnu_returns_data_pointer 779 virtual const void * getBytesNoCopy() const; 780 781 782 /*! 783 * @function getBytesNoCopy 784 * 785 * @abstract 786 * Returns a pointer into the OSData object's internal data buffer 787 * with a given offset and length. 788 * 789 * @param start The offset from the base of the internal data buffer. 790 * @param numBytes The length of the window. 791 * 792 * @result 793 * A pointer to the bytes in the specified range 794 * within the OSData object, 795 * or 0 if that range does not lie completely 796 * within the object's buffer. 797 * 798 * @discussion 799 * You can modify the existing contents of an OSData object 800 * via this function. 801 * It works with OSData objects that have their own data buffers 802 * as well as with OSData objects that have shared buffers. 803 * 804 * If you append bytes or characters to an OSData object, 805 * it may have to reallocate its internal storage, 806 * rendering invalid an extrated pointer to that storage. 807 */ 808 __xnu_returns_data_pointer 809 virtual const void * getBytesNoCopy( 810 unsigned int start, 811 unsigned int numBytes) const; 812 813 814 /*! 815 * @function isEqualTo 816 * 817 * @abstract 818 * Tests the equality of two OSData objects. 819 * 820 * @param aDataObj The OSData object being compared against the receiver. 821 * 822 * @result 823 * <code>true</code> if the two OSData objects are equivalent, 824 * <code>false</code> otherwise. 825 * 826 * @discussion 827 * Two OSData objects are considered equal 828 * if they have same length and if their 829 * byte buffers hold the same contents. 830 */ 831 virtual bool isEqualTo(const OSData * aDataObj) const; 832 833 834 /*! 835 * @function isEqualTo 836 * 837 * @abstract 838 * Tests the equality of an OSData object's contents 839 * to a C array of bytes. 840 * 841 * @param bytes A pointer to the bytes to compare. 842 * @param numBytes The number of bytes to compare. 843 * 844 * @result 845 * <code>true</code> if the data buffers are equal 846 * over the given length, 847 * <code>false</code> otherwise. 848 */ 849 virtual bool isEqualTo( 850 const void * bytes, 851 unsigned int numBytes) const; 852 853 854 /*! 855 * @function isEqualTo 856 * 857 * @abstract 858 * Tests the equality of an OSData object to an arbitrary object. 859 * 860 * @param anObject The object to be compared against the receiver. 861 * 862 * @result 863 * <code>true</code> if the two objects are equivalent, 864 * <code>false</code> otherwise. 865 * 866 * @discussion 867 * An OSData is considered equal to another object 868 * if that object is derived from OSData 869 * and contains the equivalent bytes of the same length. 870 */ 871 virtual bool isEqualTo(const OSMetaClassBase * anObject) const APPLE_KEXT_OVERRIDE; 872 873 874 /*! 875 * @function isEqualTo 876 * 877 * @abstract 878 * Tests the equality of an OSData object to an OSString. 879 * 880 * @param aString The string object to be compared against the receiver. 881 * 882 * @result 883 * <code>true</code> if the two objects are equivalent, 884 * <code>false</code> otherwise. 885 * 886 * @discussion 887 * This function compares the bytes of the OSData object 888 * against those of the OSString, 889 * accounting for the possibility that an OSData 890 * might explicitly include a nul 891 * character as part of its total length. 892 * Thus, for example, an OSData object containing 893 * either the bytes <'u', 's', 'b', '\0'> 894 * or <'u', 's', 'b'> 895 * will compare as equal to the OSString containing "usb". 896 */ 897 virtual bool isEqualTo(const OSString * aString) const; 898 899 900 /*! 901 * @function serialize 902 * 903 * @abstract 904 * Archives the receiver into the provided 905 * @link //apple_ref/doc/class/IORegistryEntry OSSerialize@/link object. 906 * 907 * @param serializer The OSSerialize object. 908 * 909 * @result 910 * <code>true</code> if serialization succeeds, <code>false</code> if not. 911 */ 912 virtual bool serialize(OSSerialize * serializer) const APPLE_KEXT_OVERRIDE; 913 914 915 /*! 916 * @function appendByte 917 * 918 * @abstract 919 * Appends a single byte value 920 * to the OSData object's internal data buffer 921 * a specified number of times. 922 * 923 * @param byte The byte value to append. 924 * @param numBytes The number of copies of <code>byte</code> to append. 925 * 926 * @result 927 * <code>true</code> if the new data was successfully added, 928 * <code>false</code> if not. 929 * 930 * @discussion 931 * This function immediately resizes the OSData's buffer, if necessary, 932 * to accommodate the new total size. 933 * 934 * An OSData object created "NoCopy" does not allow bytes 935 * to be appended. 936 */ 937 virtual bool appendByte( 938 unsigned char byte, 939 unsigned int numBytes); 940 941 942 void setSerializable(bool serializable); 943 944 #ifdef XNU_KERNEL_PRIVATE 945 /* Available within xnu source only */ 946 public: 947 #else 948 private: 949 #endif 950 virtual void setDeallocFunction(DeallocFunction func); 951 bool isSerializable(void); 952 953 private: 954 enum ValueAcquisition { 955 kValueCopy, 956 kValueNoCopy 957 }; 958 959 #if KERNEL_PRIVATE 960 #if __cplusplus >= 201103L 961 template <typename T, ValueAcquisition acquisition> 962 static constexpr int validateValueType()963 validateValueType() 964 { 965 static_assert(sizeof(T) <= size_t(UINT32_MAX), "value type's size is too large"); 966 static_assert(__is_trivially_copyable(T) && __is_standard_layout(T), 967 "only trivially copyable types can be contained"); 968 static_assert(!__is_pointer(T) || (acquisition == kValueNoCopy), 969 "pointers cannot be contained"); 970 static_assert(KALLOC_TYPE_IS_DATA_ONLY(T) || (acquisition == kValueNoCopy), 971 "only plain data types can be contained (consider using OSValueObject)"); 972 return 0; // C++11 does not support void-returning constexpr functions 973 } 974 #else 975 template <typename T, ValueAcquisition> 976 static void validateValueType()977 validateValueType() 978 { 979 } 980 #endif 981 #endif // KERNEL_PRIVATE 982 983 private: 984 OSMetaClassDeclareReservedUsedX86(OSData, 0); 985 OSMetaClassDeclareReservedUnused(OSData, 1); 986 OSMetaClassDeclareReservedUnused(OSData, 2); 987 OSMetaClassDeclareReservedUnused(OSData, 3); 988 OSMetaClassDeclareReservedUnused(OSData, 4); 989 OSMetaClassDeclareReservedUnused(OSData, 5); 990 OSMetaClassDeclareReservedUnused(OSData, 6); 991 OSMetaClassDeclareReservedUnused(OSData, 7); 992 }; 993 994 #endif /* !_OS_OSDATA_H */ 995