Files
sharpcompress/src/SharpCompress/LazyReadOnlyCollection.cs

127 lines
2.9 KiB
C#
Raw Permalink Normal View History

2022-12-20 15:20:49 +00:00
#nullable disable
2020-05-23 16:27:55 -07:00
using System;
using System.Collections;
2015-12-30 11:19:42 +00:00
using System.Collections.Generic;
2025-10-22 09:17:13 +01:00
namespace SharpCompress;
2022-12-20 15:06:44 +00:00
internal sealed class LazyReadOnlyCollection<T> : ICollection<T>
2015-12-30 11:19:42 +00:00
{
private readonly List<T> _backing = new();
private readonly IEnumerator<T> _source;
private bool _fullyLoaded;
2022-12-20 15:06:44 +00:00
public LazyReadOnlyCollection(IEnumerable<T> source) => _source = source.GetEnumerator();
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
private class LazyLoader : IEnumerator<T>
{
private readonly LazyReadOnlyCollection<T> _lazyReadOnlyCollection;
private bool _disposed;
private int _index = -1;
2015-12-30 11:19:42 +00:00
2022-12-20 15:20:49 +00:00
internal LazyLoader(LazyReadOnlyCollection<T> lazyReadOnlyCollection) =>
_lazyReadOnlyCollection = lazyReadOnlyCollection;
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
#region IEnumerator<T> Members
2015-12-30 11:19:42 +00:00
public T Current => _lazyReadOnlyCollection._backing[_index];
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
#endregion
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
#region IDisposable Members
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
public void Dispose()
{
if (!_disposed)
2015-12-30 11:19:42 +00:00
{
_disposed = true;
2015-12-30 11:19:42 +00:00
}
2022-12-20 15:06:44 +00:00
}
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
#endregion
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
#region IEnumerator Members
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
object IEnumerator.Current => Current;
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
public bool MoveNext()
{
if (_index + 1 < _lazyReadOnlyCollection._backing.Count)
2015-12-30 11:19:42 +00:00
{
_index++;
2022-12-20 15:06:44 +00:00
return true;
2015-12-30 11:19:42 +00:00
}
if (!_lazyReadOnlyCollection._fullyLoaded && _lazyReadOnlyCollection._source.MoveNext())
2015-12-30 11:19:42 +00:00
{
_lazyReadOnlyCollection._backing.Add(_lazyReadOnlyCollection._source.Current);
_index++;
2022-12-20 15:06:44 +00:00
return true;
2015-12-30 11:19:42 +00:00
}
_lazyReadOnlyCollection._fullyLoaded = true;
2022-12-20 15:06:44 +00:00
return false;
2015-12-30 11:19:42 +00:00
}
2022-12-20 15:20:49 +00:00
public void Reset() => throw new NotSupportedException();
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
#endregion
}
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
internal void EnsureFullyLoaded()
{
if (!_fullyLoaded)
2015-12-30 11:19:42 +00:00
{
2022-12-20 15:06:44 +00:00
this.ForEach(x => { });
_fullyLoaded = true;
2015-12-30 11:19:42 +00:00
}
2022-12-20 15:06:44 +00:00
}
2015-12-30 11:19:42 +00:00
internal IEnumerable<T> GetLoaded() => _backing;
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
#region ICollection<T> Members
2015-12-30 11:19:42 +00:00
2022-12-20 15:20:49 +00:00
public void Add(T item) => throw new NotSupportedException();
2015-12-30 11:19:42 +00:00
2022-12-20 15:20:49 +00:00
public void Clear() => throw new NotSupportedException();
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
public bool Contains(T item)
{
EnsureFullyLoaded();
return _backing.Contains(item);
2022-12-20 15:06:44 +00:00
}
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
public void CopyTo(T[] array, int arrayIndex)
{
EnsureFullyLoaded();
_backing.CopyTo(array, arrayIndex);
2022-12-20 15:06:44 +00:00
}
public int Count
{
get
2015-12-30 11:19:42 +00:00
{
2022-12-20 15:06:44 +00:00
EnsureFullyLoaded();
return _backing.Count;
2015-12-30 11:19:42 +00:00
}
2022-12-20 15:06:44 +00:00
}
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
public bool IsReadOnly => true;
2015-12-30 11:19:42 +00:00
2022-12-20 15:20:49 +00:00
public bool Remove(T item) => throw new NotSupportedException();
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
#endregion
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
#region IEnumerable<T> Members
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
//TODO check for concurrent access
2022-12-20 15:20:49 +00:00
public IEnumerator<T> GetEnumerator() => new LazyLoader(this);
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
#endregion
2015-12-30 11:19:42 +00:00
2022-12-20 15:06:44 +00:00
#region IEnumerable Members
2022-12-20 15:20:49 +00:00
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
2022-12-20 15:06:44 +00:00
#endregion
}