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.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<char, int> CharDict => _charMap;
public static Dictionary<char, int> 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);
}
}

View file

@ -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;
}

View file

@ -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

View file

@ -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<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)
{
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();
}
}