Данные, UnsafeMutablePointer и расширенные атрибуты в Swift 3

В swift 2 у меня было расширение NSURL для работы с расширенными атрибутами, и оно включало это:

func setAttribute(name: String, value: String) {
    let data = value.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
    setxattr(self.path!, name, data.bytes, data.length, 0, 0)
}

func getAttribute(name: String) -> String? {
    let length = getxattr(self.path!, name, nil, 0, 0, 0)
    if length == -1 {
        return nil
    }
    let bytes = malloc(length)
    if getxattr(self.path!, name, bytes, length, 0, 0) == -1 {
        return nil
    }
    return (String(data: NSData(bytes: bytes, length: length),
        encoding: NSUTF8StringEncoding))
}

func attributes() -> [String : String]? {
    let length = listxattr(self.path!, nil, 0, 0)
    if length == -1 {
        return nil
    }
    let bytes = UnsafeMutablePointer<Int8>(malloc(length))
    if listxattr(self.path!, bytes, length, 0) == -1 {
        return nil
    }
    if var names = NSString(bytes: bytes, length: length,
        encoding: NSUTF8StringEncoding)?.componentsSeparatedByString("\0") {
            names.removeLast()
            var attributes: [String : String] = [:]
            for name in names {
                attributes[name] = getAttribute(name)!
            }
            return attributes
    }
    return nil
}

Сейчас я пытаюсь конвертировать его в Swift 3, но Xcode продолжает жаловаться.

Я изменил первые две функции в этом, но я не уверен, что я делаю это правильно:

func setAttribute(_ name: String, value: String) {
    let data = value.data(using: String.Encoding.utf8, allowLossyConversion: false)!
    setxattr(self.path, name, (data as NSData).bytes, data.count, 0, 0)
}

func getAttribute(_ name: String) -> String? {
    let length = getxattr(self.path, name, nil, 0, 0, 0)
    if length < 0 {
        return nil
    }
    guard let bytes = malloc(length),
        getxattr(self.path, name, bytes, length, 0, 0) >= 0 else {
            return nil
    }
    if getxattr(self.path, name, bytes, length, 0, 0) < 0 {
        return nil
    }
    return (String(data: Data(bytes: bytes, count: length),
        encoding: String.Encoding.utf8))
}

Должен ли я бросить Data в NSData там на первой функции? Есть ли лучший способ сделать все это?

И эта последняя функция была преобразована Xcode в это:

func attributes() -> [String : String]? {
    let length = listxattr(self.path, nil, 0, 0)
    if length == -1 {
        return nil
    }
    let bytes = UnsafeMutablePointer<Int8>(malloc(length))
    if listxattr(self.path, bytes, length, 0) == -1 {
        return nil
    }
    if var names = NSString(bytes: bytes, length: length,
        encoding: String.Encoding.utf8)?.components(separatedBy: "\0") {
            names.removeLast()
            var attributes: [String : String] = [:]
            for name in names {
                attributes[name] = getAttribute(name)!
            }
            return attributes
    }
    return nil
}

Но я получаю

Невозможно вызвать инициализатор для типа "UnsafeMutablePointer" со списком аргументов типа "(UnsafeMutableRawPointer!)"

И я не знаю, что делать. Также преобразование XCode придерживается NSString, Я не мог использовать String там?

Если это уже не очевидно, я понятия не имею, что делаю, хаха. Я основал свой оригинальный код на этом, но я не мог понять, как все это malloc, length а также bytes вещи работают. Я пытался читать документацию для Data а также UnsafeMutablePointer и так далее, но это не сильно помогло.

Если бы кто-то мог помочь мне преобразовать этот код, я был бы очень благодарен, но даже просто указание мне в правильном направлении, чтобы понять все это, было бы огромной помощью. Я не знаю, где еще искать, и все это кажется мне загадочным. Несколько недавних источников, которые я нашел, предполагают, что я знаю много вещей, о которых я понятия не имею, и я даже не знаю, что искать.

Спасибо!

0 ответов

Другие вопросы по тегам