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> |
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 */ |
944 | public: |
945 | #else |
946 | private: |
947 | #endif |
948 | virtual void setDeallocFunction(DeallocFunction func); |
949 | bool isSerializable(void); |
950 | |
951 | private: |
952 | enum ValueAcquisition { |
953 | kValueCopy, |
954 | kValueNoCopy |
955 | }; |
956 | |
957 | #if KERNEL_PRIVATE |
958 | #if __cplusplus >= 201103L |
959 | template <typename T, ValueAcquisition acquisition> |
960 | static constexpr int |
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 | |
981 | private: |
982 | OSMetaClassDeclareReservedUsedX86(OSData, 0); |
983 | OSMetaClassDeclareReservedUnused(OSData, 1); |
984 | OSMetaClassDeclareReservedUnused(OSData, 2); |
985 | OSMetaClassDeclareReservedUnused(OSData, 3); |
986 | OSMetaClassDeclareReservedUnused(OSData, 4); |
987 | OSMetaClassDeclareReservedUnused(OSData, 5); |
988 | OSMetaClassDeclareReservedUnused(OSData, 6); |
989 | OSMetaClassDeclareReservedUnused(OSData, 7); |
990 | }; |
991 | |
992 | #endif /* !_OS_OSDATA_H */ |
993 | |