LinesFunction.cs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. using Lua.Internal;
  2. namespace Lua.Standard.IO;
  3. public sealed class LinesFunction : LuaFunction
  4. {
  5. public override string Name => "lines";
  6. public static readonly LinesFunction Instance = new();
  7. protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
  8. {
  9. if (context.ArgumentCount == 0)
  10. {
  11. var file = context.State.Environment["io"].Read<LuaTable>()["stdio"].Read<FileHandle>();
  12. buffer.Span[0] = new Iterator(file, []);
  13. return new(1);
  14. }
  15. else
  16. {
  17. var fileName = context.GetArgument<string>(0);
  18. using var methodBuffer = new PooledArray<LuaValue>(32);
  19. IOHelper.Open(context.State, fileName, "r", methodBuffer.AsMemory(), true);
  20. var file = methodBuffer[0].Read<FileHandle>();
  21. buffer.Span[0] = new Iterator(file, context.Arguments[1..]);
  22. return new(1);
  23. }
  24. }
  25. class Iterator(FileHandle file, ReadOnlySpan<LuaValue> formats) : LuaFunction
  26. {
  27. readonly LuaValue[] formats = formats.ToArray();
  28. protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
  29. {
  30. var resultCount = IOHelper.Read(context.State, file, Name, 0, formats, buffer, true);
  31. if (resultCount > 0 && buffer.Span[0].Type is LuaValueType.Nil)
  32. {
  33. file.Close();
  34. }
  35. return new(resultCount);
  36. }
  37. }
  38. }