Listing 7: recls::FileSearch class.
namespace recls
{
public class FileSearch
{
/// <summary>
/// Creates a search for the items identified by . . .
/// </summary>
public FileSearch(string searchRoot, string pattern, uint flags)
{
m_searchRoot = searchRoot;
m_pattern = pattern;
m_flags = flags;
}
public IEnumerator GetEnumerator()
{
return new Enumerator(m_searchRoot, m_pattern, m_flags);
}
private sealed class Enumerator
: IEnumerator
, IDisposable
{
internal Enumerator(string searchRoot, string pattern, uint flags)
{
m_searchRoot = searchRoot;
m_pattern = pattern;
m_flags = flags;
m_hSrch = IntPtr.Zero;
m_entry = IntPtr.Zero;
m_bComplete = false;
}
~Enumerator()
{
Dispose();
}
public void Dispose()
{
recls_api.CloseSearch(ref m_hSrch);
recls_api.CloseEntry(ref m_entry);
}
/// <summary>
/// Gets the current element in the collection.
/// </summary>
public object Current
{
get
{
if(IntPtr.Zero == m_entry)
{
throw new InvalidOperationException("Enumeration is positioned before the first element, or after the last element");
}
return new FileEntry(m_entry);
}
}
/// <summary>
/// Advances the enumerator to the next element of the collection.
/// </summary>
public bool MoveNext()
{
// MoveNext() must be called before Current is used, whether
// that is for a newly created enumerator or after Reset() is
// called. Hence,
if(m_bComplete)
{
// Was completed on the last call.
return false;
}
else
{
recls_api.CloseEntry(ref m_entry);
if(IntPtr.Zero == m_hSrch)
{
// Start a new enumeration
m_hSrch = recls_api.OpenSearch(m_searchRoot, m_pattern, m_flags);
if(IntPtr.Zero == m_hSrch)
{
m_bComplete = true;
return false;
}
else
{
recls_api.GetEntry(m_hSrch, out m_entry);
}
}
else
{
// Enumeration is in progress, so just try and advance
if(!recls_api.NextEntry(m_hSrch, out m_entry))
{
m_bComplete = true;
return false;
}
}
}
return true;
}
/// <summary>
/// Sets the enumerator to its initial position, which . . .
/// </summary>
public void Reset()
{
// Since Reset() resets an enumerator to *exactly* the same
// state as when newly created, we can just close anything
// that's open.
recls_api.CloseSearch(ref m_hSrch);
recls_api.CloseEntry(ref m_entry);
m_bComplete = false;
}
private IntPtr m_hSrch;
private IntPtr m_entry;
private string m_searchRoot;
private string m_pattern;
private RECLS_FLAG m_flags;
private bool m_bComplete;
}
private string m_searchRoot;
private string m_pattern;
private RECLS_FLAG m_flags;
}
}