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 #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); 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 virtual const void * getBytesNoCopy() const; 779 780 781 /*! 782 * @function getBytesNoCopy 783 * 784 * @abstract 785 * Returns a pointer into the OSData object's internal data buffer 786 * with a given offset and length. 787 * 788 * @param start The offset from the base of the internal data buffer. 789 * @param numBytes The length of the window. 790 * 791 * @result 792 * A pointer to the bytes in the specified range 793 * within the OSData object, 794 * or 0 if that range does not lie completely 795 * within the object's buffer. 796 * 797 * @discussion 798 * You can modify the existing contents of an OSData object 799 * via this function. 800 * It works with OSData objects that have their own data buffers 801 * as well as with OSData objects that have shared buffers. 802 * 803 * If you append bytes or characters to an OSData object, 804 * it may have to reallocate its internal storage, 805 * rendering invalid an extrated pointer to that storage. 806 */ 807 virtual const void * getBytesNoCopy( 808 unsigned int start, 809 unsigned int numBytes) const; 810 811 812 /*! 813 * @function isEqualTo 814 * 815 * @abstract 816 * Tests the equality of two OSData objects. 817 * 818 * @param aDataObj The OSData object being compared against the receiver. 819 * 820 * @result 821 * <code>true</code> if the two OSData objects are equivalent, 822 * <code>false</code> otherwise. 823 * 824 * @discussion 825 * Two OSData objects are considered equal 826 * if they have same length and if their 827 * byte buffers hold the same contents. 828 */ 829 virtual bool isEqualTo(const OSData * aDataObj) const; 830 831 832 /*! 833 * @function isEqualTo 834 * 835 * @abstract 836 * Tests the equality of an OSData object's contents 837 * to a C array of bytes. 838 * 839 * @param bytes A pointer to the bytes to compare. 840 * @param numBytes The number of bytes to compare. 841 * 842 * @result 843 * <code>true</code> if the data buffers are equal 844 * over the given length, 845 * <code>false</code> otherwise. 846 */ 847 virtual bool isEqualTo( 848 const void * bytes, 849 unsigned int numBytes) const; 850 851 852 /*! 853 * @function isEqualTo 854 * 855 * @abstract 856 * Tests the equality of an OSData object to an arbitrary object. 857 * 858 * @param anObject The object to be compared against the receiver. 859 * 860 * @result 861 * <code>true</code> if the two objects are equivalent, 862 * <code>false</code> otherwise. 863 * 864 * @discussion 865 * An OSData is considered equal to another object 866 * if that object is derived from OSData 867 * and contains the equivalent bytes of the same length. 868 */ 869 virtual bool isEqualTo(const OSMetaClassBase * anObject) const APPLE_KEXT_OVERRIDE; 870 871 872 /*! 873 * @function isEqualTo 874 * 875 * @abstract 876 * Tests the equality of an OSData object to an OSString. 877 * 878 * @param aString The string object to be compared against the receiver. 879 * 880 * @result 881 * <code>true</code> if the two objects are equivalent, 882 * <code>false</code> otherwise. 883 * 884 * @discussion 885 * This function compares the bytes of the OSData object 886 * against those of the OSString, 887 * accounting for the possibility that an OSData 888 * might explicitly include a nul 889 * character as part of its total length. 890 * Thus, for example, an OSData object containing 891 * either the bytes <'u', 's', 'b', '\0'> 892 * or <'u', 's', 'b'> 893 * will compare as equal to the OSString containing "usb". 894 */ 895 virtual bool isEqualTo(const OSString * aString) const; 896 897 898 /*! 899 * @function serialize 900 * 901 * @abstract 902 * Archives the receiver into the provided 903 * @link //apple_ref/doc/class/IORegistryEntry OSSerialize@/link object. 904 * 905 * @param serializer The OSSerialize object. 906 * 907 * @result 908 * <code>true</code> if serialization succeeds, <code>false</code> if not. 909 */ 910 virtual bool serialize(OSSerialize * serializer) const APPLE_KEXT_OVERRIDE; 911 912 913 /*! 914 * @function appendByte 915 * 916 * @abstract 917 * Appends a single byte value 918 * to the OSData object's internal data buffer 919 * a specified number of times. 920 * 921 * @param byte The byte value to append. 922 * @param numBytes The number of copies of <code>byte</code> to append. 923 * 924 * @result 925 * <code>true</code> if the new data was successfully added, 926 * <code>false</code> if not. 927 * 928 * @discussion 929 * This function immediately resizes the OSData's buffer, if necessary, 930 * to accommodate the new total size. 931 * 932 * An OSData object created "NoCopy" does not allow bytes 933 * to be appended. 934 */ 935 virtual bool appendByte( 936 unsigned char byte, 937 unsigned int numBytes); 938 939 940 void setSerializable(bool serializable); 941 942 #ifdef XNU_KERNEL_PRIVATE 943 /* Available within xnu source only */ 944 public: 945 #else 946 private: 947 #endif 948 virtual void setDeallocFunction(DeallocFunction func); 949 bool isSerializable(void); 950 951 private: 952 enum ValueAcquisition { 953 kValueCopy, 954 kValueNoCopy 955 }; 956 957 #if KERNEL_PRIVATE 958 #if __cplusplus >= 201103L 959 template <typename T, ValueAcquisition acquisition> 960 static constexpr int validateValueType()961 validateValueType() 962 { 963 static_assert(sizeof(T) <= size_t(UINT32_MAX), "value type's size is too large"); 964 static_assert(__is_trivially_copyable(T) && __is_standard_layout(T), 965 "only trivially copyable types can be contained"); 966 static_assert(!__is_pointer(T) || (acquisition == kValueNoCopy), 967 "pointers cannot be contained"); 968 static_assert(KALLOC_TYPE_IS_DATA_ONLY(T) || (acquisition == kValueNoCopy), 969 "only plain data types can be contained (consider using OSValueObject)"); 970 return 0; // C++11 does not support void-returning constexpr functions 971 } 972 #else 973 template <typename T, ValueAcquisition> 974 static void validateValueType()975 validateValueType() 976 { 977 } 978 #endif 979 #endif // KERNEL_PRIVATE 980 981 private: 982 OSMetaClassDeclareReservedUsedX86(OSData, 0); 983 OSMetaClassDeclareReservedUnused(OSData, 1); 984 OSMetaClassDeclareReservedUnused(OSData, 2); 985 OSMetaClassDeclareReservedUnused(OSData, 3); 986 OSMetaClassDeclareReservedUnused(OSData, 4); 987 OSMetaClassDeclareReservedUnused(OSData, 5); 988 OSMetaClassDeclareReservedUnused(OSData, 6); 989 OSMetaClassDeclareReservedUnused(OSData, 7); 990 }; 991 992 #endif /* !_OS_OSDATA_H */ 993