-
-
Save kimjj81/aadf55fc591220afdc8450452c2ea21d to your computer and use it in GitHub Desktop.
protocol UIntToBytesConvertable { | |
var toBytes: [UInt8] { get } | |
} | |
extension UIntToBytesConvertable { | |
func toByteArr<T: BinaryInteger>(endian: T, count: Int) -> [UInt8] { | |
var _endian = endian | |
let bytePtr = withUnsafePointer(to: &_endian) { | |
$0.withMemoryRebound(to: UInt8.self, capacity: count) { | |
UnsafeBufferPointer(start: $0, count: count) | |
} | |
} | |
return [UInt8](bytePtr) | |
} | |
} | |
extension UInt16: UIntToBytesConvertable { | |
var toBytes: [UInt8] { | |
if CFByteOrderGetCurrent() == Int(CFByteOrderLittleEndian.rawValue) { | |
return toByteArr(endian: self.littleEndian, | |
count: MemoryLayout<UInt16>.size) | |
} else { | |
return toByteArr(endian: self.bigEndian, | |
count: MemoryLayout<UInt16>.size) | |
} | |
} | |
} | |
extension UInt32: UIntToBytesConvertable { | |
var toBytes: [UInt8] { | |
if CFByteOrderGetCurrent() == Int(CFByteOrderLittleEndian.rawValue) { | |
return toByteArr(endian: self.littleEndian, | |
count: MemoryLayout<UInt32>.size) | |
} else { | |
return toByteArr(endian: self.bigEndian, | |
count: MemoryLayout<UInt32>.size) | |
} | |
} | |
} | |
extension UInt64: UIntToBytesConvertable { | |
var toBytes: [UInt8] { | |
if CFByteOrderGetCurrent() == Int(CFByteOrderLittleEndian.rawValue) { | |
return toByteArr(endian: self.littleEndian, | |
count: MemoryLayout<UInt64>.size) | |
} else { | |
return toByteArr(endian: self.bigEndian, | |
count: MemoryLayout<UInt64>.size) | |
} | |
} | |
} |
Hi, @Planet30 .
-
If you run the codes in the same machine, you don't need to worry about endian. You can get the endian information from "CFByteOrderGetCurrent()".
-
I think you can make a function by combination of CFByteOrderGetCurrent and bit shift operator.
Thank you @kimji81 for your quick answer concerning the endianness!
How do I convert the data from [UInt8] to [UInt16]? The inverse of what you showed above.
Or is there a way to directly load the binary data into the [UInt16] array?
@Planet30
As the image above, we don't need to order of the bytes and just use the bit shift operator.
ex)
let arrayOfBytes = [0x12,0x34]
var uintOf16 = arrayOfBytes[0] << 8 | arrayOfBytes[1]
Another way to convert UInt to UInt8 is to shift bits. It normally works faster that unsafe pointer
extension UInt16 {
/// Convert a UInt16 to an array of UInt8.
/// - Returns: An array of UInt8 representing the UInt16 value.
var toUInt8: [UInt8] {
return [
UInt8(self >> 8),
UInt8(self & 0xff)
]
}
}
extension UInt32 {
/// Convert a UInt32 to an array of UInt8.
/// - Returns: An array of UInt8 representing the UInt32 value.
var toUInt8: [UInt8] {
return [
UInt8((self >> 24) & 0xff),
UInt8((self >> 16) & 0xff),
UInt8((self >> 8) & 0xff),
UInt8(self & 0xff)
]
}
}
Hi, Very cool! How do I do the inverse in SWIFT?
I have a ton of files with binary data of 16 bit unsigned integer values, that I can already convert into a [UInt8] array. Because these files can be very large, I would need an efficient way to convert either the data directly or the UInt8 array into a [UInt16] array. I am not sure if the data are little or big endian. Thank you for your help.