Hey Guys,
I'm having troubles accessing (and extracting) bytes from data. I need to convert some types to bytes, put them together in a Data object and extracting back.
I used this to convert some types to Data
extension ExpressibleByBooleanLiteral {
public init(from data: Data) {
self = data.withUnsafeBytes {
$0.pointee
}
}
public var toData: Data {
get {
var value = self
return Data(buffer: UnsafeBufferPointer(start: &value, count: 1))
}
}
}
I'm doing so for simple types (Int, UInt). I can convert Bool, Int, UInt to Data and append them in one big Data. But when I want to extract them this way, I get error :
extension Data {
private mutating func getBool() -> Bool {
print(self)
//1 bytes
for v in self.enumerated() {
print(v)
}
//(offset: 0, element: 1)
let result = self.subdata(in: 0..<MemoryLayout<Bool>.size) //Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
self.removeFirst(MemoryLayout<Bool>.size)
return Bool(from: result)
Data is there but I can't access it.
I get similar error with Int and I had to copy Data to a new buffer before accessing it. But this trick doesn't work for Bool...
private mutating func getInteger<T: FixedWidthInteger>(type: T.Type) -> T {
defer {
self.removeFirst(MemoryLayout.size(ofValue: type))
}
let buffer = Data(self)
return type.init(from: buffer.subdata(in: 0..<MemoryLayout.size(ofValue: type)))
}
In my test, this is the call for the last byte. At the beginning, Data is 18 bytes long. When I breakpoint and debug, I see:
> self
> _backing
> _length = 18
> _capacity = 18
> _offset = 0
> _sliceRange = 17..<18
> lowerBound = 17
> upperBound = 18
The next one works :
private mutating func getBool() -> Bool {
defer {
self.removeFirst(MemoryLayout<Bool>.size)
}
let buffer = Data(self)
return Bool(from: buffer.subdata(in: 0..<MemoryLayout<Bool>.size))
}
But this one fails (accessing through self.getBool(type: Bool.self)
:
private mutating func getBool<T: ExpressibleByBooleanLiteral>(type: T.Type) -> T {
defer {
self.removeFirst(MemoryLayout.size(ofValue: type))
}
let buffer = Data(self)
return type.init(from: buffer.subdata(in: 0..<MemoryLayout.size(ofValue: type)))
}