首页 > 解决方案 > 如何将 16 个字节从数据复制到 uuid_t?

问题描述

给定一个类型的变量Data,如何从中复制 16 个字节并直接复制到一个类型的变量中uuid_t

我正在编写一些使用 Google 协议缓冲区与外部服务交换数据的 Swift 代码。该服务返回一个包含两个属性的数据结构:一个Int表示计数和一个原始字节数组,Uint8表示每个 16 字节的顺序 UUID。在 Swift 中,这表示如下struct

struct UUIDCollection {
  var count:Int         // Number of 16 byte identifiers.
  var identifiers:Data  // Array of bytes where every group of 16 bytes, starting at index 0, is a uuid. 
}

我无法弄清楚 Swift 指针的正确用法以允许我执行以下操作:

for i in 0..<count {
  let offset = Int(i * 16)

  var bytes:uuid_t
  let range = offset..<(offset + 16)

  withUnsafeMutablePointer(to:&bytes) { (b:UnsafeMutablePointer<UInt8>) -> Void in
    identifiers.copyBytes(to:b, from:range)

    let uuid = UUID(uuid:bytes)
    print("UUID: \(uuid.uuidString)")
  }
}

我收到的 Xcode 错误是:

无法将类型 '(UnsafeMutablePointer) -> Void' 的值转换为预期的参数类型 '(UnsafeMutablePointer<_>) -> _'

将这样的字节数组转换为 uuid_t 数组的正确且理想情况下最有效的方法是什么?

注意:Swift 代码旨在与现有 API 一起使用,该 API 将标识符作为单个字节数组出售。更改该 API 以提供标识符向量或字符串 UUID 向量目前并不是一个真正的选择。

标签: swift

解决方案


您可以跨过您的标识符子数据并加载您的 UUID,如下所示:

extension Data {
    func object<T>() -> T { withUnsafeBytes { $0.load(as: T.self) } }
}

extension UUIDCollection {
    var uuids: [UUID] {
        stride(from: 0, to: count * 16, by: 16)
            .map { identifiers[$0..<$0.advanced(by: 16)].object() }
    }
}

推荐阅读