From b5f044223a49caef5cda89f5fe8c46765639accc Mon Sep 17 00:00:00 2001 From: Alessandro Proto Date: Sat, 14 Jan 2023 15:39:54 +0100 Subject: [PATCH] Added BinaryReadHandle. Added IHandle interface. Adapted HTTP requests to return BinaryReadHandle on binary mode. --- .../LuaRuntime/Handlers/BinaryReadHandle.cs | 494 +++++++++++++++--- .../LuaRuntime/Handlers/BinaryWriteHandle.cs | 7 +- Capy64/LuaRuntime/Handlers/IHandle.cs | 13 + Capy64/LuaRuntime/Handlers/ReadHandle.cs | 6 +- Capy64/LuaRuntime/Handlers/WriteHandle.cs | 6 +- Capy64/LuaRuntime/Libraries/HTTP.cs | 12 +- 6 files changed, 439 insertions(+), 99 deletions(-) create mode 100644 Capy64/LuaRuntime/Handlers/IHandle.cs diff --git a/Capy64/LuaRuntime/Handlers/BinaryReadHandle.cs b/Capy64/LuaRuntime/Handlers/BinaryReadHandle.cs index f87f5ce..6515c39 100644 --- a/Capy64/LuaRuntime/Handlers/BinaryReadHandle.cs +++ b/Capy64/LuaRuntime/Handlers/BinaryReadHandle.cs @@ -8,121 +8,443 @@ using System.Threading.Tasks; namespace Capy64.LuaRuntime.Handlers; -[Obsolete("Work in progress")] -public class BinaryReadHandle +public class BinaryReadHandle : IHandle { - private readonly BinaryReader _stream; - private bool isClosed = false; - private bool ended => _stream.BaseStream.Position == _stream.BaseStream.Length; + private readonly BinaryReader Stream; + private bool IsClosed = false; + private bool EndOfStream => Stream.BaseStream.Position == Stream.BaseStream.Length; public BinaryReadHandle(Stream stream) { - _stream = new BinaryReader(stream); + Stream = new BinaryReader(stream, Encoding.ASCII); } public BinaryReadHandle(BinaryReader stream) { - _stream = stream; + Stream = stream; } - /*public void Push(Lua L) + public void Push(Lua L, bool newTable = true) { - L.NewTable(); + if (newTable) + L.NewTable(); - L.PushString("readAll"); - L.PushCFunction(L_ReadAll); + L.PushString("nextByte"); + L.PushCFunction(L_NextByte); L.SetTable(-3); - L.PushString("readLine"); - L.PushCFunction(L_ReadLine); + L.PushString("nextShort"); + L.PushCFunction(L_NextShort); L.SetTable(-3); - - L.PushString("read"); - L.PushCFunction(L_Read); + + L.PushString("nextInt"); + L.PushCFunction(L_NextInt); + L.SetTable(-3); + + L.PushString("nextLong"); + L.PushCFunction(L_NextLong); + L.SetTable(-3); + + L.PushString("nextSByte"); + L.PushCFunction(L_NextSByte); + L.SetTable(-3); + + L.PushString("nextUShort"); + L.PushCFunction(L_NextUShort); + L.SetTable(-3); + + L.PushString("nextUInt"); + L.PushCFunction(L_NextUInt); + L.SetTable(-3); + + L.PushString("nextULong"); + L.PushCFunction(L_NextULong); + L.SetTable(-3); + + L.PushString("nextHalf"); + L.PushCFunction(L_NextHalf); + L.SetTable(-3); + + L.PushString("nextFloat"); + L.PushCFunction(L_NextFloat); + L.SetTable(-3); + + L.PushString("nextDouble"); + L.PushCFunction(L_NextDouble); + L.SetTable(-3); + + L.PushString("nextChar"); + L.PushCFunction(L_NextChar); + L.SetTable(-3); + + L.PushString("nextString"); + L.PushCFunction(L_NextString); + L.SetTable(-3); + + L.PushString("nextBoolean"); + L.PushCFunction(L_NextBoolean); L.SetTable(-3); L.PushString("close"); L.PushCFunction(L_Close); L.SetTable(-3); + + L.PushString("_handle"); + L.PushObject(this); + L.SetTable(-3); } - private int L_ReadAll(IntPtr state) + private static int L_NextByte(IntPtr state) { var L = Lua.FromIntPtr(state); - if (isClosed) + L.CheckType(1, LuaType.Table); + var count = (int)L.OptNumber(2, 1); + L.ArgumentCheck(count >= 1, 2, "count must be a positive integer"); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) L.Error("handle is closed"); - if (ended) - { - L.PushNil(); - return 1; - } - - //var content = _stream.read; - L.PushString(content); - - return 1; - } - - private int L_ReadLine(IntPtr state) - { - var L = Lua.FromIntPtr(state); - - if (isClosed) - L.Error("handle is closed"); - - if (ended) - { - L.PushNil(); - return 1; - } - - var line = _stream.ReadLine(); - - if (line is null) - L.PushNil(); - else - L.PushString(line); - - return 1; - } - - private int L_Read(IntPtr state) - { - var L = Lua.FromIntPtr(state); - var count = (int)L.OptNumber(1, 1); - - L.ArgumentCheck(count < 1, 1, "count must be a positive integer"); - - if (ended) - L.Error("handle is closed"); - - if (_stream.EndOfStream) - { - L.PushNil(); - return 1; - } - - var chunk = new char[count]; - - _stream.Read(chunk, 0, count); - - L.PushString(new string(chunk)); - - return 1; - } - - private int L_Close(IntPtr state) - { - var L = Lua.FromIntPtr(state); - - if (isClosed) + if (h.EndOfStream) return 0; - _stream.Close(); + if (count == 1) + { + var b = h.Stream.ReadByte(); + L.PushInteger(b); + return 1; - isClosed = true; + } + else + { + var bs = h.Stream.ReadBytes(count); + foreach (var b in bs) + { + L.PushInteger(b); + } + return bs.Length; + } + } + + private static int L_NextShort(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + var b = h.Stream.ReadInt16(); + L.PushInteger(b); + return 1; + } + + private static int L_NextInt(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + var b = h.Stream.ReadInt32(); + L.PushInteger(b); + return 1; + } + + private static int L_NextLong(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + var b = h.Stream.ReadInt64(); + L.PushInteger(b); + return 1; + } + + private static int L_NextSByte(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + var b = h.Stream.ReadSByte(); + L.PushInteger(b); + return 1; + } + + private static int L_NextUShort(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + var b = h.Stream.ReadUInt16(); + L.PushInteger(b); + return 1; + } + + private static int L_NextUInt(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + var b = h.Stream.ReadUInt32(); + L.PushInteger(b); + return 1; + } + + private static int L_NextULong(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + var b = h.Stream.ReadUInt64(); + L.PushInteger((long)b); + return 1; + } + + private static int L_NextHalf(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + var b = h.Stream.ReadHalf(); + L.PushNumber((double)b); + return 1; + } + + private static int L_NextFloat(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + var b = h.Stream.ReadSingle(); + L.PushNumber((double)b); + return 1; + } + + private static int L_NextDouble(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + var b = h.Stream.ReadDouble(); + L.PushNumber((double)b); + return 1; + } + + private static int L_NextChar(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + var count = (int)L.OptNumber(2, 1); + L.ArgumentCheck(count >= 1, 2, "count must be a positive integer"); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + if (count == 1) + { + var b = h.Stream.ReadChar(); + L.PushString(b.ToString()); + return 1; + + } + else + { + var bs = h.Stream.ReadChars(count); + foreach (var b in bs) + { + L.PushString(b.ToString()); + } + return bs.Length; + } + } + + private static int L_NextString(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + var count = (int)L.OptNumber(2, 1); + L.ArgumentCheck(count >= 1, 2, "count must be a positive integer"); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + if (count == 1) + { + var b = h.Stream.ReadChar(); + L.PushString(b.ToString()); + return 1; + + } + else + { + var bs = h.Stream.ReadBytes(count); + L.PushBuffer(bs); + return 1; + } + } + + private static int L_NextBoolean(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, false); + + if (h is null || h.IsClosed) + L.Error("handle is closed"); + + if (h.EndOfStream) + return 0; + + var b = h.Stream.ReadBoolean(); + L.PushBoolean(b); + return 1; + } + + private static int L_Close(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckType(1, LuaType.Table); + L.PushString("_handle"); + L.GetTable(1); + var h = L.ToObject(-1, true); + + if (h is null || h.IsClosed) + return 0; + + h.Stream.Close(); + + h.IsClosed = true; return 0; - }*/ + } } diff --git a/Capy64/LuaRuntime/Handlers/BinaryWriteHandle.cs b/Capy64/LuaRuntime/Handlers/BinaryWriteHandle.cs index 6a6e032..3796fb0 100644 --- a/Capy64/LuaRuntime/Handlers/BinaryWriteHandle.cs +++ b/Capy64/LuaRuntime/Handlers/BinaryWriteHandle.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace Capy64.LuaRuntime.Handlers; [Obsolete("Work in progress")] -public class BinaryWriteHandle +public class BinaryWriteHandle : IHandle { private readonly BinaryWriter _stream; private bool isClosed = false; @@ -23,6 +23,11 @@ public class BinaryWriteHandle _stream = stream; } + public void Push(Lua L, bool newTable = true) + { + throw new NotImplementedException(); + } + /*public void Push(Lua L) { L.NewTable(); diff --git a/Capy64/LuaRuntime/Handlers/IHandle.cs b/Capy64/LuaRuntime/Handlers/IHandle.cs new file mode 100644 index 0000000..3414fba --- /dev/null +++ b/Capy64/LuaRuntime/Handlers/IHandle.cs @@ -0,0 +1,13 @@ +using KeraLua; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Capy64.LuaRuntime.Handlers; + +public interface IHandle +{ + public void Push(Lua L, bool newTable = true); +} diff --git a/Capy64/LuaRuntime/Handlers/ReadHandle.cs b/Capy64/LuaRuntime/Handlers/ReadHandle.cs index 50e77dd..89c1f11 100644 --- a/Capy64/LuaRuntime/Handlers/ReadHandle.cs +++ b/Capy64/LuaRuntime/Handlers/ReadHandle.cs @@ -9,10 +9,10 @@ using System.Threading.Tasks; namespace Capy64.LuaRuntime.Handlers; -public class ReadHandle +public class ReadHandle : IHandle { - public readonly StreamReader Stream; - public bool IsClosed = false; + private readonly StreamReader Stream; + private bool IsClosed = false; public ReadHandle(Stream stream) { Stream = new StreamReader(stream); diff --git a/Capy64/LuaRuntime/Handlers/WriteHandle.cs b/Capy64/LuaRuntime/Handlers/WriteHandle.cs index 38eb398..8454675 100644 --- a/Capy64/LuaRuntime/Handlers/WriteHandle.cs +++ b/Capy64/LuaRuntime/Handlers/WriteHandle.cs @@ -8,10 +8,10 @@ using System.Threading.Tasks; namespace Capy64.LuaRuntime.Handlers; -public class WriteHandle +public class WriteHandle : IHandle { - public readonly StreamWriter Stream; - public bool IsClosed = false; + private readonly StreamWriter Stream; + private bool IsClosed = false; public WriteHandle(Stream stream) { Stream = new StreamWriter(stream); diff --git a/Capy64/LuaRuntime/Libraries/HTTP.cs b/Capy64/LuaRuntime/Libraries/HTTP.cs index 45dc99a..7726cb8 100644 --- a/Capy64/LuaRuntime/Libraries/HTTP.cs +++ b/Capy64/LuaRuntime/Libraries/HTTP.cs @@ -162,14 +162,14 @@ public class HTTP : IPlugin } var response = await task; - /*object content; - if ((bool)options["binary"]) - content = await response.Content.ReadAsByteArrayAsync(); - else - content = await response.Content.ReadAsStringAsync();*/ var stream = await response.Content.ReadAsStreamAsync(); - var handler = new ReadHandle(stream); + + IHandle handler; + if ((bool)options["binary"]) + handler = new BinaryReadHandle(stream); + else + handler = new ReadHandle(stream); _game.LuaRuntime.PushEvent("http_response", L => {