@micampe’s code compiles just fine for me (in an Xcode 11.2 command-line tool project). It does not, alas, work )-: The problem is that it iterates every index of the input data, and it should be iterating every other index.
Here’s something that does work:
import Foundation
func main() {
let data = Data([0x12, 0x34, 0x45, 0x67, 0x78])
var numbers: [Int16] = []
var iter = data.makeIterator()
while true {
guard
let b1 = iter.next(),
let b2 = iter.next()
else {
break
}
let num = Int16(b1) << 8 | Int16(b2)
numbers.append(num)
}
print(numbers)
// prints [4660, 17767]
// where 4660 is 0x1234 and 17767 is 4567
}
main()
Alternatively, you could make something that works on any sequence of bytes:
import Foundation
func asUInt16s<Input>(_ input: Input) -> AnySequence<UInt16>
where
Input: Sequence,
Input.Element == UInt8
{
let s = sequence(state: input.makeIterator()) { iter -> UInt16? in
guard
let b1 = iter.next(),
let b2 = iter.next()
else {
return nil
}
return UInt16(b1) << 8 | UInt16(b2)
}
return AnySequence(s)
}
func main() {
let d = Data([0x12, 0x34, 0x45, 0x67, 0x78])
print([UInt16](asUInt16s(d)))
// prints [4660, 17767]
let b: [UInt8] = [0x12, 0x34, 0x45, 0x67, 0x78]
print([UInt16](asUInt16s(b)))
// likewise
}
main()
There is, of course, a question of whether you should using this approach at all. I’m a big fan of avoiding unsafe techniques in general, but it’s not always the best option.
How big is your input data? Where does it come from? And where is the output array of Int16
going? And how frequently are you doing this?
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple