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