Browse Source

Fix exceptions while using Blazor Webassembly

Blazor Webassembly mode do not support `Console.OpenStandardInput()`

ref : https://learn.microsoft.com/en-us/dotnet/api/system.console.openstandardinput?view=net-9.0

```
[System.Runtime.Versioning.UnsupportedOSPlatform("android")]
[System.Runtime.Versioning.UnsupportedOSPlatform("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatform("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatform("tvos")]
public static System.IO.Stream OpenStandardInput();
```
moogle 8 months ago
parent
commit
95b3d4320b

+ 39 - 0
src/Lua/Standard/Internal/ConsoleHelper.cs

@@ -0,0 +1,39 @@
+namespace Lua.Standard.Internal;
+
+public class ConsoleHelper
+{
+    public static bool SupportStandardConsole => LuaPlatformUtility.IsSandBox;
+
+    private static Stream? _inputStream;
+    private static TextReader? _inputReader;
+
+    public static Stream OpenStandardInput()
+    {
+        if (SupportStandardConsole)
+        {
+            return Console.OpenStandardInput();
+        }
+        _inputStream ??= new MemoryStream();
+        _inputReader ??= new StreamReader(_inputStream);
+        return _inputStream;
+    }
+
+    public static int Read()
+    {
+        if (SupportStandardConsole)
+        {
+            return Console.Read();
+        }
+        return _inputReader?.Read() ?? 0;
+    }
+    
+    public static Stream OpenStandardOutput()
+    {
+        return Console.OpenStandardOutput();
+    }
+    
+    public static Stream OpenStandardError()
+    {
+        return Console.OpenStandardError();
+    }
+}

+ 31 - 0
src/Lua/Standard/Internal/LuaPlatformUtility.cs

@@ -0,0 +1,31 @@
+namespace Lua.Standard.Internal;
+
+public class LuaPlatformUtility
+{
+    public static bool IsSandBox => SupportStdio;
+    public static bool SupportStdio => _supportStdioTryLazy.Value;
+    
+    private static Lazy<bool> _supportStdioTryLazy = new Lazy<bool>(() =>
+    {
+        try
+        {
+#if NET6_0_OR_GREATER
+            var isDesktop = System.OperatingSystem.IsWindows() || 
+                            System.OperatingSystem.IsLinux() || 
+                            System.OperatingSystem.IsMacOS();
+            if (!isDesktop)
+            {
+                return false;
+            }
+#endif
+            _ = Console.OpenStandardInput();
+            _ = Console.OpenStandardOutput();
+            return true;
+        }
+        catch (Exception)
+        {
+            return false;
+        }
+    });
+
+}

+ 6 - 5
src/Lua/Standard/OpenLibsExtensions.cs

@@ -1,4 +1,5 @@
 using Lua.Runtime;
+using Lua.Standard.Internal;
 
 namespace Lua.Standard;
 
@@ -39,16 +40,16 @@ public static class OpenLibsExtensions
 
     public static void OpenIOLibrary(this LuaState state)
     {
+        
         var io = new LuaTable(0, IOLibrary.Instance.Functions.Length);
         foreach (var func in IOLibrary.Instance.Functions)
         {
             io[func.Name] = func;
         }
-
-        io["stdio"] = new LuaValue(new FileHandle(Console.OpenStandardInput()));
-        io["stdout"] = new LuaValue(new FileHandle(Console.OpenStandardOutput()));
-        io["stderr"] = new LuaValue(new FileHandle(Console.OpenStandardError()));
-
+        io["stdio"] = new LuaValue(new FileHandle(ConsoleHelper.OpenStandardInput()));
+        io["stdout"] = new LuaValue(new FileHandle(ConsoleHelper.OpenStandardOutput()));
+        io["stderr"] = new LuaValue(new FileHandle(ConsoleHelper.OpenStandardError()));
+        
         state.Environment["io"] = io;
         state.LoadedModules["io"] = io;
     }