jon
jon

Reputation: 33

trying to convert NSData of type (BigEndian) from BlueTooth to Int of type Little Endian in Swift

I am trying to convert a 6 byte hex of type NSData i got via bluetooth connection to appropriate integer values. I know this is of type Big Endian and i need to covnert to little Endian. However, every time i try to convert it, i can extract the right data, but the results look wrong, see playground code below:

var newdata = NSData(bytes: [0x26, 0x01, 0x45, 0x01, 0x04, 0x5e, ] as [UInt8], length:6)


//var timeData  = newdata.subdataWithRange(NSMakeRange(4,2))
//var heelData = newdata.subdataWithRange(NSMakeRange(2,2))
//var frontData = newdata.subdataWithRange(NSMakeRange(0,2))


var timeData:UInt16 = 0 
var heelData:UInt16 = 0
var frontData:UInt16 = 0


//var timeData = data.subdataWithRange(NSMakeRange(4,2))

var timeIn: NSNumber = NSNumber(unsignedShort: 0)
newdata.getBytes(&timeIn, range: NSRange(location: 4,length: 2))
timeData = CFSwapInt16BigToHost(timeIn.unsignedShortValue)
//24068

 var heelIn: NSNumber = NSNumber(unsignedShort: 0)
 newdata.getBytes(&heelIn, range: NSRange(location: 2, length: 2))
 heelData = CFSwapInt16BigToHost(heelIn.unsignedShortValue)
 //325

 var frontIn: NSNumber = NSNumber(unsignedShort: 0)
 newdata.getBytes(&frontIn, range: NSRange(location: 0, length: 2))
 frontData = CFSwapInt16BigToHost(frontIn.unsignedShortValue)
 //294

Upvotes: 3

Views: 1629

Answers (1)

Martin R
Martin R

Reputation: 539685

NSNumber is a Foundation class and in particular a value type, and timeIn is a pointer to a number instance. You are extracting the bytes into that pointer, which is not what you want and can cause all kinds of undefined behavior or crashes.

What you should do is to extract the bytes into an UInt16 variable:

var timeData:UInt16 = 0 
newdata.getBytes(&timeData, range: NSRange(location: 4, length: 2))
timeData = CFSwapInt16BigToHost(timeData)
// Result: 1118 = 0x045E

An alternative to the last conversion is

/// Creates an integer from its big-endian representation, changing the
/// byte order if necessary.
timeData = UInt16(bigEndian: timeData) 

Upvotes: 5

Related Questions