1
1
// Licensed to the .NET Foundation under one or more agreements.
2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
- using System . Buffers ;
5
4
using System . Collections . Generic ;
6
5
using System . Diagnostics ;
7
6
using System . Diagnostics . CodeAnalysis ;
8
7
using System . IO ;
8
+ using System . IO . Enumeration ;
9
9
using System . Runtime . InteropServices ;
10
10
using System . Security ;
11
11
using System . Text ;
@@ -271,102 +271,6 @@ private static List<string> ParseTimeZoneIds(StreamReader reader)
271
271
return Path . Join ( currentPath . AsSpan ( ) , direntName ) ;
272
272
}
273
273
274
- /// <summary>
275
- /// Enumerate files
276
- /// </summary>
277
- private static unsafe void EnumerateFilesRecursively ( string path , Predicate < string > condition )
278
- {
279
- List < string > ? toExplore = null ; // List used as a stack
280
-
281
- int bufferSize = Interop . Sys . GetReadDirRBufferSize ( ) ;
282
- byte [ ] dirBuffer = ArrayPool < byte > . Shared . Rent ( bufferSize ) ;
283
- try
284
- {
285
- string currentPath = path ;
286
-
287
- fixed ( byte * dirBufferPtr = dirBuffer )
288
- {
289
- while ( true )
290
- {
291
- IntPtr dirHandle = Interop . Sys . OpenDir ( currentPath ) ;
292
- if ( dirHandle == IntPtr . Zero )
293
- {
294
- throw Interop . GetExceptionForIoErrno ( Interop . Sys . GetLastErrorInfo ( ) , currentPath , isDirError : true ) ;
295
- }
296
-
297
- try
298
- {
299
- // Read each entry from the enumerator
300
- Interop . Sys . DirectoryEntry dirent ;
301
- while ( Interop . Sys . ReadDirR ( dirHandle , dirBufferPtr , bufferSize , & dirent ) == 0 )
302
- {
303
- string ? fullPath = GetDirectoryEntryFullPath ( ref dirent , currentPath ) ;
304
- if ( fullPath == null )
305
- continue ;
306
-
307
- // Get from the dir entry whether the entry is a file or directory.
308
- // We classify everything as a file unless we know it to be a directory.
309
- bool isDir ;
310
- if ( dirent . InodeType == Interop . Sys . NodeType . DT_DIR )
311
- {
312
- // We know it's a directory.
313
- isDir = true ;
314
- }
315
- else if ( dirent . InodeType == Interop . Sys . NodeType . DT_LNK || dirent . InodeType == Interop . Sys . NodeType . DT_UNKNOWN )
316
- {
317
- // It's a symlink or unknown: stat to it to see if we can resolve it to a directory.
318
- // If we can't (e.g. symlink to a file, broken symlink, etc.), we'll just treat it as a file.
319
-
320
- Interop . Sys . FileStatus fileinfo ;
321
- if ( Interop . Sys . Stat ( fullPath , out fileinfo ) >= 0 )
322
- {
323
- isDir = ( fileinfo . Mode & Interop . Sys . FileTypes . S_IFMT ) == Interop . Sys . FileTypes . S_IFDIR ;
324
- }
325
- else
326
- {
327
- isDir = false ;
328
- }
329
- }
330
- else
331
- {
332
- // Otherwise, treat it as a file. This includes regular files, FIFOs, etc.
333
- isDir = false ;
334
- }
335
-
336
- // Yield the result if the user has asked for it. In the case of directories,
337
- // always explore it by pushing it onto the stack, regardless of whether
338
- // we're returning directories.
339
- if ( isDir )
340
- {
341
- toExplore ??= new List < string > ( ) ;
342
- toExplore . Add ( fullPath ) ;
343
- }
344
- else if ( condition ( fullPath ) )
345
- {
346
- return ;
347
- }
348
- }
349
- }
350
- finally
351
- {
352
- if ( dirHandle != IntPtr . Zero )
353
- Interop . Sys . CloseDir ( dirHandle ) ;
354
- }
355
-
356
- if ( toExplore == null || toExplore . Count == 0 )
357
- break ;
358
-
359
- currentPath = toExplore [ toExplore . Count - 1 ] ;
360
- toExplore . RemoveAt ( toExplore . Count - 1 ) ;
361
- }
362
- }
363
- }
364
- finally
365
- {
366
- ArrayPool < byte > . Shared . Return ( dirBuffer ) ;
367
- }
368
- }
369
-
370
274
private static bool CompareTimeZoneFile ( string filePath , byte [ ] buffer , byte [ ] rawData )
371
275
{
372
276
try
@@ -424,7 +328,7 @@ private static string FindTimeZoneId(byte[] rawData)
424
328
425
329
try
426
330
{
427
- EnumerateFilesRecursively ( timeZoneDirectory , ( string filePath ) =>
331
+ foreach ( string filePath in Directory . EnumerateFiles ( timeZoneDirectory , "*" , SearchOption . AllDirectories ) )
428
332
{
429
333
// skip the localtime and posixrules file, since they won't give us the correct id
430
334
if ( ! string . Equals ( filePath , localtimeFilePath , StringComparison . OrdinalIgnoreCase )
@@ -440,11 +344,11 @@ private static string FindTimeZoneId(byte[] rawData)
440
344
{
441
345
id = id . Substring ( timeZoneDirectory . Length ) ;
442
346
}
443
- return true ;
347
+
348
+ break ;
444
349
}
445
350
}
446
- return false ;
447
- } ) ;
351
+ }
448
352
}
449
353
catch ( IOException ) { }
450
354
catch ( SecurityException ) { }
0 commit comments