From 9dda618b733a5418ae42e0322a5b6ccbcfad8a6f Mon Sep 17 00:00:00 2001 From: Amir Abbas Mousavian Date: Thu, 1 Dec 2016 12:10:14 +0330 Subject: [PATCH] Revert "createFile definition improved" This reverts commit da60c0518849d1720d32d2e9092ae53fe1876a24. --- FileProvider.podspec | 2 +- FileProvider.xcodeproj/project.pbxproj | 2 - Sources/DropboxFileProvider.swift | 5 +- Sources/FileProvider.swift | 2 +- Sources/LocalFileProvider.swift | 97 +++++++++++++------------- Sources/SMBFileProvider.swift | 2 +- Sources/WebDAVFileProvider.swift | 4 +- 7 files changed, 56 insertions(+), 58 deletions(-) diff --git a/FileProvider.podspec b/FileProvider.podspec index 42a9039..d822948 100644 --- a/FileProvider.podspec +++ b/FileProvider.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| # s.name = "FileProvider" - s.version = "0.7.1" + s.version = "0.7.0" s.summary = "FileManager replacement for Local and Remote (WebDAV/Dropbox/SMB2) files on iOS and macOS." # This description is used to generate tags and improve search results. diff --git a/FileProvider.xcodeproj/project.pbxproj b/FileProvider.xcodeproj/project.pbxproj index 25defbe..87e8f9b 100644 --- a/FileProvider.xcodeproj/project.pbxproj +++ b/FileProvider.xcodeproj/project.pbxproj @@ -557,7 +557,6 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; APPLICATION_EXTENSION_API_ONLY = YES; - BUNDLE_VERSION_STRING = 0.7.1; CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -610,7 +609,6 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; APPLICATION_EXTENSION_API_ONLY = YES; - BUNDLE_VERSION_STRING = 0.7.1; CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; diff --git a/Sources/DropboxFileProvider.swift b/Sources/DropboxFileProvider.swift index f2e615d..8e42e59 100644 --- a/Sources/DropboxFileProvider.swift +++ b/Sources/DropboxFileProvider.swift @@ -113,9 +113,8 @@ extension DropboxFileProvider: FileProviderOperations { return doOperation(.create(path: path), completionHandler: completionHandler) } - public func create(file fileName: String, at path: String, contents data: Data?, completionHandler: SimpleCompletionHandler) -> OperationHandle? { - let filePath = (path as NSString).appendingPathComponent(fileName) - return self.writeContents(path: filePath, contents: data ?? Data(), completionHandler: completionHandler) + public func create(file fileAttribs: FileObject, at path: String, contents data: Data?, completionHandler: SimpleCompletionHandler) -> OperationHandle? { + return self.writeContents(path: path, contents: data ?? Data(), completionHandler: completionHandler) } public func moveItem(path: String, to toPath: String, overwrite: Bool = false, completionHandler: SimpleCompletionHandler) -> OperationHandle? { diff --git a/Sources/FileProvider.swift b/Sources/FileProvider.swift index 0ef1868..0632c8e 100644 --- a/Sources/FileProvider.swift +++ b/Sources/FileProvider.swift @@ -175,7 +175,7 @@ public protocol FileProviderOperations: FileProviderBasic { @discardableResult func create(folder: String, at: String, completionHandler: SimpleCompletionHandler) -> OperationHandle? @discardableResult - func create(file: String, at: String, contents data: Data?, completionHandler: SimpleCompletionHandler) -> OperationHandle? + func create(file: FileObject, at: String, contents data: Data?, completionHandler: SimpleCompletionHandler) -> OperationHandle? @discardableResult func moveItem(path: String, to: String, overwrite: Bool, completionHandler: SimpleCompletionHandler) -> OperationHandle? @discardableResult diff --git a/Sources/LocalFileProvider.swift b/Sources/LocalFileProvider.swift index c7b5520..599d568 100644 --- a/Sources/LocalFileProvider.swift +++ b/Sources/LocalFileProvider.swift @@ -104,30 +104,28 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor { @discardableResult open func create(folder folderName: String, at atPath: String, completionHandler: SimpleCompletionHandler) -> OperationHandle? { - let opType = FileOperationType.create(path: (atPath as NSString).appendingPathComponent(folderName) + "/") operation_queue.async { do { try self.opFileManager.createDirectory(at: self.absoluteURL(atPath).appendingPathComponent(folderName), withIntermediateDirectories: true, attributes: [:]) completionHandler?(nil) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderSucceed(self, operation: opType) + self.delegate?.fileproviderSucceed(self, operation: .create(path: (atPath as NSString).appendingPathComponent(folderName) + "/")) }) } catch let e as NSError { completionHandler?(e) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderFailed(self, operation: opType) + self.delegate?.fileproviderFailed(self, operation: .create(path: (atPath as NSString).appendingPathComponent(folderName) + "/")) }) } } - return LocalOperationHandle(operationType: opType, baseURL: self.baseURL) + return LocalOperationHandle(operationType: .create(path: (atPath as NSString).appendingPathComponent(folderName)), baseURL: self.baseURL) } @discardableResult - open func create(file fileName: String, at atPath: String, contents data: Data?, completionHandler: SimpleCompletionHandler) -> OperationHandle? { - let opType = FileOperationType.create(path: (atPath as NSString).appendingPathComponent(fileName)) + open func create(file fileAttribs: FileObject, at atPath: String, contents data: Data?, completionHandler: SimpleCompletionHandler) -> OperationHandle? { operation_queue.async { - let fileURL = self.absoluteURL(atPath).appendingPathComponent(fileName) - /*var attributes = [String : Any]() + let fileURL = self.absoluteURL(atPath).appendingPathComponent(fileAttribs.name) + var attributes = [String : Any]() if let createdDate = fileAttribs.createdDate { attributes[FileAttributeKey.creationDate.rawValue] = createdDate as NSDate } @@ -136,29 +134,29 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor { } if fileAttribs.isReadOnly { attributes[FileAttributeKey.posixPermissions.rawValue] = NSNumber(value: 365 as Int16) - }*/ - let success = self.opFileManager.createFile(atPath: fileURL.path, contents: data, attributes: nil/*attributes*/) + } + let success = self.opFileManager.createFile(atPath: fileURL.path, contents: data, attributes: attributes) if success { - /*do { + do { try (fileURL as NSURL).setResourceValue(fileAttribs.isHidden, forKey: URLResourceKey.isHiddenKey) - } catch _ {}*/ + } catch _ {} completionHandler?(nil) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderSucceed(self, operation: opType) + self.delegate?.fileproviderSucceed(self, operation: .create(path: (atPath as NSString).appendingPathComponent(fileAttribs.name))) }) } else { completionHandler?(self.throwError(atPath, code: URLError.cannotCreateFile as FoundationErrorEnum)) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderFailed(self, operation: opType) + self.delegate?.fileproviderFailed(self, operation: .create(path: (atPath as NSString).appendingPathComponent(fileAttribs.name))) }) } } - return LocalOperationHandle(operationType: opType, baseURL: self.baseURL) + return LocalOperationHandle(operationType: .create(path: (atPath as NSString).appendingPathComponent(fileAttribs.name)), baseURL: self.baseURL) } @discardableResult open func moveItem(path: String, to toPath: String, overwrite: Bool = false, completionHandler: SimpleCompletionHandler) -> OperationHandle? { - let opType = FileOperationType.move(source: path, destination: toPath) + // FIXME: progress operation_queue.async { if !overwrite && self.fileManager.fileExists(atPath: self.absoluteURL(toPath).path) { completionHandler?(self.throwError(toPath, code: URLError.cannotMoveFile as FoundationErrorEnum)) @@ -168,21 +166,21 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor { try self.opFileManager.moveItem(at: self.absoluteURL(path), to: self.absoluteURL(toPath)) completionHandler?(nil) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderSucceed(self, operation: opType) + self.delegate?.fileproviderSucceed(self, operation: .move(source: path, destination: toPath)) }) } catch let e as NSError { completionHandler?(e) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderFailed(self, operation: opType) + self.delegate?.fileproviderFailed(self, operation: .move(source: path, destination: toPath)) }) } } - return LocalOperationHandle(operationType: opType, baseURL: self.baseURL) + return LocalOperationHandle(operationType: .move(source: path, destination: toPath), baseURL: self.baseURL) } @discardableResult open func copyItem(path: String, to toPath: String, overwrite: Bool = false, completionHandler: SimpleCompletionHandler) -> OperationHandle? { - let opType = FileOperationType.copy(source: path, destination: toPath) + // FIXME: progress, for files > 100mb, monitor file by another thread, for dirs check copied items count operation_queue.async { if !overwrite && self.fileManager.fileExists(atPath: self.absoluteURL(toPath).path) { completionHandler?(self.throwError(toPath, code: URLError.cannotWriteToFile as FoundationErrorEnum)) @@ -192,76 +190,73 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor { try self.opFileManager.copyItem(at: self.absoluteURL(path), to: self.absoluteURL(toPath)) completionHandler?(nil) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderSucceed(self, operation: opType) + self.delegate?.fileproviderSucceed(self, operation: .copy(source: path, destination: toPath)) }) } catch let e as NSError { completionHandler?(e) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderFailed(self, operation: opType) + self.delegate?.fileproviderFailed(self, operation: .copy(source: path, destination: toPath)) }) } } - return LocalOperationHandle(operationType: opType, baseURL: self.baseURL) + return LocalOperationHandle(operationType: .copy(source: path, destination: toPath), baseURL: self.baseURL) } @discardableResult open func removeItem(path: String, completionHandler: SimpleCompletionHandler) -> OperationHandle? { - let opType = FileOperationType.remove(path: path) operation_queue.async { do { try self.opFileManager.removeItem(at: self.absoluteURL(path)) completionHandler?(nil) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderSucceed(self, operation: opType) + self.delegate?.fileproviderSucceed(self, operation: .remove(path: path)) }) } catch let e as NSError { completionHandler?(e) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderFailed(self, operation: opType) + self.delegate?.fileproviderFailed(self, operation: .remove(path: path)) }) } } - return LocalOperationHandle(operationType: opType, baseURL: self.baseURL) + return LocalOperationHandle(operationType: .remove(path: path), baseURL: self.baseURL) } @discardableResult open func copyItem(localFile: URL, to toPath: String, completionHandler: SimpleCompletionHandler) -> OperationHandle? { - let opType = FileOperationType.copy(source: localFile.absoluteString, destination: toPath) operation_queue.async { do { try self.opFileManager.copyItem(at: localFile, to: self.absoluteURL(toPath)) completionHandler?(nil) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderSucceed(self, operation: opType) + self.delegate?.fileproviderSucceed(self, operation: .copy(source: localFile.absoluteString, destination: toPath)) }) } catch let e as NSError { completionHandler?(e) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderFailed(self, operation: opType) + self.delegate?.fileproviderFailed(self, operation: .copy(source: localFile.absoluteString, destination: toPath)) }) } } - return LocalOperationHandle(operationType: opType, baseURL: self.baseURL) + return LocalOperationHandle(operationType: .move(source: localFile.absoluteString, destination: toPath), baseURL: self.baseURL) } @discardableResult open func copyItem(path: String, toLocalURL: URL, completionHandler: SimpleCompletionHandler) -> OperationHandle? { - let opType = FileOperationType.copy(source: path, destination: toLocalURL.absoluteString) operation_queue.async { do { try self.opFileManager.copyItem(at: self.absoluteURL(path), to: toLocalURL) completionHandler?(nil) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderSucceed(self, operation: opType) + self.delegate?.fileproviderSucceed(self, operation: .copy(source: path, destination: toLocalURL.absoluteString)) }) } catch let e as NSError { completionHandler?(e) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderFailed(self, operation: opType) + self.delegate?.fileproviderFailed(self, operation: .copy(source: path, destination: toLocalURL.absoluteString)) }) } } - return LocalOperationHandle(operationType: opType, baseURL: self.baseURL) + return LocalOperationHandle(operationType: .move(source: path, destination: toLocalURL.absoluteString), baseURL: self.baseURL) } @discardableResult @@ -275,43 +270,49 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor { @discardableResult open func contents(path: String, offset: Int64, length: Int, completionHandler: @escaping ((_ contents: Data?, _ error: Error?) -> Void)) -> OperationHandle? { - let opType = FileOperationType.fetch(path: path) + // Unfortunatlely there is no method provided in NSFileManager to read a segment of file. + // So we have to fallback to POSIX provided methods dispatch_queue.async { let aPath = self.absoluteURL(path).path guard !self.attributesOfItem(url: self.absoluteURL(path)).isDirectory && self.fileManager.fileExists(atPath: aPath) else { completionHandler(nil, self.throwError(path, code: URLError.cannotOpenFile as FoundationErrorEnum)) return } - guard let handle = FileHandle(forReadingAtPath: aPath) else { + let fd_from = open(aPath, O_RDONLY) + if fd_from < 0 { completionHandler(nil, self.throwError(path, code: URLError.cannotOpenFile as FoundationErrorEnum)) return } - defer { - handle.closeFile() + defer { precondition(close(fd_from) >= 0) } + lseek(fd_from, offset, SEEK_SET) + var buf = [UInt8](repeating: 0, count: length) + let nread = read(fd_from, &buf, buf.count) + if nread < 0 { + completionHandler(nil, self.throwError(path, code: URLError.noPermissionsToReadFile as FoundationErrorEnum)) + } else if nread == 0 { + completionHandler(nil, nil) + } else { + let data = Data(bytesNoCopy: UnsafeMutablePointer(&buf), count: nread, deallocator: .free) + completionHandler(data, nil) } - handle.seek(toFileOffset: UInt64(offset)) - let data = handle.readData(ofLength: length) - completionHandler(data, nil) - } - return LocalOperationHandle(operationType: opType, baseURL: self.baseURL) + return LocalOperationHandle(operationType: .fetch(path: path), baseURL: self.baseURL) } @discardableResult open func writeContents(path: String, contents data: Data, atomically: Bool, completionHandler: SimpleCompletionHandler) -> OperationHandle? { - let opType = FileOperationType.modify(path: path) operation_queue.async { try? data.write(to: self.absoluteURL(path), options: atomically ? [.atomic] : []) DispatchQueue.main.async(execute: { - self.delegate?.fileproviderSucceed(self, operation: opType) + self.delegate?.fileproviderSucceed(self, operation: .modify(path: path)) }) } - return LocalOperationHandle(operationType: opType, baseURL: self.baseURL) + return LocalOperationHandle(operationType: .modify(path: path), baseURL: self.baseURL) } open func searchFiles(path: String, recursive: Bool, query: String, foundItemHandler: ((FileObject) -> Void)?, completionHandler: @escaping ((_ files: [FileObject], _ error: Error?) -> Void)) { dispatch_queue.async { - let iterator = self.fileManager.enumerator(at: self.absoluteURL(path), includingPropertiesForKeys: nil, options: recursive ? [] : [.skipsSubdirectoryDescendants, .skipsPackageDescendants]) { (url, e) -> Bool in + let iterator = self.fileManager.enumerator(at: self.absoluteURL(path), includingPropertiesForKeys: nil, options: recursive ? FileManager.DirectoryEnumerationOptions() : .skipsSubdirectoryDescendants) { (url, e) -> Bool in completionHandler([], e) return true } diff --git a/Sources/SMBFileProvider.swift b/Sources/SMBFileProvider.swift index 85224cf..ff941ed 100644 --- a/Sources/SMBFileProvider.swift +++ b/Sources/SMBFileProvider.swift @@ -48,7 +48,7 @@ class SMBFileProvider: FileProvider, FileProviderMonitor { return nil } - open func create(file fileName: String, at atPath: String, contents data: Data?, completionHandler: SimpleCompletionHandler) -> OperationHandle? { + open func create(file fileAttribs: FileObject, at atPath: String, contents data: Data?, completionHandler: SimpleCompletionHandler) -> OperationHandle? { NotImplemented() return nil } diff --git a/Sources/WebDAVFileProvider.swift b/Sources/WebDAVFileProvider.swift index 96d7019..9893b7e 100644 --- a/Sources/WebDAVFileProvider.swift +++ b/Sources/WebDAVFileProvider.swift @@ -176,8 +176,8 @@ extension WebDAVFileProvider: FileProviderOperations { } @discardableResult - public func create(file fileName: String, at path: String, contents data: Data?, completionHandler: SimpleCompletionHandler) -> OperationHandle? { - let opType = FileOperationType.create(path: (path as NSString).appendingPathComponent(fileName)) + public func create(file fileAttribs: FileObject, at path: String, contents data: Data?, completionHandler: SimpleCompletionHandler) -> OperationHandle? { + let opType = FileOperationType.create(path: (path as NSString).appendingPathComponent(fileAttribs.name)) guard fileOperationDelegate?.fileProvider(self, shouldDoOperation: opType) ?? true == true else { return nil }