efl/src/bindings/mono/eina_mono/eina_common.cs

247 lines
7.3 KiB
C#

/*
* Copyright 2019 by its authors. See AUTHORS.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma warning disable 1591
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace Eina
{
namespace Callbacks
{
internal delegate int EinaCompareCb(IntPtr data1, IntPtr data2);
internal delegate void EinaFreeCb(IntPtr data);
}
internal static class NativeCustomExportFunctions
{
[DllImport(efl.Libs.CustomExports)] public static extern void
efl_mono_native_free(IntPtr ptr);
[DllImport(efl.Libs.CustomExports)] public static extern void
efl_mono_native_free_ref(IntPtr ptr);
[DllImport(efl.Libs.CustomExports)] public static extern IntPtr
efl_mono_native_alloc(uint count);
[DllImport(efl.Libs.CustomExports)] public static extern IntPtr
efl_mono_native_memset(IntPtr ptr, uint fill, uint count);
[DllImport(efl.Libs.CustomExports)] public static extern IntPtr
efl_mono_native_alloc_copy(IntPtr val, uint size);
[DllImport(efl.Libs.CustomExports)] public static extern IntPtr
efl_mono_native_strdup(string str);
[DllImport(efl.Libs.CustomExports)] public static extern IntPtr
efl_mono_native_ptr_compare_addr_get();
[DllImport(efl.Libs.CustomExports)] public static extern IntPtr
efl_mono_native_str_compare_addr_get();
[DllImport(efl.Libs.CustomExports)] public static extern IntPtr
efl_mono_native_free_addr_get();
[DllImport(efl.Libs.CustomExports)] public static extern IntPtr
efl_mono_native_efl_unref_addr_get();
}
/// <summary>Wrapper around native memory DllImport'd functions.
/// <para>Since EFL 1.23.</para>
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static class MemoryNative
{
public static void Free(IntPtr ptr)
{
NativeCustomExportFunctions.efl_mono_native_free(ptr);
}
public static void FreeRef(IntPtr ptr)
{
NativeCustomExportFunctions.efl_mono_native_free_ref(ptr);
}
// This public api uses int as Marshal.SizeOf return an int instead of uint.
public static IntPtr Alloc(int count)
{
return NativeCustomExportFunctions.efl_mono_native_alloc(Convert.ToUInt32(count));
}
public static void Memset(IntPtr ptr, int fill, int count)
{
NativeCustomExportFunctions.efl_mono_native_memset(ptr, Convert.ToUInt32(fill), Convert.ToUInt32(count));
}
public static IntPtr AllocCopy(IntPtr ptr, int count)
{
return NativeCustomExportFunctions.efl_mono_native_alloc_copy(ptr, Convert.ToUInt32(count));
}
public static IntPtr StrDup(string str)
{
return NativeCustomExportFunctions.efl_mono_native_strdup(str);
}
/// <summary>
/// Retrieves an instance of a string for use in program.
/// <para>Since EFL 1.23.</para>
/// </summary>
/// <param name="str"> The NULL-terminated string to retrieve an instance of.</param>
/// <returns> A pointer to an instance of the string on success,
/// on failure a exception is raised.</returns>
public static IntPtr AddStringshare(string str)
{
IntPtr nativeStr = StringConversion.ManagedStringToNativeUtf8Alloc(str);
try
{
var strShare = NativeMethods.eina_stringshare_add(nativeStr);
return strShare;
}
finally
{
Eina.MemoryNative.Free(nativeStr);
}
}
/// <summary>
/// Notes that the given string has lost an instance.
/// </summary>
/// <param name="str">the given string</param>
public static void DelStringshare(IntPtr str)
{
NativeMethods.eina_stringshare_del(str);
}
public static void DelStringshareRef(IntPtr ptr)
{
NativeMethods.efl_mono_native_stringshare_del_ref(ptr);
}
// IntPtr's for some native functions
public static IntPtr PtrCompareFuncPtrGet()
{
return NativeCustomExportFunctions.efl_mono_native_ptr_compare_addr_get();
}
public static IntPtr StrCompareFuncPtrGet()
{
return NativeCustomExportFunctions.efl_mono_native_str_compare_addr_get();
}
public static IntPtr FreeFuncPtrGet()
{
return NativeCustomExportFunctions.efl_mono_native_free_addr_get();
}
public static IntPtr StringshareDelFuncPtrGet()
{
return NativeMethods.efl_mono_native_stringshare_del_addr_get();
}
public static IntPtr EflUnrefFuncPtrGet()
{
return NativeCustomExportFunctions.efl_mono_native_efl_unref_addr_get();
}
}
/// <summary>
/// Conversor of raw pointer to a type and type to raw pointer
/// <para>Since EFL 1.23.</para>
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static class PrimitiveConversion
{
public static T PointerToManaged<T>(IntPtr nat)
{
if (nat == IntPtr.Zero)
{
Eina.Log.Error("Null pointer for primitive type.");
return default(T);
}
var w = Marshal.PtrToStructure<T>(nat);
return w;
}
public static IntPtr ManagedToPointerAlloc<T>(T man)
{
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf<T>());
Marshal.StructureToPtr(man, ptr, false);
return ptr;
}
}
/// <summary>
/// Conversor of string to native string and native string to string.
/// <para>Since EFL 1.23.</para>
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static class StringConversion
{
public static IntPtr ManagedStringToNativeUtf8Alloc(string managedString)
{
if (managedString == null)
{
return IntPtr.Zero;
}
byte[] strbuf = Encoding.UTF8.GetBytes(managedString);
IntPtr native = MemoryNative.Alloc(strbuf.Length + 1);
try
{
Marshal.Copy(strbuf, 0, native, strbuf.Length);
Marshal.WriteByte(native + strbuf.Length, 0); // write the terminating null
return native;
}
catch(Exception e)
{
MemoryNative.Free(native);
throw e;
}
}
public static string NativeUtf8ToManagedString(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero)
{
return null;
}
int len = 0;
while (Marshal.ReadByte(pNativeData, len) != 0)
{
++len;
}
byte[] strbuf = new byte[len];
Marshal.Copy(pNativeData, strbuf, 0, strbuf.Length);
return Encoding.UTF8.GetString(strbuf);
}
}
/// <summary>Enum to handle resource ownership between managed and unmanaged code.
/// <para>Since EFL 1.23.</para>
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public enum Ownership
{
/// <summary> The resource is owned by the managed code. It should free the handle on disposal.</summary>
Managed,
/// <summary> The resource is owned by the unmanaged code. It won't be freed on disposal.</summary>
Unmanaged
}
}