using System.Collections; using System.Collections.Generic; using System.Linq; using Vanara.PInvoke; using static Vanara.PInvoke.BITS; namespace Vanara.IO; /// Provides information about a peer in the neighborhood. public class CachePeer { private readonly ComReleaser ciPeer; internal CachePeer(IBitsPeer peer) => ciPeer = ComReleaserFactory.Create(peer); private CachePeer() => throw new NotImplementedException(); /// Determines whether the peer is authenticated. /// if the peer is authenticated, otherwise, . public bool IsAuthenticated => ciPeer.Item.IsAuthenticated(); /// Determines whether the peer is available (online) to serve content. /// if the peer is available to serve content, otherwise, . public bool IsAvailable => ciPeer.Item.IsAvailable(); /// Gets the server principal name that uniquely identifies the peer. /// The server principal name of the peer. The principal name is of the form, server$.domain.suffix. public string Name => ciPeer.Item.GetPeerName(); } /// Provides the ability to enumerate the list of peers that BITS has discovered. public class CachePeers : IReadOnlyCollection { private readonly IBitsPeerCacheAdministration iCacheAdmin; internal CachePeers(IBitsPeerCacheAdministration admin) => iCacheAdmin = admin; /// Gets the number of elements in the collection. public int Count => EnumPeers().Count(); /// Removes all peers from the list of peers that can serve content. public void Clear() => iCacheAdmin.ClearPeers(); /// Returns an enumerator that iterates through the collection. /// An enumerator that can be used to iterate through the collection. public IEnumerator GetEnumerator() { iCacheAdmin.DiscoverPeers(); return EnumPeers().GetEnumerator(); } /// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); private IEnumerable EnumPeers() => iCacheAdmin.EnumPeers().Enumerate().Select(i => new CachePeer(i)); } /// Use PeerCacheAdministration to manage the pool of peers from which you can download content. public class PeerCacheAdministration { internal readonly ComReleaser ciCacheAdmin; private CachePeers? peers; private PeerCacheRecords? recs; internal PeerCacheAdministration(IBackgroundCopyManager mgr) => ciCacheAdmin = ComReleaserFactory.Create((IBitsPeerCacheAdministration)mgr); /// /// Gets or sets the configuration flags that determine if the computer serves content to peers and can download content from peers. /// /// Flags that determine if the computer serves content to peers and can download content from peers. public PeerCaching ConfigurationFlags { get => (PeerCaching)ciCacheAdmin.Item.GetConfigurationFlags(); set => ciCacheAdmin.Item.SetConfigurationFlags((BG_ENABLE_PEERCACHING)value); } /// Gets or sets the maximum size of the cache. /// Maximum size of the cache, as a percentage of available hard disk drive space. public uint MaximumCacheSize { get => ciCacheAdmin.Item.GetMaximumCacheSize(); set => ciCacheAdmin.Item.SetMaximumCacheSize(value); } /// Gets or sets the age by when files are removed from the cache. /// Age. If the last time that the file was accessed is older than this age, BITS removes the file from the cache. public TimeSpan MaximumContentAge { get => TimeSpan.FromSeconds(ciCacheAdmin.Item.GetMaximumContentAge()); set => ciCacheAdmin.Item.SetMaximumContentAge((uint)value.TotalSeconds); } /// Gets a instance that you use to enumerate the peers that can serve content. /// A instance that you use to enumerate the peers that can serve content. public CachePeers Peers => peers ??= new CachePeers(ciCacheAdmin.Item); /// /// Gets a instance that you use to enumerate the records in the cache. The enumeration is a snapshot of /// the records in the cache. /// /// A instance that you use to enumerate the records in the cache. public PeerCacheRecords Records => recs ??= new PeerCacheRecords(ciCacheAdmin.Item); /// Deletes all cache records and the file from the cache for the given URL. /// /// Null-terminated string that contains the URL of the file whose cache records and file you want to delete from the cache. /// public void DeleteUrl(string url) => ciCacheAdmin.Item.DeleteUrl(url); } /// Provides the ability to enumerate the records of the cache. public class PeerCacheRecords : IReadOnlyCollection { private readonly IBitsPeerCacheAdministration iCacheAdmin; internal PeerCacheRecords(IBitsPeerCacheAdministration admin) => iCacheAdmin = admin; /// Gets the number of elements in the collection. public int Count => EnumRecords().Count(); /// Gets a record from the cache. /// Identifier of the record to get from the cache. /// A instance of the cache record. public PeerCacheRecord this[Guid id] => new(iCacheAdmin.GetRecord(id)); /// Removes all the records and files from the cache. public void Clear() => iCacheAdmin.ClearRecords(); /// Returns an enumerator that iterates through the collection. /// An enumerator that can be used to iterate through the collection. public IEnumerator GetEnumerator() => EnumRecords().GetEnumerator(); /// Deletes a record and file from the cache. /// The record to delete from the cache. public bool Remove(PeerCacheRecord item) { try { iCacheAdmin.DeleteRecord(item.Id); return true; } catch { return false; } } /// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); private IEnumerable EnumRecords() => iCacheAdmin.EnumRecords()?.Enumerate().Select(i => new PeerCacheRecord(i)) ?? Enumerable.Empty(); } /// Provides information about a file in the BITS peer cache. public class PeerCacheRecord { private readonly ComReleaser ciRecord; internal PeerCacheRecord(IBitsPeerCacheRecord bitsPeerCacheRecord) => ciRecord = ComReleaserFactory.Create(bitsPeerCacheRecord); private PeerCacheRecord() => throw new NotImplementedException(); /// Gets the date and time that the file was last modified on the server. /// Date and time that the file was last modified on the server. public DateTime FileModificationTime => ciRecord.Item.GetFileModificationTime().ToDateTime(); /// Gets the ranges of the file that are in the cache. /// Array of structures that specify the ranges of the file that are in the cache. public BackgroundCopyFileRange[] FileRanges => Array.ConvertAll(ciRecord.Item.GetFileRanges(), i => (BackgroundCopyFileRange)i); /// Gets the size of the file. /// Size of the file, in bytes. public ulong FileSize => ciRecord.Item.GetFileSize(); /// Gets the record identifier. /// The identifier. public Guid Id => ciRecord.Item.GetId(); /// Determines whether the file has been validated. /// if file has been validated; otherwise . public bool IsFileValidated => ciRecord.Item.IsFileValidated() == HRESULT.S_OK; /// Gets the date and time that the file was last accessed. /// Date and time that the file was last accessed. public DateTime LastAccessTime => ciRecord.Item.GetLastAccessTime().ToDateTime(); /// Gets the origin URL of the cached file. /// String that contains the origin URL of the cached file. public string OriginUrl => ciRecord.Item.GetOriginUrl(); }