The following code originally written in Swift 3, worked without warning in Swift 4.2, gave the warning "Inout expression creates a temporary pointer, but argument #1 should be a pointer that outlives the call to '+'" in Swift 5, now not compiling in Xcode 12 at all with an error saying "Generic parameter 'Element' could not be inferred".
func readNUInt8(_ n:UInt32) throws -> [UInt8] {
var buffer = [UInt8](repeating: 0, count: Int(n))
var read = 0
while read < Int(n) {
read += recv(s, &buffer + read, Int(n) - read, 0)
if read <= 0 {
throw SocketError.recvFailed(Socket.descriptionOfLastError())
}
}
if bytesToRead >= UInt32(n) {
bytesToRead -= UInt32(n)
}
return buffer
}
I tried to solve this by converting read to UInt8 and appending to buffer before calling recv() function, but the app crashed elsewhere probably because I broke the socket reading by incorrectly storing read bytes like that.
Any suggestions how to correct the above code to read and store the buffer the right way?
I solved the problem by explicitly using .withUnsafeMutableBytes for the buffer, hence changing the function block to the following:
func readNUInt8(_ n:UInt32) throws -> [UInt8] {
var buffer = [UInt8](repeating: 0, count: Int(n))
var read = 0
while read < Int(n) {
var recvResult : ssize_t = 0
// let recvResult = recv(s, &buffer + read, Int(n) - read, 0)
buffer.withUnsafeMutableBytes { goPointer in recvResult = recv(s, goPointer.baseAddress! + read, Int(n) - read, 0) }
read += recvResult
if read <= 0 {
throw SocketError.recvFailed(Socket.descriptionOfLastError())
}
}
if bytesToRead >= UInt32(n) {
bytesToRead -= UInt32(n)
}
return buffer
}