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