forked from ironfede/openmcdf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDirectoryTreeEnumerator.cs
77 lines (66 loc) · 1.8 KB
/
DirectoryTreeEnumerator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System.Collections;
namespace OpenMcdf;
/// <summary>
/// Enumerates the children of a <see cref="DirectoryEntry"/>.
/// </summary>
internal sealed class DirectoryTreeEnumerator : IEnumerator<DirectoryEntry>
{
private readonly DirectoryEntries directories;
private readonly DirectoryEntry root;
private readonly Stack<DirectoryEntry> stack = new();
DirectoryEntry? current;
internal DirectoryTreeEnumerator(DirectoryEntries directories, DirectoryEntry root)
{
this.directories = directories;
this.root = root;
Reset();
}
/// <inheritdoc/>
public void Dispose()
{
}
/// <inheritdoc/>
public DirectoryEntry Current
{
get
{
if (current is null)
throw new InvalidOperationException("Enumeration has not started. Call MoveNext.");
return current;
}
}
/// <inheritdoc/>
object IEnumerator.Current => Current;
/// <inheritdoc/>
public bool MoveNext()
{
if (stack.Count == 0)
{
current = null;
return false;
}
current = stack.Pop();
if (directories.TryGetDictionaryEntry(current.RightSiblingId, out DirectoryEntry? rightSibling))
PushLeft(rightSibling!);
return true;
}
/// <inheritdoc/>
public void Reset()
{
current = null;
stack.Clear();
if (root.ChildId != StreamId.NoStream)
{
DirectoryEntry child = directories.GetDictionaryEntry(root.ChildId);
PushLeft(child);
}
}
private void PushLeft(DirectoryEntry? node)
{
while (node is not null)
{
stack.Push(node);
directories.TryGetDictionaryEntry(node.LeftSiblingId, out node);
}
}
}