Skip to content

Commit 5a17914

Browse files
authored
Revert "Implemented _getFileSystemRepresentation for Windows"
1 parent 2bf476e commit 5a17914

File tree

6 files changed

+46
-173
lines changed

6 files changed

+46
-173
lines changed

CoreFoundation/URL.subproj/CFURL.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3965,13 +3965,10 @@ CF_EXPORT void __CFURLSetResourceInfoPtr(CFURLRef url, void *ptr) {
39653965
/* HFSPath<->URLPath functions at the bottom of the file */
39663966
static CFArrayRef WindowsPathToURLComponents(CFStringRef path, CFAllocatorRef alloc, Boolean isDir, Boolean isAbsolute) CF_RETURNS_RETAINED {
39673967
CFArrayRef tmp;
3968-
CFMutableStringRef mutablePath = CFStringCreateMutableCopy(alloc, 0, path);
39693968
CFMutableArrayRef urlComponents = NULL;
39703969
CFIndex i=0;
3971-
// Since '/' is a valid Windows path separator, we convert / to \ before splitting
3972-
CFStringFindAndReplace(mutablePath, CFSTR("/"), CFSTR("\\"), CFRangeMake(0, CFStringGetLength(mutablePath)), 0);
3973-
tmp = CFStringCreateArrayBySeparatingStrings(alloc, mutablePath, CFSTR("\\"));
3974-
CFRelease(mutablePath);
3970+
3971+
tmp = CFStringCreateArrayBySeparatingStrings(alloc, path, CFSTR("\\"));
39753972
urlComponents = CFArrayCreateMutableCopy(alloc, 0, tmp);
39763973
CFRelease(tmp);
39773974

Foundation/FileManager+Win32.swift

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ extension FileManager {
637637
var szDirectory: [WCHAR] = Array<WCHAR>(repeating: 0, count: Int(dwLength + 1))
638638

639639
GetCurrentDirectoryW(dwLength, &szDirectory)
640-
return String(decodingCString: &szDirectory, as: UTF16.self).standardizingPath
640+
return String(decodingCString: &szDirectory, as: UTF16.self)
641641
}
642642

643643
@discardableResult
@@ -701,8 +701,8 @@ extension FileManager {
701701
return true
702702
}
703703

704-
internal func _lstatFile(atPath path: String, withFileSystemRepresentation fsRep: UnsafePointer<NativeFSRCharType>? = nil) throws -> stat {
705-
let _fsRep: UnsafePointer<NativeFSRCharType>
704+
internal func _lstatFile(atPath path: String, withFileSystemRepresentation fsRep: UnsafePointer<Int8>? = nil) throws -> stat {
705+
let _fsRep: UnsafePointer<Int8>
706706
if fsRep == nil {
707707
_fsRep = try __fileSystemRepresentation(withPath: path)
708708
} else {
@@ -714,13 +714,15 @@ extension FileManager {
714714
}
715715

716716
var statInfo = stat()
717-
let h = CreateFileW(_fsRep,
718-
/*dwDesiredAccess=*/DWORD(0),
719-
DWORD(FILE_SHARE_READ),
720-
/*lpSecurityAttributes=*/nil,
721-
DWORD(OPEN_EXISTING),
722-
DWORD(FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS),
723-
/*hTemplateFile=*/nil)
717+
let h = path.withCString(encodedAs: UTF16.self) {
718+
CreateFileW(/*lpFileName=*/$0,
719+
/*dwDesiredAccess=*/DWORD(0),
720+
/*dwShareMode=*/DWORD(FILE_SHARE_READ),
721+
/*lpSecurityAttributes=*/nil,
722+
/*dwCreationDisposition=*/DWORD(OPEN_EXISTING),
723+
/*dwFlagsAndAttributes=*/DWORD(FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS),
724+
/*hTemplateFile=*/nil)
725+
}
724726
if h == INVALID_HANDLE_VALUE {
725727
throw _NSErrorWithWindowsError(GetLastError(), reading: false, paths: [path])
726728
}
@@ -856,7 +858,7 @@ extension FileManager {
856858
}
857859

858860
internal func _updateTimes(atPath path: String,
859-
withFileSystemRepresentation fsr: UnsafePointer<NativeFSRCharType>,
861+
withFileSystemRepresentation fsr: UnsafePointer<Int8>,
860862
creationTime: Date? = nil,
861863
accessTime: Date? = nil,
862864
modificationTime: Date? = nil) throws {
@@ -867,7 +869,10 @@ extension FileManager {
867869
var mtime: FILETIME =
868870
FILETIME(from: time_t((modificationTime ?? stat.lastModificationDate).timeIntervalSince1970))
869871

870-
let hFile = CreateFileW(fsr, DWORD(GENERIC_WRITE), DWORD(FILE_SHARE_WRITE), nil, DWORD(OPEN_EXISTING), 0, nil)
872+
let hFile: HANDLE = String(utf8String: fsr)!.withCString(encodedAs: UTF16.self) {
873+
CreateFileW($0, DWORD(GENERIC_WRITE), DWORD(FILE_SHARE_WRITE),
874+
nil, DWORD(OPEN_EXISTING), 0, nil)
875+
}
871876
if hFile == INVALID_HANDLE_VALUE {
872877
throw _NSErrorWithWindowsError(GetLastError(), reading: true, paths: [path])
873878
}

Foundation/FileManager.swift

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,6 @@ import CoreFoundation
2020
import MSVCRT
2121
#endif
2222

23-
#if os(Windows)
24-
internal typealias NativeFSRCharType = WCHAR
25-
let NativeFSREncoding = String.Encoding.utf16LittleEndian.rawValue
26-
#else
27-
internal typealias NativeFSRCharType = CChar
28-
let NativeFSREncoding = String.Encoding.utf8.rawValue
29-
#endif
30-
3123
open class FileManager : NSObject {
3224

3325
/* Returns the default singleton instance.
@@ -391,12 +383,7 @@ open class FileManager : NSObject {
391383
#elseif os(Linux) || os(Android) || os(Windows)
392384
let modeT = number.uint32Value
393385
#endif
394-
#if os(Windows)
395-
let result = _wchmod(fsRep, mode_t(modeT))
396-
#else
397-
let result = chmod(fsRep, mode_t(modeT))
398-
#endif
399-
guard result == 0 else {
386+
guard chmod(fsRep, mode_t(modeT)) == 0 else {
400387
throw _NSErrorWithErrno(errno, reading: false, path: path)
401388
}
402389

@@ -1034,29 +1021,15 @@ open class FileManager : NSObject {
10341021
*/
10351022
open func fileSystemRepresentation(withPath path: String) -> UnsafePointer<Int8> {
10361023
precondition(path != "", "Empty path argument")
1037-
#if os(Windows)
1038-
// On Windows, the internal _fileSystemRepresentation returns
1039-
// UTF16 encoded data, so we need to re-encode the result as
1040-
// UTF8 before returning.
1041-
return try! _fileSystemRepresentation(withPath: path) {
1042-
String(decodingCString: $0, as: UTF16.self).withCString() {
1043-
let sz = strnlen($0, Int(MAX_PATH))
1044-
let buf = UnsafeMutablePointer<Int8>.allocate(capacity: sz + 1)
1045-
buf.initialize(from: $0, count: sz + 1)
1046-
return UnsafePointer(buf)
1047-
}
1048-
}
1049-
#else
10501024
return try! __fileSystemRepresentation(withPath: path)
1051-
#endif
10521025
}
10531026

1054-
internal func __fileSystemRepresentation(withPath path: String) throws -> UnsafePointer<NativeFSRCharType> {
1027+
internal func __fileSystemRepresentation(withPath path: String) throws -> UnsafePointer<Int8> {
10551028
let len = CFStringGetMaximumSizeOfFileSystemRepresentation(path._cfObject)
10561029
if len != kCFNotFound {
1057-
let buf = UnsafeMutablePointer<NativeFSRCharType>.allocate(capacity: len)
1030+
let buf = UnsafeMutablePointer<Int8>.allocate(capacity: len)
10581031
buf.initialize(repeating: 0, count: len)
1059-
if path._nsObject._getFileSystemRepresentation(buf, maxLength: len) {
1032+
if path._nsObject.getFileSystemRepresentation(buf, maxLength: len) {
10601033
return UnsafePointer(buf)
10611034
}
10621035
buf.deinitialize(count: len)
@@ -1065,13 +1038,13 @@ open class FileManager : NSObject {
10651038
throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.fileReadInvalidFileName.rawValue, userInfo: [NSFilePathErrorKey: path])
10661039
}
10671040

1068-
internal func _fileSystemRepresentation<ResultType>(withPath path: String, _ body: (UnsafePointer<NativeFSRCharType>) throws -> ResultType) throws -> ResultType {
1041+
internal func _fileSystemRepresentation<ResultType>(withPath path: String, _ body: (UnsafePointer<Int8>) throws -> ResultType) throws -> ResultType {
10691042
let fsRep = try __fileSystemRepresentation(withPath: path)
10701043
defer { fsRep.deallocate() }
10711044
return try body(fsRep)
10721045
}
10731046

1074-
internal func _fileSystemRepresentation<ResultType>(withPath path1: String, andPath path2: String, _ body: (UnsafePointer<NativeFSRCharType>, UnsafePointer<NativeFSRCharType>) throws -> ResultType) throws -> ResultType {
1047+
internal func _fileSystemRepresentation<ResultType>(withPath path1: String, andPath path2: String, _ body: (UnsafePointer<Int8>, UnsafePointer<Int8>) throws -> ResultType) throws -> ResultType {
10751048
let fsRep1 = try __fileSystemRepresentation(withPath: path1)
10761049
defer { fsRep1.deallocate() }
10771050
let fsRep2 = try __fileSystemRepresentation(withPath: path2)
@@ -1085,7 +1058,7 @@ open class FileManager : NSObject {
10851058
open func string(withFileSystemRepresentation str: UnsafePointer<Int8>, length len: Int) -> String {
10861059
return NSString(bytes: str, length: len, encoding: String.Encoding.utf8.rawValue)!._swiftObject
10871060
}
1088-
1061+
10891062
/* -replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error: is for developers who wish to perform a safe-save without using the full NSDocument machinery that is available in the AppKit.
10901063

10911064
The `originalItemURL` is the item being replaced.

Foundation/NSPathUtilities.swift

Lines changed: 6 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public func NSTemporaryDirectory() -> String {
2222
guard GetTempPathW(DWORD(wszPath.count), &wszPath) <= cchLength else {
2323
preconditionFailure("GetTempPathW mutation race")
2424
}
25-
return String(decodingCString: wszPath, as: UTF16.self).standardizingPath
25+
return String(decodingCString: wszPath, as: UTF16.self)
2626
#else
2727
#if canImport(Darwin)
2828
let safe_confstr = { (name: Int32, buf: UnsafeMutablePointer<Int8>?, len: Int) -> Int in
@@ -348,32 +348,14 @@ extension NSString {
348348

349349
return result
350350
}
351-
352-
#if os(Windows)
353-
// Convert to a posix style '/' separated path
354-
internal var unixPath: String {
355-
var droppedPrefix = self as String
356-
// If there is anything before the drive letter,
357-
// e.g. "\\?\, \\host\, \??\", remove it
358-
if isAbsolutePath, let idx = droppedPrefix.firstIndex(of: ":") {
359-
droppedPrefix.removeSubrange(..<droppedPrefix.index(before: idx))
360-
}
361-
let slashesConverted = String(droppedPrefix.map({ $0 == "\\" ? "/" : $0 }))
362-
let compressTrailing = slashesConverted._stringByFixingSlashes(stripTrailing: false)
363-
return compressTrailing
364-
}
365-
#endif
366-
351+
367352
public var standardizingPath: String {
368-
#if os(Windows)
369-
let expanded = unixPath.expandingTildeInPath
370-
#else
371353
let expanded = expandingTildeInPath
372-
#endif
373-
let resolved = expanded._bridgeToObjectiveC().resolvingSymlinksInPath
354+
var resolved = expanded._bridgeToObjectiveC().resolvingSymlinksInPath
374355

375356
let automount = "/var/automount"
376-
return resolved._tryToRemovePathPrefix(automount) ?? resolved
357+
resolved = resolved._tryToRemovePathPrefix(automount) ?? resolved
358+
return resolved
377359
}
378360

379361
public var resolvingSymlinksInPath: String {
@@ -572,61 +554,11 @@ extension NSString {
572554
}
573555

574556
public func getFileSystemRepresentation(_ cname: UnsafeMutablePointer<Int8>, maxLength max: Int) -> Bool {
575-
#if os(Windows)
576-
let fsr = UnsafeMutablePointer<WCHAR>.allocate(capacity: max)
577-
defer { fsr.deallocate() }
578-
guard _getFileSystemRepresentation(fsr, maxLength: max) else { return false }
579-
return String(decodingCString: fsr, as: UTF16.self).withCString() {
580-
let chars = strnlen_s($0, max)
581-
guard chars < max else { return false }
582-
cname.assign(from: $0, count: chars + 1)
583-
return true
584-
}
585-
#else
586-
return _getFileSystemRepresentation(cname, maxLength: max)
587-
#endif
588-
}
589-
590-
internal func _getFileSystemRepresentation(_ cname: UnsafeMutablePointer<NativeFSRCharType>, maxLength max: Int) -> Bool {
591557
guard self.length > 0 else {
592558
return false
593559
}
594-
#if os(Windows)
595-
var fsr = self._swiftObject
596-
let idx = fsr.startIndex
597-
598-
// If we have an RFC 8089 style path e.g. `/[drive-letter]:/...`, drop the
599-
// leading /, otherwise, a leading slash indicates a rooted path on the
600-
// drive for the current working directory
601-
if fsr.count >= 3 && fsr[idx] == "/" && fsr[fsr.index(after: idx)].isLetter && fsr[fsr.index(idx, offsetBy: 2)] == ":" {
602-
fsr.removeFirst()
603-
}
604-
605-
// Windows APIS that go through the path parser can handle
606-
// forward slashes in paths. However, symlinks created with
607-
// forward slashes do not resolve properly, so we normalize
608-
// the path separators anyways.
609-
fsr = fsr.replacingOccurrences(of: "/", with: "\\")
610-
611-
// Drop trailing slashes unless it follows a drive letter. On
612-
// Windows the path `C:\` indicates the root directory of the
613-
// `C:` drive. The path `C:` indicates the current working
614-
// directory on the `C:` drive.
615-
while fsr.count > 1
616-
&& (fsr[fsr.index(before: fsr.endIndex)] == "\\")
617-
&& !(fsr.count == 3 && fsr[fsr.index(fsr.endIndex, offsetBy: -2)] == ":") {
618-
fsr.removeLast()
619-
}
620-
621-
return fsr.withCString(encodedAs: UTF16.self) {
622-
let wchars = wcsnlen_s($0, max)
623-
guard wchars < max else { return false }
624-
cname.assign(from: $0, count: wchars + 1)
625-
return true
626-
}
627-
#else
560+
628561
return CFStringGetFileSystemRepresentation(self._cfObject, cname, max)
629-
#endif
630562
}
631563

632564
}

Foundation/NSURL.swift

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,7 @@ private func _standardizedPath(_ path: String) -> String {
3030
if !path.isAbsolutePath {
3131
return path._nsObject.standardizingPath
3232
}
33-
#if os(Windows)
34-
return path.unixPath
35-
#else
3633
return path
37-
#endif
3834
}
3935

4036
internal func _pathComponents(_ path: String?) -> [String]? {
@@ -339,7 +335,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
339335
let thePath = _standardizedPath(path)
340336

341337
var isDir: ObjCBool = false
342-
if validPathSeps.contains(where: { thePath.hasSuffix(String($0)) }) {
338+
if thePath.hasSuffix("/") {
343339
isDir = true
344340
} else {
345341
let absolutePath: String
@@ -360,9 +356,16 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
360356
}
361357

362358
public init(fileURLWithPath path: String) {
363-
let thePath = _standardizedPath(path)
359+
let thePath: String
360+
let pathString = NSString(string: path)
361+
if !pathString.isAbsolutePath {
362+
thePath = pathString.standardizingPath
363+
} else {
364+
thePath = path
365+
}
366+
364367
var isDir: ObjCBool = false
365-
if validPathSeps.contains(where: { thePath.hasSuffix(String($0)) }) {
368+
if thePath.hasSuffix("/") {
366369
isDir = true
367370
} else {
368371
if !FileManager.default.fileExists(atPath: path, isDirectory: &isDir) {
@@ -539,19 +542,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
539542

540543
open var path: String? {
541544
let absURL = CFURLCopyAbsoluteURL(_cfObject)
542-
guard var url = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle)?._swiftObject else {
543-
return nil
544-
}
545-
#if os(Windows)
546-
// Per RFC 8089:E.2, if we have an absolute Windows/DOS path
547-
// we can begin the url with a drive letter rather than a '/'
548-
let scalars = Array(url.unicodeScalars)
549-
if isFileURL, url.isAbsolutePath,
550-
scalars.count >= 3, scalars[0] == "/", scalars[2] == ":" {
551-
url.removeFirst()
552-
}
553-
#endif
554-
return url
545+
return CFURLCopyFileSystemPath(absURL, kCFURLPlatformPathStyle)?._swiftObject
555546
}
556547

557548
open var fragment: String? {
@@ -568,7 +559,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
568559

569560
// The same as path if baseURL is nil
570561
open var relativePath: String? {
571-
return CFURLCopyFileSystemPath(_cfObject, kCFURLPOSIXPathStyle)?._swiftObject
562+
return CFURLCopyFileSystemPath(_cfObject, kCFURLPlatformPathStyle)?._swiftObject
572563
}
573564

574565
/* Determines if a given URL string's path represents a directory (i.e. the path component in the URL string ends with a '/' character). This does not check the resource the URL refers to.

0 commit comments

Comments
 (0)