Reputation: 1250
I am trying to write a generic function that will read an int-typed value from NSInputStream
:
func read<T : IntegerType>() -> T? {
var buffer : T = 0
let n = withUnsafePointer(&buffer) { (p) in
self.read(UnsafePointer<UInt8>(p), maxLength: sizeof(T))
}
if n > 0 {
assert(n == sizeof(T), "read length must be sizeof(T)")
return buffer
} else {
return nil
}
}
I am basing this on my previous Google searcg: https://gist.github.com/ishikawa/c3917ea4daa107f1ce68
Everything seems just fine, except for one thing:
withUnsafePointer(&buffer)
shows an error:
Cannot convert value of type 'inout T' to expected argument type 'inout _'
I am unsure, how to fix this - or if this approach is completely wrong and won't work...
Anyone any ideas?
EDIT:
The desired functionality:
let i: Int8 = stream.read()
let o: UInt32 = stream.read()
// etc.
Upvotes: 1
Views: 410
Reputation: 539795
The read()
method requires a mutable buffer pointer:
let n = withUnsafeMutablePointer(&buffer) { (p) in
self.read(UnsafeMutablePointer(p), maxLength: sizeof(T))
}
The placeholder type <UInt8>
in UnsafeMutablePointer(p)
can be inferred automatically from the context.
Note that there is a general problem with your approach: If the input
stream is not connected to a real file but to some communication channel
(e.g. a TCP socket, pipe, ...) then the only guarantee is that read()
waits until at least one byte is read and the assertion n == sizeof(T)
can fail. You have to read again in a loop until the required amount
is read.
Upvotes: 2