0

I'm trying to have a helper method for Data class to convert bytes to UInt32. So far this worked:

extension Data {    
    var uint32:UInt32 {
        return UInt32(littleEndian: self.withUnsafeBytes { (ptr: UnsafePointer<UInt32>) in ptr.pointee })
    }
}

Since swift 5 the compiler gives the following warning:

'withUnsafeBytes' is deprecated: use `withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R` instead`

After some research I tried to use withUnsafeMutableBytes along with UnsafeMutablePointer<UInt32>

but this gives an error: Cannot use mutating member on immutable value: 'self' is immutable. (This would work if it wasn't a part of an inmutable getter function)

How can I fix my read only helper variable so the compiler doesn't give warnings?

(Of course the same applies to UInt8 or UInt16)

Tamas
  • 3,254
  • 4
  • 29
  • 51

2 Answers2

2

Try this:

let data = Data([0x01,0x02,0x03,0x04])
extension Data {
    var uint32:UInt32 {
        return UInt32(littleEndian: self.withUnsafeBytes { bytes in
            bytes.load(as: UInt32.self)
        })
    }
}
print(String(format: "%08X", data.uint32)) //->04030201

The new withUnsafeBytes passes an UnsafeRawBufferPointer, which has a useful method load(as:).

OOPer
  • 47,149
  • 6
  • 107
  • 142
  • Thanks, @MartinR. I should have noted it. Frankly, I did not know I can make such a misaligned `Data` so easily. – OOPer Apr 22 '19 at 11:42
  • 1
    (Previous comment deleted inadvertently.) This requires that the memory is properly aligned, it crashes e.g. for `let data = Data([0x00, 0x01,0x02,0x03,0x04]).dropFirst()`. – `Data` is its own slice type, and there is no guarantee that a given (or created) `Data` is aligned at all. Also discussed here: https://forums.swift.org/t/about-data-alignment/17447 – Martin R Apr 22 '19 at 11:48
1

You can assign self to a variable

extension Data {
    var uint32:UInt32 {
        var data = self
        return UInt32(littleEndian: data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt32>) in ptr.pointee })
    }
}
Kamran
  • 14,987
  • 4
  • 33
  • 51
  • It solves the error related to immutability but the result still has warnings. Seems `withUnsafeMutableBytes` is just as bad. – Tamas Apr 22 '19 at 11:04