I wanted to append Different byte storage types like Int8, Int16, Int32, ..
into data. It has become very complex as every time I have to convert one by one to data and append the same.
How to create extension for Data which will accept Int8, Int16, Int16 Int32
in any order and return bytes
Typically the below code should work. I tried but. not able to finish the extension method
let value1: Int8 = 0x01
let value2: Int16 = 0x0001
let value3: Int32 = 0x00000001
let data = Data.getBytes(value1, value2, value3)
extension Data {
static func getBytes(...) -> Data {
// How to proceed?
}
}
First, you need a common type that will be accepted by getBytes
. Unfortunately we cannot use FixedWidthInteger
directly, because it contains a Self
constraint. We cannot use FixedWidthInteger
as a generic parameter either, because then we would not be able to mix Int8
and Int16
and so on in a single call.
Therefore, instead of using Any
, I would suggest to introduce a new protocol MyIntType
and let all the types you want to support implement this:
protocol MyIntType {
// ...
}
extension Int8: MyIntType { }
extension Int16: MyIntType { }
extension Int32: MyIntType { }
extension Data {
static func getBytes(_ values : MyIntType...) -> Data { /* ... */ }
}
In getBytes
, you need to access the internal bytes from the concrete Int-Type, e.g. call something like Data(bytes: &intValue, count: MemoryLayout<Int8>.size)
. Fortunately, Int8
etc. support something like bitWidth
(which is similar to the MemoryLayout
) because the all conform to the FixedWidthInteger
protocol.
Nevertheless, we cannot use FixedWidthInteger
directly in the getBytes
function, because it contains a Self
constraint.
As a work-around, we just need to add the bitWidth
property to our MyIntType
protocol:
protocol MyIntType {
var bitWidth:Int { get }
}
All those Int
x-Types already implement it, so we do not need an extension for them, and can simply use it in getBytes
:
extension Data {
static func getBytes (_ values:MyIntType...) -> Data {
var d = Data()
for var v in values {
let data = Data(bytes:&v, count:v.bitWidth / 8)
d.append(contentsOf:data)
}
return d
}
}
Now we can check it:
let value1: Int8 = 0x01
let value2: Int16 = 0x0010
let value3: Int32 = 0x00000100
let bytes = Data.getBytes(value1, value2, value3)
print (bytes)
for b in bytes {
print (b)
}
User contributions licensed under CC BY-SA 3.0