diff --git a/src/CalcManager/CCalcManager.cpp b/src/CalcManager/CCalcManager.cpp index 1663554c..efdb020d 100644 --- a/src/CalcManager/CCalcManager.cpp +++ b/src/CalcManager/CCalcManager.cpp @@ -65,12 +65,9 @@ public: // Inherited via ICalcDisplay virtual void SetPrimaryDisplay(const std::wstring& pszText, bool isError) override { - std::wstring_convert> convert; - auto str = convert.to_bytes(pszText); - DBGPRINT("Native:SetPrimaryDisplay(%ls, %d)\n", pszText.data(), isError); - _params.SetPrimaryDisplay(_params.CalculatorState, str.data(), isError); + _params.SetPrimaryDisplay(_params.CalculatorState, pszText.data(), isError); } virtual void SetIsInError(bool isInError) override diff --git a/src/CalcManager/CCalcManager.h b/src/CalcManager/CCalcManager.h index 4eb4e663..ab35e888 100644 --- a/src/CalcManager/CCalcManager.h +++ b/src/CalcManager/CCalcManager.h @@ -9,7 +9,7 @@ struct GetHistoryItemResult; struct GetHistoryItemsResult; -typedef void (*SetPrimaryDisplayFunc)(void* state, const char* text, bool isError); +typedef void (*SetPrimaryDisplayFunc)(void* state, const wchar_t* text, bool isError); typedef void (*SetIsInErrorFunc)(void* state, bool isInError); typedef void (*SetExpressionDisplayFunc)(void* state, GetHistoryItemResult* data); typedef void (*SetParenthesisNumberFunc)(void* state, unsigned int count); diff --git a/src/CalcManager/CalcManager.wasm b/src/CalcManager/CalcManager.wasm index 7ba36e06..097aba74 100644 Binary files a/src/CalcManager/CalcManager.wasm and b/src/CalcManager/CalcManager.wasm differ diff --git a/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs b/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs index 009198e3..0dc8959b 100644 --- a/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs +++ b/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs @@ -98,7 +98,7 @@ namespace CalculationManager public delegate IntPtr GetCEngineStringFunc(IntPtr state, IntPtr id); public delegate void BinaryOperatorReceivedFunc(IntPtr state); - public delegate void SetPrimaryDisplayCallbackFunc(IntPtr state, string displayStringValue, bool isError); + public delegate void SetPrimaryDisplayCallbackFunc(IntPtr state, IntPtr pDisplayStringValue, bool isError); public delegate void SetIsInErrorCallbackFunc(IntPtr state, bool isError); public delegate void SetParenthesisNumberCallbackFunc(IntPtr state, int parenthesisCount); @@ -163,6 +163,10 @@ namespace CalculationManager var nativeResult = Marshal.PtrToStructure(historyItem); var itemResult = CalculatorManager.UnmarshalHistoryItemResult(nativeResult); + var tokens = string.Join("; ", itemResult.historyItemVector.spTokens.Select(v => $"{v.Item1} : {v.Item2}")); + + DebugTrace($"CalculatorManager.SetExpressionDisplayCallback: Tokens {tokens}"); + manager.SetExpressionDisplay(itemResult.historyItemVector.spTokens, itemResult.historyItemVector.spCommands); } @@ -174,7 +178,7 @@ namespace CalculationManager var numbers = new List(); for (int i = 0; i < count; i++) { - var value = Marshal.PtrToStringUni(Marshal.ReadIntPtr(newMemorizedNumbers, i)); + var value = PtrToString(Marshal.ReadIntPtr(newMemorizedNumbers, i)); numbers.Add(value); } @@ -199,8 +203,10 @@ namespace CalculationManager DebugTrace($"CalculatorManager.BinaryOperatorReceivedCallback"); } - public static void SetPrimaryDisplayCallback(IntPtr state, [MarshalAs(UnmanagedType.LPWStr)] string displayStringValue, bool isError) + public static void SetPrimaryDisplayCallback(IntPtr state, IntPtr pDisplayStringValue, bool isError) { + var displayStringValue = PtrToString(pDisplayStringValue); + var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay; manager.SetPrimaryDisplay(displayStringValue, isError); @@ -218,21 +224,59 @@ namespace CalculationManager public static IntPtr GetCEngineStringCallback(IntPtr state, IntPtr pResourceId) { var provider = GCHandle.FromIntPtr(state).Target as EngineResourceProvider; - var resourceId = Marshal.PtrToStringUni(pResourceId); + + var resourceId = PtrToString(pResourceId); + var resourceValue = provider.GetCEngineString(resourceId) ?? ""; -#if __WASM__ - // wchar_t is 32bits with emscripten - var pEngineString = StringToHGlobalUTF32(resourceValue); -#else - var pEngineString = Marshal.StringToHGlobalUni(resourceValue); -#endif + var pEngineString = StringToHGlobal(resourceValue); DebugTrace($"GetCEngineStringCallback({resourceId}, {resourceValue})"); return pEngineString; } + internal static IntPtr StringToHGlobal(string resourceValue) + { +#if __WASM__ || __IOS__ + // wchar_t is 32bits + return StringToHGlobalUTF32(resourceValue); +#else + return Marshal.StringToHGlobalUni(resourceValue); +#endif + } + + internal static string PtrToString(IntPtr pResourceId) + { +#if __WASM__ || __IOS__ + return PtrToStringUTF32(pResourceId); +#else + return Marshal.PtrToStringUni(pResourceId); +#endif + } + + private static string PtrToStringUTF32(IntPtr ptr) + { + var endPtr = ptr; + while (Marshal.ReadInt32(endPtr) is int c && c != 0) + { + endPtr += 4; + } + + if (endPtr != ptr) + { + var b = new byte[(int)endPtr - (int)ptr]; + Marshal.Copy(ptr, b, 0, b.Length); + + return Encoding.UTF32.GetString(b); + } + else + { + return ""; + } + + } + private static IntPtr StringToHGlobalUTF32(string resourceValue) { var ret = Encoding.UTF32.GetBytes(resourceValue); @@ -244,7 +288,7 @@ namespace CalculationManager private static void DebugTrace(string message) { - // Debug.WriteLine(message); + Debug.WriteLine(message); } } diff --git a/src/Calculator.Shared/CalcManager/CalculatorManager.cs b/src/Calculator.Shared/CalcManager/CalculatorManager.cs index a3937fae..ce28e75d 100644 --- a/src/Calculator.Shared/CalcManager/CalculatorManager.cs +++ b/src/Calculator.Shared/CalcManager/CalculatorManager.cs @@ -257,7 +257,7 @@ namespace CalculationManager for (var i = 0; i < historyResultItem.TokenCount; i++) { - var tokenString = Marshal.PtrToStringUni(Marshal.ReadIntPtr(historyResultItem.TokenStrings, i * Marshal.SizeOf())); + var tokenString = NativeDispatch.PtrToString(Marshal.ReadIntPtr(historyResultItem.TokenStrings, i * Marshal.SizeOf())); var tokenValue = Marshal.ReadInt32(historyResultItem.TokenValues, i * Marshal.SizeOf()); historyItem.historyItemVector.spTokens.Append((tokenString, tokenValue)); diff --git a/src/Calculator.Wasm/WasmScripts/CalcManager.js b/src/Calculator.Wasm/WasmScripts/CalcManager.js index fe4fdf17..30b998b4 100644 --- a/src/Calculator.Wasm/WasmScripts/CalcManager.js +++ b/src/Calculator.Wasm/WasmScripts/CalcManager.js @@ -16,7 +16,7 @@ var fGetCEngineStringCallback = Module.addFunction((state, id) => _getCEngineStringCallback(state, id), 'iii'); var fBinaryOperatorReceivedCallback = Module.addFunction((state) => _binaryOperatorReceivedCallback(state), 'vi'); - var fSetPrimaryDisplayCallback = Module.addFunction((state, displayStringValue, isError) => _setPrimaryDisplayCallback(state, Module.UTF8ToString(displayStringValue), isError), 'viii'); + var fSetPrimaryDisplayCallback = Module.addFunction((state, displayStringValue, isError) => _setPrimaryDisplayCallback(state, displayStringValue, isError), 'viii'); var fSetIsInErrorCallback = Module.addFunction((state, isError) => _setIsInErrorCallback(state, isError), 'vii'); var fSetParenthesisNumberCallback = Module.addFunction((state, parenthesisCount) => _setParenthesisNumberCallback(state, parenthesisCount), 'vii'); var fMaxDigitsReachedCallback = Module.addFunction((state) => _maxDigitsReachedCallback(state), 'vii');