How to work with bit operations in Swift?

I need to form a 20-byte data packet and send the payload to the hardware peripheral via Bluetooth.

This 20-byte data packet is divided into 14 data sets internally, each of 11 bits, the last 6 bits must be a null character.

Therefore, Total: 160 bits (20 bytes) = 14 (sets) * 11 (bits) + 6 (null characters)

11 bits are again divided into 3 sets of 2 bits, 3 bits and 6 bits each. However, this is not important for the main question, at present I can form 11 bits by taking "Int16". I will do a shift operation to filter 11 bits, I know that.

If I have only one data set, then I have to fill in all 20 bytes, except for the first 11 bits with a null character, if there are two data sets, then all but 22 bits should have a null character and, accordingly.

The problem I am facing is to generate these consecutive 160 bits due to the odd bits, which are 11. I thought about doing the "Int" and do shift (<<) operations, and then doing bitwise OR (| ) but Int is 64 bits.

Currently, I think that using an array of characters with a fixed size of 20 will fit this situation. Although conceptually I consider this the best way, programmatically I can’t form a logic with all the conditions to achieve this. I think I need to put all the logic in a loop.

Can anyone say that this is the right way to achieve this, and help me solve it if this is the best way. Or indicate any other method, if available.

+5
source share
2 answers

You do not need to pack all data arrays into a 20-byte array until the very end, so keep them in an Int array of length 14. It is easier to work with this path. When you need to send it to hardware, convert it to a UInt8 array of length 20:

 struct DataPacket { var dataSets = [Int](count: 14, repeatedValue: 0) func toCArray() -> [UInt8] { var result = [UInt8](count: 20, repeatedValue: 0) var index = 0 var bitsRemaining = 8 var offset = 0 for value in self.dataSets { offset = 10 while offset >= 0 { let mask = 1 << offset let bit = ((value & mask) >> offset) << (bitsRemaining - 1) result[index] |= UInt8(bit) offset -= 1 bitsRemaining -= 1 if bitsRemaining == 0 { index += 1 bitsRemaining = 8 } } } return result } } // Usage: var packet = DataPacket() packet.dataSets[0] = 0b11111111111 packet.dataSets[1] = 0b00000000011 // etc... let arr = packet.toCArray() 

There are many switching operations, so I cannot explain them. A common ideal allocates each of these 11-bit data sets to bytes, moving to the next byte if necessary.

+1
source

The solution proposed by Code Different:

 struct DataPacket { var dataSets = [Int16](count: 14, repeatedValue: 0) func getPacket() -> [UInt8] { var packet = [UInt8](count: 20, repeatedValue: 0) var idxPacket = 0 for dataSet in dataSets { for idxBit in 1...11 { if dataSet & 1 << (11 - idxBit) != 0 { packet[idxPacket / 8] |= UInt8(0b1000_0000 >> (idxPacket % 8)) } idxPacket += 1 } } return packet } } 
+1
source

Source: https://habr.com/ru/post/1244055/


All Articles