@@ -2377,46 +2377,107 @@ extension FileManager {
2377
2377
self . innerEnumerator = ie
2378
2378
}
2379
2379
2380
- @available ( Windows, deprecated, message: " Not Yet Implemented " )
2381
2380
override func nextObject( ) -> Any ? {
2382
2381
let o = innerEnumerator. nextObject ( )
2383
2382
guard let url = o as? URL else {
2384
2383
return nil
2385
2384
}
2386
2385
2387
2386
#if os(Windows)
2388
- NSUnimplemented ( )
2387
+ let path = url . path . replacingOccurrences ( of : baseURL . path + " \\ " , with : " " )
2389
2388
#else
2390
2389
let path = url. path. replacingOccurrences ( of: baseURL. path+ " / " , with: " " )
2390
+ #endif
2391
2391
_currentItemPath = path
2392
2392
return path
2393
- #endif
2394
2393
}
2395
2394
}
2396
2395
2397
- #if os(Windows)
2398
2396
internal class NSURLDirectoryEnumerator : DirectoryEnumerator {
2399
- internal typealias ErrorHandler = /* @escaping */ ( URL , Error ) -> Bool
2397
+ #if os(Windows)
2398
+ var _options : FileManager . DirectoryEnumerationOptions
2399
+ var _errorHandler : ( ( URL , Error ) -> Bool ) ?
2400
+ var _stack : [ URL ]
2401
+ var _current : URL ?
2402
+ var _root_depth : Int
2403
+
2400
2404
2401
- init ( url: URL , options: FileManager . DirectoryEnumerationOptions , errorHandler: ErrorHandler ? ) {
2405
+ init ( url: URL , options: FileManager . DirectoryEnumerationOptions , errorHandler: ( /* @escaping */ ( URL , Error ) -> Bool ) ? ) {
2406
+ _options = options
2407
+ _errorHandler = errorHandler
2408
+ _stack = [ url]
2409
+ _root_depth = url. pathComponents. count
2410
+ }
2411
+
2412
+
2413
+ override func nextObject( ) -> Any ? {
2414
+ func contentsOfDir( directory: URL ) -> [ URL ] ? {
2415
+ var ffd : WIN32_FIND_DATAW = WIN32_FIND_DATAW ( )
2416
+ let dirPath = Array ( ( directory. absoluteString + " \\ * \0 " ) . utf16)
2417
+ guard let h = dirPath. withContiguousStorageIfAvailable (
2418
+ { FindFirstFileW ( $0. baseAddress, & ffd) } ) ,
2419
+ h != INVALID_HANDLE_VALUE else {
2420
+ return nil
2421
+ }
2422
+ defer {
2423
+ FindClose ( h)
2424
+ }
2425
+
2426
+ var files : [ URL ] = [ ]
2427
+ repeat {
2428
+ let fileArr = [ WCHAR] ( UnsafeBufferPointer ( start: & ffd. cFileName. 0 ,
2429
+ count: MemoryLayout . size ( ofValue: ffd. cFileName) ) )
2430
+ let file = String ( decodingCString: fileArr, as: UTF16 . self)
2431
+ if file != " . "
2432
+ && file != " .. "
2433
+ && ( _options. contains ( . skipsHiddenFiles)
2434
+ && ( ffd. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_HIDDEN) == 0 ) ) {
2435
+ files. append ( URL ( fileURLWithPath: " \( directory. absoluteString) \\ \( file) " ) )
2436
+ }
2437
+ } while ( FindNextFileW ( h, & ffd) != 0 )
2438
+ return files
2439
+ }
2440
+ while let url = _stack. popLast ( ) {
2441
+ if url. hasDirectoryPath && !_options. contains ( . skipsSubdirectoryDescendants) {
2442
+ guard let dirContents = contentsOfDir ( directory: url) ? . reversed ( ) else {
2443
+ if let handler = _errorHandler,
2444
+ handler ( URL ( fileURLWithPath: url. absoluteString) ,
2445
+ _NSErrorWithWindowsError ( GetLastError ( ) , reading: true ) ) {
2446
+ return nil
2447
+ }
2448
+ continue
2449
+ }
2450
+ _stack. append ( contentsOf: dirContents)
2451
+ }
2452
+ _current = url
2453
+ return url
2454
+ }
2455
+ return nil
2456
+ }
2457
+
2458
+ override var level : Int {
2459
+ return _root_depth - ( _current? . pathComponents. count ?? _root_depth)
2460
+ }
2461
+
2462
+ override func skipDescendants( ) {
2463
+ _options. insert ( . skipsSubdirectoryDescendants)
2402
2464
}
2403
- }
2404
2465
#else
2405
- internal class NSURLDirectoryEnumerator : DirectoryEnumerator {
2406
2466
var _url : URL
2407
2467
var _options : FileManager . DirectoryEnumerationOptions
2408
2468
var _errorHandler : ( ( URL , Error ) -> Bool ) ?
2409
2469
var _stream : UnsafeMutablePointer < FTS > ? = nil
2410
2470
var _current : UnsafeMutablePointer < FTSENT > ? = nil
2411
2471
var _rootError : Error ? = nil
2412
2472
var _gotRoot : Bool = false
2413
-
2473
+
2474
+
2414
2475
// See @escaping comments above.
2415
2476
init ( url: URL , options: FileManager . DirectoryEnumerationOptions , errorHandler: ( /* @escaping */ ( URL , Error ) -> Bool ) ? ) {
2416
2477
_url = url
2417
2478
_options = options
2418
2479
_errorHandler = errorHandler
2419
-
2480
+
2420
2481
if FileManager . default. fileExists ( atPath: _url. path) {
2421
2482
let fsRep = FileManager . default. fileSystemRepresentation ( withPath: _url. path)
2422
2483
let ps = UnsafeMutablePointer< UnsafeMutablePointer< Int8>?> . allocate( capacity: 2 )
@@ -2430,15 +2491,15 @@ extension FileManager {
2430
2491
_rootError = _NSErrorWithErrno ( ENOENT, reading: true , url: url)
2431
2492
}
2432
2493
}
2433
-
2494
+
2434
2495
deinit {
2435
2496
if let stream = _stream {
2436
2497
fts_close ( stream)
2437
2498
}
2438
2499
}
2439
-
2440
- override func nextObject( ) -> Any ? {
2441
2500
2501
+
2502
+ override func nextObject( ) -> Any ? {
2442
2503
func match( filename: String , to options: DirectoryEnumerationOptions , isDir: Bool ) -> ( Bool , Bool ) {
2443
2504
var showFile = true
2444
2505
var skipDescendants = false
@@ -2459,10 +2520,10 @@ extension FileManager {
2459
2520
2460
2521
2461
2522
if let stream = _stream {
2462
-
2523
+
2463
2524
if !_gotRoot {
2464
2525
_gotRoot = true
2465
-
2526
+
2466
2527
// Skip the root.
2467
2528
_current = fts_read ( stream)
2468
2529
}
@@ -2504,7 +2565,7 @@ extension FileManager {
2504
2565
_current = fts_read ( stream)
2505
2566
}
2506
2567
// TODO: Error handling if fts_read fails.
2507
-
2568
+
2508
2569
} else if let error = _rootError {
2509
2570
// Was there an error opening the stream?
2510
2571
if let handler = _errorHandler {
@@ -2513,24 +2574,21 @@ extension FileManager {
2513
2574
}
2514
2575
return nil
2515
2576
}
2516
-
2517
- override var directoryAttributes : [ FileAttributeKey : Any ] ? {
2518
- return nil
2519
- }
2520
-
2521
- override var fileAttributes : [ FileAttributeKey : Any ] ? {
2522
- return nil
2523
- }
2524
-
2525
2577
override var level : Int {
2526
2578
return Int ( _current? . pointee. fts_level ?? 0 )
2527
2579
}
2528
-
2580
+
2529
2581
override func skipDescendants( ) {
2530
2582
if let stream = _stream, let current = _current {
2531
2583
fts_set ( stream, current, FTS_SKIP)
2532
2584
}
2533
2585
}
2534
- }
2535
2586
#endif
2587
+ override var directoryAttributes : [ FileAttributeKey : Any ] ? {
2588
+ return nil
2589
+ }
2590
+ override var fileAttributes : [ FileAttributeKey : Any ] ? {
2591
+ return nil
2592
+ }
2593
+ }
2536
2594
}
0 commit comments