Bläddra i källkod

Add: file:seek

AnnulusGames 1 år sedan
förälder
incheckning
d14a16f0d7
2 ändrade filer med 65 tillägg och 1 borttagningar
  1. 24 1
      src/Lua/Standard/IO/FileHandle.cs
  2. 41 0
      src/Lua/Standard/IO/FileSeekFunction.cs

+ 24 - 1
src/Lua/Standard/IO/FileHandle.cs

@@ -78,6 +78,29 @@ public class FileHandle : LuaUserData
         writer!.Write(buffer);
     }
 
+    public long Seek(string whence, long offset)
+    {
+        if (whence != null)
+        {
+            switch (whence)
+            {
+                case "set":
+                    stream.Seek(offset, SeekOrigin.Begin);
+                    break;
+                case "cur":
+                    stream.Seek(offset, SeekOrigin.Current);
+                    break;
+                case "end":
+                    stream.Seek(offset, SeekOrigin.End);
+                    break;
+                default:
+                    throw new ArgumentException($"Invalid option '{whence}'");
+            }
+        }
+
+        return stream.Position;
+    }
+
     public void Flush()
     {
         writer!.Flush();
@@ -86,7 +109,7 @@ public class FileHandle : LuaUserData
     public void SetVBuf(string mode, int size)
     {
         // Ignore size parameter
-        
+
         if (writer != null)
         {
             writer.AutoFlush = mode is "no" or "line";

+ 41 - 0
src/Lua/Standard/IO/FileSeekFunction.cs

@@ -0,0 +1,41 @@
+namespace Lua.Standard.IO;
+
+public sealed class FileSeekFunction : LuaFunction
+{
+    public override string Name => "seek";
+    public static readonly FileSeekFunction Instance = new();
+
+    protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
+    {
+        var file = context.ReadArgument<FileHandle>(0);
+        var whence = context.ArgumentCount >= 2
+            ? context.ReadArgument<string>(1)
+            : "cur";
+        var offset = context.ArgumentCount >= 3
+            ? context.ReadArgument<double>(2)
+            : 0;
+        
+        if (whence is not ("set" or "cur" or "end"))
+        {
+            throw new LuaRuntimeException(context.State.GetTraceback(), $"bad argument #2 to 'seek' (invalid option '{whence}')");
+        }
+
+        if (!MathEx.IsInteger(offset))
+        {
+            throw new LuaRuntimeException(context.State.GetTraceback(), $"bad argument #3 to 'seek' (number has no integer representation)");
+        }
+        
+        try
+        {
+            buffer.Span[0] = file.Seek(whence, (long)offset);
+            return new(1);
+        }
+        catch (IOException ex)
+        {
+            buffer.Span[0] = LuaValue.Nil;
+            buffer.Span[1] = ex.Message;
+            buffer.Span[2] = ex.HResult;
+            return new(3);
+        }
+    }
+}