PorygonSharp/PorygonSharp/EvalValues/EvalValue.cs

136 lines
4.8 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Text;
namespace PorygonSharp.EvalValues
{
public class EvalValue : IDisposable
{
protected IntPtr Handle;
public EvalValue(IntPtr handle)
{
Handle = handle;
}
protected EvalValue(){}
public void Dispose()
{
if (Handle != IntPtr.Zero)
{
Marshal.FreeHGlobal(Handle);
Handle = IntPtr.Zero;
}
}
public TypeClass GetTypeClass()
{
return (TypeClass)GetTypeClass(Handle);
}
public long EvaluateInteger()
{
return EvaluateInteger(Handle);
}
public double EvaluateFloat()
{
return EvaluateFloat(Handle);
}
public bool EvaluateBool()
{
return EvaluateBool(Handle) == 1;
}
public string EvaluateString()
{
var stringLength = GetStringLength(Handle);
// The library uses 16 bit chars for strings, so create a byte array of twice the length given.
var byteArr = new byte[stringLength * 2];
var result = EvaluateString(Handle, byteArr, stringLength);
if (result != 0)
{
throw new Exception("Something went wrong while evaluating a string.");
}
var str = Encoding.Unicode.GetString(byteArr);
return str;
}
private object EvaluateGenericObject()
{
var ptr = EvaluateUserDataObj(Handle);
return GCHandle.FromIntPtr(ptr).Target;
}
private object EvaluateUserdataCollection()
{
var listHelper = ListEvalValue.Fetch(Handle);
return listHelper.List;
}
public object GetObjectValue()
{
if (Handle == IntPtr.Zero)
return null;
switch (GetTypeClass())
{
case TypeClass.Nil:
return null;
case TypeClass.Number:
if (IsNumericValueFloat())
return EvaluateFloat();
else
return EvaluateInteger();
case TypeClass.Bool:
return EvaluateBool();
case TypeClass.String:
return EvaluateString();
case TypeClass.UserData:
return EvaluateGenericObject();
case TypeClass.UserdataCollection:
return EvaluateUserdataCollection();
case TypeClass.Table:
var val = new TableEvalValue(Handle);
return val.EvaluateNumericalTable();
default:
throw new ArgumentOutOfRangeException();
}
}
internal IntPtr GetPointer()
{
return Handle;
}
private bool IsNumericValueFloat()
{
return IsNumericValueFloat(Handle) == 1;
}
[DllImport("PorygonLang", EntryPoint = "GetEvalValueTypeClass", CallingConvention = CallingConvention.Cdecl)]
private static extern int GetTypeClass(IntPtr ptr);
[DllImport("PorygonLang", EntryPoint = "GetEvalValueType", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetScriptType(IntPtr ptr);
[DllImport("PorygonLang", EntryPoint = "IsNumericValueFloat", CallingConvention = CallingConvention.Cdecl)]
private static extern byte IsNumericValueFloat(IntPtr ptr);
[DllImport("PorygonLang", EntryPoint = "EvaluateEvalValueInteger", CallingConvention = CallingConvention.Cdecl)]
private static extern long EvaluateInteger(IntPtr ptr);
[DllImport("PorygonLang", EntryPoint = "EvaluateEvalValueFloat", CallingConvention = CallingConvention.Cdecl)]
private static extern double EvaluateFloat(IntPtr ptr);
[DllImport("PorygonLang", EntryPoint = "EvaluateEvalValueBool", CallingConvention = CallingConvention.Cdecl)]
private static extern byte EvaluateBool(IntPtr ptr);
[DllImport("PorygonLang", EntryPoint = "GetEvalValueStringLength",CallingConvention = CallingConvention.Cdecl)]
private static extern int GetStringLength(IntPtr ptr);
[DllImport("PorygonLang", EntryPoint = "EvaluateEvalValueString",CallingConvention = CallingConvention.Cdecl)]
private static extern int EvaluateString(IntPtr ptr, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer, int capacity);
[DllImport("PorygonLang", EntryPoint = "EvaluateUserDataObj",CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr EvaluateUserDataObj(IntPtr ptr);
}
}