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 class OSData; 39 class OSString; 40 41 typedef OSData* OSDataPtr; 42 typedef OSData const* OSDataConstPtr; 43 44 /*! 45 * @header 46 * 47 * @abstract 48 * This header declares the OSData container class. 49 */ 50 51 52 /*! 53 * @class OSData 54 * 55 * @abstract 56 * OSData wraps an array of bytes in a C++ object 57 * for use in Libkern collections. 58 * 59 * @discussion 60 * OSData represents an array of bytes as a Libkern C++ object. 61 * OSData objects are mutable: 62 * You can add bytes to them and 63 * overwrite portions of the byte array. 64 * 65 * <b>Use Restrictions</b> 66 * 67 * With very few exceptions in the I/O Kit, all Libkern-based C++ 68 * classes, functions, and macros are <b>unsafe</b> 69 * to use in a primary interrupt context. 70 * Consult the I/O Kit documentation related to primary interrupts 71 * for more information. 72 * 73 * OSData provides no concurrency protection; 74 * it's up to the usage context to provide any protection necessary. 75 * Some portions of the I/O Kit, such as 76 * @link //apple_ref/doc/class/IORegistryEntry IORegistryEntry@/link, 77 * handle synchronization via defined member functions for setting 78 * properties. 79 */ 80 class OSData : public OSObject 81 { 82 friend class OSSerialize; 83 84 OSDeclareDefaultStructors(OSData); 85 86 #if APPLE_KEXT_ALIGN_CONTAINERS 87 88 protected: 89 unsigned int length; 90 unsigned int capacity; 91 unsigned int capacityIncrement; 92 void * OS_PTRAUTH_SIGNED_PTR("OSData.data") data; 93 94 #else /* APPLE_KEXT_ALIGN_CONTAINERS */ 95 96 protected: 97 void * OS_PTRAUTH_SIGNED_PTR("OSData.data") data; 98 unsigned int length; 99 unsigned int capacity; 100 unsigned int capacityIncrement; 101 102 #endif /* APPLE_KEXT_ALIGN_CONTAINERS */ 103 104 #ifdef XNU_KERNEL_PRIVATE 105 /* Available within xnu source only */ 106 public: 107 typedef void (*DeallocFunction)(void * ptr, unsigned int length); 108 protected: 109 struct ExpansionData { 110 DeallocFunction deallocFunction; 111 bool disableSerialization; 112 }; 113 #else /* XNU_KERNEL_PRIVATE */ 114 private: 115 typedef void (*DeallocFunction)(void * ptr, unsigned int length); 116 protected: 117 struct ExpansionData; 118 #endif /* XNU_KERNEL_PRIVATE */ 119 120 /* Reserved for future use. (Internal use only) */ 121 ExpansionData * reserved; 122 123 public: 124 125 /*! 126 * @function withCapacity 127 * 128 * @abstract 129 * Creates and initializes an empty instance of OSData. 130 * 131 * @param capacity The initial capacity of the OSData object in bytes. 132 * 133 * @result 134 * An instance of OSData with a reference count of 1; 135 * <code>NULL</code> on failure. 136 * 137 * @discussion 138 * <code>capacity</code> may be zero. 139 * The OSData object will allocate a buffer internally 140 * when necessary, and will grow as needed to accommodate more bytes 141 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 142 * for which a nonzero initial capacity is a hard limit). 143 */ 144 static OSPtr<OSData> withCapacity(unsigned int capacity); 145 146 147 /*! 148 * @function withBytes 149 * 150 * @abstract 151 * Creates and initializes an instance of OSData 152 * with a copy of the provided data buffer. 153 * 154 * @param bytes The buffer of data to copy. 155 * @param numBytes The length of <code>bytes</code>. 156 * 157 * @result 158 * An instance of OSData containing a copy of the provided byte array, 159 * with a reference count of 1; 160 * <code>NULL</code> on failure. 161 * 162 * @discussion 163 * The new OSData object will grow as needed to accommodate more bytes 164 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 165 * for which a nonzero initial capacity is a hard limit). 166 */ 167 static OSPtr<OSData> withBytes( 168 const void * bytes, 169 unsigned int numBytes); 170 171 172 /*! 173 * @function withBytesNoCopy 174 * 175 * @abstract 176 * Creates and initializes an instance of OSData 177 * that shares the provided data buffer. 178 * 179 * @param bytes The buffer of data to represent. 180 * @param numBytes The length of <code>bytes</code>. 181 * 182 * @result 183 * A instance of OSData that shares the provided byte array, 184 * with a reference count of 1; 185 * <code>NULL</code> on failure. 186 * 187 * @discussion 188 * An OSData object created with this function 189 * does not claim ownership 190 * of the data buffer, but shares it with the caller. 191 * When the caller determines that the OSData object has actually been freed, 192 * it can safely dispose of the data buffer. 193 * Conversely, if it frees the shared data buffer, 194 * it must not attempt to use the OSData object and should release it. 195 * 196 * An OSData object created with shared external data cannot append bytes, 197 * but you can get the byte pointer and 198 * modify bytes within the shared buffer. 199 */ 200 static OSPtr<OSData> withBytesNoCopy( 201 void * bytes, 202 unsigned int numBytes); 203 204 205 /*! 206 * @function withData 207 * 208 * @abstract 209 * Creates and initializes an instance of OSData 210 * with contents copied from another OSData object. 211 * 212 * @param inData An OSData object that provides the initial data. 213 * 214 * @result 215 * An instance of OSData containing a copy of the data in <code>inData</code>, 216 * with a reference count of 1; 217 * <code>NULL</code> on failure. 218 * 219 * @discussion 220 * The new OSData object will grow as needed to accommodate more bytes 221 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 222 * for which a nonzero initial capacity is a hard limit). 223 */ 224 static OSPtr<OSData> withData(const OSData * inData); 225 226 227 /*! 228 * @function withData 229 * 230 * @abstract 231 * Creates and initializes an instance of OSData 232 * with contents copied from a range within another OSData object. 233 * 234 * @param inData An OSData object that provides the initial data. 235 * @param start The starting index from which bytes will be copied. 236 * @param numBytes The number of bytes to be copied from <code>start</code>. 237 * 238 * @result 239 * An instance of OSData containing a copy 240 * of the specified data range from <code>inData</code>, 241 * with a reference count of 1; 242 * <code>NULL</code> on failure. 243 * 244 * @discussion 245 * The new OSData object will grow as needed to accommodate more bytes 246 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 247 * for which a nonzero initial capacity is a hard limit). 248 */ 249 static OSPtr<OSData> withData( 250 const OSData * inData, 251 unsigned int start, 252 unsigned int numBytes); 253 254 255 /*! 256 * @function initWithCapacity 257 * 258 * @abstract 259 * Initializes an instance of OSData. 260 * 261 * @param capacity The initial capacity of the OSData object in bytes. 262 * 263 * @result 264 * <code>true</code> on success, <code>false</code> on failure. 265 * 266 * @discussion 267 * Not for general use. Use the static instance creation method 268 * <code>@link 269 * //apple_ref/cpp/clm/OSData/withCapacity/staticOSData*\/(unsignedint) 270 * withCapacity@/link</code> instead. 271 * 272 * <code>capacity</code> may be zero. 273 * The OSData object will allocate a buffer internally 274 * when necessary, and will grow as needed to accommodate more bytes 275 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 276 * for which a nonzero initial capacity is a hard limit). 277 */ 278 virtual bool initWithCapacity(unsigned int capacity); 279 280 281 /*! 282 * @function initWithBytes 283 * 284 * @abstract 285 * Initializes an instance of OSData 286 * with a copy of the provided data buffer. 287 * 288 * @param bytes The buffer of data to copy. 289 * @param numBytes The length of <code>bytes</code>. 290 * 291 * @result 292 * <code>true</code> on success, <code>false</code> on failure. 293 * 294 * @discussion 295 * Not for general use. Use the static instance creation method 296 * <code>@link withBytes withBytes@/link</code> instead. 297 * 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 virtual bool initWithBytes( 303 const void * bytes, 304 unsigned int numBytes); 305 306 307 /*! 308 * @function initWithBytesNoCopy 309 * 310 * @abstract 311 * Initializes an instance of OSData 312 * to share the provided data buffer. 313 * 314 * @param bytes The buffer of data to represent. 315 * @param numBytes The length of <code>bytes</code>. 316 * 317 * @result 318 * <code>true</code> on success, <code>false</code> on failure. 319 * 320 * @discussion 321 * Not for general use. Use the static instance creation method 322 * <code>@link withBytesNoCopy withBytesNoCopy@/link</code> instead. 323 * 324 * An OSData object initialized with this function 325 * does not claim ownership 326 * of the data buffer, but merely shares it with the caller. 327 * 328 * An OSData object created with shared external data cannot append bytes, 329 * but you can get the byte pointer and 330 * modify bytes within the shared buffer. 331 */ 332 virtual bool initWithBytesNoCopy( 333 void * bytes, 334 unsigned int numBytes); 335 336 337 /*! 338 * @function initWithData 339 * 340 * @abstract 341 * Creates and initializes an instance of OSData 342 * with contents copied from another OSData object. 343 * 344 * @param inData An OSData object that provides the initial data. 345 * 346 * @result 347 * <code>true</code> on success, <code>false</code> on failure. 348 * 349 * @discussion 350 * Not for general use. Use the static instance creation method 351 * <code>@link 352 * //apple_ref/cpp/clm/OSData/withData/staticOSData*\/(constOSData*) 353 * withData(OSData *)@/link</code> 354 * instead. 355 * 356 * The new OSData object will grow as needed to accommodate more bytes 357 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 358 * for which a nonzero initial capacity is a hard limit). 359 */ 360 virtual bool initWithData(const OSData * inData); 361 362 363 /*! 364 * @function initWithData 365 * 366 * @abstract 367 * Initializes an instance of OSData 368 * with contents copied from a range within another OSData object. 369 * 370 * @param inData An OSData object that provides the initial data. 371 * @param start The starting index from which bytes will be copied. 372 * @param numBytes The number of bytes to be copied from <code>start</code>. 373 * 374 * @result 375 * Returns <code>true</code> on success, <code>false</code> on failure. 376 * 377 * @discussion 378 * Not for general use. Use the static instance creation method 379 * <code>@link 380 * //apple_ref/cpp/clm/OSData/withData/staticOSData*\/(constOSData*,unsignedint,unsignedint) 381 * withData(OSData *, unsigned int, unsigned int)@/link</code> 382 * instead. 383 * 384 * The new OSData object will grow as needed to accommodate more bytes 385 * (<i>unlike</i> @link //apple_ref/doc/uid/20001498 CFMutableData@/link, 386 * for which a nonzero initial capacity is a hard limit). 387 */ 388 virtual bool initWithData( 389 const OSData * inData, 390 unsigned int start, 391 unsigned int numBytes); 392 393 394 /*! 395 * @function free 396 * 397 * @abstract 398 * Deallocates or releases any resources 399 * used by the OSData instance. 400 * 401 * @discussion 402 * This function should not be called directly; 403 * use 404 * <code>@link 405 * //apple_ref/cpp/instm/OSObject/release/virtualvoid/() 406 * release@/link</code> 407 * instead. 408 */ 409 virtual void free() APPLE_KEXT_OVERRIDE; 410 411 412 /*! 413 * @function getLength 414 * 415 * @abstract 416 * Returns the number of bytes in or referenced by the OSData object. 417 * 418 * @result 419 * The number of bytes in or referenced by the OSData object. 420 */ 421 virtual unsigned int getLength() const; 422 423 424 /*! 425 * @function getCapacity 426 * 427 * @abstract 428 * Returns the total number of bytes the OSData can store without reallocating. 429 * 430 * @result 431 * The total number bytes the OSData can store without reallocating. 432 * 433 * @discussion 434 * OSData objects grow when full to accommodate additional bytes. 435 * See 436 * <code>@link 437 * //apple_ref/cpp/instm/OSData/getCapacityIncrement/virtualunsignedint/() 438 * getCapacityIncrement@/link</code> 439 * and 440 * <code>@link 441 * //apple_ref/cpp/instm/OSData/ensureCapacity/virtualunsignedint/(unsignedint) 442 * ensureCapacity@/link</code>. 443 * 444 * OSData objects created or initialized to use a shared buffer 445 * do not make use of this attribute, and return -1 from this function. 446 */ 447 virtual unsigned int getCapacity() const; 448 449 450 /*! 451 * @function getCapacityIncrement 452 * 453 * @abstract 454 * Returns the storage increment of the OSData object. 455 * 456 * @result 457 * The storage increment of the OSData object. 458 * 459 * @discussion 460 * An OSData object allocates storage for bytes in multiples 461 * of the capacity increment. 462 * 463 * OSData objects created or initialized to use a shared buffer 464 * do not make use of this attribute. 465 */ 466 virtual unsigned int getCapacityIncrement() const; 467 468 469 /*! 470 * @function setCapacityIncrement 471 * 472 * @abstract 473 * Sets the storage increment of the array. 474 * 475 * @result 476 * The original storage increment of the array. 477 * 478 * @discussion 479 * An OSArray allocates storage for objects in multiples 480 * of the capacity increment. 481 * 482 * OSData objects created or initialized to use a shared buffer 483 * do not make use of this attribute. 484 */ 485 virtual unsigned int setCapacityIncrement(unsigned increment); 486 487 488 // xx-review: does not check for capacity == EXTERNAL 489 490 /*! 491 * @function ensureCapacity 492 * 493 * @abstract 494 * Ensures the array has enough space 495 * to store the requested number of bytes. 496 * 497 * @param newCapacity The total number of bytes the OSData object 498 * should be able to store. 499 * 500 * @result 501 * Returns the new capacity of the OSData object, 502 * which may be different from the number requested 503 * (if smaller, reallocation of storage failed). 504 * 505 * @discussion 506 * This function immediately resizes the OSData's buffer, if necessary, 507 * to accommodate at least <code>newCapacity</code> bytes. 508 * If <code>newCapacity</code> is not greater than the current capacity, 509 * or if an allocation error occurs, the original capacity is returned. 510 * 511 * There is no way to reduce the capacity of an OSData. 512 * 513 * An OSData object created "NoCopy" does not allow resizing. 514 */ 515 virtual unsigned int ensureCapacity(unsigned int newCapacity); 516 517 518 /*! 519 * @function appendBytes 520 * 521 * @abstract 522 * Appends a buffer of bytes to the OSData object's internal data buffer. 523 * 524 * @param bytes A pointer to the data to append. 525 * If <code>bytes</code> is <code>NULL</code> 526 * then a zero-filled buffer of length <code>numBytes</code> 527 * is appended. 528 * @param numBytes The number of bytes from <code>bytes</code> to append. 529 * 530 * @result 531 * <code>true</code> if the new data was successfully added, 532 * <code>false</code> on failure. 533 * 534 * @discussion 535 * This function immediately resizes the OSData's buffer, if necessary, 536 * to accommodate the new total size. 537 * 538 * An OSData object created "NoCopy" does not allow bytes 539 * to be appended. 540 */ 541 virtual bool appendBytes( 542 const void * bytes, 543 unsigned int numBytes); 544 545 546 /*! 547 * @function appendBytes 548 * 549 * @abstract 550 * Appends the data contained in another OSData object. 551 * 552 * @param aDataObj The OSData object whose contents will be appended. 553 * 554 * @result 555 * <code>true</code> if the new data was successfully added, 556 * <code>false</code> on failure. 557 * 558 * @discussion 559 * This function immediately resizes the OSData's buffer, if necessary, 560 * to accommodate the new total size. 561 * 562 * An OSData object created "NoCopy" does not allow bytes 563 * to be appended. 564 */ 565 virtual bool appendBytes(const OSData * aDataObj); 566 567 568 /*! 569 * @function getBytesNoCopy 570 * 571 * @abstract 572 * Returns a pointer to the OSData object's internal data buffer. 573 * 574 * @result 575 * A pointer to the OSData object's internal data buffer. 576 * 577 * @discussion 578 * You can modify the existing contents of an OSData object 579 * via this function. 580 * It works with OSData objects that have their own data buffers 581 * as well as with OSData objects that have shared buffers. 582 * 583 * If you append bytes or characters to an OSData object, 584 * it may have to reallocate its internal storage, 585 * rendering invalid an extrated pointer to that storage. 586 */ 587 virtual const void * getBytesNoCopy() const; 588 589 590 /*! 591 * @function getBytesNoCopy 592 * 593 * @abstract 594 * Returns a pointer into the OSData object's internal data buffer 595 * with a given offset and length. 596 * 597 * @param start The offset from the base of the internal data buffer. 598 * @param numBytes The length of the window. 599 * 600 * @result 601 * A pointer to the bytes in the specified range 602 * within the OSData object, 603 * or 0 if that range does not lie completely 604 * within the object's buffer. 605 * 606 * @discussion 607 * You can modify the existing contents of an OSData object 608 * via this function. 609 * It works with OSData objects that have their own data buffers 610 * as well as with OSData objects that have shared buffers. 611 * 612 * If you append bytes or characters to an OSData object, 613 * it may have to reallocate its internal storage, 614 * rendering invalid an extrated pointer to that storage. 615 */ 616 virtual const void * getBytesNoCopy( 617 unsigned int start, 618 unsigned int numBytes) const; 619 620 621 /*! 622 * @function isEqualTo 623 * 624 * @abstract 625 * Tests the equality of two OSData objects. 626 * 627 * @param aDataObj The OSData object being compared against the receiver. 628 * 629 * @result 630 * <code>true</code> if the two OSData objects are equivalent, 631 * <code>false</code> otherwise. 632 * 633 * @discussion 634 * Two OSData objects are considered equal 635 * if they have same length and if their 636 * byte buffers hold the same contents. 637 */ 638 virtual bool isEqualTo(const OSData * aDataObj) const; 639 640 641 /*! 642 * @function isEqualTo 643 * 644 * @abstract 645 * Tests the equality of an OSData object's contents 646 * to a C array of bytes. 647 * 648 * @param bytes A pointer to the bytes to compare. 649 * @param numBytes The number of bytes to compare. 650 * 651 * @result 652 * <code>true</code> if the data buffers are equal 653 * over the given length, 654 * <code>false</code> otherwise. 655 */ 656 virtual bool isEqualTo( 657 const void * bytes, 658 unsigned int numBytes) const; 659 660 661 /*! 662 * @function isEqualTo 663 * 664 * @abstract 665 * Tests the equality of an OSData object to an arbitrary object. 666 * 667 * @param anObject The object to be compared against the receiver. 668 * 669 * @result 670 * <code>true</code> if the two objects are equivalent, 671 * <code>false</code> otherwise. 672 * 673 * @discussion 674 * An OSData is considered equal to another object 675 * if that object is derived from OSData 676 * and contains the equivalent bytes of the same length. 677 */ 678 virtual bool isEqualTo(const OSMetaClassBase * anObject) const APPLE_KEXT_OVERRIDE; 679 680 681 /*! 682 * @function isEqualTo 683 * 684 * @abstract 685 * Tests the equality of an OSData object to an OSString. 686 * 687 * @param aString The string object to be compared against the receiver. 688 * 689 * @result 690 * <code>true</code> if the two objects are equivalent, 691 * <code>false</code> otherwise. 692 * 693 * @discussion 694 * This function compares the bytes of the OSData object 695 * against those of the OSString, 696 * accounting for the possibility that an OSData 697 * might explicitly include a nul 698 * character as part of its total length. 699 * Thus, for example, an OSData object containing 700 * either the bytes <'u', 's', 'b', '\0'> 701 * or <'u', 's', 'b'> 702 * will compare as equal to the OSString containing "usb". 703 */ 704 virtual bool isEqualTo(const OSString * aString) const; 705 706 707 /*! 708 * @function serialize 709 * 710 * @abstract 711 * Archives the receiver into the provided 712 * @link //apple_ref/doc/class/IORegistryEntry OSSerialize@/link object. 713 * 714 * @param serializer The OSSerialize object. 715 * 716 * @result 717 * <code>true</code> if serialization succeeds, <code>false</code> if not. 718 */ 719 virtual bool serialize(OSSerialize * serializer) const APPLE_KEXT_OVERRIDE; 720 721 722 /*! 723 * @function appendByte 724 * 725 * @abstract 726 * Appends a single byte value 727 * to the OSData object's internal data buffer 728 * a specified number of times. 729 * 730 * @param byte The byte value to append. 731 * @param numBytes The number of copies of <code>byte</code> to append. 732 * 733 * @result 734 * <code>true</code> if the new data was successfully added, 735 * <code>false</code> if not. 736 * 737 * @discussion 738 * This function immediately resizes the OSData's buffer, if necessary, 739 * to accommodate the new total size. 740 * 741 * An OSData object created "NoCopy" does not allow bytes 742 * to be appended. 743 */ 744 virtual bool appendByte( 745 unsigned char byte, 746 unsigned int numBytes); 747 748 749 void setSerializable(bool serializable); 750 751 #ifdef XNU_KERNEL_PRIVATE 752 /* Available within xnu source only */ 753 public: 754 #else 755 private: 756 #endif 757 virtual void setDeallocFunction(DeallocFunction func); 758 bool isSerializable(void); 759 760 private: 761 OSMetaClassDeclareReservedUsedX86(OSData, 0); 762 OSMetaClassDeclareReservedUnused(OSData, 1); 763 OSMetaClassDeclareReservedUnused(OSData, 2); 764 OSMetaClassDeclareReservedUnused(OSData, 3); 765 OSMetaClassDeclareReservedUnused(OSData, 4); 766 OSMetaClassDeclareReservedUnused(OSData, 5); 767 OSMetaClassDeclareReservedUnused(OSData, 6); 768 OSMetaClassDeclareReservedUnused(OSData, 7); 769 }; 770 771 #endif /* !_OS_OSDATA_H */ 772