summaryrefslogtreecommitdiff
path: root/src/bindings/mono/eina_mono/eina_common.cs
blob: badd62ecfa310b8ac8604dee954bbd5dcfda3c9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#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
}

}