Convert an Objective-C method into Swift for NSInputStream (convert bytes into double)

后端 未结 3 592
终归单人心
终归单人心 2021-01-15 06:13

I have the following code in Objective-C:

- (double)readDouble
{
    double value = 0.0;

    if ([self read:(uint8_t *)&value maxLength:8] != 8)
    {
          


        
相关标签:
3条回答
  • 2021-01-15 06:39

    This should work:

    let num = withUnsafeMutablePointer(&value) {
        self.read(UnsafeMutablePointer($0), maxLength: sizeofValue(value))
    }
    

    Explanation: withUnsafeMutablePointer() calls the closure (block) with the only argument ($0 in shorthand notation) set to the address of value.

    $0 has the type UnsafeMutablePointer<Double> and read() expects an UnsafeMutablePointer<UInt8> as the first argument, therefore another conversion is necessary. The return value of the closure is then assigned to num.

    0 讨论(0)
  • 2021-01-15 06:41

    The method above does not work for me, using Swift 2 but I discovered a much more simpler method to do this conversion and vice versa:

    func binarytotype <T> (value: [UInt8], _: T.Type) -> T
    {
        return value.withUnsafeBufferPointer
        {
            return UnsafePointer<T>($0.baseAddress).memory
        }
    }
    
    func typetobinary <T> (var value: T) -> [UInt8]
    {
        return withUnsafePointer(&value)
        {
            Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>($0), count: sizeof(T)))
        }
    }
    
    let a: Double = 0.25
    let b: [UInt8] = typetobinary(a) // -> [0, 0, 0, 0, 0, 0, 208, 63]
    let c = binarytotype(b, Double.self) // -> 0.25
    

    I have tested it with Xcode 7.2 in the playground.

    0 讨论(0)
  • 2021-01-15 06:51

    Here is the updated version for Swift 3 beta 6 which is different, thanx to Martin.

    func binarytotype <T> (_ value: [UInt8], _ : T.Type) -> T
    {
        return value.withUnsafeBufferPointer
        {
            UnsafeRawPointer($0.baseAddress!).load(as: T.self)
        }
    }
    
    func typetobinary <T> (_ value: T) -> [UInt8]
    {
        var v = value
        let size = MemoryLayout<T>.size
        return withUnsafePointer(to: &v)
        {
            $0.withMemoryRebound(to: UInt8.self, capacity: size)
            {
                Array(UnsafeBufferPointer(start: $0, count: size))
            }
        }    
    }
    
    let dd: Double = 1.23456             // -> 1.23456
    let d = typetobinary(dd)             // -> [56, 50, 143, 252, 193, 192, 243, 63]
    let i = binarytotype(d, Double.self) // -> 1.23456
    
    0 讨论(0)
提交回复
热议问题