From 7b9a6fe1e79c54386a30df1bd7d037f68b3fd0c0 Mon Sep 17 00:00:00 2001 From: Alessandro Proto Date: Wed, 22 Feb 2023 09:12:34 +0100 Subject: [PATCH] Adapt FileHandle for ANSI --- Capy64/Core/Charset.cs | 32 +++++++- Capy64/Runtime/Libraries/FileSystem.cs | 2 +- Capy64/Runtime/Libraries/HTTP.cs | 2 +- .../{FileHandle.cs => FileHandleLib.cs} | 77 ++++++++++++++----- 4 files changed, 90 insertions(+), 23 deletions(-) rename Capy64/Runtime/Objects/{FileHandle.cs => FileHandleLib.cs} (78%) diff --git a/Capy64/Core/Charset.cs b/Capy64/Core/Charset.cs index f86ab96..bc682a3 100644 --- a/Capy64/Core/Charset.cs +++ b/Capy64/Core/Charset.cs @@ -17,6 +17,7 @@ using Capy64.API; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System.Collections.Generic; +using System.Text; namespace Capy64.Core; @@ -44,7 +45,7 @@ public class Charset : IComponent '\u03B1', '\u00DF', '\u0393', '\u03C0', '\u03A3', '\u03C3', '\u00B5', '\u03C4', '\u03A6', '\u0398', '\u03A9', '\u03B4', '\u221E', '\u03C6', '\u03B5', '\u2229', '\u2261', '\u00B1', '\u2265', '\u2264', '\u2320', '\u2321', '\u00F7', '\u2248', '\u00B0', '\u2219', '\u00B7', '\u221A', '\u207F', '\u00B2', '\u25A0', '\u00A0', }; - public static Dictionary CharDict => _charMap; + public static Dictionary CharMap => _charMap; public static Texture2D Source => _source; public static Rectangle[] Coords => _coords; @@ -76,4 +77,33 @@ public class Charset : IComponent return _charMap['?']; } + + public static byte[] Encode(string text, Encoding encoding = default) + { + encoding ??= Encoding.Default; + + return Encode(text.ToCharArray()); + } + + public static byte[] Encode(char[] text) + { + var bytes = new byte[text.Length]; + for (int i = 0; i < text.Length; i++) + { + bytes[i] = (byte)_charMap[text[i]]; + } + + return bytes; + } + + public static byte[] Decode(byte[] bytes, Encoding encoding = default) + { + encoding ??= Encoding.Default; + var chars = new char[bytes.Length]; + for (int i = 0; i < bytes.Length; i++) + { + chars[i] = Codepoints[bytes[i]]; + } + return encoding.GetBytes(chars); + } } diff --git a/Capy64/Runtime/Libraries/FileSystem.cs b/Capy64/Runtime/Libraries/FileSystem.cs index e70f38b..a54369b 100644 --- a/Capy64/Runtime/Libraries/FileSystem.cs +++ b/Capy64/Runtime/Libraries/FileSystem.cs @@ -558,7 +558,7 @@ public class FileSystem : IComponent var fileStream = File.Open(path, fileMode, fileAccess, FileShare.ReadWrite | FileShare.Delete); ObjectManager.PushObject(L, fileStream); - L.SetMetaTable(FileHandle.ObjectType); + L.SetMetaTable(FileHandleLib.ObjectType); return 1; } diff --git a/Capy64/Runtime/Libraries/HTTP.cs b/Capy64/Runtime/Libraries/HTTP.cs index c45575c..40c994a 100644 --- a/Capy64/Runtime/Libraries/HTTP.cs +++ b/Capy64/Runtime/Libraries/HTTP.cs @@ -226,7 +226,7 @@ public class HTTP : IComponent // arg 2, response data ObjectManager.PushObject(L, stream); //L.PushObject(stream); - L.SetMetaTable(FileHandle.ObjectType); + L.SetMetaTable(FileHandleLib.ObjectType); /*if ((bool)options["binary"]) BinaryReadHandle.Push(LK, new(stream)); else diff --git a/Capy64/Runtime/Objects/FileHandle.cs b/Capy64/Runtime/Objects/FileHandleLib.cs similarity index 78% rename from Capy64/Runtime/Objects/FileHandle.cs rename to Capy64/Runtime/Objects/FileHandleLib.cs index f5b3de0..7006570 100644 --- a/Capy64/Runtime/Objects/FileHandle.cs +++ b/Capy64/Runtime/Objects/FileHandleLib.cs @@ -14,13 +14,15 @@ // limitations under the License. using Capy64.API; +using Capy64.Core; using KeraLua; using System; using System.IO; +using System.Reflection.Metadata; namespace Capy64.Runtime.Objects; -public class FileHandle : IComponent +public class FileHandleLib : IComponent { public const string ObjectType = "file"; @@ -115,14 +117,14 @@ public class FileHandle : IComponent return modes[i]; } - private static Stream ToStream(Lua L, bool gc = false) + private static FileHandle ToStream(Lua L, bool gc = false) { - return ObjectManager.ToObject(L, 1, gc); + return ObjectManager.ToObject(L, 1, gc); } - private static Stream CheckStream(Lua L, bool gc = false) + private static FileHandle CheckStream(Lua L, bool gc = false) { - var obj = ObjectManager.CheckObject(L, 1, ObjectType, gc); + var obj = ObjectManager.CheckObject(L, 1, ObjectType, gc); if (obj is null) { L.Error("attempt to use a closed file"); @@ -131,13 +133,15 @@ public class FileHandle : IComponent return obj; } - private static bool ReadNumber(Lua L, Stream stream) + private static bool ReadNumber(Lua L, FileHandle handle) { + var stream = handle.Stream; return false; } - private static bool ReadLine(Lua L, Stream stream, bool chop) + private static bool ReadLine(Lua L, FileHandle handle, bool chop) { + var stream = handle.Stream; var buffer = new byte[stream.Length]; int i = 0; int c = 0; @@ -153,32 +157,44 @@ public class FileHandle : IComponent buffer[i++] = (byte)c; Array.Resize(ref buffer, i); + if (!handle.BinaryMode) + buffer = Charset.Decode(buffer); + L.PushBuffer(buffer); return c == '\n' || L.RawLen(-1) > 0; } - private static void ReadAll(Lua L, Stream stream) + private static void ReadAll(Lua L, FileHandle handle) { + var stream = handle.Stream; var buffer = new byte[stream.Length]; var read = stream.Read(buffer, 0, buffer.Length); Array.Resize(ref buffer, read); + if (!handle.BinaryMode) + buffer = Charset.Decode(buffer); + L.PushBuffer(buffer); } - private static bool ReadChars(Lua L, Stream stream, int n) + private static bool ReadChars(Lua L, FileHandle handle, int n) { + var stream = handle.Stream; var buffer = new byte[n]; var read = stream.Read(buffer, 0, n); Array.Resize(ref buffer, read); L.PushBuffer(buffer); + if (!handle.BinaryMode) + buffer = Charset.Decode(buffer); + return read != 0; } private static int L_Read(IntPtr state) { var L = Lua.FromIntPtr(state); - var stream = CheckStream(L); + var handle = CheckStream(L); + var stream = handle.Stream; if (!stream.CanRead) { @@ -196,7 +212,7 @@ public class FileHandle : IComponent bool success; if (L.Type(2) == LuaType.Number) { - success = ReadChars(L, stream, (int)L.ToNumber(2)); + success = ReadChars(L, handle, (int)L.ToNumber(2)); } else { @@ -205,16 +221,16 @@ public class FileHandle : IComponent switch (mode) { case 'n': - success = ReadNumber(L, stream); + success = ReadNumber(L, handle); break; case 'l': - success = ReadLine(L, stream, true); + success = ReadLine(L, handle, true); break; case 'L': - success = ReadLine(L, stream, false); + success = ReadLine(L, handle, false); break; case 'a': - ReadAll(L, stream); + ReadAll(L, handle); success = true; break; default: @@ -238,7 +254,9 @@ public class FileHandle : IComponent var nargs = L.GetTop(); - var stream = CheckStream(L); + var handle = CheckStream(L); + var stream = handle.Stream; + if (!stream.CanWrite) { L.PushNil(); @@ -284,7 +302,8 @@ public class FileHandle : IComponent { var L = Lua.FromIntPtr(state); - var stream = CheckStream(L, false); + var handle = CheckStream(L); + var stream = handle.Stream; stream.Flush(); @@ -295,7 +314,8 @@ public class FileHandle : IComponent { var L = Lua.FromIntPtr(state); - var stream = CheckStream(L, false); + var handle = CheckStream(L); + var stream = handle.Stream; var whence = L.CheckOption(2, "cur", new[] { @@ -319,7 +339,7 @@ public class FileHandle : IComponent var L = Lua.FromIntPtr(state); var stream = CheckStream(L, true); - stream.Close(); + stream.Dispose(); return 0; } @@ -345,8 +365,25 @@ public class FileHandle : IComponent var stream = ToStream(L, true); if (stream is not null) - stream.Close(); + stream.Dispose(); return 0; } } + +public class FileHandle : IDisposable +{ + public Stream Stream { get; set; } + public bool BinaryMode { get; set; } = false; + + public void Close() + { + Stream.Close(); + } + + public void Dispose() + { + GC.SuppressFinalize(this); + Stream.Dispose(); + } +} \ No newline at end of file