Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@kimjj81
Last active February 23, 2024 06:53
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kimjj81/aadf55fc591220afdc8450452c2ea21d to your computer and use it in GitHub Desktop.
Save kimjj81/aadf55fc591220afdc8450452c2ea21d to your computer and use it in GitHub Desktop.
Convert UInt to UInt8(byte) Array in swift.
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)
}
}
}
@Planet30
Copy link

Planet30 commented Apr 23, 2022

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.

@kimjj81
Copy link
Author

kimjj81 commented Apr 23, 2022

Hi, @Planet30 .

  1. 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()".

  2. I think you can make a function by combination of CFByteOrderGetCurrent and bit shift operator.

@Planet30
Copy link

Planet30 commented Apr 24, 2022

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?

@kimjj81
Copy link
Author

kimjj81 commented Apr 24, 2022

@Planet30
image
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]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment