VisualNes/GUI/UTF8Marshaler.cs

79 lines
1.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace 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;
}
}
}