0

I stored the data bytes in an Array. Now, in the program I used getBytes:range:NSmakeRange(position, length). When I printed my received bytes I think their position got swapped and my answer was 0x0292 instead of 0x9202 (check my program below).

Now, I am confused on which one is the correct answer. Is it really necessary for me to always swap the bytes that I received. Please explain to me this concept so that I can understand in a clear way.

Here is my code!! Thank you.

const Byte dataBytesArray[] = {
    0x92, 0x02, 0x13, 0x14 //in Hex
};

NSData *myDataArray = [[NSData alloc]initWithBytes:dataBytesArray length:4];
uint16_t ef;
[myDataArray getBytes:&ef range:NSMakeRange(0, 2)];

NSLog(@"dataByteArray is %@ ",[NSNumber numberWithUnsignedInteger:ef]);//the answer I got is 658 in decimal format which is 0x0292

uint16_t swapping = CFSwapInt16BigToHost(ef); //swapping the bytes
NSLog(@"swap is %@ ",[NSNumber numberWithUnsignedInteger:swapping]); //after swapping I got 37378 which is 0x9202
Raj0689
  • 73
  • 1
  • 1
  • 9

2 Answers2

1

Whether you make use of functions like CFSwapInt16BigToHost depends on what you are dealing with on both ends.

If your "host" (the machine this code is running on) could vary, then using one of the many CFSwap...ToHost functions is a really good idea. For example, Intel Macs and ARM iOS devices use different byte ordering. PowerPC Macs and Intel Macs use different byte ordering (I think that is true). To make your code safe to run in these different environments, it is wise to use the proper "toHost" function.

Even if your code is currently meant to only run on one type of device, it is still wise to use these to avoid any confusion in the proper order for the host.

So the key decision is to know what byte ordering is used in the received data. If you know for a fact that the received data is in big-endian byte order then use the proper "BigToHost" functions. If you know for a fact that the received data is in little-endian bye order then use the proper "LittleToHost" functions. If you don't know then you must find out.

Another thing to consider is sending data from your app. You should use the proper "HostTo" functions. This is really important in iOS apps for example. Your iOS app may be run on an ARM iOS device or it may run in the Simulator on an Intel Mac. If you just send host bytes then the order will vary depending on where the app is run. This is bad. So the app should pick an order and then use the proper "HostTo" functions to convert data to the chosen order. Then any code that needs to read that data can specify that same order in its use of the "ToHost" functions.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Hi,Thank you for your previous answer. I also used CFByteOrderGetCurrent() and came to know that my machine is using Little Endian Format. So, When I am receiving Data from sensor Device which uses MSB to LSB data format then I need to use CFSwap...BigToHost in my IOS right? Since my machine uses Little Endian format!! – Raj0689 May 21 '13 at 08:52
  • 1
    If the data from your sensor is big-endian, then yes, you must use the `CFSwap...BigtoHost`. This will allow your iOS app to work properly when run on a real iOS device as well as when run in the simulator. – rmaddy May 21 '13 at 15:29
0

It's all about endianness. If you receive your data form the network, it will be big endian. Your machine is little endian, so in that case you need to swap the bytes.

See: http://en.wikipedia.org/wiki/Endianness

Markus
  • 528
  • 1
  • 5
  • 10
  • Your general statements may or may not be true. Just because data comes from a network doesn't mean the data is big endian. And "your machine" may or may not be little endian. It depends on the machine. An Intel Mac is one way while an ARM iOS device is another. – rmaddy May 20 '13 at 15:27
  • @rmaddy You're right, the answer was very general. But the issue he's having is related to endianness. I will try be more precise next time. – Markus May 20 '13 at 15:43