From de74817b8670005ef16a4ada9ebded309d2db1d6 Mon Sep 17 00:00:00 2001 From: Amir Abbas Date: Thu, 28 Nov 2019 12:11:11 +0330 Subject: [PATCH] Refactoring async_await(), Bump version --- AMSMB2.podspec | 2 +- AMSMB2.xcodeproj/project.pbxproj | 4 +- AMSMB2/AMSMB2.swift | 4 +- AMSMB2/Context.swift | 82 +++++++++++++------------------- AMSMB2/Extensions.swift | 13 ++--- AMSMB2/FileHandle.swift | 2 - AMSMB2/Parsers.swift | 36 +++++++------- 7 files changed, 59 insertions(+), 84 deletions(-) diff --git a/AMSMB2.podspec b/AMSMB2.podspec index 011ffb8..84f15a8 100644 --- a/AMSMB2.podspec +++ b/AMSMB2.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| # s.name = "AMSMB2" - s.version = "2.5.0" + s.version = "2.6.0" s.summary = "Swift framework to connect SMB2/3 shares" # This description is used to generate tags and improve search results. diff --git a/AMSMB2.xcodeproj/project.pbxproj b/AMSMB2.xcodeproj/project.pbxproj index 0004672..a2fb006 100644 --- a/AMSMB2.xcodeproj/project.pbxproj +++ b/AMSMB2.xcodeproj/project.pbxproj @@ -410,7 +410,7 @@ "@loader_path/../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/libsmb2/lib"; - MARKETING_VERSION = 2.5.0; + MARKETING_VERSION = 2.6.0; OTHER_LDFLAGS = ""; "OTHER_LDFLAGS[sdk=appletvos*]" = "-lsmb2-tvos"; "OTHER_LDFLAGS[sdk=appletvsimulator*]" = "-lsmb2-tvos"; @@ -446,7 +446,7 @@ "@loader_path/../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/libsmb2/lib"; - MARKETING_VERSION = 2.5.0; + MARKETING_VERSION = 2.6.0; "OTHER_LDFLAGS[sdk=appletvos*]" = "-lsmb2-tvos"; "OTHER_LDFLAGS[sdk=appletvsimulator*]" = "-lsmb2-tvos"; "OTHER_LDFLAGS[sdk=iphoneos*]" = "-lsmb2-ios"; diff --git a/AMSMB2/AMSMB2.swift b/AMSMB2/AMSMB2.swift index 0269fc4..996364a 100644 --- a/AMSMB2/AMSMB2.swift +++ b/AMSMB2/AMSMB2.swift @@ -858,7 +858,7 @@ extension AMSMB2 { if stat.smb2_type == SMB2_TYPE_DIRECTORY { try context.mkdir(toPath) - let list = try listDirectory(context: context, path: path, recursive: recursive).sortedByName(.orderedAscending) + let list = try listDirectory(context: context, path: path, recursive: recursive).sortedByPath(.orderedAscending) let overallSize = list.overallSize var totalCopied: Int64 = 0 @@ -931,7 +931,7 @@ extension AMSMB2 { // Then we will unlink/rmdir every entry. // // This block will only delete children of directory, the path itself will removed after if block. - let list = try self.listDirectory(context: context, path: path, recursive: true).sortedByName(.orderedDescending) + let list = try self.listDirectory(context: context, path: path, recursive: true).sortedByPath(.orderedDescending) for item in list { let itemPath = try item.path.unwrap() diff --git a/AMSMB2/Context.swift b/AMSMB2/Context.swift index cfef611..e8b0095 100644 --- a/AMSMB2/Context.swift +++ b/AMSMB2/Context.swift @@ -352,88 +352,70 @@ extension SMB2Context { } catch { } } - typealias ContextHandler = (_ context: UnsafeMutablePointer, _ ptr: UnsafeMutableRawPointer) throws -> R + typealias ContextHandler = (_ context: UnsafeMutablePointer, _ ptr: UnsafeMutableRawPointer?) throws -> R @discardableResult func async_await(execute handler: ContextHandler) throws -> Int32 { - return try withThreadSafeContext { (context) -> Int32 in - var cb = CBData() - let result = try handler(context, &cb) - try POSIXError.throwIfError(result, description: error) - try wait_for_reply(&cb) - let cbResult = cb.result - try POSIXError.throwIfError(cbResult, description: error) - return cbResult - } + return try async_await(dataHandler: Parser.toVoid, execute: handler).result } @discardableResult - func async_await(dataHandler: @escaping ContextHandler, execute handler: ContextHandler) - throws -> (result: Int32, data: T) + func async_await(dataHandler: @escaping ContextHandler, execute handler: ContextHandler) + throws -> (result: Int32, data: DataType) { - var cb = CBData() - var resultData: T? - var dataHandlerError: Error? - - let result = try withThreadSafeContext { (context) -> Int32 in + return try withThreadSafeContext { (context) -> (Int32, DataType) in + var cb = CBData() + var resultData: DataType? + var dataHandlerError: Error? cb.dataHandler = { ptr in do { - resultData = try dataHandler(context, ptr.unwrap()) + resultData = try dataHandler(context, ptr) } catch { dataHandlerError = error } } - return try handler(context, &cb) + let result = try handler(context, &cb) + try POSIXError.throwIfError(result, description: error) + try wait_for_reply(&cb) + let cbResult = cb.result + + try POSIXError.throwIfError(cbResult, description: error) + if let error = dataHandlerError { throw error } + return try (cbResult, resultData.unwrap()) } - try POSIXError.throwIfError(result, description: error) - try wait_for_reply(&cb) - let cbResult = cb.result - - try POSIXError.throwIfError(cbResult, description: error) - if let error = dataHandlerError { throw error } - return try (cbResult, resultData.unwrap()) } @discardableResult func async_await_pdu(execute handler: ContextHandler?>) throws -> UInt32 { - var cb = CBData() - - try withThreadSafeContext { (context) -> Void in - let pdu = try handler(context, &cb).unwrap() - smb2_queue_pdu(context, pdu) - } - try wait_for_reply(&cb) - let status = cb.status - try POSIXError.throwIfErrorStatus(status) - return status + return try async_await_pdu(dataHandler: Parser.toVoid, execute: handler).status } @discardableResult - func async_await_pdu(dataHandler: @escaping ContextHandler, execute handler: ContextHandler?>) - throws -> (status: UInt32, data: T) + func async_await_pdu(dataHandler: @escaping ContextHandler, execute handler: ContextHandler?>) + throws -> (status: UInt32, data: DataType) { - var cb = CBData() - var resultData: T? - var dataHandlerError: Error? - - try withThreadSafeContext { (context) -> Void in - let pdu = try handler(context, &cb).unwrap() + return try withThreadSafeContext { (context) -> (UInt32, DataType) in + var cb = CBData() + var resultData: DataType? + var dataHandlerError: Error? cb.dataHandler = { ptr in do { - resultData = try dataHandler(context, ptr.unwrap()) + resultData = try dataHandler(context, ptr) } catch { dataHandlerError = error } } + let pdu = try handler(context, &cb).unwrap() smb2_queue_pdu(context, pdu) + try wait_for_reply(&cb) + let status = cb.status + + try POSIXError.throwIfErrorStatus(status) + if let error = dataHandlerError { throw error } + return try (status, resultData.unwrap()) } - try wait_for_reply(&cb) - let status = cb.status - try POSIXError.throwIfErrorStatus(status) - if let error = dataHandlerError { throw error } - return try (status, resultData.unwrap()) } } diff --git a/AMSMB2/Extensions.swift b/AMSMB2/Extensions.swift index 1e8b252..4288522 100644 --- a/AMSMB2/Extensions.swift +++ b/AMSMB2/Extensions.swift @@ -29,9 +29,7 @@ extension Optional where Wrapped: SMB2Context { extension POSIXError { static func throwIfError(_ result: Int32, description: String?) throws { - guard result < 0 else { - return - } + guard result < 0 else { return } let errno = -result let errorDesc = description.map { "Error code \(errno): \($0)" } throw POSIXError(.init(errno), description: errorDesc) @@ -104,7 +102,7 @@ extension Dictionary where Key == URLResourceKey, Value == Any { } extension Array where Element == [URLResourceKey: Any] { - func sortedByName(_ comparison: ComparisonResult) -> [[URLResourceKey: Any]] { + func sortedByPath(_ comparison: ComparisonResult) -> [[URLResourceKey: Any]] { return sorted { guard let firstPath = $0.path, let secPath = $1.path else { return false @@ -115,11 +113,8 @@ extension Array where Element == [URLResourceKey: Any] { var overallSize: Int64 { return reduce(0, { (result, value) -> Int64 in - if value.isRegularFile { - return result + (value.fileSize ?? 0) - } else { - return result - } + guard value.isRegularFile else { return result } + return result + (value.fileSize ?? 0) }) } } diff --git a/AMSMB2/FileHandle.swift b/AMSMB2/FileHandle.swift index dc16339..9778ab1 100644 --- a/AMSMB2/FileHandle.swift +++ b/AMSMB2/FileHandle.swift @@ -54,8 +54,6 @@ final class SMB2FileHandle { shareAccess: Int32 = SMB2_FILE_SHARE_READ | SMB2_FILE_SHARE_WRITE | SMB2_FILE_SHARE_DELETE, createDisposition: Int32 = SMB2_FILE_OPEN, createOptions: Int32 = 0, on context: SMB2Context) throws { - // smb2_open() sets overwrite flag, which is incompatible with pipe in mac's smbx - let (_, file_id) = try context.async_await_pdu(dataHandler: Parser.toFileId) { (context, cbPtr) -> UnsafeMutablePointer? in return path.replacingOccurrences(of: "/", with: "\\").withCString { (path) in var req = smb2_create_request() diff --git a/AMSMB2/Parsers.swift b/AMSMB2/Parsers.swift index 75d893b..893d5d3 100644 --- a/AMSMB2/Parsers.swift +++ b/AMSMB2/Parsers.swift @@ -10,28 +10,32 @@ import Foundation import SMB2 struct Parser { - static func toString(_ context: UnsafeMutablePointer, _ dataPtr: UnsafeMutableRawPointer) throws -> String { - return String(cString: dataPtr.assumingMemoryBound(to: Int8.self)) + static func toVoid(_ context: UnsafeMutablePointer, _ dataPtr: UnsafeMutableRawPointer?) throws -> Void { + return () } - static func toSMB2Shares(_ context: UnsafeMutablePointer, _ dataPtr: UnsafeMutableRawPointer) throws -> [SMB2Share] { + static func toString(_ context: UnsafeMutablePointer, _ dataPtr: UnsafeMutableRawPointer?) throws -> String { + return try String(cString: dataPtr.unwrap().assumingMemoryBound(to: Int8.self)) + } + + static func toSMB2Shares(_ context: UnsafeMutablePointer, _ dataPtr: UnsafeMutableRawPointer?) throws -> [SMB2Share] { defer { smb2_free_data(context, dataPtr) } - let result = dataPtr.assumingMemoryBound(to: srvsvc_netshareenumall_rep.self).pointee + let result = try dataPtr.unwrap().assumingMemoryBound(to: srvsvc_netshareenumall_rep.self).pointee return .init(result.ctr.pointee.ctr1) } - static func toOpaquePointer(_ context: UnsafeMutablePointer, _ dataPtr: UnsafeMutableRawPointer) throws -> OpaquePointer { - return OpaquePointer(dataPtr) + static func toOpaquePointer(_ context: UnsafeMutablePointer, _ dataPtr: UnsafeMutableRawPointer?) throws -> OpaquePointer { + return try OpaquePointer(dataPtr.unwrap()) } - static func toFileId(_ context: UnsafeMutablePointer, _ dataPtr: UnsafeMutableRawPointer) throws -> smb2_file_id { - return dataPtr.assumingMemoryBound(to: smb2_create_reply.self).pointee.file_id + static func toFileId(_ context: UnsafeMutablePointer, _ dataPtr: UnsafeMutableRawPointer?) throws -> smb2_file_id { + return try dataPtr.unwrap().assumingMemoryBound(to: smb2_create_reply.self).pointee.file_id } static func ioctlOutputConverter(as: R.Type) -> - ((_ context: UnsafeMutablePointer, _ dataPtr: UnsafeMutableRawPointer) throws -> R) { + ((_ context: UnsafeMutablePointer, _ dataPtr: UnsafeMutableRawPointer?) throws -> R) { return { context, dataPtr in - let reply = dataPtr.assumingMemoryBound(to: smb2_ioctl_reply.self).pointee + let reply = try dataPtr.unwrap().assumingMemoryBound(to: smb2_ioctl_reply.self).pointee guard reply.output_count > 0, let output = reply.output else { return try .empty() } @@ -44,14 +48,10 @@ struct Parser { extension Array where Element == SMB2Share { init(_ ctr1: srvsvc_netsharectr1) { - var result = [SMB2Share]() - let array = Array(UnsafeBufferPointer(start: ctr1.array, count: Int(ctr1.count))) - for item in array { - let name = String(cString: item.name) - let type = ShareProperties(rawValue: item.type) - let comment = String(cString: item.comment) - result.append(.init(name: name, props: type, comment: comment)) + self = [srvsvc_netshareinfo1](UnsafeBufferPointer(start: ctr1.array, count: Int(ctr1.count))).map { + SMB2Share(name: .init(cString: $0.name), + props: .init(rawValue: $0.type), + comment: .init(cString: $0.comment)) } - self = result } }