Adapt FileHandle for ANSI

This commit is contained in:
Alessandro Proto 2023-02-22 09:12:34 +01:00
parent af6b885751
commit 7b9a6fe1e7
4 changed files with 90 additions and 23 deletions

View file

@ -17,6 +17,7 @@ using Capy64.API;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
namespace Capy64.Core; 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', '\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', '\u2261', '\u00B1', '\u2265', '\u2264', '\u2320', '\u2321', '\u00F7', '\u2248', '\u00B0', '\u2219', '\u00B7', '\u221A', '\u207F', '\u00B2', '\u25A0', '\u00A0',
}; };
public static Dictionary<char, int> CharDict => _charMap; public static Dictionary<char, int> CharMap => _charMap;
public static Texture2D Source => _source; public static Texture2D Source => _source;
public static Rectangle[] Coords => _coords; public static Rectangle[] Coords => _coords;
@ -76,4 +77,33 @@ public class Charset : IComponent
return _charMap['?']; 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);
}
} }

View file

@ -558,7 +558,7 @@ public class FileSystem : IComponent
var fileStream = File.Open(path, fileMode, fileAccess, FileShare.ReadWrite | FileShare.Delete); var fileStream = File.Open(path, fileMode, fileAccess, FileShare.ReadWrite | FileShare.Delete);
ObjectManager.PushObject(L, fileStream); ObjectManager.PushObject(L, fileStream);
L.SetMetaTable(FileHandle.ObjectType); L.SetMetaTable(FileHandleLib.ObjectType);
return 1; return 1;
} }

View file

@ -226,7 +226,7 @@ public class HTTP : IComponent
// arg 2, response data // arg 2, response data
ObjectManager.PushObject(L, stream); ObjectManager.PushObject(L, stream);
//L.PushObject(stream); //L.PushObject(stream);
L.SetMetaTable(FileHandle.ObjectType); L.SetMetaTable(FileHandleLib.ObjectType);
/*if ((bool)options["binary"]) /*if ((bool)options["binary"])
BinaryReadHandle.Push(LK, new(stream)); BinaryReadHandle.Push(LK, new(stream));
else else

View file

@ -14,13 +14,15 @@
// limitations under the License. // limitations under the License.
using Capy64.API; using Capy64.API;
using Capy64.Core;
using KeraLua; using KeraLua;
using System; using System;
using System.IO; using System.IO;
using System.Reflection.Metadata;
namespace Capy64.Runtime.Objects; namespace Capy64.Runtime.Objects;
public class FileHandle : IComponent public class FileHandleLib : IComponent
{ {
public const string ObjectType = "file"; public const string ObjectType = "file";
@ -115,14 +117,14 @@ public class FileHandle : IComponent
return modes[i]; return modes[i];
} }
private static Stream ToStream(Lua L, bool gc = false) private static FileHandle ToStream(Lua L, bool gc = false)
{ {
return ObjectManager.ToObject<Stream>(L, 1, gc); return ObjectManager.ToObject<FileHandle>(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<Stream>(L, 1, ObjectType, gc); var obj = ObjectManager.CheckObject<FileHandle>(L, 1, ObjectType, gc);
if (obj is null) if (obj is null)
{ {
L.Error("attempt to use a closed file"); L.Error("attempt to use a closed file");
@ -131,13 +133,15 @@ public class FileHandle : IComponent
return obj; return obj;
} }
private static bool ReadNumber(Lua L, Stream stream) private static bool ReadNumber(Lua L, FileHandle handle)
{ {
var stream = handle.Stream;
return false; 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]; var buffer = new byte[stream.Length];
int i = 0; int i = 0;
int c = 0; int c = 0;
@ -153,32 +157,44 @@ public class FileHandle : IComponent
buffer[i++] = (byte)c; buffer[i++] = (byte)c;
Array.Resize(ref buffer, i); Array.Resize(ref buffer, i);
if (!handle.BinaryMode)
buffer = Charset.Decode(buffer);
L.PushBuffer(buffer); L.PushBuffer(buffer);
return c == '\n' || L.RawLen(-1) > 0; 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 buffer = new byte[stream.Length];
var read = stream.Read(buffer, 0, buffer.Length); var read = stream.Read(buffer, 0, buffer.Length);
Array.Resize(ref buffer, read); Array.Resize(ref buffer, read);
if (!handle.BinaryMode)
buffer = Charset.Decode(buffer);
L.PushBuffer(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 buffer = new byte[n];
var read = stream.Read(buffer, 0, n); var read = stream.Read(buffer, 0, n);
Array.Resize(ref buffer, read); Array.Resize(ref buffer, read);
L.PushBuffer(buffer); L.PushBuffer(buffer);
if (!handle.BinaryMode)
buffer = Charset.Decode(buffer);
return read != 0; return read != 0;
} }
private static int L_Read(IntPtr state) private static int L_Read(IntPtr state)
{ {
var L = Lua.FromIntPtr(state); var L = Lua.FromIntPtr(state);
var stream = CheckStream(L); var handle = CheckStream(L);
var stream = handle.Stream;
if (!stream.CanRead) if (!stream.CanRead)
{ {
@ -196,7 +212,7 @@ public class FileHandle : IComponent
bool success; bool success;
if (L.Type(2) == LuaType.Number) if (L.Type(2) == LuaType.Number)
{ {
success = ReadChars(L, stream, (int)L.ToNumber(2)); success = ReadChars(L, handle, (int)L.ToNumber(2));
} }
else else
{ {
@ -205,16 +221,16 @@ public class FileHandle : IComponent
switch (mode) switch (mode)
{ {
case 'n': case 'n':
success = ReadNumber(L, stream); success = ReadNumber(L, handle);
break; break;
case 'l': case 'l':
success = ReadLine(L, stream, true); success = ReadLine(L, handle, true);
break; break;
case 'L': case 'L':
success = ReadLine(L, stream, false); success = ReadLine(L, handle, false);
break; break;
case 'a': case 'a':
ReadAll(L, stream); ReadAll(L, handle);
success = true; success = true;
break; break;
default: default:
@ -238,7 +254,9 @@ public class FileHandle : IComponent
var nargs = L.GetTop(); var nargs = L.GetTop();
var stream = CheckStream(L); var handle = CheckStream(L);
var stream = handle.Stream;
if (!stream.CanWrite) if (!stream.CanWrite)
{ {
L.PushNil(); L.PushNil();
@ -284,7 +302,8 @@ public class FileHandle : IComponent
{ {
var L = Lua.FromIntPtr(state); var L = Lua.FromIntPtr(state);
var stream = CheckStream(L, false); var handle = CheckStream(L);
var stream = handle.Stream;
stream.Flush(); stream.Flush();
@ -295,7 +314,8 @@ public class FileHandle : IComponent
{ {
var L = Lua.FromIntPtr(state); 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[] var whence = L.CheckOption(2, "cur", new[]
{ {
@ -319,7 +339,7 @@ public class FileHandle : IComponent
var L = Lua.FromIntPtr(state); var L = Lua.FromIntPtr(state);
var stream = CheckStream(L, true); var stream = CheckStream(L, true);
stream.Close(); stream.Dispose();
return 0; return 0;
} }
@ -345,8 +365,25 @@ public class FileHandle : IComponent
var stream = ToStream(L, true); var stream = ToStream(L, true);
if (stream is not null) if (stream is not null)
stream.Close(); stream.Dispose();
return 0; 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();
}
}