I am confused to convert byte array to short vice-versa and also int to byte array vice-versa in Objective-C.
I have seen in Java like following
public static short byteArrayToShort(byte[] b) {
if (b.length > 1) {
return (ByteBuffer.wrap(b)).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get();
} else {
return b[0];
}
}
/**
* Short to byte array.
*
* @param value the value
* @return the byte[]
*/
public static byte[] shortToByteArray(short value) {
return ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(value).array();
}
/**
* Int to byte array.
*
* @param value the value
* @return the byte[]
*/
public static byte[] intToByteArray(int value) {
return ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(value).array();
}
/**
* Convert the byte array to an short starting from the given offset.
*
* @param b The byte array
* @return The integer
*/
public static int byteArrayToInt(byte[] b) {
if (b.length > 1) {
return (ByteBuffer.wrap(b)).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().get();
} else {
return b[0];
}
}
In Objective-C I have tried like following:
//Byte to Short array
- (uint16_t*) byte2short:(uint8_t *)bytes size:(int)size{
uint16_t*shorts = (uint16_t*)malloc(size/2);
for (int i=0; i < size/2; i++){
shorts[i] = (bytes[i*2+1] << 8) | bytes[i*2];
}
return shorts;
}
//Short to Byte array
- (uint8_t *) short2byte:(uint16_t*)shorts size:(int)size{
uint8_t *bytes = (uint8_t *)malloc(size*2);
for (int i = 0; i < size; i++)
{
bytes[i * 2] = (uint16_t) (shorts[i] & 0x00FF);
bytes[(i * 2) + 1] = (uint16_t) (shorts[i] >> 8);
shorts[i] = 0;
}
return bytes;
}
I have tried like this and also I dont have idea in conversion of int to Byte array in Objective-c.
Please suggest me
The problem with your code is that you are assuming that malloc
somehow "knows" about the size of whatever is being allocated, in the same way that Java's array new
knows the difference between allocating 5 int
s and 5 short
s. Well, malloc
does not. Unless you tell it otherwise, it allocates the required number of bytes. That's why when you do this
uint16_t*shorts = (uint16_t*)malloc(size/2);
and then write size/2
uint16_t
into it, you overrun the buffer.
A proper way of allocating an array of primitives in C (and in Objective-C, which is a superset of C) is as follows:
size_t count = (size+1)/2; // Do not assume that size is even
uint16_t *shorts = malloc(sizeof(uint16_t)*count);
Now you have enough memory to fit all your shorts.
In your other function you should use
uint8_t *bytes = malloc(sizeof(uint8_t)*size*2);
Note that the cast is unnecessary in both cases. The type of bytes
variable matters, though, because that's what determines the actual address written to in bytes[i * 2]
and bytes[(i * 2)+1]
expressions:
for (int i = 0; i < size; i++)
{
bytes[i * 2] = (uint8_t) (shorts[i] & 0xFF);
bytes[(i * 2) + 1] = (uint8_t) (shorts[i] >> 8);
shorts[i] = 0;
}