91 lines
2.8 KiB
C#
91 lines
2.8 KiB
C#
/*----------------------------------------------------------------
|
|
// Copyright (C) 2025 Beijing All rights reserved.
|
|
//
|
|
// Author: huachangmiao
|
|
// Create Date: 2025/04/11
|
|
// Module Describe:
|
|
//----------------------------------------------------------------*/
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
|
|
namespace LeviathanVideo.Abstractions
|
|
{
|
|
|
|
public class UTF8Marshaler : ICustomMarshaler
|
|
{
|
|
private static readonly UTF8Marshaler Instance = new UTF8Marshaler();
|
|
|
|
public virtual object MarshalNativeToManaged(IntPtr pNativeData) => FromNative(Encoding.UTF8, pNativeData);
|
|
|
|
public virtual IntPtr MarshalManagedToNative(object managedObj)
|
|
{
|
|
if (managedObj == null)
|
|
return IntPtr.Zero;
|
|
|
|
if (!(managedObj is string str))
|
|
throw new MarshalDirectiveException($"{GetType().Name} must be used on a string.");
|
|
|
|
return FromManaged(Encoding.UTF8, str);
|
|
}
|
|
|
|
public virtual void CleanUpNativeData(IntPtr pNativeData)
|
|
{
|
|
//Free anything allocated by MarshalManagedToNative
|
|
//This is called after the native function call completes
|
|
|
|
if (pNativeData != IntPtr.Zero)
|
|
Marshal.FreeHGlobal(pNativeData);
|
|
}
|
|
|
|
public void CleanUpManagedData(object managedObj)
|
|
{
|
|
//Free anything allocated by MarshalNativeToManaged
|
|
//This is called after the native function call completes
|
|
}
|
|
|
|
public int GetNativeDataSize() => -1; // Not a value type
|
|
|
|
public static ICustomMarshaler GetInstance(string cookie) => Instance;
|
|
|
|
public static unsafe string FromNative(Encoding encoding, IntPtr pNativeData) => FromNative(encoding, (byte*)pNativeData);
|
|
|
|
public static unsafe string FromNative(Encoding encoding, byte* pNativeData)
|
|
{
|
|
if (pNativeData == null)
|
|
return null;
|
|
|
|
var start = pNativeData;
|
|
var walk = start;
|
|
|
|
// Find the end of the string
|
|
while (*walk != 0) walk++;
|
|
|
|
if (walk == start)
|
|
return string.Empty;
|
|
|
|
return new string((sbyte*)pNativeData, 0, (int)(walk - start), encoding);
|
|
}
|
|
|
|
public static unsafe IntPtr FromManaged(Encoding encoding, string value)
|
|
{
|
|
if (encoding == null || value == null)
|
|
return IntPtr.Zero;
|
|
|
|
var length = encoding.GetByteCount(value);
|
|
var buffer = (byte*)Marshal.AllocHGlobal(length + 1).ToPointer();
|
|
|
|
if (length > 0)
|
|
{
|
|
fixed (char* pValue = value)
|
|
{
|
|
encoding.GetBytes(pValue, value.Length, buffer, length);
|
|
}
|
|
}
|
|
|
|
buffer[length] = 0;
|
|
|
|
return new IntPtr(buffer);
|
|
}
|
|
}
|
|
} |