summaryrefslogtreecommitdiff
path: root/src/bindings/mono/eina_mono/eina_common.cs
blob: 4bd93ce25bb3428d0ada80b97217aac7726a1a23 (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
#pragma warning disable 1591

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace eina
{
namespace Callbacks
{

public delegate int Eina_Compare_Cb(IntPtr data1, IntPtr data2);
public delegate void Eina_Free_Cb(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_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</summary>
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 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);
    }

    // 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 EflUnrefFuncPtrGet()
    {
        return NativeCustomExportFunctions.efl_mono_native_efl_unref_addr_get();
    }
}

[StructLayout(LayoutKind.Sequential)]
public struct ConvertWrapper<T>
{
    public T val;
}

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<eina.ConvertWrapper<T> >(nat);
       return w.val;
   }

   public static IntPtr ManagedToPointerAlloc<T>(T man)
   {
       GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned);
       IntPtr ptr = pinnedData.AddrOfPinnedObject();
       IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<T>());
       pinnedData.Free();
       return nat;
   }
}

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);
        Marshal.Copy(strbuf, 0, native, strbuf.Length);
        Marshal.WriteByte(native + strbuf.Length, 0); // write the terminating null
        return native;
    }

    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);
    }
}

public struct Unicode {
    private uint val;

    public static implicit operator Unicode(uint x)
    {
        return new Unicode{val=x};
    }
    public static implicit operator uint(Unicode x)
    {
        return x.val;
    }
}


}