From bfb6682360cccbaa751432af7aa1adf99e473e4d Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Fri, 25 Oct 2024 13:38:40 +0800 Subject: [PATCH] stash changes --- src/CalcViewModel/Snapshots.cpp | 102 ++++++++++++-- src/CalcViewModel/Snapshots.h | 63 +++++---- src/Calculator/Common/LaunchArguments.cs | 18 ++- src/Calculator/Utils/DeflateUtils.cs | 23 +--- src/Calculator/Utils/JsonUtils.cs | 166 +++++++++++++++++++---- 5 files changed, 291 insertions(+), 81 deletions(-) diff --git a/src/CalcViewModel/Snapshots.cpp b/src/CalcViewModel/Snapshots.cpp index e12c44cf..404cce36 100644 --- a/src/CalcViewModel/Snapshots.cpp +++ b/src/CalcViewModel/Snapshots.cpp @@ -11,12 +11,13 @@ namespace CalculatorApp::ViewModel::Snapshot { - UnaryCommand::UnaryCommand(Windows::Foundation::Collections::IVectorView ^ cmds) + UnaryCommand::UnaryCommand() + { + } + + UnaryCommand::UnaryCommand(std::vector cmds) + : m_cmds(std::move(cmds)) { - for (auto cmd : cmds) - { - m_cmds.push_back(cmd); - } } Windows::Foundation::Collections::IVectorView ^ UnaryCommand::Commands::get() @@ -24,22 +25,64 @@ namespace CalculatorApp::ViewModel::Snapshot return ref new Platform::Collections::VectorView(m_cmds); } - OperandCommand::OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, Windows::Foundation::Collections::IVectorView ^ cmds) + void UnaryCommand::Commands::set(Windows::Foundation::Collections::IVectorView ^ commands) { - IsNegative = isNegative; - IsDecimalPresent = isDecimal; - IsSciFmt = isSciFmt; - for (auto cmd : cmds) + m_cmds.clear(); + for (auto cmd : commands) { m_cmds.push_back(cmd); } } + BinaryCommand::BinaryCommand() + { + Command = 0; + } + + BinaryCommand::BinaryCommand(int cmd) + { + Command = cmd; + } + + OperandCommand::OperandCommand() + { + IsNegative = false; + IsDecimalPresent = false; + IsSciFmt = false; + } + + OperandCommand::OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, std::vector cmds) + { + IsNegative = isNegative; + IsDecimalPresent = isDecimal; + IsSciFmt = isSciFmt; + m_cmds = std::move(cmds); + } + Windows::Foundation::Collections::IVectorView ^ OperandCommand::Commands::get() { return ref new Platform::Collections::VectorView(m_cmds); } + void OperandCommand::Commands::set(Windows::Foundation::Collections::IVectorView ^ commands) + { + m_cmds.clear(); + for (auto cmd : commands) + { + m_cmds.push_back(cmd); + } + } + + Parentheses::Parentheses() + { + Command = 0; + } + + Parentheses::Parentheses(int cmd) + { + Command = cmd; + } + ICalcManagerIExprCommand ^ CreateExprCommand(const IExpressionCommand* exprCmd) { switch (exprCmd->GetCommandType()) { @@ -78,6 +121,12 @@ namespace CalculatorApp::ViewModel::Snapshot } } + CalcManagerHistoryToken::CalcManagerHistoryToken() + { + OpCodeName = nullptr; + CommandIndex = 0; + } + CalcManagerHistoryToken::CalcManagerHistoryToken(Platform::String ^ opCodeName, int cmdIndex) { assert(opCodeName != nullptr && "opCodeName is mandatory."); @@ -85,6 +134,14 @@ namespace CalculatorApp::ViewModel::Snapshot CommandIndex = cmdIndex; } + CalcManagerHistoryItem::CalcManagerHistoryItem() + { + Tokens = ref new Platform::Collections::Vector(); + Commands = ref new Platform::Collections::Vector(); + Expression = ref new Platform::String(); + Result = ref new Platform::String(); + } + CalcManagerHistoryItem::CalcManagerHistoryItem(const CalculationManager::HISTORYITEM& item) { Tokens = ref new Platform::Collections::Vector(); @@ -103,6 +160,11 @@ namespace CalculatorApp::ViewModel::Snapshot Result = ref new Platform::String(item.historyItemVector.result.c_str()); } + CalcManagerSnapshot::CalcManagerSnapshot() + { + HistoryItems = nullptr; + } + CalcManagerSnapshot::CalcManagerSnapshot(const CalculationManager::CalculatorManager& calcMgr) { auto& items = calcMgr.GetHistoryItems(); @@ -116,6 +178,12 @@ namespace CalculatorApp::ViewModel::Snapshot } } + PrimaryDisplaySnapshot::PrimaryDisplaySnapshot() + { + DisplayValue = ref new Platform::String(); + IsError = false; + } + PrimaryDisplaySnapshot::PrimaryDisplaySnapshot(Platform::String ^ display, bool isError) { assert(display != nullptr && "display is mandatory"); @@ -123,6 +191,12 @@ namespace CalculatorApp::ViewModel::Snapshot IsError = isError; } + ExpressionDisplaySnapshot::ExpressionDisplaySnapshot() + { + Tokens = ref new Platform::Collections::Vector(); + Commands = ref new Platform::Collections::Vector(); + } + ExpressionDisplaySnapshot::ExpressionDisplaySnapshot( const std::vector& tokens, const std::vector>& commands) @@ -140,6 +214,14 @@ namespace CalculatorApp::ViewModel::Snapshot } } + StandardCalculatorSnapshot::StandardCalculatorSnapshot() + { + CalcManager = ref new CalcManagerSnapshot(); + PrimaryDisplay = ref new PrimaryDisplaySnapshot(); + ExpressionDisplay = nullptr; + DisplayCommands = ref new Platform::Collections::Vector(); + } + std::vector> ToUnderlying(Windows::Foundation::Collections::IVector ^ items) { return {}; // TODO diff --git a/src/CalcViewModel/Snapshots.h b/src/CalcViewModel/Snapshots.h index f22d1c36..cee12933 100644 --- a/src/CalcViewModel/Snapshots.h +++ b/src/CalcViewModel/Snapshots.h @@ -17,15 +17,15 @@ public public ref struct UnaryCommand sealed : public ICalcManagerIExprCommand { - property Windows::Foundation::Collections::IVectorView ^ Commands { Windows::Foundation::Collections::IVectorView ^ get(); }; + property Windows::Foundation::Collections::IVectorView ^ Commands { + Windows::Foundation::Collections::IVectorView ^ get(); + void set(Windows::Foundation::Collections::IVectorView ^ commands); + }; - explicit UnaryCommand(Windows::Foundation::Collections::IVectorView ^ cmds); + UnaryCommand(); internal :; - explicit UnaryCommand(std::vector cmds) - : m_cmds(std::move(cmds)) - { - } + explicit UnaryCommand(std::vector cmds); std::vector m_cmds; }; @@ -33,10 +33,11 @@ public ref struct BinaryCommand sealed : public ICalcManagerIExprCommand { property int Command; - explicit BinaryCommand(int cmd) - { - Command = cmd; - } + + BinaryCommand(); + + internal :; + explicit BinaryCommand(int cmd); }; public @@ -45,17 +46,15 @@ public property bool IsNegative; property bool IsDecimalPresent; property bool IsSciFmt; - property Windows::Foundation::Collections::IVectorView ^ Commands { Windows::Foundation::Collections::IVectorView ^ get(); }; + property Windows::Foundation::Collections::IVectorView ^ Commands { + Windows::Foundation::Collections::IVectorView ^ get(); + void set(Windows::Foundation::Collections::IVectorView ^ commands); + }; + + OperandCommand(); - explicit OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, Windows::Foundation::Collections::IVectorView ^ cmds); internal :; - explicit OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, std::vector cmds) - { - IsNegative = isNegative; - IsDecimalPresent = isDecimal; - IsSciFmt = isSciFmt; - m_cmds = std::move(cmds); - } + explicit OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, std::vector cmds); std::vector m_cmds; }; @@ -63,10 +62,11 @@ public ref struct Parentheses sealed : public ICalcManagerIExprCommand { property int Command; - explicit Parentheses(int cmd) - { - Command = cmd; - } + + Parentheses(); + + internal :; + explicit Parentheses(int cmd); }; public @@ -75,6 +75,9 @@ public property Platform::String ^ OpCodeName; // mandatory property int CommandIndex; + CalcManagerHistoryToken(); + + internal :; explicit CalcManagerHistoryToken(Platform::String ^ opCodeName, int cmdIndex); }; @@ -86,11 +89,7 @@ public property Platform::String ^ Expression; // mandatory property Platform::String ^ Result; // mandatory - // explicit CalcManagerHistoryItem( - // Windows::Foundation::Collections::IVector ^ tokens, - // Windows::Foundation::Collections::IVector ^ commands, - // Platform::String ^ expression, - // Platform::String ^ result); + CalcManagerHistoryItem(); internal :; explicit CalcManagerHistoryItem(const CalculationManager::HISTORYITEM& item); @@ -101,6 +100,8 @@ public { property Windows::Foundation::Collections::IVector ^ HistoryItems; // optional + CalcManagerSnapshot(); + internal :; explicit CalcManagerSnapshot(const CalculationManager::CalculatorManager& calcMgr); }; @@ -111,6 +112,8 @@ public property Platform::String ^ DisplayValue; // mandatory property bool IsError; + PrimaryDisplaySnapshot(); + internal :; explicit PrimaryDisplaySnapshot(Platform::String ^ display, bool isError); }; @@ -121,6 +124,8 @@ public property Windows::Foundation::Collections::IVector ^ Tokens; property Windows::Foundation::Collections::IVector ^ Commands; + ExpressionDisplaySnapshot(); + internal :; using CalcHistoryToken = std::pair; explicit ExpressionDisplaySnapshot(const std::vector& tokens, const std::vector>& commands); @@ -133,6 +138,8 @@ public property PrimaryDisplaySnapshot ^ PrimaryDisplay; // mandatory property ExpressionDisplaySnapshot ^ ExpressionDisplay; // optional property Windows::Foundation::Collections::IVector ^ DisplayCommands; // mandatory + + StandardCalculatorSnapshot(); }; public diff --git a/src/Calculator/Common/LaunchArguments.cs b/src/Calculator/Common/LaunchArguments.cs index 3d60896d..fc887356 100644 --- a/src/Calculator/Common/LaunchArguments.cs +++ b/src/Calculator/Common/LaunchArguments.cs @@ -1,5 +1,10 @@ +using System; +using System.Linq; +using System.Text.Json; using Windows.ApplicationModel.Activation; + using CalculatorApp.ViewModel.Snapshot; +using CalculatorApp.JsonUtils; namespace CalculatorApp { @@ -29,7 +34,18 @@ namespace CalculatorApp public static SnapshotLaunchArguments GetSnapshotLaunchArgs(this IProtocolActivatedEventArgs args) { - return null; + try + { + var rawbase64 = args.Uri.Segments.Skip(1).Aggregate((folded, x) => folded += x); + var compressed = Convert.FromBase64String(rawbase64); + var jsonStr = DeflateUtils.Decompress(compressed); + var snapshot = JsonSerializer.Deserialize(jsonStr); + return new SnapshotLaunchArguments { HasError = false, Snapshot = snapshot.Value }; + } + catch (Exception) + { + return new SnapshotLaunchArguments { HasError = true }; + } } } } diff --git a/src/Calculator/Utils/DeflateUtils.cs b/src/Calculator/Utils/DeflateUtils.cs index 1cdb4c6c..3d4b2fbd 100644 --- a/src/Calculator/Utils/DeflateUtils.cs +++ b/src/Calculator/Utils/DeflateUtils.cs @@ -20,24 +20,15 @@ namespace CalculatorApp } } - public static bool TryDecompress(byte[] data, out string text) + public static string Decompress(byte[] data) { - text = null; - try + using (var srcStream = new MemoryStream(data)) + using (var deflateStream = new DeflateStream(srcStream, CompressionMode.Decompress)) + using (var resultStream = new MemoryStream()) { - using (var srcStream = new MemoryStream(data)) - using (var deflateStream = new DeflateStream(srcStream, CompressionMode.Decompress)) - using (var resultStream = new MemoryStream()) - { - deflateStream.CopyTo(resultStream); - byte[] decompressed = resultStream.ToArray(); - text = Encoding.UTF8.GetString(decompressed); - return true; - } - } - catch (Exception) - { - return false; + deflateStream.CopyTo(resultStream); + byte[] decompressed = resultStream.ToArray(); + return Encoding.UTF8.GetString(decompressed); } } } diff --git a/src/Calculator/Utils/JsonUtils.cs b/src/Calculator/Utils/JsonUtils.cs index 060c2b14..33a947e9 100644 --- a/src/Calculator/Utils/JsonUtils.cs +++ b/src/Calculator/Utils/JsonUtils.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.Json.Serialization; using CalculatorApp.ViewModel.Snapshot; +using Windows.ApplicationModel; namespace CalculatorApp.JsonUtils { @@ -18,7 +19,11 @@ namespace CalculatorApp.JsonUtils set => Value.OpCodeName = value; } [JsonPropertyName("c")] - public int CommandIndex { get => Value.CommandIndex; } + public int CommandIndex + { + get => Value.CommandIndex; + set => Value.CommandIndex = value; + } } [JsonPolymorphic(TypeDiscriminatorPropertyName = "$t")] @@ -36,7 +41,11 @@ namespace CalculatorApp.JsonUtils public UnaryCommand Value; [JsonPropertyName("c")] - public IList Commands { get => Value.Commands.ToList(); } + public IReadOnlyList Commands + { + get => Value.Commands; + set => Value.Commands = value; + } } internal class BinaryCommandAlias : ICalcManagerIExprCommandAlias @@ -45,7 +54,11 @@ namespace CalculatorApp.JsonUtils public BinaryCommand Value; [JsonPropertyName("c")] - public int Command { get => Value.Command; } + public int Command + { + get => Value.Command; + set => Value.Command = value; + } } internal class OperandCommandAlias : ICalcManagerIExprCommandAlias @@ -54,13 +67,29 @@ namespace CalculatorApp.JsonUtils public OperandCommand Value; [JsonPropertyName("n")] - public bool IsNegative { get => Value.IsNegative; } + public bool IsNegative + { + get => Value.IsNegative; + set => Value.IsNegative = value; + } [JsonPropertyName("d")] - public bool IsDecimalPresent { get => Value.IsDecimalPresent; } + public bool IsDecimalPresent + { + get => Value.IsDecimalPresent; + set => Value.IsDecimalPresent = value; + } [JsonPropertyName("s")] - public bool IsSciFmt { get => Value.IsSciFmt; } + public bool IsSciFmt + { + get => Value.IsSciFmt; + set => Value.IsSciFmt = value; + } [JsonPropertyName("c")] - public IList Commands { get => Value.Commands.ToList(); } + public IReadOnlyList Commands + { + get => Value.Commands; + set => Value.Commands = value; + } } internal class ParenthesesAlias : ICalcManagerIExprCommandAlias @@ -69,7 +98,11 @@ namespace CalculatorApp.JsonUtils public Parentheses Value; [JsonPropertyName("c")] - public int Command { get => Value.Command; } + public int Command + { + get => Value.Command; + set => Value.Command = value; + } } internal class CalcManagerHistoryItemAlias @@ -78,23 +111,32 @@ namespace CalculatorApp.JsonUtils public CalcManagerHistoryItem Value; [JsonPropertyName("t")] - public IList Tokens + public IEnumerable Tokens { - get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }).ToList(); + get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }); + set => Value.Tokens = value.Select(Helpers.MapHistoryToken).ToList(); } [JsonPropertyName("c")] - public IList Commands + public IEnumerable Commands { - get => Value.Commands.Select(Helpers.MapCommandAlias).ToList(); + get => Value.Commands.Select(Helpers.MapCommandAlias); + set => Value.Commands = value.Select(Helpers.MapCommandAlias).ToList(); } [JsonPropertyName("e")] - public string Expression { get => Value.Expression; } + public string Expression + { + get => Value.Expression; + set => Value.Expression = value; + } [JsonPropertyName("r")] - public string Result { get => Value.Result; } - + public string Result + { + get => Value.Result; + set => Value.Result = value; + } } internal class CalcManagerSnapshotAlias @@ -103,7 +145,11 @@ namespace CalculatorApp.JsonUtils public CalcManagerSnapshot Value; [JsonPropertyName("h")] - public IList HistoryItems { get => Value.HistoryItems.Select(x => new CalcManagerHistoryItemAlias { Value = x }).ToList(); } + public IEnumerable HistoryItems + { + get => Value.HistoryItems.Select(x => new CalcManagerHistoryItemAlias { Value = x }); + set => Value.HistoryItems = value.Select(x => new CalcManagerHistoryItem { Tokens = x.Tokens.Select(Helpers.MapHistoryToken).ToList() }).ToList(); + } } internal class PrimaryDisplaySnapshotAlias @@ -112,9 +158,17 @@ namespace CalculatorApp.JsonUtils public PrimaryDisplaySnapshot Value; [JsonPropertyName("d")] - public string DisplayValue { get => Value.DisplayValue; } + public string DisplayValue + { + get => Value.DisplayValue; + set => Value.DisplayValue = value; + } [JsonPropertyName("e")] - public bool IsError { get => Value.IsError; } + public bool IsError + { + get => Value.IsError; + set => IsError = value; + } } internal class ExpressionDisplaySnapshotAlias @@ -123,9 +177,17 @@ namespace CalculatorApp.JsonUtils public ExpressionDisplaySnapshot Value; [JsonPropertyName("t")] - public IList Tokens { get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }).ToList(); } + public IEnumerable Tokens + { + get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }); + set => Value.Tokens = value.Select(Helpers.MapHistoryToken).ToList(); + } [JsonPropertyName("c")] - public IList Commands { get => Value.Commands.Select(Helpers.MapCommandAlias).ToList(); } + public IEnumerable Commands + { + get => Value.Commands.Select(Helpers.MapCommandAlias); + set => Value.Commands = value.Select(Helpers.MapCommandAlias).ToList(); + } } internal class StandardCalculatorSnapshotAlias @@ -134,13 +196,29 @@ namespace CalculatorApp.JsonUtils public StandardCalculatorSnapshot Value; [JsonPropertyName("m")] - public CalcManagerSnapshotAlias CalcManager { get => new CalcManagerSnapshotAlias { Value = Value.CalcManager }; } + public CalcManagerSnapshotAlias CalcManager + { + get => new CalcManagerSnapshotAlias { Value = Value.CalcManager }; + set => Value.CalcManager = value.Value; + } [JsonPropertyName("p")] - public PrimaryDisplaySnapshotAlias PrimaryDisplay { get => new PrimaryDisplaySnapshotAlias { Value = Value.PrimaryDisplay }; } + public PrimaryDisplaySnapshotAlias PrimaryDisplay + { + get => new PrimaryDisplaySnapshotAlias { Value = Value.PrimaryDisplay }; + set => Value.PrimaryDisplay = value.Value; + } [JsonPropertyName("e")] - public ExpressionDisplaySnapshotAlias ExpressionDisplay { get => new ExpressionDisplaySnapshotAlias { Value = Value.ExpressionDisplay }; } + public ExpressionDisplaySnapshotAlias ExpressionDisplay + { + get => new ExpressionDisplaySnapshotAlias { Value = Value.ExpressionDisplay }; + set => Value.ExpressionDisplay = value.Value; + } [JsonPropertyName("c")] - public IList Commands { get => Value.DisplayCommands.Select(Helpers.MapCommandAlias).ToList(); } + public IEnumerable Commands + { + get => Value.DisplayCommands.Select(Helpers.MapCommandAlias); + set => Value.DisplayCommands = value.Select(Helpers.MapCommandAlias).ToList(); + } } internal class ApplicationSnapshotAlias @@ -149,13 +227,22 @@ namespace CalculatorApp.JsonUtils public ApplicationSnapshot Value; [JsonPropertyName("m")] - public int Mode { get => Value.Mode; } + public int Mode { get => Value.Mode; set => Value.Mode = value; } [JsonPropertyName("s")] - public StandardCalculatorSnapshotAlias StandardCalculatorSnapshot { get => new StandardCalculatorSnapshotAlias { Value = Value.StandardCalculator }; } + public StandardCalculatorSnapshotAlias StandardCalculatorSnapshot + { + get => new StandardCalculatorSnapshotAlias { Value = Value.StandardCalculator }; + set => Value.StandardCalculator = value.Value; + } } internal static class Helpers { + public static CalcManagerHistoryToken MapHistoryToken(CalcManagerHistoryTokenAlias token) + { + return new CalcManagerHistoryToken { OpCodeName = token.OpCodeName, CommandIndex = token.CommandIndex }; + } + public static ICalcManagerIExprCommandAlias MapCommandAlias(ICalcManagerIExprCommand exprCmd) { if (exprCmd is UnaryCommand unary) @@ -176,5 +263,32 @@ namespace CalculatorApp.JsonUtils } throw new NotImplementedException("unhandled command type."); } + + public static ICalcManagerIExprCommand MapCommandAlias(ICalcManagerIExprCommandAlias exprCmd) + { + if (exprCmd is UnaryCommandAlias unary) + { + return new UnaryCommand { Commands = unary.Commands }; + } + else if (exprCmd is BinaryCommandAlias binary) + { + return new BinaryCommand { Command = binary.Command }; + } + else if (exprCmd is OperandCommandAlias operand) + { + return new OperandCommand + { + IsNegative = operand.IsNegative, + IsDecimalPresent = operand.IsDecimalPresent, + IsSciFmt = operand.IsSciFmt, + Commands = operand.Commands + }; + } + else if (exprCmd is ParenthesesAlias paren) + { + return new Parentheses { Command = paren.Command }; + } + throw new NotImplementedException("unhandled command type."); + } } }