diff --git a/FileProvider.xcodeproj/project.pbxproj b/FileProvider.xcodeproj/project.pbxproj index 077d400..728921c 100644 --- a/FileProvider.xcodeproj/project.pbxproj +++ b/FileProvider.xcodeproj/project.pbxproj @@ -47,6 +47,9 @@ 794C220E1D591A4B00EC49B8 /* SMB2QueryTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 794C220D1D591A4B00EC49B8 /* SMB2QueryTypes.swift */; }; 794C220F1D591A4B00EC49B8 /* SMB2QueryTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 794C220D1D591A4B00EC49B8 /* SMB2QueryTypes.swift */; }; 794C22101D591A4B00EC49B8 /* SMB2QueryTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 794C220D1D591A4B00EC49B8 /* SMB2QueryTypes.swift */; }; + 796807551E7BF17E00BBB87B /* FileProviderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 796807541E7BF17E00BBB87B /* FileProviderExtensions.swift */; }; + 796807561E7BF17E00BBB87B /* FileProviderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 796807541E7BF17E00BBB87B /* FileProviderExtensions.swift */; }; + 796807571E7BF17E00BBB87B /* FileProviderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 796807541E7BF17E00BBB87B /* FileProviderExtensions.swift */; }; 799396AA1D48C02300086753 /* DropboxFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 799396931D48C02300086753 /* DropboxFileProvider.swift */; }; 799396AB1D48C02300086753 /* DropboxFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 799396931D48C02300086753 /* DropboxFileProvider.swift */; }; 799396AC1D48C02300086753 /* DropboxFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 799396931D48C02300086753 /* DropboxFileProvider.swift */; }; @@ -134,6 +137,7 @@ 794C21FD1D58912A00EC49B8 /* DropboxHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropboxHelper.swift; sourceTree = ""; }; 794C22091D5893F800EC49B8 /* SMB2Notification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SMB2Notification.swift; sourceTree = ""; }; 794C220D1D591A4B00EC49B8 /* SMB2QueryTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SMB2QueryTypes.swift; sourceTree = ""; }; + 796807541E7BF17E00BBB87B /* FileProviderExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileProviderExtensions.swift; sourceTree = ""; }; 799396671D48B7F600086753 /* FileProvider.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FileProvider.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 799396751D48B80D00086753 /* FileProvider.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FileProvider.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 799396821D48B82700086753 /* FileProvider.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FileProvider.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -281,6 +285,7 @@ 799396991D48C02300086753 /* SMBTypes */, 799396941D48C02300086753 /* FileProvider.h */, 799396951D48C02300086753 /* FileProvider.swift */, + 796807541E7BF17E00BBB87B /* FileProviderExtensions.swift */, 79F5745A1DFDB10A00179ABF /* FileObject.swift */, 799396961D48C02300086753 /* LocalFileProvider.swift */, 792572401DF23BDA006A1526 /* LocalHelper.swift */, @@ -475,6 +480,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 796807551E7BF17E00BBB87B /* FileProviderExtensions.swift in Sources */, 799396B31D48C02300086753 /* LocalFileProvider.swift in Sources */, 799396D41D48C02300086753 /* SMB2Tree.swift in Sources */, 7924B1A21D89DAE000589DB7 /* Options.swift in Sources */, @@ -515,6 +521,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 796807561E7BF17E00BBB87B /* FileProviderExtensions.swift in Sources */, 799396B41D48C02300086753 /* LocalFileProvider.swift in Sources */, 799396D51D48C02300086753 /* SMB2Tree.swift in Sources */, 7924B1A31D89DAE000589DB7 /* Options.swift in Sources */, @@ -555,6 +562,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 796807571E7BF17E00BBB87B /* FileProviderExtensions.swift in Sources */, 799396B51D48C02300086753 /* LocalFileProvider.swift in Sources */, 799396D61D48C02300086753 /* SMB2Tree.swift in Sources */, 7924B1A41D89DAE000589DB7 /* Options.swift in Sources */, diff --git a/Sources/DropboxFileProvider.swift b/Sources/DropboxFileProvider.swift index cd6a252..8582db2 100644 --- a/Sources/DropboxFileProvider.swift +++ b/Sources/DropboxFileProvider.swift @@ -110,14 +110,14 @@ open class DropboxFileProvider: FileProviderBasicRemote { request.setValue("Bearer \(credential?.password ?? "")", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") let requestDictionary: [String: AnyObject] = ["path": correctPath(path)! as NSString] - request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) + request.httpBody = Data(jsonDictionary: requestDictionary) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var serverError: FileProviderDropboxError? var fileObject: DropboxFileObject? if let response = response as? HTTPURLResponse { let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) serverError = code != nil ? FileProviderDropboxError(code: code!, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) : nil - if let data = data, let jsonStr = String(data: data, encoding: .utf8), let json = jsonToDictionary(jsonStr), let file = DropboxFileObject(json: json) { + if let json = data?.deserializeJSON(), let file = DropboxFileObject(json: json) { fileObject = file } } @@ -134,7 +134,7 @@ open class DropboxFileProvider: FileProviderBasicRemote { let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var totalSize: Int64 = -1 var usedSize: Int64 = 0 - if let data = data, let jsonStr = String(data: data, encoding: .utf8), let json = jsonToDictionary(jsonStr) { + if let json = data?.deserializeJSON() { totalSize = ((json["allocation"] as? NSDictionary)?["allocated"] as? NSNumber)?.int64Value ?? -1 usedSize = (json["used"] as? NSNumber)?.int64Value ?? 0 } @@ -232,7 +232,7 @@ extension DropboxFileProvider: FileProviderOperations { } else { requestDictionary["path"] = correctPath(sourcePath) as NSString? } - request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) + request.httpBody = Data(jsonDictionary: requestDictionary) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var serverError: FileProviderDropboxError? if let response = response as? HTTPURLResponse, response.statusCode >= 300, let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) { @@ -264,7 +264,7 @@ extension DropboxFileProvider: FileProviderOperations { request.httpMethod = "GET" request.setValue("Bearer \(credential?.password ?? "")", forHTTPHeaderField: "Authorization") let requestDictionary: [String: AnyObject] = ["path": path as NSString] - let requestJson = dictionaryToJSON(requestDictionary) ?? "" + let requestJson = String(jsonDictionary: requestDictionary) ?? "" request.setValue(requestJson, forHTTPHeaderField: "Dropbox-API-Arg") let task = session.downloadTask(with: request, completionHandler: { (cacheURL, response, error) in guard let cacheURL = cacheURL, let httpResponse = response as? HTTPURLResponse , httpResponse.statusCode < 300 else { @@ -307,7 +307,7 @@ extension DropboxFileProvider: FileProviderReadWrite { request.setValue("bytes=\(offset)-", forHTTPHeaderField: "Range") } let requestDictionary: [String: AnyObject] = ["path": correctPath(path)! as NSString] - request.setValue(dictionaryToJSON(requestDictionary), forHTTPHeaderField: "Dropbox-API-Arg") + request.setValue(String(jsonDictionary: requestDictionary), forHTTPHeaderField: "Dropbox-API-Arg") let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var serverError: FileProviderDropboxError? if let httpResponse = response as? HTTPURLResponse , httpResponse.statusCode >= 300, let code = FileProviderHTTPErrorCode(rawValue: httpResponse.statusCode) { @@ -384,7 +384,7 @@ extension DropboxFileProvider { request.setValue("Bearer \(credential?.password ?? "")", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") let requestDictionary: [String: AnyObject] = ["path": correctPath(path)! as NSString] - request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) + request.httpBody = Data(jsonDictionary: requestDictionary) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var serverError: FileProviderDropboxError? var link: URL? @@ -392,7 +392,7 @@ extension DropboxFileProvider { if let response = response as? HTTPURLResponse { let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) serverError = code != nil ? FileProviderDropboxError(code: code!, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) : nil - if let data = data, let jsonStr = String(data: data, encoding: .utf8), let json = jsonToDictionary(jsonStr) { + if let json = data?.deserializeJSON() { if let linkStr = json["link"] as? String { link = URL(string: linkStr) } @@ -430,7 +430,7 @@ extension DropboxFileProvider { request.setValue("Bearer \(credential?.password ?? "")", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") let requestDictionary: [String: AnyObject] = ["path": correctPath(toPath)! as NSString, "url" : remoteURL.absoluteString as NSString] - request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) + request.httpBody = Data(jsonDictionary: requestDictionary) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var serverError: FileProviderDropboxError? var jobId: String? @@ -438,7 +438,7 @@ extension DropboxFileProvider { if let response = response as? HTTPURLResponse { let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) serverError = code != nil ? FileProviderDropboxError(code: code!, path: toPath, errorDescription: String(data: data ?? Data(), encoding: .utf8)) : nil - if let data = data, let jsonStr = String(data: data, encoding: .utf8), let json = jsonToDictionary(jsonStr) { + if let json = data?.deserializeJSON() { jobId = json["async_job_id"] as? String if let attribDic = json["metadata"] as? [String: AnyObject] { fileObject = DropboxFileObject(json: attribDic) @@ -465,7 +465,7 @@ extension DropboxFileProvider { request.setValue("Bearer \(credential?.password ?? "")", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") let requestDictionary: [String: AnyObject] = ["path": correctPath(toPath)! as NSString, "copy_reference" : reference as NSString] - request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) + request.httpBody = Data(jsonDictionary: requestDictionary) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var serverError: FileProviderDropboxError? if let response = response as? HTTPURLResponse { @@ -530,16 +530,16 @@ extension DropboxFileProvider: ExtendedFileProvider { if let dimension = dimension { requestDictionary["size"] = "w\(Int(dimension.width))h\(Int(dimension.height))" as NSString } - request.setValue(dictionaryToJSON(requestDictionary), forHTTPHeaderField: "Dropbox-API-Arg") + request.setValue(String(jsonDictionary: requestDictionary), forHTTPHeaderField: "Dropbox-API-Arg") let task = self.session.dataTask(with: request, completionHandler: { (data, response, error) in var image: ImageClass? = nil - if let r = response as? HTTPURLResponse, let result = r.allHeaderFields["Dropbox-API-Result"] as? String, let jsonResult = jsonToDictionary(result) { + if let r = response as? HTTPURLResponse, let result = r.allHeaderFields["Dropbox-API-Result"] as? String, let jsonResult = result.deserializeJSON() { if jsonResult["error"] != nil { completionHandler(nil, self.throwError(path, code: URLError.cannotDecodeRawData as FoundationErrorEnum)) } } if let data = data { - if DropboxFileProvider.dataIsPDF(data), let pageImage = DropboxFileProvider.convertToImage(pdfData: data) { + if data.isPDF, let pageImage = DropboxFileProvider.convertToImage(pdfData: data) { image = pageImage } else if let contentType = (response as? HTTPURLResponse)?.allHeaderFields["Content-Type"] as? String, contentType.contains("text/html") { // TODO: Implement converting html returned type of get_preview to image @@ -559,7 +559,7 @@ extension DropboxFileProvider: ExtendedFileProvider { request.setValue("Bearer \(credential?.password ?? "")", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") let requestDictionary: [String: AnyObject] = ["path": correctPath(path)! as NSString, "include_media_info": NSNumber(value: true)] - request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) + request.httpBody = Data(jsonDictionary: requestDictionary) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var serverError: FileProviderDropboxError? var dic = [String: Any]() @@ -567,7 +567,7 @@ extension DropboxFileProvider: ExtendedFileProvider { if let response = response as? HTTPURLResponse { let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) serverError = code != nil ? FileProviderDropboxError(code: code!, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) : nil - if let data = data, let jsonStr = String(data: data, encoding: .utf8), let json = jsonToDictionary(jsonStr), let properties = json["media_info"] as? [String: Any] { + if let json = data?.deserializeJSON(), let properties = json["media_info"] as? [String: Any] { (dic, keys) = self.mapMediaInfo(properties) } } diff --git a/Sources/DropboxHelper.swift b/Sources/DropboxHelper.swift index 74daba9..b6bad4a 100644 --- a/Sources/DropboxHelper.swift +++ b/Sources/DropboxHelper.swift @@ -22,7 +22,7 @@ public final class DropboxFileObject: FileObject { } internal convenience init? (jsonStr: String) { - guard let json = jsonToDictionary(jsonStr) else { return nil } + guard let json = jsonStr.deserializeJSON() else { return nil } self.init(json: json) } @@ -90,24 +90,23 @@ internal extension DropboxFileProvider { request.httpMethod = "POST" request.setValue("Bearer \(credential?.password ?? "")", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") - request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) + request.httpBody = Data(jsonDictionary: requestDictionary) let task = (session ?? self.session).dataTask(with: request, completionHandler: { (data, response, error) in var responseError: FileProviderDropboxError? var files = [DropboxFileObject]() if let code = (response as? HTTPURLResponse)?.statusCode , code >= 300, let rCode = FileProviderHTTPErrorCode(rawValue: code) { responseError = FileProviderDropboxError(code: rCode, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) } - if let data = data, let jsonStr = String(data: data, encoding: .utf8) { - let json = jsonToDictionary(jsonStr) - if let entries = json?["entries"] as? [AnyObject] , entries.count > 0 { + if let json = data?.deserializeJSON() { + if let entries = json["entries"] as? [AnyObject] , entries.count > 0 { files.reserveCapacity(entries.count) for entry in entries { if let entry = entry as? [String: AnyObject], let file = DropboxFileObject(json: entry) { files.append(file) } } - let ncursor = json?["cursor"] as? String - let hasmore = (json?["has_more"] as? NSNumber)?.boolValue ?? false + let ncursor = json["cursor"] as? String + let hasmore = (json["has_more"] as? NSNumber)?.boolValue ?? false if hasmore { progressHandler?(files, ncursor, responseError ?? error) self.list(path, cursor: ncursor, prevContents: prevContents + files, completionHandler: completionHandler) @@ -139,7 +138,7 @@ internal extension DropboxFileProvider { request.httpMethod = "POST" request.setValue("Bearer \(credential?.password ?? "")", forHTTPHeaderField: "Authorization") request.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type") - request.setValue(dictionaryToJSON(requestDictionary), forHTTPHeaderField: "Dropbox-API-Arg") + request.setValue(String(jsonDictionary: requestDictionary), forHTTPHeaderField: "Dropbox-API-Arg") request.httpBody = data let task = session.uploadTask(with: request, from: data, completionHandler: { (data, response, error) in var responseError: FileProviderDropboxError? @@ -172,7 +171,7 @@ internal extension DropboxFileProvider { request.httpMethod = "POST" request.setValue("Bearer \(credential?.password ?? "")", forHTTPHeaderField: "Authorization") request.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type") - request.setValue(dictionaryToJSON(requestDictionary), forHTTPHeaderField: "Dropbox-API-Arg") + request.setValue(String(jsonDictionary: requestDictionary), forHTTPHeaderField: "Dropbox-API-Arg") let task = session.uploadTask(with: request, fromFile: localFile, completionHandler: { (data, response, error) in var responseError: FileProviderDropboxError? if let code = (response as? HTTPURLResponse)?.statusCode , code >= 300, let rCode = FileProviderHTTPErrorCode(rawValue: code) { @@ -196,22 +195,21 @@ internal extension DropboxFileProvider { requestDictionary["query"] = query as NSString requestDictionary["start"] = start as NSNumber requestDictionary["max_results"] = maxResultPerPage as NSNumber - request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) + request.httpBody = Data(jsonDictionary: requestDictionary) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var responseError: FileProviderDropboxError? if let code = (response as? HTTPURLResponse)?.statusCode , code >= 300, let rCode = FileProviderHTTPErrorCode(rawValue: code) { responseError = FileProviderDropboxError(code: rCode, path: startPath, errorDescription: String(data: data ?? Data(), encoding: .utf8)) } - if let data = data, let jsonStr = String(data: data, encoding: .utf8) { - let json = jsonToDictionary(jsonStr) - if let entries = json?["matches"] as? [AnyObject] , entries.count > 0 { + if let json = data?.deserializeJSON() { + if let entries = json["matches"] as? [AnyObject] , entries.count > 0 { for entry in entries { if let entry = entry as? [String: AnyObject], let file = DropboxFileObject(json: entry) { foundItem(file) } } - let rstart = json?["start"] as? Int - let hasmore = (json?["more"] as? NSNumber)?.boolValue ?? false + let rstart = json["start"] as? Int + let hasmore = (json["more"] as? NSNumber)?.boolValue ?? false if hasmore, let rstart = rstart { self.search(startPath, query: query, start: rstart + entries.count, maxResultPerPage: maxResultPerPage, foundItem: foundItem, completionHandler: completionHandler) } else { @@ -254,7 +252,7 @@ internal extension DropboxFileProvider { } if let duration = json["duration"] as? UInt64 { keys.append("Duration") - dic["Duration"] = DropboxFileProvider.formatshort(interval: TimeInterval(duration)) + dic["Duration"] = TimeInterval(duration).formatshort } return (dic, keys) } diff --git a/Sources/ExtendedLocalFileProvider.swift b/Sources/ExtendedLocalFileProvider.swift index 6b412df..faf1384 100644 --- a/Sources/ExtendedLocalFileProvider.swift +++ b/Sources/ExtendedLocalFileProvider.swift @@ -338,7 +338,7 @@ public struct LocalFileInformationGenerator { } } if let ap = try? AVAudioPlayer(contentsOf: fileURL) { - add(key: "Duration", value: LocalFileProvider.formatshort(interval: ap.duration)) + add(key: "Duration", value: ap.duration.formatshort) add(key: "Bitrate", value: ap.settings[AVSampleRateKey] as? Int) } } @@ -377,7 +377,7 @@ public struct LocalFileInformationGenerator { duration += track.timeRange.duration.timescale > 0 ? track.timeRange.duration.value / Int64(track.timeRange.duration.timescale) : 0 bitrate += track.estimatedDataRate } - add(key: "Duration", value: LocalFileProvider.formatshort(interval: TimeInterval(duration))) + add(key: "Duration", value: TimeInterval(duration).formatshort) add(key: "Video Bitrate", value: "\(Int(ceil(bitrate / 1000))) kbps") } let audioTracks = asset.tracks(withMediaType: AVMediaTypeAudio) diff --git a/Sources/FileObject.swift b/Sources/FileObject.swift index badc62a..9e5d1a3 100644 --- a/Sources/FileObject.swift +++ b/Sources/FileObject.swift @@ -321,62 +321,3 @@ public struct FileObjectSorting { } } } - -extension Array where Element: FileObject { - /// Returns a sorted array of `FileObject`s by criterias set in attributes. - public func sort(by type: FileObjectSorting.SortType, ascending: Bool = true, isDirectoriesFirst: Bool = false) -> [Element] { - let sorting = FileObjectSorting(type: type, ascending: ascending, isDirectoriesFirst: isDirectoriesFirst) - return sorting.sort(self) as! [Element] - } - - /// Sorts array of `FileObject`s by criterias set in attributes. - public mutating func sorted(by type: FileObjectSorting.SortType, ascending: Bool = true, isDirectoriesFirst: Bool = false) { - self = self.sort(by: type, ascending: ascending, isDirectoriesFirst: isDirectoriesFirst) - } -} - -extension URLFileResourceType { - /// Returns corresponding `URLFileResourceType` of a `FileAttributeType` value - public init(fileTypeValue: FileAttributeType) { - switch fileTypeValue { - case FileAttributeType.typeCharacterSpecial: self = .characterSpecial - case FileAttributeType.typeDirectory: self = .directory - case FileAttributeType.typeBlockSpecial: self = .blockSpecial - case FileAttributeType.typeRegular: self = .regular - case FileAttributeType.typeSymbolicLink: self = .symbolicLink - case FileAttributeType.typeSocket: self = .socket - case FileAttributeType.typeUnknown: self = .unknown - default: self = .unknown - } - } -} - -internal extension URLResourceKey { - static let fileURL = URLResourceKey(rawValue: "NSURLFileURLKey") - static let serverDate = URLResourceKey(rawValue: "NSURLServerDateKey") - static let entryTag = URLResourceKey(rawValue: "NSURLEntryTagKey") - static let mimeType = URLResourceKey(rawValue: "NSURLMIMETypeIdentifierKey") -} - -internal extension URL { - var uw_scheme: String { - return self.scheme ?? "" - } -} - -internal func jsonToDictionary(_ jsonString: String) -> [String: AnyObject]? { - guard let data = jsonString.data(using: .utf8) else { - return nil - } - if let dic = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions()) as? [String: AnyObject] { - return dic - } - return nil -} - -internal func dictionaryToJSON(_ dictionary: [String: AnyObject]) -> String? { - if let data = try? JSONSerialization.data(withJSONObject: dictionary, options: JSONSerialization.WritingOptions()) { - return String(data: data, encoding: .utf8) - } - return nil -} diff --git a/Sources/FileProvider.swift b/Sources/FileProvider.swift index 270b11a..73e8b03 100644 --- a/Sources/FileProvider.swift +++ b/Sources/FileProvider.swift @@ -170,7 +170,7 @@ public func ==(lhs: FileProviderBasic, rhs: FileProviderBasic) -> Bool { return lhs.type == rhs.type && lhs.baseURL == rhs.baseURL && lhs.credential == rhs.credential } -/// Cancels all active underlying tasks +/// Cancels all active underlying tasks when deallocating remote providers public var fileProviderCancelTasksOnInvalidating = true /// Extending `FileProviderBasic` for web-based file providers @@ -777,34 +777,6 @@ extension ExtendedFileProvider { self.thumbnailOfFile(path: path, dimension: nil, completionHandler: completionHandler) } - internal static func formatshort(interval: TimeInterval) -> String { - var result = "0:00" - if interval < TimeInterval(Int32.max) { - result = "" - var time = DateComponents() - time.hour = Int(interval / 3600) - time.minute = Int((interval.truncatingRemainder(dividingBy: 3600)) / 60) - time.second = Int(interval.truncatingRemainder(dividingBy: 60)) - let formatter = NumberFormatter() - formatter.paddingCharacter = "0" - formatter.minimumIntegerDigits = 2 - formatter.maximumFractionDigits = 0 - let formatterFirst = NumberFormatter() - formatterFirst.maximumFractionDigits = 0 - if time.hour! > 0 { - result = "\(formatterFirst.string(from: NSNumber(value: time.hour!))!):\(formatter.string(from: NSNumber(value: time.minute!))!):\(formatter.string(from: NSNumber(value: time.second!))!)" - } else { - result = "\(formatterFirst.string(from: NSNumber(value: time.minute!))!):\(formatter.string(from: NSNumber(value: time.second!))!)" - } - } - result = result.trimmingCharacters(in: CharacterSet(charactersIn: ": ")) - return result - } - - internal static func dataIsPDF(_ data: Data) -> Bool { - return data.count > 4 && data.scanString(length: 4, encoding: .ascii) == "%PDF" - } - internal static func convertToImage(pdfData: Data?, page: Int = 1) -> ImageClass? { guard let pdfData = pdfData else { return nil } @@ -992,7 +964,7 @@ public enum FileOperationType: CustomStringConvertible { var dictionary: [String: AnyObject] = ["type": self.description as NSString] dictionary["source"] = source as NSString? dictionary["dest"] = destination as NSString? - return dictionaryToJSON(dictionary) + return String(jsonDictionary: dictionary) } } @@ -1064,32 +1036,3 @@ public protocol FoundationErrorEnum { var rawValue: Int { get } } -extension NSPredicate { - func findValue(forKey key: String?, operator op: NSComparisonPredicate.Operator? = nil) -> Any? { - let val = findAllValues(forKey: key).lazy.filter { (op == nil || $0.operator == op!) && !$0.not } - return val.first?.value - } - - func findAllValues(forKey key: String?) -> [(value: Any, operator: NSComparisonPredicate.Operator, not: Bool)] { - if let cQuery = self as? NSCompoundPredicate { - let find = cQuery.subpredicates.flatMap { ($0 as! NSPredicate).findAllValues(forKey: key) } - if cQuery.compoundPredicateType == .not { - return find.map { return ($0.value, $0.operator, !$0.not) } - } - return find - } else if let cQuery = self as? NSComparisonPredicate { - if cQuery.leftExpression.expressionType == .keyPath, key == nil || cQuery.leftExpression.keyPath == key!, let const = cQuery.rightExpression.constantValue { - return [(value: const, operator: cQuery.predicateOperatorType, false)] - } - if cQuery.rightExpression.expressionType == .keyPath, key == nil || cQuery.rightExpression.keyPath == key!, let const = cQuery.leftExpression.constantValue { - return [(value: const, operator: cQuery.predicateOperatorType, false)] - } - return [] - } else { - return [] - } - } -} - -extension URLError.Code: FoundationErrorEnum {} -extension CocoaError.Code: FoundationErrorEnum {} diff --git a/Sources/FileProviderExtensions.swift b/Sources/FileProviderExtensions.swift new file mode 100644 index 0000000..15e38c0 --- /dev/null +++ b/Sources/FileProviderExtensions.swift @@ -0,0 +1,182 @@ +// +// FileProviderExtensions.swift +// FileProvider +// +// Created by Amir Abbas on 12/27/1395 AP. +// +// + +import Foundation + +extension Array where Element: FileObject { + /// Returns a sorted array of `FileObject`s by criterias set in attributes. + public func sort(by type: FileObjectSorting.SortType, ascending: Bool = true, isDirectoriesFirst: Bool = false) -> [Element] { + let sorting = FileObjectSorting(type: type, ascending: ascending, isDirectoriesFirst: isDirectoriesFirst) + return sorting.sort(self) as! [Element] + } + + /// Sorts array of `FileObject`s by criterias set in attributes. + public mutating func sorted(by type: FileObjectSorting.SortType, ascending: Bool = true, isDirectoriesFirst: Bool = false) { + self = self.sort(by: type, ascending: ascending, isDirectoriesFirst: isDirectoriesFirst) + } +} + +extension URLFileResourceType { + /// Returns corresponding `URLFileResourceType` of a `FileAttributeType` value + public init(fileTypeValue: FileAttributeType) { + switch fileTypeValue { + case FileAttributeType.typeCharacterSpecial: self = .characterSpecial + case FileAttributeType.typeDirectory: self = .directory + case FileAttributeType.typeBlockSpecial: self = .blockSpecial + case FileAttributeType.typeRegular: self = .regular + case FileAttributeType.typeSymbolicLink: self = .symbolicLink + case FileAttributeType.typeSocket: self = .socket + case FileAttributeType.typeUnknown: self = .unknown + default: self = .unknown + } + } +} + +internal extension URLResourceKey { + static let fileURL = URLResourceKey(rawValue: "NSURLFileURLKey") + static let serverDate = URLResourceKey(rawValue: "NSURLServerDateKey") + static let entryTag = URLResourceKey(rawValue: "NSURLEntryTagKey") + static let mimeType = URLResourceKey(rawValue: "NSURLMIMETypeIdentifierKey") +} + +internal extension URL { + var uw_scheme: String { + return self.scheme ?? "" + } + + var fileIsDirectory: Bool { + return (try? self.resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory ?? false + } + + var fileSize: Int64 { + return Int64((try? self.resourceValues(forKeys: [.fileSizeKey]))?.fileSize ?? -1) + } + + var fileExists: Bool { + return self.isFileURL && FileManager.default.fileExists(atPath: self.path) + } +} + +internal extension Data { + internal var isPDF: Bool { + return self.count > 4 && self.scanString(length: 4, using: .ascii) == "%PDF" + } + + init? (jsonDictionary dictionary: [String: AnyObject]) { + guard let data = try? JSONSerialization.data(withJSONObject: dictionary, options: []) else { + return nil + } + self = data + } + + func deserializeJSON() -> [String: AnyObject]? { + if let dic = try? JSONSerialization.jsonObject(with: self, options: []) as? [String: AnyObject] { + return dic + } + return nil + } + + init(value: T) { + var value = value + self = Data(buffer: UnsafeBufferPointer(start: &value, count: 1)) + } + + func scanValue() -> T? { + guard MemoryLayout.size <= self.count else { return nil } + return self.withUnsafeBytes { $0.pointee } + } + + func scanValue(start: Int) -> T? { + let length = MemoryLayout.size + guard self.count >= start + length else { return nil } + return self.subdata(in: start.. String? { + guard self.count >= start + length else { return nil } + return String(data: self.subdata(in: start..(from: T) -> U? { + guard MemoryLayout.size >= MemoryLayout.size else { return nil } + let data = Data(value: from) + return data.scanValue() + } +} + +internal extension String { + init? (jsonDictionary: [String: AnyObject]) { + guard let data = Data(jsonDictionary: jsonDictionary) else { + return nil + } + self.init(data: data, encoding: .utf8) + } + + func deserializeJSON(using encoding: String.Encoding = .utf8) -> [String: AnyObject]? { + guard let data = self.data(using: encoding) else { + return nil + } + return data.deserializeJSON() + } +} + +internal extension TimeInterval { + internal var formatshort: String { + var result = "0:00" + if self < TimeInterval(Int32.max) { + result = "" + var time = DateComponents() + time.hour = Int(self / 3600) + time.minute = Int((self.truncatingRemainder(dividingBy: 3600)) / 60) + time.second = Int(self.truncatingRemainder(dividingBy: 60)) + let formatter = NumberFormatter() + formatter.paddingCharacter = "0" + formatter.minimumIntegerDigits = 2 + formatter.maximumFractionDigits = 0 + let formatterFirst = NumberFormatter() + formatterFirst.maximumFractionDigits = 0 + if time.hour! > 0 { + result = "\(formatterFirst.string(from: NSNumber(value: time.hour!))!):\(formatter.string(from: NSNumber(value: time.minute!))!):\(formatter.string(from: NSNumber(value: time.second!))!)" + } else { + result = "\(formatterFirst.string(from: NSNumber(value: time.minute!))!):\(formatter.string(from: NSNumber(value: time.second!))!)" + } + } + result = result.trimmingCharacters(in: CharacterSet(charactersIn: ": ")) + return result + } +} + +extension NSPredicate { + func findValue(forKey key: String?, operator op: NSComparisonPredicate.Operator? = nil) -> Any? { + let val = findAllValues(forKey: key).lazy.filter { (op == nil || $0.operator == op!) && !$0.not } + return val.first?.value + } + + func findAllValues(forKey key: String?) -> [(value: Any, operator: NSComparisonPredicate.Operator, not: Bool)] { + if let cQuery = self as? NSCompoundPredicate { + let find = cQuery.subpredicates.flatMap { ($0 as! NSPredicate).findAllValues(forKey: key) } + if cQuery.compoundPredicateType == .not { + return find.map { return ($0.value, $0.operator, !$0.not) } + } + return find + } else if let cQuery = self as? NSComparisonPredicate { + if cQuery.leftExpression.expressionType == .keyPath, key == nil || cQuery.leftExpression.keyPath == key!, let const = cQuery.rightExpression.constantValue { + return [(value: const, operator: cQuery.predicateOperatorType, false)] + } + if cQuery.rightExpression.expressionType == .keyPath, key == nil || cQuery.rightExpression.keyPath == key!, let const = cQuery.leftExpression.constantValue { + return [(value: const, operator: cQuery.predicateOperatorType, false)] + } + return [] + } else { + return [] + } + } +} + +extension URLError.Code: FoundationErrorEnum {} +extension CocoaError.Code: FoundationErrorEnum {} diff --git a/Sources/LocalFileProvider.swift b/Sources/LocalFileProvider.swift index 54b04c8..c92c053 100644 --- a/Sources/LocalFileProvider.swift +++ b/Sources/LocalFileProvider.swift @@ -291,7 +291,7 @@ open class LocalFileProvider: FileProvider, FileProviderMonitor, FileProvideUndo if sourcePath.hasSuffix("/") { try self.opFileManager.createDirectory(at: source, withIntermediateDirectories: true, attributes: [:]) } else { - try data?.write(to: source, options: Data.WritingOptions.atomic) + try data?.write(to: source, options: .atomic) } case .modify: try data?.write(to: source, options: atomically ? [.atomic] : []) diff --git a/Sources/LocalHelper.swift b/Sources/LocalHelper.swift index a7f4fab..3f03453 100644 --- a/Sources/LocalHelper.swift +++ b/Sources/LocalHelper.swift @@ -323,17 +323,3 @@ class UndoBox: NSObject { self.undoOperation = undoOperation } } - -internal extension URL { - var fileIsDirectory: Bool { - return (try? self.resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory ?? false - } - - var fileSize: Int64 { - return Int64((try? self.resourceValues(forKeys: [.fileSizeKey]))?.fileSize ?? -1) - } - - var fileExists: Bool { - return self.isFileURL && FileManager.default.fileExists(atPath: self.path) - } -} diff --git a/Sources/OneDriveFileProvide.swift b/Sources/OneDriveFileProvide.swift index e7b6327..0fe25b0 100644 --- a/Sources/OneDriveFileProvide.swift +++ b/Sources/OneDriveFileProvide.swift @@ -105,7 +105,7 @@ open class OneDriveFileProvider: FileProviderBasicRemote { if let response = response as? HTTPURLResponse { let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) serverError = code != nil ? FileProviderOneDriveError(code: code!, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) : nil - if let data = data, let jsonStr = String(data: data, encoding: .utf8), let json = jsonToDictionary(jsonStr), let file = OneDriveFileObject(baseURL: self.baseURL, drive: self.drive, json: json) { + if let json = data?.deserializeJSON(), let file = OneDriveFileObject(baseURL: self.baseURL, drive: self.drive, json: json) { fileObject = file } } @@ -121,7 +121,7 @@ open class OneDriveFileProvider: FileProviderBasicRemote { let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var totalSize: Int64 = -1 var usedSize: Int64 = 0 - if let data = data, let jsonStr = String(data: data, encoding: .utf8), let json = jsonToDictionary(jsonStr) { + if let json = data?.deserializeJSON() { totalSize = (json["total"] as? NSNumber)?.int64Value ?? -1 usedSize = (json["used"] as? NSNumber)?.int64Value ?? 0 } @@ -236,7 +236,7 @@ extension OneDriveFileProvider: FileProviderOperations { request.setValue("application/json", forHTTPHeaderField: "Content-Type") requestDictionary["parentReference"] = ("/drive/\(drive):" + dest.deletingLastPathComponent) as NSString requestDictionary["name"] = dest.lastPathComponent as NSString - request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) + request.httpBody = Data(jsonDictionary: requestDictionary) } let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var serverError: FileProviderOneDriveError? @@ -356,14 +356,14 @@ extension OneDriveFileProvider: FileProviderReadWrite { var request = URLRequest(url: self.url(of: path, modifier: "action.createLink")) request.httpMethod = "POST" let requestDictionary: [String: AnyObject] = ["type": "view" as NSString] - request.httpBody = dictionaryToJSON(requestDictionary)?.data(using: .utf8) + request.httpBody = Data(jsonDictionary: requestDictionary) let task = session.dataTask(with: request, completionHandler: { (data, response, error) in var serverError: FileProviderOneDriveError? var link: URL? if let response = response as? HTTPURLResponse { let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) serverError = code != nil ? FileProviderOneDriveError(code: code!, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) : nil - if let data = data, let jsonStr = String(data: data, encoding: .utf8), let json = jsonToDictionary(jsonStr) { + if let json = data?.deserializeJSON() { if let linkDic = json["link"] as? NSDictionary, let linkStr = linkDic["webUrl"] as? String { link = URL(string: linkStr) } @@ -432,7 +432,7 @@ extension OneDriveFileProvider: ExtendedFileProvider { if let response = response as? HTTPURLResponse { let code = FileProviderHTTPErrorCode(rawValue: response.statusCode) serverError = code != nil ? FileProviderOneDriveError(code: code!, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) : nil - if let data = data, let jsonStr = String(data: data, encoding: .utf8), let json = jsonToDictionary(jsonStr) { + if let json = data?.deserializeJSON() { (dic, keys) = self.mapMediaInfo(json) } } diff --git a/Sources/OneDriveHelper.swift b/Sources/OneDriveHelper.swift index a798e76..581a8fc 100644 --- a/Sources/OneDriveHelper.swift +++ b/Sources/OneDriveHelper.swift @@ -27,7 +27,7 @@ public final class OneDriveFileObject: FileObject { } internal convenience init? (baseURL: URL?, drive: String, jsonStr: String) { - guard let json = jsonToDictionary(jsonStr) else { return nil } + guard let json = jsonStr.deserializeJSON() else { return nil } self.init(baseURL: baseURL, drive: drive, json: json) } @@ -92,15 +92,14 @@ internal extension OneDriveFileProvider { if let code = (response as? HTTPURLResponse)?.statusCode , code >= 300, let rCode = FileProviderHTTPErrorCode(rawValue: code) { responseError = FileProviderOneDriveError(code: rCode, path: path, errorDescription: String(data: data ?? Data(), encoding: .utf8)) } - if let data = data, let jsonStr = String(data: data, encoding: .utf8) { - let json = jsonToDictionary(jsonStr) - if let entries = json?["value"] as? [AnyObject] , entries.count > 0 { + if let json = data?.deserializeJSON() { + if let entries = json["value"] as? [AnyObject] , entries.count > 0 { for entry in entries { if let entry = entry as? [String: AnyObject], let file = OneDriveFileObject(baseURL: self.baseURL, drive: self.drive, json: entry) { files.append(file) } } - let ncursor: URL? = (json?["@odata.nextLink"] as? String).flatMap { URL(string: $0) } + let ncursor: URL? = (json["@odata.nextLink"] as? String).flatMap { URL(string: $0) } let hasmore = ncursor != nil if hasmore { self.list(path, cursor: ncursor, prevContents: files, completionHandler: completionHandler) @@ -181,15 +180,14 @@ internal extension OneDriveFileProvider { if let code = (response as? HTTPURLResponse)?.statusCode , code >= 300, let rCode = FileProviderHTTPErrorCode(rawValue: code) { responseError = FileProviderOneDriveError(code: rCode, path: startPath, errorDescription: String(data: data ?? Data(), encoding: .utf8)) } - if let data = data, let jsonStr = String(data: data, encoding: .utf8) { - let json = jsonToDictionary(jsonStr) - if let entries = json?["value"] as? [AnyObject] , entries.count > 0 { + if let json = data?.deserializeJSON() { + if let entries = json["value"] as? [AnyObject] , entries.count > 0 { for entry in entries { if let entry = entry as? [String: AnyObject], let file = OneDriveFileObject(baseURL: self.baseURL, drive: self.drive, json: entry) { foundItem(file) } } - let next: URL? = (json?["@odata.nextLink"] as? String).flatMap { URL(string: $0) } + let next: URL? = (json["@odata.nextLink"] as? String).flatMap { URL(string: $0) } if let next = next { self.search(startPath, query: query, next: next, foundItem: foundItem, completionHandler: completionHandler) } else { @@ -247,7 +245,7 @@ internal extension OneDriveFileProvider { add(key: "Location", value: "\(latStr), \(longStr)") } if let parent = json["image"] as? [String: Any] ?? json["video"] as? [String: Any], let duration = parent["duration"] as? UInt64 { - add(key: "Duration", value: OneDriveFileProvider.formatshort(interval: TimeInterval(duration) / 1000)) + add(key: "Duration", value: (TimeInterval(duration) / 1000).formatshort) } if let timeTakenStr = json["takenDateTime"] as? String, let timeTaken = resolve(dateString: timeTakenStr) { OneDriveFileProvider.dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" diff --git a/Sources/RemoteSession.swift b/Sources/RemoteSession.swift index b50de56..d0b4542 100644 --- a/Sources/RemoteSession.swift +++ b/Sources/RemoteSession.swift @@ -102,7 +102,7 @@ class SessionDelegate: NSObject, URLSessionDataDelegate, URLSessionDownloadDeleg func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { self.didSendDataHandler?(session, task, bytesSent, totalBytesSent, totalBytesExpectedToSend) - guard let desc = task.taskDescription, let json = jsonToDictionary(desc), + guard let json = task.taskDescription?.deserializeJSON(), let op = FileOperationType(json: json), let fileProvider = fileProvider else { return } @@ -115,7 +115,7 @@ class SessionDelegate: NSObject, URLSessionDataDelegate, URLSessionDownloadDeleg func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { self.didReceivedData?(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) - guard let desc = downloadTask.taskDescription, let json = jsonToDictionary(desc), + guard let json = downloadTask.taskDescription?.deserializeJSON(), let op = FileOperationType(json: json), let fileProvider = fileProvider else { return } diff --git a/Sources/SMBTypes/SMB2DataTypes.swift b/Sources/SMBTypes/SMB2DataTypes.swift index 4f30499..309151e 100644 --- a/Sources/SMBTypes/SMB2DataTypes.swift +++ b/Sources/SMBTypes/SMB2DataTypes.swift @@ -66,32 +66,3 @@ struct SMBTime { return Date(timeIntervalSince1970: Double(self.time) / 10000000 - 11644473600) } } - -extension Data { - init(value: T) { - var value = value - self = Data(buffer: UnsafeBufferPointer(start: &value, count: 1)) - } - - func scanValue() -> T? { - guard MemoryLayout.size <= self.count else { return nil } - return self.withUnsafeBytes { $0.pointee } - } - - func scanValue(start: Int) -> T? { - let length = MemoryLayout.size - guard self.count >= start + length else { return nil } - return self.subdata(in: start.. String? { - guard self.count >= start + length else { return nil } - return String(data: self.subdata(in: start..(from: T) -> U? { - guard MemoryLayout.size >= MemoryLayout.size else { return nil } - let data = Data(value: from) - return data.scanValue() - } -} diff --git a/Sources/SMBTypes/SMB2IOCtl.swift b/Sources/SMBTypes/SMB2IOCtl.swift index 629a1fc..bece831 100644 --- a/Sources/SMBTypes/SMB2IOCtl.swift +++ b/Sources/SMBTypes/SMB2IOCtl.swift @@ -243,7 +243,7 @@ extension SMB2 { if data.count < offset + 48 { return nil } - let datestring = data.scanString(start: offset, length: 48, encoding: .utf16) + let datestring = data.scanString(start: offset, length: 48, using: .utf16) if let datestring = datestring, let date = dateFormatter.date(from: datestring) { snapshots.append(SMBTime(date: date)) } diff --git a/Sources/SMBTypes/SMB2Notification.swift b/Sources/SMBTypes/SMB2Notification.swift index d94f2bf..23cdb92 100644 --- a/Sources/SMBTypes/SMB2Notification.swift +++ b/Sources/SMBTypes/SMB2Notification.swift @@ -92,7 +92,7 @@ extension SMB2 { } let fileNameLen = Int(data.scanValue(start: offset + 8) as UInt32? ?? 0) - let fileName = data.scanString(start: offset + 12, length: fileNameLen, encoding: .utf16) ?? "" + let fileName = data.scanString(start: offset + 12, length: fileNameLen, using: .utf16) ?? "" result.append((action: action, fileName: fileName)) offset += Int(nextOffset) diff --git a/Sources/SMBTypes/SMB2Query.swift b/Sources/SMBTypes/SMB2Query.swift index 2928194..3a4a3b3 100644 --- a/Sources/SMBTypes/SMB2Query.swift +++ b/Sources/SMBTypes/SMB2Query.swift @@ -85,7 +85,7 @@ extension SMB2 { return [] } let headersize = MemoryLayout.size(ofValue: header) - let fileName = buffer.scanString(start: headersize, length: Int(header.fileNameLength), encoding: .utf16) ?? "" + let fileName = buffer.scanString(start: headersize, length: Int(header.fileNameLength), using: .utf16) ?? "" result.append((header: header, fileName: fileName)) if header.nextEntryOffset == 0 { break @@ -216,12 +216,12 @@ extension SMB2 { var asAllInformation: (header: FileAllInformationHeader, name: String) { let header: FileAllInformationHeader = buffer.scanValue()! let headersize = MemoryLayout.size - let name = buffer.scanString(start: headersize, length: Int(header.nameLength), encoding: .utf16) ?? "" + let name = buffer.scanString(start: headersize, length: Int(header.nameLength), using: .utf16) ?? "" return (header, name) } var asAlternateNameInformation: String { - return buffer.scanString(start: 0, length: buffer.count, encoding: .utf16) ?? "" + return buffer.scanString(start: 0, length: buffer.count, using: .utf16) ?? "" } var asAttributeTagInformation: FileAttributeTagInformation { @@ -280,14 +280,14 @@ extension SMB2 { var asStreamInformation: (header: FileStreamInformationHeader, name: String) { let header: FileStreamInformationHeader = buffer.scanValue()! let headersize = MemoryLayout.size - let name = buffer.scanString(start: headersize, length: Int(header.streamNameLength), encoding: .utf16) ?? "" + let name = buffer.scanString(start: headersize, length: Int(header.streamNameLength), using: .utf16) ?? "" return (header, name) } var asFsVolumeInformation: (header: FileFsVolumeInformationHeader, name: String) { let header: FileFsVolumeInformationHeader = buffer.scanValue()! let headersize = MemoryLayout.size - let name = buffer.scanString(start: headersize, length: Int(header.labelLength), encoding: .utf16) ?? "" + let name = buffer.scanString(start: headersize, length: Int(header.labelLength), using: .utf16) ?? "" return (header, name) } @@ -302,7 +302,7 @@ extension SMB2 { var asFsAttributeInformation: (header: FileFsAttributeInformationHeader, name: String) { let header: FileFsAttributeInformationHeader = buffer.scanValue()! let headersize = MemoryLayout.size - let name = buffer.scanString(start: headersize, length: Int(header.nameLength), encoding: .utf16) ?? "" + let name = buffer.scanString(start: headersize, length: Int(header.nameLength), using: .utf16) ?? "" return (header, name) }