wasStitchNET – Rev 13

Subversion Repositories:
Rev:
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////

using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Threading.Tasks;
using wasDAVClient;
using wasSharp;
using wasSharpNET.IO.Utilities;

namespace wasStitchNET.Repository
{
    public class Hashing
    {
        /// <summary>
        ///     Hash local files inside a directory.
        /// </summary>
        /// <param name="path">the path to a directory to hash</param>
        /// <param name="bufferSize">the partial hash buffer (default: 16384)</param>
        /// <returns>a SHA1 hash of all files in a directory ordered by name</returns>
        public static async Task<string> HashLocalFiles(string path, int bufferSize = 16384)
        {
            return await new Task<string>(() =>
            {
                using (var sha1managed = new SHA1Managed())
                {
                    foreach (var stream in Directory
                        .GetFiles(path, "*.*", SearchOption.AllDirectories)
                        .OrderBy(o => o.Split(Path.DirectorySeparatorChar).Last())
                        .AsParallel()
                        .AsOrdered()
                        .Select(file => IOExtensions.GetWriteStream(file, FileMode.Open,
                            FileAccess.Read, FileShare.Read, STITCH_CONSTANTS.LOCAL_FILE_ACCESS_TIMEOUT))
                        .AsSequential())
                        using (var binaryReader = new BinaryReader(stream))
                        {
                            var buff = new byte[bufferSize];
                            int read;
                            while ((read = binaryReader.Read(buff, 0, buff.Length)) != 0)
                                sha1managed.TransformBlock(buff, 0, read, null, 0);
                        }

                    sha1managed.TransformFinalBlock(new byte[] { }, 0, 0);
                    return sha1managed.Hash.ToHexString();
                }
            });
        }

        /// <summary>
        ///     Hash the files of a Stitch remote repository release.
        /// </summary>
        /// <param name="server">the server to hash the release for</param>
        /// <param name="update">the Stitch release to hash</param>
        /// <param name="timeout">the timeout in milliseconds to allow the server to respond</param>
        /// <returns>a SHA1 hash of all files in the release directory ordered by name</returns>
        public static async Task<string> HashRemoteFiles(string server, string update, int timeout)
        {
            using (var client = new Client(new NetworkCredential())
            {
                Timeout = timeout,
                UserAgent = STITCH_CONSTANTS.USER_AGENT.Product.Name,
                UserAgentVersion = STITCH_CONSTANTS.USER_AGENT.Product.Version,
                Server = server,
                BasePath = string.Join(@"/", STITCH_CONSTANTS.UPDATE_PATH,
                    STITCH_CONSTANTS.PROGRESSIVE_PATH)
            })
            {
                return $"{await HashRemoteFiles(client, string.Join(@"/", update, STITCH_CONSTANTS.UPDATE_DATA_PATH))}";
            }
        }

        /// <summary>
        ///     Hash the files of a Stitch remote repository release using an existing was DAV client.
        /// </summary>
        /// <param name="client">the was DAV client to use</param>
        /// <param name="path">the path to the repository release folder</param>
        /// <param name="bufferSize">the partial hash buffer (default: 16384)</param>
        /// <returns>a SHA1 hash of all files in the release directory ordered by name</returns>
        public static async Task<string> HashRemoteFiles(Client client, string path, int bufferSize = 16384)
        {
            using (var sha1managed = new SHA1Managed())
            {
                foreach (var stream in (await client.List(path, Constants.DavDepth.ALL))
                    .OrderBy(o => o.DisplayName)
                    .Where(item => !item.IsCollection)
                    .AsParallel()
                    .AsOrdered()
                    .Select(file => client.Download(file.Href))
                    .AsSequential())
                    using (var binaryReader = new BinaryReader(await stream))
                    {
                        var buff = new byte[bufferSize];
                        int read;
                        while ((read = binaryReader.Read(buff, 0, buff.Length)) != 0)
                            sha1managed.TransformBlock(buff, 0, read, null, 0);
                    }

                sha1managed.TransformFinalBlock(new byte[] { }, 0, 0);
                return sha1managed.Hash.ToHexString();
            }
        }
    }
}

Generated by GNU Enscript 1.6.5.90.