public bool MoveNext() { if (_lastEntryFound) { return(false); } FileSystemEntry entry = default; lock (_lock) { if (_lastEntryFound) { return(false); } do { FindNextEntry(); if (_lastEntryFound) { return(false); } bool isDirectory = FileSystemEntry.Initialize(ref entry, _entry, _currentPath, _rootDirectory, _originalRootDirectory, new Span <char>(_pathBuffer)); bool isSpecialDirectory = false; if (isDirectory) { // Subdirectory found if (_entry.Name[0] == '.' && (_entry.Name[1] == 0 || (_entry.Name[1] == '.' && _entry.Name[2] == 0))) { // "." or "..", don't process unless the option is set if (!_options.ReturnSpecialDirectories) { continue; } isSpecialDirectory = true; } } if (!isSpecialDirectory && _options.AttributesToSkip != 0) { if ((_options.AttributesToSkip & ~(FileAttributes.Directory | FileAttributes.Hidden | FileAttributes.ReparsePoint)) == 0) { // These three we don't have to hit the disk again to evaluate if (((_options.AttributesToSkip & FileAttributes.Directory) != 0 && isDirectory) || ((_options.AttributesToSkip & FileAttributes.Hidden) != 0 && _entry.Name[0] == '.') || ((_options.AttributesToSkip & FileAttributes.ReparsePoint) != 0 && _entry.InodeType == Interop.Sys.NodeType.DT_LNK)) { continue; } } else if (entry.Attributes != (FileAttributes)(-1) && (_options.AttributesToSkip & entry.Attributes) != 0) { // Hitting Attributes on the FileSystemEntry will cause a stat call continue; } } if (isDirectory && !isSpecialDirectory) { if (_options.RecurseSubdirectories && ShouldRecurseIntoEntry(ref entry)) { // Recursion is on and the directory was accepted, Queue it if (_pending == null) { _pending = new Queue <string>(); } _pending.Enqueue(PathHelpers.CombineNoChecks(_currentPath, entry.FileName)); } } if (ShouldIncludeEntry(ref entry)) { _current = TransformEntry(ref entry); return(true); } } while (true); } }
public bool MoveNext() { if (_lastEntryFound) { return(false); } FileSystemEntry entry = default; lock (_lock) { if (_lastEntryFound) { return(false); // If HAVE_READDIR_R is defined for the platform FindNextEntry depends on _entryBuffer being fixed since // _entry will point to a string in the middle of the array. If the array is not fixed GC can move it after // the native call and _entry will point to a bogus file name. fixed(byte *entryBufferPtr = _entryBuffer) { do { FindNextEntry(entryBufferPtr, _entryBuffer == null ? 0 : _entryBuffer.Length); if (_lastEntryFound) { return(false); } FileAttributes attributes = FileSystemEntry.Initialize( ref entry, _entry, _currentPath, _rootDirectory, _originalRootDirectory, new Span <char>(_pathBuffer)); bool isDirectory = (attributes & FileAttributes.Directory) != 0; bool isSpecialDirectory = false; if (isDirectory) { // Subdirectory found if (_entry.Name[0] == '.' && (_entry.Name[1] == 0 || (_entry.Name[1] == '.' && _entry.Name[2] == 0))) { // "." or "..", don't process unless the option is set if (!_options.ReturnSpecialDirectories) { continue; } isSpecialDirectory = true; } } if (!isSpecialDirectory && _options.AttributesToSkip != 0) { if ((_options.AttributesToSkip & FileAttributes.ReadOnly) != 0) { // ReadOnly is the only attribute that requires hitting entry.Attributes (which hits the disk) attributes = entry.Attributes; } if ((_options.AttributesToSkip & attributes) != 0) { continue; } } if (isDirectory && !isSpecialDirectory) { if (_options.RecurseSubdirectories && ShouldRecurseIntoEntry(ref entry)) { // Recursion is on and the directory was accepted, Queue it if (_pending == null) { _pending = new Queue <string>(); } _pending.Enqueue(Path.Join(_currentPath, entry.FileName)); } } if (ShouldIncludeEntry(ref entry)) { _current = TransformEntry(ref entry); return(true); } } while (true); } } }
public bool MoveNext() { if (_lastEntryFound) { return(false); } FileSystemEntry entry = default; lock (_lock) { if (_lastEntryFound) { return(false); } do { FindNextEntry(); if (_lastEntryFound) { return(false); } FileAttributes attributes = FileSystemEntry.Initialize(ref entry, _entry, _currentPath, _rootDirectory, _originalRootDirectory, new Span <char>(_pathBuffer)); bool isDirectory = (attributes & FileAttributes.Directory) != 0; bool isSpecialDirectory = false; if (isDirectory) { // Subdirectory found if (_entry.Name[0] == '.' && (_entry.Name[1] == 0 || (_entry.Name[1] == '.' && _entry.Name[2] == 0))) { // "." or "..", don't process unless the option is set if (!_options.ReturnSpecialDirectories) { continue; } isSpecialDirectory = true; } } if (!isSpecialDirectory && _options.AttributesToSkip != 0) { if ((_options.AttributesToSkip & FileAttributes.ReadOnly) != 0) { // ReadOnly is the only attribute that requires hitting entry.Attributes (which hits the disk) attributes = entry.Attributes; } if (attributes != (FileAttributes)(-1) && (_options.AttributesToSkip & attributes) != 0) { continue; } } if (isDirectory && !isSpecialDirectory) { if (_options.RecurseSubdirectories && ShouldRecurseIntoEntry(ref entry)) { // Recursion is on and the directory was accepted, Queue it if (_pending == null) { _pending = new Queue <string>(); } _pending.Enqueue(PathHelpers.CombineNoChecks(_currentPath, entry.FileName)); } } if (ShouldIncludeEntry(ref entry)) { _current = TransformEntry(ref entry); return(true); } } while (true); } }