Sam
Sam

Reputation: 840

Swift 3 reading from network socket using 'withUnsafeBufferPointer' - 'init' unavailable use 'withMemoryRebound'

I have a function in Swift 2.3 which reads Int value from a network socket

open func readInt() -> Int32 {
    var intValueBuffer = [UInt8](repeating: 0, count: MemoryLayout<Int32>.size)
    self.stream!.read (&intValueBuffer, maxLength: MemoryLayout<Int32>.size)
    let intValue = intValueBuffer.withUnsafeBufferPointer({
        UnsafePointer<Int32>($0.baseAddress!).pointee
    })
    return Int32(bigEndian: intValue)
}

After migrating to Swift 3 I'm hitting this error. I haven't been able to figure out what actually needs to change, any help would be really appreciated

enter image description here

Upvotes: 1

Views: 267

Answers (1)

Martin R
Martin R

Reputation: 540005

The conversion from a pointer to UInt8 to a pointer to Int32 must be made explicit with withMemoryRebound():

func readInt() -> Int32 {
    var intValueBuffer = [UInt8](repeating: 0, count: MemoryLayout<Int32>.size)
    self.stream!.read(&intValueBuffer, maxLength: MemoryLayout<Int32>.size)
    let intValue = intValueBuffer.withUnsafeBufferPointer({
        $0.baseAddress!.withMemoryRebound(to: Int32.self, capacity: 1) {
            $0.pointee
        }
    })
    return Int32(bigEndian: intValue)
}

Alternatively, read into a Data object instead of an array:

func readInt() -> Int32 {
    var intValueBuffer = Data(count: MemoryLayout<Int32>.size)
    intValueBuffer.withUnsafeMutableBytes {
        _ = self.stream!.read($0, maxLength: MemoryLayout<Int32>.size)
    }
    return Int32(bigEndian: intValueBuffer.withUnsafeBytes { $0.pointee })
}

or directly into an integer variable:

func readInt() -> Int32 {
    var intValue: Int32 = 0
    withUnsafePointer(to: &intValue) {
        $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout<Int32>.size) {
            _ = self.stream!.read($0, maxLength: MemoryLayout<Int32>.size)
        }
    }
    return Int32(bigEndian: intValue)
}

For more information see UnsafeRawPointer Migration on swift.org.

You may also want to check the return value of the read method which is the number of bytes actually read, or -1 if the read operation failed.

Upvotes: 2

Related Questions