Reputation: 16803
I want to convert NSData
to a byte array, so I write the following code:
NSData *data = [NSData dataWithContentsOfFile:filePath];
int len = [data length];
Byte byteData[len];
byteData = [data bytes];
But the last line of code pops up an error saying "incompatible types in assignment". What is the correct way to convert the data to byte array then?
Upvotes: 51
Views: 128336
Reputation: 3077
Here's what I believe is the Swift equivalent:
if let data = NSData(contentsOfFile: filePath) {
let length = data.length
let byteData = malloc(length)
memcmp(byteData, data.bytes, length)
}
Upvotes: -1
Reputation: 14968
You can't declare an array using a variable so Byte byteData[len];
won't work. If you want to copy the data from a pointer, you also need to memcpy (which will go through the data pointed to by the pointer and copy each byte up to a specified length).
Try:
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSUInteger len = [data length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [data bytes], len);
This code will dynamically allocate the array to the correct size (you must free(byteData)
when you're done) and copy the bytes into it.
You could also use getBytes:length:
as indicated by others if you want to use a fixed length array. This avoids malloc/free but is less extensible and more prone to buffer overflow issues so I rarely ever use it.
Upvotes: 63
Reputation: 3559
Already answered, but to generalize to help other readers:
//Here: NSData * fileData;
uint8_t * bytePtr = (uint8_t * )[fileData bytes];
// Here, For getting individual bytes from fileData, uint8_t is used.
// You may choose any other data type per your need, eg. uint16, int32, char, uchar, ... .
// Make sure, fileData has atleast number of bytes that a single byte chunk would need. eg. for int32, fileData length must be > 4 bytes. Makes sense ?
// Now, if you want to access whole data (fileData) as an array of uint8_t
NSInteger totalData = [fileData length] / sizeof(uint8_t);
for (int i = 0 ; i < totalData; i ++)
{
NSLog(@"data byte chunk : %x", bytePtr[i]);
}
Upvotes: 16
Reputation: 5827
You could also just use the bytes where they are, casting them to the type you need.
unsigned char *bytePtr = (unsigned char *)[data bytes];
Upvotes: 43
Reputation: 75077
That's because the return type for [data bytes] is a void* c-style array, not a Uint8 (which is what Byte is a typedef for).
The error is because you are trying to set an allocated array when the return is a pointer type, what you are looking for is the getBytes:length: call which would look like:
[data getBytes:&byteData length:len];
Which fills the array you have allocated with data from the NSData object.
Upvotes: 2
Reputation: 44371
The signature of -[NSData bytes]
is - (const void *)bytes
. You can't assign a pointer to an array on the stack. If you want to copy the buffer managed by the NSData
object into the array, use -[NSData getBytes:]
. If you want to do it without copying, then don't allocate an array; just declare a pointer variable and let NSData
manage the memory for you.
Upvotes: 10