@@ -12,10 +12,12 @@ import CoreFoundation
12
12
#if os(Windows)
13
13
internal func joinPath( prefix: String , suffix: String ) -> String {
14
14
var pszPath : PWSTR ?
15
- _ = prefix. withCString ( encodedAs: UTF16 . self) { prefix in
16
- _ = suffix. withCString ( encodedAs: UTF16 . self) { suffix in
17
- PathAllocCombine ( prefix, suffix, ULONG ( PATHCCH_ALLOW_LONG_PATHS . rawValue) , & pszPath)
18
- }
15
+
16
+ guard !prefix. isEmpty else { return suffix }
17
+ guard !suffix. isEmpty else { return prefix }
18
+
19
+ _ = try ! FileManager . default. _fileSystemRepresentation ( withPath: prefix, andPath: suffix) {
20
+ PathAllocCombine ( $0, $1, ULONG ( PATHCCH_ALLOW_LONG_PATHS . rawValue) , & pszPath)
19
21
}
20
22
21
23
let path : String = String ( decodingCString: pszPath!, as: UTF16 . self)
@@ -196,7 +198,7 @@ extension FileManager {
196
198
guard path != " " else {
197
199
throw NSError ( domain: NSCocoaErrorDomain, code: CocoaError . fileReadInvalidFileName. rawValue, userInfo: [ NSFilePathErrorKey : NSString ( path) ] )
198
200
}
199
- try ( path + " \\ * " ) . withCString ( encodedAs : UTF16 . self ) {
201
+ try FileManager . default . _fileSystemRepresentation ( withPath : path + " \\ * " ) {
200
202
var ffd : WIN32_FIND_DATAW = WIN32_FIND_DATAW ( )
201
203
202
204
let hDirectory : HANDLE = FindFirstFileW ( $0, & ffd)
@@ -250,20 +252,19 @@ extension FileManager {
250
252
internal func _attributesOfFileSystem( forPath path: String ) throws -> [ FileAttributeKey : Any ] {
251
253
var result : [ FileAttributeKey : Any ] = [ : ]
252
254
253
- try path . withCString ( encodedAs : UTF16 . self ) {
255
+ try FileManager . default . _fileSystemRepresentation ( withPath : path ) {
254
256
let dwLength : DWORD = GetFullPathNameW ( $0, 0 , nil , nil )
255
- guard dwLength != 0 else {
257
+ guard dwLength > 0 else {
256
258
throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: true , paths: [ path] )
257
259
}
258
- var szVolumePath : [ WCHAR ] = Array < WCHAR > ( repeating: 0 , count: Int ( dwLength + 1 ) )
259
260
261
+ var szVolumePath : [ WCHAR ] = Array < WCHAR > ( repeating: 0 , count: Int ( dwLength + 1 ) )
260
262
guard GetVolumePathNameW ( $0, & szVolumePath, dwLength) else {
261
263
throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: true , paths: [ path] )
262
264
}
263
265
264
266
var liTotal : ULARGE_INTEGER = ULARGE_INTEGER ( )
265
267
var liFree : ULARGE_INTEGER = ULARGE_INTEGER ( )
266
-
267
268
guard GetDiskFreeSpaceExW ( & szVolumePath, nil , & liTotal, & liFree) else {
268
269
throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: true , paths: [ path] )
269
270
}
@@ -412,24 +413,26 @@ extension FileManager {
412
413
}
413
414
414
415
internal func _canonicalizedPath( toFileAtPath path: String ) throws -> String {
415
- var hFile : HANDLE = INVALID_HANDLE_VALUE
416
- path. withCString ( encodedAs: UTF16 . self) { link in
416
+ let hFile : HANDLE = try FileManager . default. _fileSystemRepresentation ( withPath: path) {
417
417
// BACKUP_SEMANTICS are (confusingly) required in order to receive a
418
418
// handle to a directory
419
- hFile = CreateFileW ( link , 0 , DWORD ( FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE ) ,
420
- nil , DWORD ( OPEN_EXISTING ) , DWORD ( FILE_FLAG_BACKUP_SEMANTICS ) ,
421
- nil )
422
- }
423
- guard hFile != INVALID_HANDLE_VALUE else {
424
- return try path . withCString ( encodedAs : UTF16 . self ) {
425
- var dwLength = GetFullPathNameW ( $0 , 0 , nil , nil )
426
- var szPath = Array < WCHAR > ( repeating : 0 , count : Int ( dwLength + 1 ) )
427
- dwLength = GetFullPathNameW ( $0 , DWORD ( szPath . count ) , & szPath , nil )
428
- guard dwLength > 0 && dwLength <= szPath . count else {
429
- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading : true , paths : [ path ] )
430
- }
431
- return String ( decodingCString : szPath , as : UTF16 . self )
419
+ CreateFileW ( $ 0, /*dwDesiredAccess=*/ DWORD ( 0 ) ,
420
+ DWORD ( FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE ) ,
421
+ /*lpSecurityAttributes=*/ nil , DWORD ( OPEN_EXISTING ) ,
422
+ DWORD ( FILE_FLAG_BACKUP_SEMANTICS ) , /*hTemplateFile=*/ nil )
423
+ }
424
+ if hFile == INVALID_HANDLE_VALUE {
425
+ return try FileManager . default . _fileSystemRepresentation ( withPath : path ) {
426
+ var dwLength = GetFullPathNameW ( $0 , 0 , nil , nil )
427
+
428
+ var szPath = Array < WCHAR > ( repeating : 0 , count : Int ( dwLength + 1 ) )
429
+ dwLength = GetFullPathNameW ( $0 , DWORD ( szPath . count ) , & szPath , nil )
430
+ guard dwLength > 0 && dwLength <= szPath . count else {
431
+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading : true , paths : [ path ] )
432
432
}
433
+
434
+ return String ( decodingCString: szPath, as: UTF16 . self)
435
+ }
433
436
}
434
437
defer { CloseHandle ( hFile) }
435
438
@@ -441,13 +444,11 @@ extension FileManager {
441
444
}
442
445
443
446
internal func _copyRegularFile( atPath srcPath: String , toPath dstPath: String , variant: String = " Copy " ) throws {
444
- try srcPath. withCString ( encodedAs: UTF16 . self) { src in
445
- try dstPath. withCString ( encodedAs: UTF16 . self) { dst in
446
- if !CopyFileW( src, dst, false ) {
447
- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: true , paths: [ srcPath, dstPath] )
448
- }
449
- }
447
+ try FileManager . default. _fileSystemRepresentation ( withPath: srcPath, andPath: dstPath) {
448
+ if !CopyFileW( $0, $1, false ) {
449
+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: true , paths: [ srcPath, dstPath] )
450
450
}
451
+ }
451
452
}
452
453
453
454
internal func _copySymlink( atPath srcPath: String , toPath dstPath: String , variant: String = " Copy " ) throws {
@@ -539,19 +540,9 @@ extension FileManager {
539
540
return
540
541
}
541
542
542
- guard path != " " else {
543
- throw NSError ( domain: NSCocoaErrorDomain, code: CocoaError . fileReadInvalidFileName. rawValue, userInfo: [ NSFilePathErrorKey : NSString ( path) ] )
544
- }
545
-
546
- let url = URL ( fileURLWithPath: path)
547
- var fsrBuf : [ WCHAR ] = Array < WCHAR > ( repeating: 0 , count: Int ( MAX_PATH) )
548
- _CFURLGetWideFileSystemRepresentation ( url. _cfObject, false , & fsrBuf, Int ( MAX_PATH) )
549
- let length = wcsnlen_s ( & fsrBuf, fsrBuf. count)
550
- let fsrPath = String ( utf16CodeUnits: & fsrBuf, count: length)
551
-
552
543
let faAttributes : WIN32_FILE_ATTRIBUTE_DATA
553
544
do {
554
- faAttributes = try windowsFileAttributes ( atPath: fsrPath )
545
+ faAttributes = try windowsFileAttributes ( atPath: path )
555
546
} catch {
556
547
// removeItem on POSIX throws fileNoSuchFile rather than
557
548
// fileReadNoSuchFile that windowsFileAttributes will
@@ -562,29 +553,33 @@ extension FileManager {
562
553
throw error
563
554
}
564
555
}
556
+
565
557
if faAttributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY {
566
- let readableAttributes = faAttributes. dwFileAttributes & DWORD ( bitPattern: ~ FILE_ATTRIBUTE_READONLY)
567
- guard fsrPath. withCString ( encodedAs: UTF16 . self, { SetFileAttributesW ( $0, readableAttributes) } ) else {
568
- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ path] )
569
- }
558
+ if try ! FileManager. default. _fileSystemRepresentation ( withPath: path, {
559
+ SetFileAttributesW ( $0, faAttributes. dwFileAttributes & DWORD ( bitPattern: ~ FILE_ATTRIBUTE_READONLY) )
560
+ } ) {
561
+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ path] )
562
+ }
570
563
}
571
564
572
565
if faAttributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_DIRECTORY) == 0 {
573
- if !fsrPath . withCString ( encodedAs : UTF16 . self , DeleteFileW) {
574
- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ path] )
575
- }
576
- return
566
+ if try ! FileManager . default . _fileSystemRepresentation ( withPath : path , DeleteFileW) {
567
+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ path] )
568
+ }
569
+ return
577
570
}
578
- var dirStack = [ fsrPath]
571
+
572
+ var dirStack = [ path]
579
573
var itemPath = " "
580
574
while let currentDir = dirStack. popLast ( ) {
581
575
do {
582
576
itemPath = currentDir
583
577
guard alreadyConfirmed || shouldRemoveItemAtPath ( itemPath, isURL: isURL) else {
584
578
continue
585
579
}
586
- guard !itemPath. withCString ( encodedAs: UTF16 . self, RemoveDirectoryW) else {
587
- continue
580
+
581
+ if try FileManager . default. _fileSystemRepresentation ( withPath: itemPath, RemoveDirectoryW) {
582
+ continue
588
583
}
589
584
guard GetLastError ( ) == ERROR_DIR_NOT_EMPTY else {
590
585
throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ itemPath] )
@@ -593,7 +588,7 @@ extension FileManager {
593
588
var ffd : WIN32_FIND_DATAW = WIN32_FIND_DATAW ( )
594
589
let capacity = MemoryLayout . size ( ofValue: ffd. cFileName)
595
590
596
- let handle : HANDLE = try FileManager . default. _fileSystemRepresentation ( withPath: joinPath ( prefix : itemPath, suffix : " * " ) ) {
591
+ let handle : HANDLE = try FileManager . default. _fileSystemRepresentation ( withPath: itemPath + " \\ * " ) {
597
592
FindFirstFileW ( $0, & ffd)
598
593
}
599
594
if handle == INVALID_HANDLE_VALUE {
@@ -610,10 +605,11 @@ extension FileManager {
610
605
611
606
itemPath = " \( currentDir) \\ \( file) "
612
607
if ffd. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY {
613
- let readableAttributes = ffd. dwFileAttributes & DWORD ( bitPattern: ~ FILE_ATTRIBUTE_READONLY)
614
- guard itemPath. withCString ( encodedAs: UTF16 . self, { SetFileAttributesW ( $0, readableAttributes) } ) else {
615
- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ file] )
616
- }
608
+ if try ! FileManager. default. _fileSystemRepresentation ( withPath: itemPath, {
609
+ SetFileAttributesW ( $0, ffd. dwFileAttributes & DWORD ( bitPattern: ~ FILE_ATTRIBUTE_READONLY) )
610
+ } ) {
611
+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ file] )
612
+ }
617
613
}
618
614
619
615
if ( ffd. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_DIRECTORY) != 0 ) {
@@ -624,8 +620,8 @@ extension FileManager {
624
620
guard alreadyConfirmed || shouldRemoveItemAtPath ( itemPath, isURL: isURL) else {
625
621
continue
626
622
}
627
- if !itemPath . withCString ( encodedAs : UTF16 . self , DeleteFileW) {
628
- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ file] )
623
+ if try ! FileManager . default . _fileSystemRepresentation ( withPath : itemPath , DeleteFileW) {
624
+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ file] )
629
625
}
630
626
}
631
627
} while FindNextFileW ( handle, & ffd)
@@ -936,7 +932,7 @@ extension FileManager {
936
932
var ffd = WIN32_FIND_DATAW ( )
937
933
let capacity = MemoryLayout . size ( ofValue: ffd. cFileName)
938
934
939
- let handle = ( try ? FileManager . default. _fileSystemRepresentation ( withPath: joinPath ( prefix : _lastReturned. path, suffix : " * " ) ) {
935
+ let handle = ( try ? FileManager . default. _fileSystemRepresentation ( withPath: _lastReturned. path + " \\ * " ) {
940
936
FindFirstFileW ( $0, & ffd)
941
937
} ) ?? INVALID_HANDLE_VALUE
942
938
if handle == INVALID_HANDLE_VALUE { return firstValidItem ( ) }
0 commit comments