[EflSharp] Update Circle and efl cs files (#819)
[platform/core/csapi/tizenfx.git] / internals / src / EflSharp / EflSharp / efl / eina_hash.cs
1 #pragma warning disable 1591
2
3 using System;
4 using System.Runtime.InteropServices;
5 using System.Collections.Generic;
6
7 using static Eina.TraitFunctions;
8 using static Eina.IteratorNativeFunctions;
9 using static Eina.HashNativeFunctions;
10 using Eina.Callbacks;
11
12 namespace Eina
13 {
14
15 [StructLayout(LayoutKind.Sequential)]
16 public struct HashTupleNative
17 {
18     public IntPtr key;
19     public IntPtr data;
20     public uint   key_length;
21 }
22
23 public static class HashNativeFunctions
24 {
25     [DllImport(efl.Libs.Eina)] public static extern IntPtr
26         eina_hash_new(IntPtr key_length_cb, IntPtr key_cmp_cb, IntPtr key_hash_cb, IntPtr data_free_cb, int buckets_power_size);
27
28     [DllImport(efl.Libs.Eina)] public static extern void
29         eina_hash_free_cb_set(IntPtr hash, IntPtr data_free_cb);
30
31     [DllImport(efl.Libs.Eina)] public static extern IntPtr
32         eina_hash_string_djb2_new(IntPtr data_free_cb);
33
34     [DllImport(efl.Libs.Eina)] public static extern IntPtr
35         eina_hash_string_superfast_new(IntPtr data_free_cb);
36
37     [DllImport(efl.Libs.Eina)] public static extern IntPtr
38         eina_hash_string_small_new(IntPtr data_free_cb);
39
40     [DllImport(efl.Libs.Eina)] public static extern IntPtr
41         eina_hash_int32_new(IntPtr data_free_cb);
42
43     [DllImport(efl.Libs.Eina)] public static extern IntPtr
44         eina_hash_int64_new(IntPtr data_free_cb);
45
46     [DllImport(efl.Libs.Eina)] public static extern IntPtr
47         eina_hash_pointer_new(IntPtr data_free_cb);
48
49     [DllImport(efl.Libs.Eina)] public static extern IntPtr
50         eina_hash_stringshared_new(IntPtr data_free_cb);
51
52     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
53         eina_hash_add(IntPtr hash, IntPtr key, IntPtr data);
54
55     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
56         eina_hash_direct_add(IntPtr hash, IntPtr key, IntPtr data);
57
58     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
59         eina_hash_del(IntPtr hash, IntPtr key, IntPtr data);
60
61     [DllImport(efl.Libs.Eina)] public static extern IntPtr
62         eina_hash_find(IntPtr hash, IntPtr key);
63
64     [DllImport(efl.Libs.Eina)] public static extern IntPtr
65         eina_hash_modify(IntPtr hash, IntPtr key, IntPtr data);
66
67     [DllImport(efl.Libs.Eina)] public static extern IntPtr
68         eina_hash_set(IntPtr hash, IntPtr key, IntPtr data);
69
70     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
71         eina_hash_move(IntPtr hash, IntPtr old_key, IntPtr new_key);
72
73     [DllImport(efl.Libs.Eina)] public static extern void
74         eina_hash_free(IntPtr hash);
75
76     [DllImport(efl.Libs.Eina)] public static extern void
77         eina_hash_free_buckets(IntPtr hash);
78
79     [DllImport(efl.Libs.Eina)] public static extern int
80         eina_hash_population(IntPtr hash);
81
82     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
83         eina_hash_add_by_hash(IntPtr hash, IntPtr key, int key_length, int key_hash, IntPtr data);
84
85     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
86         eina_hash_direct_add_by_hash(IntPtr hash, IntPtr key, int key_length, int key_hash, IntPtr data);
87
88     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
89         eina_hash_del_by_key_hash(IntPtr hash, IntPtr key, int key_length, int key_hash);
90
91     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
92         eina_hash_del_by_key(IntPtr hash, IntPtr key);
93
94     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
95         eina_hash_del_by_data(IntPtr hash, IntPtr data);
96
97     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
98         eina_hash_del_by_hash(IntPtr hash, IntPtr key, int key_length, int key_hash, IntPtr data);
99
100     [DllImport(efl.Libs.Eina)] public static extern IntPtr
101         eina_hash_find_by_hash(IntPtr hash, IntPtr key, int key_length, int key_hash);
102
103     [DllImport(efl.Libs.Eina)] public static extern IntPtr
104         eina_hash_modify_by_hash(IntPtr hash, IntPtr key, int key_length, int key_hash, IntPtr data);
105
106     [DllImport(efl.Libs.Eina)] public static extern IntPtr
107         eina_hash_iterator_key_new(IntPtr hash);
108
109     [DllImport(efl.Libs.Eina)] public static extern IntPtr
110         eina_hash_iterator_data_new(IntPtr hash);
111
112     [DllImport(efl.Libs.Eina)] public static extern IntPtr
113         eina_hash_iterator_tuple_new(IntPtr hash);
114
115     [DllImport(efl.Libs.Eina)] public static extern void
116         eina_hash_foreach(IntPtr hash, IntPtr func, IntPtr fdata);
117
118
119     [DllImport(efl.Libs.Eina)] public static extern void
120         eina_hash_list_append(IntPtr hash, IntPtr key, IntPtr data);
121     [DllImport(efl.Libs.Eina)] public static extern void
122         eina_hash_list_prepend(IntPtr hash, IntPtr key, IntPtr data);
123     [DllImport(efl.Libs.Eina)] public static extern void
124         eina_hash_list_remove(IntPtr hash, IntPtr key, IntPtr data);
125
126     [DllImport(efl.Libs.Eina)] public static extern int
127         eina_hash_superfast(string key, int len);
128
129     [DllImport(efl.Libs.CustomExports)] public static extern IntPtr
130         eina_hash_iterator_ptr_key_wrapper_new_custom_export_mono(IntPtr hash);
131 }
132
133 public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDisposable
134 {
135     public IntPtr Handle {get; set;} = IntPtr.Zero;
136     public bool Own {get; set;}
137     public bool OwnKey {get; set;}
138     public bool OwnValue {get; set;}
139
140     public int Count
141     {
142         get
143         {
144             return Population();
145         }
146     }
147
148
149     private void InitNew()
150     {
151         Handle = EinaHashNew<TKey>();
152         SetOwn(true);
153         SetOwnKey(true);
154         SetOwnValue(true);
155     }
156
157     public Hash()
158     {
159         InitNew();
160     }
161
162     public Hash(IntPtr handle, bool own)
163     {
164         Handle = handle;
165         SetOwnership(own);
166     }
167
168     public Hash(IntPtr handle, bool own, bool ownKey, bool ownValue)
169     {
170         Handle = handle;
171         SetOwnership(own, ownKey, ownValue);
172     }
173
174     ~Hash()
175     {
176         Dispose(false);
177     }
178
179     protected virtual void Dispose(bool disposing)
180     {
181         IntPtr h = Handle;
182         Handle = IntPtr.Zero;
183         if (h == IntPtr.Zero)
184         {
185             return;
186         }
187
188         if (Own)
189         {
190             if (disposing)
191             {
192                 eina_hash_free(h);
193             }
194             else
195             {
196                 Efl.Eo.Globals.ThreadSafeFreeCbExec(eina_hash_free, h);
197             }
198         }
199     }
200
201     public void Dispose()
202     {
203         Dispose(true);
204         GC.SuppressFinalize(this);
205     }
206
207     public void Free()
208     {
209         Dispose();
210     }
211
212     public IntPtr Release()
213     {
214         IntPtr h = Handle;
215         Handle = IntPtr.Zero;
216         return h;
217     }
218
219     public void SetOwn(bool own)
220     {
221         Own = own;
222     }
223
224     public void SetOwnKey(bool ownKey)
225     {
226         OwnKey = ownKey;
227     }
228
229     public void SetOwnValue(bool ownValue)
230     {
231         OwnValue = ownValue;
232
233         if (ownValue)
234         {
235             eina_hash_free_cb_set(Handle, EinaFreeCb<TValue>());
236         }
237     }
238
239     public void SetOwnership(bool ownAll)
240     {
241         SetOwn(ownAll);
242         SetOwnKey(ownAll);
243         SetOwnValue(ownAll);
244     }
245
246     public void SetOwnership(bool own, bool ownKey, bool ownValue)
247     {
248         SetOwn(own);
249         SetOwnKey(ownKey);
250         SetOwnValue(ownValue);
251     }
252
253     public void UnSetFreeCb()
254     {
255         eina_hash_free_cb_set(Handle, IntPtr.Zero);
256     }
257
258     public bool AddNew(TKey key, TValue val)
259     {
260         IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
261         IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
262         IntPtr gchnv = CopyNativeObject(val, false);
263         IntPtr nv = GetNativePtr<TValue>(gchnv, false);
264         var r = eina_hash_add(Handle, nk, nv);
265         FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
266         FreeNativeIndirection<TValue>(gchnv, false);
267         return r;
268     }
269
270     public void Add(TKey key, TValue val)
271     {
272         Set(key, val);
273     }
274
275     public bool DelByKey(TKey key)
276     {
277         IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
278         IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
279         var r = eina_hash_del_by_key(Handle, nk);
280         FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
281         // NativeFreeRef<TKey>(nk, OwnKey && r);
282         return r;
283     }
284
285     public bool DelByValue(TValue val)
286     {
287         IntPtr gchnv = CopyNativeObject(val, false);
288         IntPtr nv = GetNativePtr<TValue>(gchnv, false);
289         var r = eina_hash_del_by_data(Handle, nv);
290         FreeNativeIndirection<TValue>(gchnv, false);
291         return r;
292     }
293
294     public void Remove(TKey key)
295     {
296         DelByKey(key);
297     }
298
299     public TValue Find(TKey key)
300     {
301         var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
302         var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
303         var found = eina_hash_find(Handle, nk);
304         //NativeFreeRef<TKey>(nk);
305         FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
306         if (found == IntPtr.Zero)
307         {
308             throw new KeyNotFoundException();
309         }
310
311         return NativeToManaged<TValue>(IndirectNative<TValue>(found, false));
312     }
313
314     public bool TryGetValue(TKey key, out TValue val)
315     {
316         var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
317         var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
318         var found = eina_hash_find(Handle, nk);
319         FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
320         if (found == IntPtr.Zero)
321         {
322             val = default(TValue);
323             return false;
324         }
325
326         val = NativeToManaged<TValue>(IndirectNative<TValue>(found, false));
327         return true;
328     }
329
330     public bool ContainsKey(TKey key)
331     {
332         var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
333         var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
334         // var nk = ManagedToNativeAllocRef(key);
335         var found = eina_hash_find(Handle, nk);
336         // NativeFreeRef<TKey>(nk);
337         FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
338         return found != IntPtr.Zero;
339     }
340
341     public bool Modify(TKey key, TValue val)
342     {
343         var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
344         var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
345         var gchnv = CopyNativeObject<TValue>(val, false);
346         var nv = GetNativePtr<TValue>(gchnv, false);
347         var old = eina_hash_modify(Handle, nk, nv);
348         FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
349         // NativeFreeRef<TKey>(nk);
350         if (old == IntPtr.Zero)
351         {
352             NativeFree<TValue>(nv);
353             return false;
354         }
355
356         if (OwnValue)
357         {
358             NativeFree<TValue>(old);
359         }
360
361         return true;
362     }
363
364     private static bool ForceRefKey<T>()
365     {
366         return (!typeof(T).IsValueType) && (typeof(T) != typeof(string));
367     }
368
369     private static IntPtr CopyNativeObject<T>(T value, bool forceRef)
370     {
371         if (!IsEflObject(typeof(T)) && forceRef)
372         {
373             GCHandle gch = GCHandle.Alloc(new byte[Marshal.SizeOf<T>()], GCHandleType.Pinned);
374             IntPtr pin = gch.AddrOfPinnedObject();
375
376             ManagedToNativeCopyTo(value, pin);
377
378             return GCHandle.ToIntPtr(gch);
379         }
380         else if (IsEflObject(typeof(T)) && forceRef)
381         {
382             GCHandle gch = GCHandle.Alloc(new byte[Marshal.SizeOf<IntPtr>()], GCHandleType.Pinned);
383             IntPtr pin = gch.AddrOfPinnedObject();
384
385             ManagedToNativeCopyTo(value, pin);
386
387             return GCHandle.ToIntPtr(gch);
388         }
389         else
390         {
391             return ManagedToNativeAlloc(value);
392         }
393     }
394
395     private static IntPtr GetNativePtr<T>(IntPtr gchptr, bool forceRef)
396     {
397         if (forceRef)
398         {
399             GCHandle gch = GCHandle.FromIntPtr(gchptr);
400             IntPtr pin = gch.AddrOfPinnedObject();
401
402             return pin;
403         }
404         else
405         {
406             return gchptr;
407         }
408     }
409
410     private static void FreeNativeIndirection<T>(IntPtr gchptr, bool forceRef)
411     {
412         if (forceRef)
413         {
414             GCHandle gch = GCHandle.FromIntPtr(gchptr);
415             gch.Free();
416         }
417     }
418
419     private static IntPtr IndirectNative<T>(IntPtr ptr, bool forceRef)
420     {
421         if (forceRef)
422         {
423             IntPtr val = Marshal.ReadIntPtr(ptr);
424             return val;
425         }
426         else
427         {
428             return ptr;
429         }
430     }
431
432     public void Set(TKey key, TValue val)
433     {
434         IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
435         IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
436
437         IntPtr gchnv = CopyNativeObject(val, false);
438         IntPtr nv = GetNativePtr<TValue>(gchnv, false);
439         IntPtr old = eina_hash_set(Handle, nk, nv);
440         FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
441         FreeNativeIndirection<TValue>(gchnv, false);
442         if (OwnValue || old != IntPtr.Zero)
443         {
444             NativeFree<TValue>(old);
445         }
446     }
447
448     public TValue this[TKey key]
449     {
450         get
451         {
452             return Find(key);
453         }
454         set
455         {
456             Set(key, value);
457         }
458     }
459
460     public bool Move(TKey key_old, TKey key_new)
461     {
462         IntPtr gchnko = CopyNativeObject(key_old, ForceRefKey<TKey>());
463         IntPtr nko = GetNativePtr<TKey>(gchnko, ForceRefKey<TKey>());
464         IntPtr gchnk = CopyNativeObject(key_new, ForceRefKey<TKey>());
465         IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
466         // var nk_old = ManagedToNativeAllocRef(key_old);
467         // var nk_new = ManagedToNativeAllocRef(key_new, true);
468         var r = eina_hash_move(Handle, nko, nk);
469         FreeNativeIndirection<TKey>(gchnko, ForceRefKey<TKey>());
470         FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
471         // NativeFreeRef<TKey>(nk_old, OwnKey && r);
472         // NativeFreeRef<TKey>(nk_new, !r);
473         return r;
474     }
475
476     public void FreeBuckets()
477     {
478         eina_hash_free_buckets(Handle);
479     }
480
481     public int Population()
482     {
483         return eina_hash_population(Handle);
484     }
485
486     public Eina.Iterator<TKey> Keys()
487     {
488         return new Eina.Iterator<TKey>(EinaHashIteratorKeyNew<TKey>(Handle), true, false);
489     }
490
491     public Eina.Iterator<TValue> Values()
492     {
493         return new Eina.Iterator<TValue>(eina_hash_iterator_data_new(Handle), true, false);
494     }
495
496     public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
497     {
498         IntPtr itr = eina_hash_iterator_tuple_new(Handle);
499         try
500         {
501             for (IntPtr tuplePtr; eina_iterator_next(itr, out tuplePtr);)
502             {
503                 var tuple = Marshal.PtrToStructure<Eina.HashTupleNative>(tuplePtr);
504                 IntPtr ikey = IndirectNative<TKey>(tuple.key, ForceRefKey<TKey>());
505                 var key = NativeToManaged<TKey>(ikey);
506                 var val = NativeToManaged<TValue>(tuple.data);
507                 yield return new KeyValuePair<TKey, TValue>(key, val);
508             }
509         }
510         finally
511         {
512             eina_iterator_free(itr);
513         }
514     }
515
516     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
517     {
518         return this.GetEnumerator();
519     }
520 }
521
522 }