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
42class OSData;
43class OSString;
44
45typedef OSData* OSDataPtr;
46typedef 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 */
84class OSData : public OSObject
85{
86 friend class OSSerialize;
87
88 OSDeclareDefaultStructors(OSData);
89
90#if APPLE_KEXT_ALIGN_CONTAINERS
91
92protected:
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
100protected:
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 */
110public:
111 typedef void (*DeallocFunction)(void * ptr, unsigned int length);
112protected:
113 struct ExpansionData {
114 DeallocFunction deallocFunction;
115 bool disableSerialization;
116 };
117#else /* XNU_KERNEL_PRIVATE */
118private:
119 typedef void (*DeallocFunction)(void * ptr, unsigned int length);
120protected:
121 struct ExpansionData;
122#endif /* XNU_KERNEL_PRIVATE */
123
124/* Reserved for future use. (Internal use only) */
125 ExpansionData * reserved;
126
127public:
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>
198 withValue(const T& value)
199 {
200 validateValueType<T, kValueCopy>();
201 return withBytes(bytes: &value, numBytes: 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>
268 withValueNoCopy(T& value)
269 {
270 validateValueType<T, kValueNoCopy>();
271 return withBytesNoCopy(bytes: &value, numBytes: 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
408 initWithValue(const T& value)
409 {
410 validateValueType<T, kValueCopy>();
411 return initWithBytes(bytes: &value, numBytes: 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
472 initWithValueNoCopy(T& value)
473 {
474 validateValueType<T, kValueNoCopy>();
475 return initWithBytesNoCopy(bytes: &value, numBytes: 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
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 */
944public:
945#else
946private:
947#endif
948 virtual void setDeallocFunction(DeallocFunction func);
949 bool isSerializable(void);
950
951private:
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
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
975 validateValueType()
976 {
977 }
978#endif
979#endif // KERNEL_PRIVATE
980
981private:
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