Skip to content

Commit

Permalink
Refactoring async_await(), Bump version
Browse files Browse the repository at this point in the history
  • Loading branch information
amosavian committed Nov 28, 2019
1 parent c31c2a8 commit de74817
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 84 deletions.
2 changes: 1 addition & 1 deletion AMSMB2.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions AMSMB2.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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";
Expand Down
4 changes: 2 additions & 2 deletions AMSMB2/AMSMB2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
82 changes: 32 additions & 50 deletions AMSMB2/Context.swift
Original file line number Diff line number Diff line change
Expand Up @@ -352,88 +352,70 @@ extension SMB2Context {
} catch { }
}

typealias ContextHandler<R> = (_ context: UnsafeMutablePointer<smb2_context>, _ ptr: UnsafeMutableRawPointer) throws -> R
typealias ContextHandler<R> = (_ context: UnsafeMutablePointer<smb2_context>, _ ptr: UnsafeMutableRawPointer?) throws -> R

@discardableResult
func async_await(execute handler: ContextHandler<Int32>) 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<T>(dataHandler: @escaping ContextHandler<T>, execute handler: ContextHandler<Int32>)
throws -> (result: Int32, data: T)
func async_await<DataType>(dataHandler: @escaping ContextHandler<DataType>, execute handler: ContextHandler<Int32>)
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<UnsafeMutablePointer<smb2_pdu>?>) 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<T>(dataHandler: @escaping ContextHandler<T>, execute handler: ContextHandler<UnsafeMutablePointer<smb2_pdu>?>)
throws -> (status: UInt32, data: T)
func async_await_pdu<DataType>(dataHandler: @escaping ContextHandler<DataType>, execute handler: ContextHandler<UnsafeMutablePointer<smb2_pdu>?>)
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())
}
}

Expand Down
13 changes: 4 additions & 9 deletions AMSMB2/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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)
})
}
}
Expand Down
2 changes: 0 additions & 2 deletions AMSMB2/FileHandle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<smb2_pdu>? in
return path.replacingOccurrences(of: "/", with: "\\").withCString { (path) in
var req = smb2_create_request()
Expand Down
36 changes: 18 additions & 18 deletions AMSMB2/Parsers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,32 @@ import Foundation
import SMB2

struct Parser {
static func toString(_ context: UnsafeMutablePointer<smb2_context>, _ dataPtr: UnsafeMutableRawPointer) throws -> String {
return String(cString: dataPtr.assumingMemoryBound(to: Int8.self))
static func toVoid(_ context: UnsafeMutablePointer<smb2_context>, _ dataPtr: UnsafeMutableRawPointer?) throws -> Void {
return ()
}

static func toSMB2Shares(_ context: UnsafeMutablePointer<smb2_context>, _ dataPtr: UnsafeMutableRawPointer) throws -> [SMB2Share] {
static func toString(_ context: UnsafeMutablePointer<smb2_context>, _ dataPtr: UnsafeMutableRawPointer?) throws -> String {
return try String(cString: dataPtr.unwrap().assumingMemoryBound(to: Int8.self))
}

static func toSMB2Shares(_ context: UnsafeMutablePointer<smb2_context>, _ 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<smb2_context>, _ dataPtr: UnsafeMutableRawPointer) throws -> OpaquePointer {
return OpaquePointer(dataPtr)
static func toOpaquePointer(_ context: UnsafeMutablePointer<smb2_context>, _ dataPtr: UnsafeMutableRawPointer?) throws -> OpaquePointer {
return try OpaquePointer(dataPtr.unwrap())
}

static func toFileId(_ context: UnsafeMutablePointer<smb2_context>, _ dataPtr: UnsafeMutableRawPointer) throws -> smb2_file_id {
return dataPtr.assumingMemoryBound(to: smb2_create_reply.self).pointee.file_id
static func toFileId(_ context: UnsafeMutablePointer<smb2_context>, _ dataPtr: UnsafeMutableRawPointer?) throws -> smb2_file_id {
return try dataPtr.unwrap().assumingMemoryBound(to: smb2_create_reply.self).pointee.file_id
}

static func ioctlOutputConverter<R: DataInitializable>(as: R.Type) ->
((_ context: UnsafeMutablePointer<smb2_context>, _ dataPtr: UnsafeMutableRawPointer) throws -> R) {
((_ context: UnsafeMutablePointer<smb2_context>, _ 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()
}
Expand All @@ -44,14 +48,10 @@ struct Parser {

extension Array where Element == SMB2Share {
init(_ ctr1: srvsvc_netsharectr1) {
var result = [SMB2Share]()
let array = Array<srvsvc_netshareinfo1>(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
}
}

0 comments on commit de74817

Please sign in to comment.