Charlie Monroe
Charlie Monroe

Reputation: 1250

Read IntegerType from NSInputStream

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

Answers (1)

Martin R
Martin R

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

Related Questions