KerepWrapper project

This commit is contained in:
2023-02-12 18:45:05 +06:00
parent 8c4426abc1
commit 4c2d0a03e5
18 changed files with 123 additions and 41 deletions

View File

@@ -0,0 +1,27 @@
using System.Runtime.InteropServices;
using DTLib.Extensions;
namespace KerepWrapper.KerepTypes;
[StructLayout(LayoutKind.Sequential)]
public struct KVPair
{
public DtsodPtr key;
public Unitype value;
public KVPair(DtsodPtr k, Unitype v)
{
key = k;
value = v;
}
public KVPair(string k, Unitype v)
{
key = k.StringToHGlobalUTF8();
value = v;
}
public override string ToString()
{
return $"{{{Unmanaged.HGlobalUTF8ToString(key)}, {value}}}";
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
namespace KerepWrapper.KerepTypes;
public enum KerepTypeCode : byte
{
Null, Float32, Float64, Char, Bool,
UInt8, Int8, UInt16, Int16, UInt32, Int32, UInt64, Int64,
UInt8Ptr, Int8Ptr, UInt16Ptr, Int16Ptr, UInt32Ptr, Int32Ptr, UInt64Ptr, Int64Ptr,
CharPtr, STNodePtr, HashtablePtr,
UniversalType,
AutoarrInt8Ptr, AutoarrUInt8Ptr, AutoarrInt16Ptr, AutoarrUInt16Ptr,
AutoarrInt32Ptr, AutoarrUInt32Ptr, AutoarrInt64Ptr, AutoarrUInt64Ptr,
AutoarrUnitypePtr, AutoarrKVPairPtr
}
public static class KerepTypeHelper
{
static readonly Dictionary<Type, KerepTypeCode> type_comparsion_dict = new()
{
{typeof(bool), KerepTypeCode.Bool},
{typeof(byte), KerepTypeCode.UInt8},
{typeof(ushort), KerepTypeCode.UInt16},
{typeof(uint), KerepTypeCode.UInt32},
{typeof(ulong), KerepTypeCode.UInt64},
{typeof(sbyte), KerepTypeCode.Int8},
{typeof(short), KerepTypeCode.Int16},
{typeof(int), KerepTypeCode.Int32},
{typeof(long), KerepTypeCode.Int64},
{typeof(float), KerepTypeCode.Float32},
{typeof(double), KerepTypeCode.Float64},
{typeof(string), KerepTypeCode.CharPtr}
};
public static KerepTypeCode GetKerepTypeCode(object something)
{
if (type_comparsion_dict.TryGetValue(something.GetType(), out var ktype))
return ktype;
else return something switch
{
IList<object> => KerepTypeCode.AutoarrUnitypePtr,
IDictionary<string, object> => KerepTypeCode.HashtablePtr,
_ => throw new Exception($"can't get KerepTypeCode for type {something.GetType()}")
};
}
}

View File

@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using DTLib.Extensions;
using KerepWrapper.Autoarr;
using KerepWrapper.Dtsod;
namespace KerepWrapper.KerepTypes;
[StructLayout(LayoutKind.Explicit)]
public struct Unitype
{
[FieldOffset(0)] public long Int64;
[FieldOffset(0)] public ulong UInt64;
[FieldOffset(0)] public double Float64;
[MarshalAs(UnmanagedType.I1)]
[FieldOffset(0)] public bool Bool;
[FieldOffset(0)] public DtsodPtr VoidPtr;
[FieldOffset(8)] public KerepTypeCode TypeCode;
public Unitype(object v) : this()
{
TypeCode = KerepTypeHelper.GetKerepTypeCode(v);
switch (TypeCode)
{
case KerepTypeCode.Bool:
Bool = (bool) v;
break;
case KerepTypeCode.UInt8:
case KerepTypeCode.UInt16:
case KerepTypeCode.UInt32:
UInt64 = v.ToULong();
TypeCode = KerepTypeCode.UInt64;
break;
case KerepTypeCode.UInt64:
UInt64 = (ulong) v;
break;
case KerepTypeCode.Int8:
case KerepTypeCode.Int16:
case KerepTypeCode.Int32:
Int64 = v.ToLong();
TypeCode = KerepTypeCode.Int64;
break;
case KerepTypeCode.Int64:
Int64 = (long) v;
break;
case KerepTypeCode.Float32:
Float64 = v.ToDouble();
TypeCode = KerepTypeCode.Float64;
break;
case KerepTypeCode.Float64:
Float64 = (double) v;
break;
case KerepTypeCode.CharPtr:
VoidPtr = ((string)v).StringToHGlobalUTF8();
break;
case KerepTypeCode.AutoarrUnitypePtr:
TypeCode = KerepTypeCode.AutoarrUnitypePtr;
var ar = new Autoarr<Unitype>(64,1024,false);
foreach (var sub in (List<object>)v)
ar.Add(new Unitype(sub));
VoidPtr = ar.UnmanagedPtr;
break;
case KerepTypeCode.HashtablePtr:
TypeCode = KerepTypeCode.HashtablePtr;
var ht = new DtsodV24((IDictionary<string,object>)v,false);
VoidPtr = ht.UnmanagedPtr;
break;
default: throw new Exception($"can't box value of type {TypeCode}");
}
}
public dynamic ToDynamic()
{
switch (TypeCode)
{
case KerepTypeCode.Null: return null;
case KerepTypeCode.Bool: return Bool;
case KerepTypeCode.Int64: return Int64;
case KerepTypeCode.UInt64: return UInt64;
case KerepTypeCode.Float64: return Float64;
case KerepTypeCode.CharPtr: return VoidPtr.HGlobalUTF8ToString();
case KerepTypeCode.AutoarrUnitypePtr: return new Autoarr<Unitype>(VoidPtr, false);
case KerepTypeCode.AutoarrKVPairPtr: return new Autoarr<KVPair>(VoidPtr, false);
case KerepTypeCode.HashtablePtr: return new DtsodV24(VoidPtr);
default: throw new Exception($"can't unbox value of type {TypeCode}");
}
}
public override string ToString()
{
switch (TypeCode)
{
case KerepTypeCode.Null: return "{Null}";
case KerepTypeCode.Bool: return $"{{Bool:{Bool}}}";
case KerepTypeCode.Int64: return $"{{Int64:{Int64}}}";
case KerepTypeCode.UInt64: return $"{{UInt64:{UInt64}}}";
case KerepTypeCode.Float64: return $"{{Float64:{Float64}}}";
case KerepTypeCode.CharPtr: return $"{{CharPtr:{Unmanaged.HGlobalUTF8ToString(VoidPtr)}}}";
case KerepTypeCode.AutoarrUnitypePtr: return $"{{AutoarrUnitypePtr:{VoidPtr.ToString()}}}";
case KerepTypeCode.AutoarrKVPairPtr: return $"{{AutoarrKVPairPtr:{VoidPtr.ToString()}}}";
case KerepTypeCode.HashtablePtr: return $"{{HashtablePtr:{VoidPtr.ToString()}}}";
default: throw new Exception($"can't unbox value of type {TypeCode}");
}
}
}