diff --git a/Source/AaxDecrypter/NetworkFileStream.cs b/Source/AaxDecrypter/NetworkFileStream.cs index ca89532b..53f1753e 100644 --- a/Source/AaxDecrypter/NetworkFileStream.cs +++ b/Source/AaxDecrypter/NetworkFileStream.cs @@ -247,7 +247,15 @@ namespace AaxDecrypter public override bool CanWrite => false; [JsonIgnore] - public override long Length => ContentLength; + public override long Length + { + get + { + if (_backgroundDownloadTask is null) + throw new InvalidOperationException($"Background downloader must first be started by calling {nameof(BeginDownloadingAsync)}"); + return ContentLength; + } + } [JsonIgnore] public override long Position { get => _readFile.Position; set => Seek(value, SeekOrigin.Begin); } @@ -267,6 +275,9 @@ namespace AaxDecrypter public override int Read(byte[] buffer, int offset, int count) { + if (_backgroundDownloadTask is null) + throw new InvalidOperationException($"Background downloader must first be started by calling {nameof(BeginDownloadingAsync)}"); + var toRead = Math.Min(count, Length - Position); WaitToPosition(Position + toRead); return IsCancelled ? 0 : _readFile.Read(buffer, offset, count); diff --git a/Source/AppScaffolding/LibationScaffolding.cs b/Source/AppScaffolding/LibationScaffolding.cs index f7389977..1756da77 100644 --- a/Source/AppScaffolding/LibationScaffolding.cs +++ b/Source/AppScaffolding/LibationScaffolding.cs @@ -9,7 +9,7 @@ using Dinah.Core; using Dinah.Core.IO; using Dinah.Core.Logging; using LibationFileManager; -using Microsoft.EntityFrameworkCore; +using System.Runtime.InteropServices; using Newtonsoft.Json.Linq; using Serilog; @@ -18,16 +18,22 @@ namespace AppScaffolding public enum ReleaseIdentifier { None, - WindowsClassic, - WindowsAvalonia, - LinuxAvalonia, - MacOSAvalonia, - LinuxAvalonia_Arm64, - MacOSAvalonia_Arm64 + WindowsClassic = OS.Windows | Variety.Classic | Architecture.X64, + WindowsAvalonia = OS.Windows | Variety.Chardonnay | Architecture.X64, + LinuxAvalonia = OS.Linux | Variety.Chardonnay | Architecture.X64, + MacOSAvalonia = OS.MacOS | Variety.Chardonnay | Architecture.X64, + LinuxAvalonia_Arm64 = OS.Linux | Variety.Chardonnay | Architecture.Arm64, + MacOSAvalonia_Arm64 = OS.MacOS | Variety.Chardonnay | Architecture.Arm64 } // I know I'm taking the wine metaphor a bit far by naming this "Variety", but I don't know what else to call it - public enum VarietyType { None, Classic, Chardonnay } + [Flags] + public enum Variety + { + None, + Classic = 0x10000, + Chardonnay = 0x20000, + } public static class LibationScaffolding { @@ -35,13 +41,22 @@ namespace AppScaffolding public const string WebsiteUrl = "ht" + "tps://getlibation.com"; public const string RepositoryLatestUrl = "ht" + "tps://github.com/rmcrackan/Libation/releases/latest"; public static ReleaseIdentifier ReleaseIdentifier { get; private set; } - public static VarietyType Variety - => ReleaseIdentifier == ReleaseIdentifier.WindowsClassic ? VarietyType.Classic - : Enum.IsDefined(ReleaseIdentifier) ? VarietyType.Chardonnay - : VarietyType.None; + public static Variety Variety { get; private set; } - public static void SetReleaseIdentifier(ReleaseIdentifier releaseID) - => ReleaseIdentifier = releaseID; + public static void SetReleaseIdentifier(Variety varietyType) + { + Variety = Enum.IsDefined(varietyType) ? varietyType : Variety.None; + + var releaseID = (ReleaseIdentifier)((int)varietyType | (int)Configuration.OS | (int)RuntimeInformation.ProcessArchitecture); + + if (Enum.IsDefined(releaseID)) + ReleaseIdentifier = releaseID; + else + { + ReleaseIdentifier = ReleaseIdentifier.None; + Serilog.Log.Logger.Warning("Unknown release identifier @{DebugInfo}", new { Variety = varietyType, Configuration.OS, RuntimeInformation.ProcessArchitecture }); + } + } // AppScaffolding private static Assembly _executingAssembly; diff --git a/Source/LibationAvalonia/Program.cs b/Source/LibationAvalonia/Program.cs index 8953cb67..3aecb91f 100644 --- a/Source/LibationAvalonia/Program.cs +++ b/Source/LibationAvalonia/Program.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.Runtime.InteropServices; using System.Threading.Tasks; using ApplicationServices; +using AppScaffolding; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.ReactiveUI; @@ -42,7 +43,7 @@ namespace LibationAvalonia // // //***********************************************// // Migrations which must occur before configuration is loaded for the first time. Usually ones which alter the Configuration - var config = AppScaffolding.LibationScaffolding.RunPreConfigMigrations(); + var config = LibationScaffolding.RunPreConfigMigrations(); App.SetupRequired = !config.LibationSettingsAreValid; @@ -50,29 +51,10 @@ namespace LibationAvalonia var classicLifetimeTask = Task.Run(() => new ClassicDesktopStyleApplicationLifetime()); var appBuilderTask = Task.Run(BuildAvaloniaApp); - if (Configuration.IsWindows) - AppScaffolding.LibationScaffolding.SetReleaseIdentifier(AppScaffolding.ReleaseIdentifier.WindowsAvalonia); - else if (Configuration.IsLinux) - { - var releaseID = RuntimeInformation.OSArchitecture switch - { - Architecture.X64 => AppScaffolding.ReleaseIdentifier.LinuxAvalonia, - Architecture.Arm64 => AppScaffolding.ReleaseIdentifier.LinuxAvalonia_Arm64, - _ => throw new PlatformNotSupportedException() - }; - AppScaffolding.LibationScaffolding.SetReleaseIdentifier(releaseID); - } - else if (Configuration.IsMacOs) - { - var releaseID = RuntimeInformation.OSArchitecture switch - { - Architecture.X64 => AppScaffolding.ReleaseIdentifier.MacOSAvalonia, - Architecture.Arm64 => AppScaffolding.ReleaseIdentifier.MacOSAvalonia_Arm64, - _ => throw new PlatformNotSupportedException() - }; - AppScaffolding.LibationScaffolding.SetReleaseIdentifier(releaseID); - } - else return; + LibationScaffolding.SetReleaseIdentifier(Variety.Chardonnay); + + if (LibationScaffolding.ReleaseIdentifier is ReleaseIdentifier.None) + return; if (!App.SetupRequired) @@ -99,8 +81,8 @@ namespace LibationAvalonia try { // most migrations go in here - AppScaffolding.LibationScaffolding.RunPostConfigMigrations(config); - AppScaffolding.LibationScaffolding.RunPostMigrationScaffolding(config); + LibationScaffolding.RunPostConfigMigrations(config); + LibationScaffolding.RunPostMigrationScaffolding(config); return true; } diff --git a/Source/LibationFileManager/Configuration.Environment.cs b/Source/LibationFileManager/Configuration.Environment.cs index f18c9944..1eec30a1 100644 --- a/Source/LibationFileManager/Configuration.Environment.cs +++ b/Source/LibationFileManager/Configuration.Environment.cs @@ -6,16 +6,25 @@ using System.Threading.Tasks; namespace LibationFileManager { - public partial class Configuration + [Flags] + public enum OS + { + Unknown, + Windows = 0x100000, + Linux = 0x200000, + MacOS = 0x400000, + } + + public partial class Configuration { - public static bool IsWindows { get; } = OperatingSystem.IsWindows(); + public static bool IsWindows { get; } = OperatingSystem.IsWindows(); public static bool IsLinux { get; } = OperatingSystem.IsLinux(); public static bool IsMacOs { get; } = OperatingSystem.IsMacOS(); - public static string OS { get; } - = IsLinux ? "Linux" - : IsMacOs ? "MacOS" - : IsWindows ? "Windows" - : "UNKNOWN_OS"; + public static OS OS { get; } + = IsLinux ? OS.Linux + : IsMacOs ? OS.MacOS + : IsWindows ? OS.Windows + : OS.Unknown; } } diff --git a/Source/LibationWinForms/Program.cs b/Source/LibationWinForms/Program.cs index 333114e3..28148e21 100644 --- a/Source/LibationWinForms/Program.cs +++ b/Source/LibationWinForms/Program.cs @@ -30,7 +30,7 @@ namespace LibationWinForms ApplicationConfiguration.Initialize(); - AppScaffolding.LibationScaffolding.SetReleaseIdentifier(AppScaffolding.ReleaseIdentifier.WindowsClassic); + AppScaffolding.LibationScaffolding.SetReleaseIdentifier(AppScaffolding.Variety.Classic); //***********************************************// // //