Code/AutoRig/Dl/DownloadCore.cs

Utility class for transport-agnostic download plumbing. It copies data from a source stream to a target stream while reporting progress, supporting cancellation, computing a streaming SHA-256 hash, and verifies a completed file against an optional pinned checksum.

File Access
namespace AutoRig.Dl;

/// <summary>
/// Transport-agnostic download plumbing (testable without HTTP): copy with progress
/// + cancellation + streaming SHA-256, and resume-offset bookkeeping. The editor
/// layer supplies the HTTP streams and file IO.
/// </summary>
public static class DownloadCore
{
    /// <summary>
    /// Copies <paramref name="source"/> into <paramref name="target"/>, reporting
    /// (doneBytes, totalBytes) and hashing what passes through. Returns the hex
    /// SHA-256 of THE COPIED PORTION (callers hash-verify only full downloads).
    /// </summary>
    public static string Copy(
        Stream source, Stream target, long alreadyDone, long totalBytes,
        Action<long, long> progress, Func<bool> cancelled )
    {
        ArgumentNullException.ThrowIfNull( source );
        ArgumentNullException.ThrowIfNull( target );

        var hasher = new Sha256Pure.Hasher();
        var buffer = new byte[81920];
        var done = alreadyDone;
        while ( true )
        {
            if ( cancelled?.Invoke() == true )
                throw new OperationCanceledException();
            var read = source.Read( buffer, 0, buffer.Length );
            if ( read <= 0 )
                break;
            target.Write( buffer, 0, read );
            hasher.Update( buffer, 0, read );
            done += read;
            progress?.Invoke( done, totalBytes );
        }
        return hasher.FinishHex();
    }

    /// <summary>
    /// Verifies a completed file's hash against a pin. Empty pin = unpinned: accepted
    /// with <paramref name="warning"/> set so the UI can surface it.
    /// </summary>
    public static bool Verify( string actualSha256Hex, string pinnedSha256Hex, out string warning )
    {
        warning = "";
        if ( string.IsNullOrEmpty( pinnedSha256Hex ) )
        {
            warning = "No pinned checksum for this file - downloaded content was not verified.";
            return true;
        }
        return string.Equals( actualSha256Hex, pinnedSha256Hex, StringComparison.OrdinalIgnoreCase );
    }
}