100 lines
2 KiB
C#
100 lines
2 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using System.Text;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace Mesen.GUI
|
|||
|
{
|
|||
|
public class Utf8Marshaler : ICustomMarshaler
|
|||
|
{
|
|||
|
static Utf8Marshaler _instance;
|
|||
|
|
|||
|
public IntPtr MarshalManagedToNative(object managedObj)
|
|||
|
{
|
|||
|
if(managedObj == null) {
|
|||
|
return IntPtr.Zero;
|
|||
|
}
|
|||
|
if(!(managedObj is string)) {
|
|||
|
throw new MarshalDirectiveException("UTF8Marshaler must be used on a string.");
|
|||
|
}
|
|||
|
|
|||
|
// not null terminated
|
|||
|
byte[] strbuf = Encoding.UTF8.GetBytes((string)managedObj);
|
|||
|
IntPtr buffer = Marshal.AllocHGlobal(strbuf.Length + 1);
|
|||
|
Marshal.Copy(strbuf, 0, buffer, strbuf.Length);
|
|||
|
|
|||
|
// write the terminating null
|
|||
|
Marshal.WriteByte(buffer + strbuf.Length, 0);
|
|||
|
return buffer;
|
|||
|
}
|
|||
|
|
|||
|
public object MarshalNativeToManaged(IntPtr pNativeData)
|
|||
|
{
|
|||
|
return GetStringFromIntPtr(pNativeData);
|
|||
|
}
|
|||
|
|
|||
|
public void CleanUpNativeData(IntPtr pNativeData)
|
|||
|
{
|
|||
|
Marshal.FreeHGlobal(pNativeData);
|
|||
|
}
|
|||
|
|
|||
|
public void CleanUpManagedData(object managedObj)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public int GetNativeDataSize()
|
|||
|
{
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
public static ICustomMarshaler GetInstance(string cookie)
|
|||
|
{
|
|||
|
if(_instance == null) {
|
|||
|
return _instance = new Utf8Marshaler();
|
|||
|
}
|
|||
|
return _instance;
|
|||
|
}
|
|||
|
|
|||
|
public static string GetStringFromIntPtr(IntPtr pNativeData)
|
|||
|
{
|
|||
|
int offset = 0;
|
|||
|
byte b = 0;
|
|||
|
do {
|
|||
|
b = Marshal.ReadByte(pNativeData, offset);
|
|||
|
offset++;
|
|||
|
} while(b != 0);
|
|||
|
|
|||
|
int length = offset - 1;
|
|||
|
|
|||
|
// should not be null terminated
|
|||
|
byte[] strbuf = new byte[length];
|
|||
|
// skip the trailing null
|
|||
|
Marshal.Copy((IntPtr)pNativeData, strbuf, 0, length);
|
|||
|
string data = Encoding.UTF8.GetString(strbuf);
|
|||
|
return data;
|
|||
|
}
|
|||
|
|
|||
|
public static string PtrToStringUtf8(IntPtr ptr)
|
|||
|
{
|
|||
|
if(ptr == IntPtr.Zero) {
|
|||
|
return "";
|
|||
|
}
|
|||
|
|
|||
|
int len = 0;
|
|||
|
while(Marshal.ReadByte(ptr, len) != 0) {
|
|||
|
len++;
|
|||
|
}
|
|||
|
|
|||
|
if(len == 0) {
|
|||
|
return "";
|
|||
|
}
|
|||
|
|
|||
|
byte[] array = new byte[len];
|
|||
|
Marshal.Copy(ptr, array, 0, len);
|
|||
|
return Encoding.UTF8.GetString(array);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|