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