Working With Binary Data
This article contains code examples of common tasks that apply to immutable and mutable data objects, CFData
and CFMutableData
objects.
Creating Data Objects From Raw Bytes
Generally, you create a data object from raw bytes using the CFDataCreate
and CFDataCreateMutable
functions for immutable and mutable data objects respectively. These functions make a copy of the bytes you pass as an argument. The copied bytes are owned by the data object and are freed when the data object is released. It is your responsibility to free the original bytes.
In contrast, the bytes are not copied when you create a data object using CFDataCreateWithBytesNoCopy
with a deallocator argument which is not kCFAllocatorNull
. Instead, the data object takes ownership of the bytes passed in as an argument and frees them when the object is released. For this reason, the bytes you pass to this function must have been allocated using the allocator you provide as the deallocator argument.
If you prefer that the bytes not be copied or freed when the object is released, you can create a no-copy, no-free CFData
object using the CFDataCreateWithBytesNoCopy
function and passing kCFAllocatorNull
as the deallocator argument, as in:
CFDataRef dictData = CFDataCreateWithBytesNoCopy( |
NULL, bytes, length, kCFAllocatorNull); |
Accessing and Comparing Bytes
The three basic CFData
functions are CFDataGetBytesPtr
, CFDataGetBytes
, and CFDataGetLength
. The CFDataGetBytesPtr
function returns a pointer to the bytes contained in the data object. The CFDataGetBytes
function puts the bytes in a supplied buffer. The CFDataGetLength
function returns the number of bytes contained in the data object.
For example, the following code fragment initializes a data object, myData
, with the string myString
. It then uses CFDataGetBytesPtr
to return the bytes as a pointer.
const UInt8 *myString = "Test string."; |
CFDataRef myData = |
CFDataCreateWithBytesNoCopy(NULL, myString, strlen(myString), kCFAllocatorNull); |
const UInt8 *ptr = CFDataGetBytePtr(myData); |
To create a data object that contains a subset of the bytes in another data object, pass a value for the range when calling the CFDataGetBytes
function. For example, the following code fragment initializes a data object, data2
, to contain a subrange of data1
:
unsigned char aBuffer[20]; |
const UInt8 *strPtr = "ABCDEFG"; |
CFDataRef data1 = |
CFDataCreateWithBytesNoCopy(NULL, strPtr, strlen(strPtr), kCFAllocatorNull); |
CFDataGetBytes(data1, CFRangeMake(2, 4), aBuffer); |
CFDataRef data2 = CFDataCreate(NULL, aBuffer, 20); |
To determine whether two data objects are equal, use the CFEqual
function, which performs a byte-for-byte comparison.
Copying Data Objects
Data objects make it convenient to convert between efficient, read-only data objects and mutable data objects. You use the CFDataCreateCopy
and CFDataCreateMutableCopy
functions to get an immutable and mutable copy of an existing data object respectively.
Copyright © 2006 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2006-01-10