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