xref: /xnu-11215/libkern/libkern/c++/OSData.h (revision 8d741a5d)
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