Skip to content

Commit

Permalink
fix: pathKey value using attributesOfItem
Browse files Browse the repository at this point in the history
test: Rewrite all tests to use async/await instead of callback
  • Loading branch information
amosavian committed Nov 18, 2023
1 parent f1170bf commit 5db046a
Show file tree
Hide file tree
Showing 5 changed files with 287 additions and 544 deletions.
105 changes: 66 additions & 39 deletions AMSMB2/AMSMB2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,17 @@ public class SMB2Manager: NSObject, NSSecureCoding, Codable, NSCopying, CustomRe
}
}

/// Only for test case coverage
func _swift_listShares(
enumerateHidden: Bool = false
) async throws -> [(name: String, comment: String)] {
return try await withCheckedThrowingContinuation { continuation in
_swift_listShares(enumerateHidden: enumerateHidden) { result in
continuation.resume(with: result)
}
}
}

/**
Enumerates directory contents in the give path.
Expand Down Expand Up @@ -471,10 +482,9 @@ public class SMB2Manager: NSObject, NSSecureCoding, Codable, NSCopying, CustomRe
with(completionHandler: completionHandler) { context in
let stat = try context.stat(path)
var result = [URLResourceKey: Any]()
let name = (path as NSString).lastPathComponent
result[.nameKey] = name
result[.pathKey] = (path as NSString).appendingPathComponent(name)
self.populateResourceValue(&result, stat: stat)
result[.nameKey] = path.fileURL().lastPathComponent
result[.pathKey] = path.fileURL(stat.isDirectory).path
stat.populateResourceValue(&result)
return result
}
}
Expand Down Expand Up @@ -813,6 +823,16 @@ public class SMB2Manager: NSObject, NSSecureCoding, Codable, NSCopying, CustomRe
}
}

open func contents(
atPath path: String, offset: Int64 = 0,
fetchedData: @escaping ((_ offset: Int64, _ total: Int64, _ data: Data) -> Bool)
) async throws {
return try await withCheckedThrowingContinuation { continuation in
contents(
atPath: path, offset: offset, fetchedData: fetchedData,
completionHandler: asyncHandler(continuation))
}
}
/**
Creates and writes data to file. With reporting progress on about every 1MiB.
Expand Down Expand Up @@ -1237,36 +1257,6 @@ extension SMB2Manager {
}
}
}

fileprivate func populateResourceValue(_ dic: inout [URLResourceKey: Any], stat: smb2_stat_64) {
dic.reserveCapacity(11)
dic[.fileSizeKey] = NSNumber(value: stat.smb2_size)
dic[.linkCountKey] = NSNumber(value: stat.smb2_nlink)
dic[.documentIdentifierKey] = NSNumber(value: stat.smb2_ino)

switch Int32(stat.smb2_type) {
case SMB2_TYPE_DIRECTORY:
dic[.fileResourceTypeKey] = URLFileResourceType.directory
case SMB2_TYPE_FILE:
dic[.fileResourceTypeKey] = URLFileResourceType.regular
case SMB2_TYPE_LINK:
dic[.fileResourceTypeKey] = URLFileResourceType.symbolicLink
default:
dic[.fileResourceTypeKey] = URLFileResourceType.unknown
}
dic[.isDirectoryKey] = NSNumber(value: stat.smb2_type == SMB2_TYPE_DIRECTORY)
dic[.isRegularFileKey] = NSNumber(value: stat.smb2_type == SMB2_TYPE_FILE)
dic[.isSymbolicLinkKey] = NSNumber(value: stat.smb2_type == SMB2_TYPE_LINK)

dic[.contentModificationDateKey] = Date(
timespec(tv_sec: Int(stat.smb2_mtime), tv_nsec: Int(stat.smb2_mtime_nsec)))
dic[.attributeModificationDateKey] = Date(
timespec(tv_sec: Int(stat.smb2_ctime), tv_nsec: Int(stat.smb2_ctime_nsec)))
dic[.contentAccessDateKey] = Date(
timespec(tv_sec: Int(stat.smb2_atime), tv_nsec: Int(stat.smb2_atime_nsec)))
dic[.creationDateKey] = Date(
timespec(tv_sec: Int(stat.smb2_btime), tv_nsec: Int(stat.smb2_btime_nsec)))
}
}

extension SMB2Manager {
Expand All @@ -1280,8 +1270,9 @@ extension SMB2Manager {
if [".", ".."].contains(name) { continue }
var result = [URLResourceKey: Any]()
result[.nameKey] = name
result[.pathKey] = (path as NSString).appendingPathComponent(name)
populateResourceValue(&result, stat: ent.st)
result[.pathKey] =
path.fileURL().appendingPathComponent(name, isDirectory: ent.st.isDirectory).path
ent.st.populateResourceValue(&result)
contents.append(result)
}

Expand All @@ -1307,7 +1298,7 @@ extension SMB2Manager {
) throws -> Bool
) throws {
let stat = try context.stat(path)
if stat.smb2_type == SMB2_TYPE_DIRECTORY {
if stat.isDirectory {
try context.mkdir(toPath)

let list = try listDirectory(context: context, path: path, recursive: recursive)
Expand All @@ -1317,8 +1308,8 @@ extension SMB2Manager {
var totalCopied: Int64 = 0
for item in list {
let itemPath = try item.path.unwrap()
let destPath = itemPath.replacingOccurrences(
of: path, with: toPath, options: .anchored)
let destPath = itemPath.canonical
.replacingOccurrences(of: path, with: toPath, options: .anchored)
if item.isDirectory {
try context.mkdir(destPath)
} else {
Expand Down Expand Up @@ -1492,3 +1483,39 @@ extension SMB2Manager {
}
}
}

extension smb2_stat_64 {
var isDirectory: Bool {
smb2_type == SMB2_TYPE_DIRECTORY
}

func populateResourceValue(_ dic: inout [URLResourceKey: Any]) {
dic.reserveCapacity(11 + dic.count)
dic[.fileSizeKey] = NSNumber(value: smb2_size)
dic[.linkCountKey] = NSNumber(value: smb2_nlink)
dic[.documentIdentifierKey] = NSNumber(value: smb2_ino)

switch Int32(smb2_type) {
case SMB2_TYPE_DIRECTORY:
dic[.fileResourceTypeKey] = URLFileResourceType.directory
case SMB2_TYPE_FILE:
dic[.fileResourceTypeKey] = URLFileResourceType.regular
case SMB2_TYPE_LINK:
dic[.fileResourceTypeKey] = URLFileResourceType.symbolicLink
default:
dic[.fileResourceTypeKey] = URLFileResourceType.unknown
}
dic[.isDirectoryKey] = NSNumber(value: smb2_type == SMB2_TYPE_DIRECTORY)
dic[.isRegularFileKey] = NSNumber(value: smb2_type == SMB2_TYPE_FILE)
dic[.isSymbolicLinkKey] = NSNumber(value: smb2_type == SMB2_TYPE_LINK)

dic[.contentModificationDateKey] = Date(
timespec(tv_sec: Int(smb2_mtime), tv_nsec: Int(smb2_mtime_nsec)))
dic[.attributeModificationDateKey] = Date(
timespec(tv_sec: Int(smb2_ctime), tv_nsec: Int(smb2_ctime_nsec)))
dic[.contentAccessDateKey] = Date(
timespec(tv_sec: Int(smb2_atime), tv_nsec: Int(smb2_atime_nsec)))
dic[.creationDateKey] = Date(
timespec(tv_sec: Int(smb2_btime), tv_nsec: Int(smb2_btime_nsec)))
}
}
2 changes: 1 addition & 1 deletion AMSMB2/Context.swift
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ extension smb2_negotiate_version: Hashable {
static func == (lhs: smb2_negotiate_version, rhs: smb2_negotiate_version) -> Bool {
lhs.rawValue == rhs.rawValue
}

public func hash(into hasher: inout Hasher) {
hasher.combine(rawValue)
}
Expand Down
16 changes: 14 additions & 2 deletions AMSMB2/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ protocol EmptyInitializable {
}

/// Booleans can be initialized with no arguments and it would be `false` by default.
extension Bool: EmptyInitializable { }
extension Bool: EmptyInitializable {}

extension Dictionary where Key == URLResourceKey {
private func value<T>(forKey key: Key) -> T? {
Expand All @@ -75,7 +75,7 @@ extension Dictionary where Key == URLResourceKey {
return self[key] as? T ?? T.init()
}

public var name: String? {
public var name: String? {
return self.value(forKey: .nameKey)
}

Expand Down Expand Up @@ -198,6 +198,18 @@ extension String {
var canonical: String {
return trimmingCharacters(in: .init(charactersIn: "/\\"))
}

func fileURL(_ isDirectory: Bool = false) -> URL {
if #available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) {
return .init(
filePath: self, directoryHint: isDirectory ? .isDirectory : .notDirectory,
relativeTo: .init(filePath: "/"))
} else {
return .init(
fileURLWithPath: self, isDirectory: isDirectory,
relativeTo: .init(fileURLWithPath: "/"))
}
}
}

extension Stream {
Expand Down
4 changes: 2 additions & 2 deletions AMSMB2/Fsctl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ extension IOCtlArgument {
func index(after i: Int) -> Int {
return i + 1
}

func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
try Data(regions.joined()).withUnsafeBytes(body)
}
Expand All @@ -50,7 +50,7 @@ protocol IOCtlReply {

struct AnyIOCtlReply: IOCtlReply {
private let data: Data

init(data: Data) {
self.data = data
}
Expand Down
Loading

0 comments on commit 5db046a

Please sign in to comment.