164 lines
5.5 KiB
Swift
164 lines
5.5 KiB
Swift
//
|
|
// SambaFileProvider.swift
|
|
// FileProvider
|
|
//
|
|
// Created by Amir Abbas Mousavian.
|
|
// Copyright © 2016 Mousavian. Distributed under MIT license.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
class SMBFileProvider: FileProvider, FileProviderMonitor {
|
|
open class var type: String { return "SMB" }
|
|
open var baseURL: URL?
|
|
open var dispatch_queue: DispatchQueue
|
|
open var operation_queue: OperationQueue
|
|
open weak var delegate: FileProviderDelegate?
|
|
open var credential: URLCredential?
|
|
|
|
public typealias FileObjectClass = FileObject
|
|
|
|
public init? (baseURL: URL, credential: URLCredential?) {
|
|
guard baseURL.uw_scheme.lowercased() == "smb" else {
|
|
return nil
|
|
}
|
|
self.baseURL = baseURL.appendingPathComponent("")
|
|
|
|
let queueLabel = "FileProvider.\(Swift.type(of: self).type)"
|
|
dispatch_queue = DispatchQueue(label: queueLabel, attributes: .concurrent)
|
|
operation_queue = OperationQueue()
|
|
operation_queue.name = "\(queueLabel).Operation"
|
|
|
|
self.credential = credential
|
|
}
|
|
|
|
public required convenience init?(coder aDecoder: NSCoder) {
|
|
guard let baseURL = aDecoder.decodeObject(of: NSURL.self, forKey: "baseURL") as URL? else {
|
|
if #available(macOS 10.11, iOS 9.0, tvOS 9.0, *) {
|
|
aDecoder.failWithError(CocoaError(.coderValueNotFound,
|
|
userInfo: [NSLocalizedDescriptionKey: "Base URL is not set."]))
|
|
}
|
|
return nil
|
|
}
|
|
self.init(baseURL: baseURL,
|
|
credential: aDecoder.decodeObject(of: URLCredential.self, forKey: "credential"))
|
|
}
|
|
|
|
open func encode(with aCoder: NSCoder) {
|
|
aCoder.encode(self.baseURL, forKey: "baseURL")
|
|
aCoder.encode(self.credential, forKey: "credential")
|
|
}
|
|
|
|
public static var supportsSecureCoding: Bool {
|
|
return true
|
|
}
|
|
|
|
open func contentsOfDirectory(path: String, completionHandler: @escaping (_ contents: [FileObjectClass], _ error: Error?) -> Void) {
|
|
NotImplemented()
|
|
}
|
|
|
|
open func attributesOfItem(path: String, completionHandler: @escaping (_ attributes: FileObjectClass?, _ error: Error?) -> Void) {
|
|
NotImplemented()
|
|
}
|
|
|
|
open func storageProperties(completionHandler: @escaping (_ volume: VolumeObject?) -> Void) {
|
|
NotImplemented()
|
|
}
|
|
|
|
func isReachable(completionHandler: @escaping (_ success: Bool, _ error: Error?) -> Void) {
|
|
NotImplemented()
|
|
}
|
|
|
|
open weak var fileOperationDelegate: FileOperationDelegate?
|
|
|
|
open func create(folder folderName: String, at atPath: String, completionHandler: SimpleCompletionHandler) -> Progress? {
|
|
NotImplemented()
|
|
return nil
|
|
}
|
|
|
|
open func moveItem(path: String, to toPath: String, overwrite: Bool = false, completionHandler: SimpleCompletionHandler) -> Progress? {
|
|
NotImplemented()
|
|
return nil
|
|
}
|
|
|
|
open func copyItem(path: String, to toPath: String, overwrite: Bool = false, completionHandler: SimpleCompletionHandler) -> Progress? {
|
|
NotImplemented()
|
|
return nil
|
|
}
|
|
|
|
open func removeItem(path: String, completionHandler: SimpleCompletionHandler) -> Progress? {
|
|
NotImplemented()
|
|
return nil
|
|
}
|
|
|
|
open func copyItem(localFile: URL, to toPath: String, overwrite: Bool, completionHandler: SimpleCompletionHandler) -> Progress? {
|
|
NotImplemented()
|
|
return nil
|
|
}
|
|
|
|
open func copyItem(path: String, toLocalURL: URL, completionHandler: SimpleCompletionHandler) -> Progress? {
|
|
NotImplemented()
|
|
return nil
|
|
}
|
|
|
|
open func contents(path: String, completionHandler: @escaping ((_ contents: Data?, _ error: Error?) -> Void)) -> Progress? {
|
|
NotImplemented()
|
|
return nil
|
|
}
|
|
|
|
open func contents(path: String, offset: Int64, length: Int, completionHandler: @escaping ((_ contents: Data?, _ error: Error?) -> Void)) -> Progress? {
|
|
NotImplemented()
|
|
return nil
|
|
}
|
|
|
|
open func writeContents(path: String, contents data: Data?, atomically: Bool, overwrite: Bool, completionHandler: SimpleCompletionHandler) -> Progress? {
|
|
NotImplemented()
|
|
return nil
|
|
}
|
|
|
|
open func searchFiles(path: String, recursive: Bool, query: NSPredicate, foundItemHandler:((FileObjectClass) -> Void)?, completionHandler: @escaping ((_ files: [FileObjectClass], _ error: Error?) -> Void)) -> Progress? {
|
|
NotImplemented()
|
|
return nil
|
|
}
|
|
|
|
open func registerNotifcation(path: String, eventHandler: @escaping (() -> Void)) {
|
|
NotImplemented()
|
|
}
|
|
|
|
open func unregisterNotifcation(path: String) {
|
|
NotImplemented()
|
|
}
|
|
|
|
open func isRegisteredForNotification(path: String) -> Bool {
|
|
return false
|
|
}
|
|
|
|
open func copy(with zone: NSZone? = nil) -> Any {
|
|
let copy = SMBFileProvider(baseURL: self.baseURL!, credential: self.credential!)!
|
|
copy.delegate = self.delegate
|
|
copy.fileOperationDelegate = self.fileOperationDelegate
|
|
return copy
|
|
}
|
|
}
|
|
|
|
// MARK: basic CIFS interactivity
|
|
enum SMBFileProviderError: Int, Error, CustomStringConvertible {
|
|
case badHeader
|
|
case incompatibleHeader
|
|
case incorrectParamsLength
|
|
case incorrectMessageLength
|
|
case invalidCommand
|
|
|
|
public var description: String {
|
|
return "SMB message structure is invalid"
|
|
}
|
|
}
|
|
|
|
private extension SMBFileProvider {
|
|
func getPID() -> UInt32 {
|
|
return UInt32(ProcessInfo.processInfo.processIdentifier)
|
|
}
|
|
}
|
|
|
|
|