[EflSharp] Introduce EflSharp project (#749)
[platform/core/csapi/tizenfx.git] / internals / src / EflSharp / EflSharp / eina_array.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.ArrayNativeFunctions;
9
10 namespace Eina {
11
12 public static class ArrayNativeFunctions
13 {
14     [DllImport(efl.Libs.Eina)] public static extern IntPtr
15         eina_array_new(uint step);
16     [DllImport(efl.Libs.Eina)] public static extern void
17         eina_array_free(IntPtr array);
18     [DllImport(efl.Libs.Eina)] public static extern void
19         eina_array_flush(IntPtr array);
20     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
21         eina_array_remove(IntPtr array, IntPtr keep, IntPtr gdata);
22     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
23         eina_array_push(IntPtr array, IntPtr data);
24
25     [DllImport(efl.Libs.Eina)] public static extern IntPtr
26         eina_array_iterator_new(IntPtr array);
27     [DllImport(efl.Libs.Eina)] public static extern IntPtr
28         eina_array_accessor_new(IntPtr array);
29
30     [DllImport(efl.Libs.CustomExports)] public static extern void
31         eina_array_clean_custom_export_mono(IntPtr array);
32     [DllImport(efl.Libs.CustomExports)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
33         eina_array_push_custom_export_mono(IntPtr array, IntPtr data);
34     [DllImport(efl.Libs.CustomExports)] public static extern IntPtr
35         eina_array_pop_custom_export_mono(IntPtr array);
36     [DllImport(efl.Libs.CustomExports)] public static extern IntPtr
37         eina_array_data_get_custom_export_mono(IntPtr array, uint idx);
38     [DllImport(efl.Libs.CustomExports)] public static extern void
39         eina_array_data_set_custom_export_mono(IntPtr array, uint idx, IntPtr data);
40     [DllImport(efl.Libs.CustomExports)] public static extern uint
41         eina_array_count_custom_export_mono(IntPtr array);
42
43     [DllImport(efl.Libs.CustomExports)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
44         eina_array_foreach_custom_export_mono(IntPtr array, IntPtr cb, IntPtr fdata);
45 }
46
47 public class Array<T> : IEnumerable<T>, IDisposable
48 {
49     public static uint DefaultStep = 32;
50
51     public IntPtr Handle {get;set;} = IntPtr.Zero;
52     public bool Own {get;set;}
53     public bool OwnContent {get;set;}
54
55     public int Length
56     {
57         get { return Count(); }
58     }
59
60
61     private void InitNew(uint step)
62     {
63         Handle = eina_array_new(step);
64         Own = true;
65         OwnContent = true;
66         if (Handle == IntPtr.Zero)
67             throw new SEHException("Could not alloc array");
68     }
69
70     internal bool InternalPush(IntPtr ele)
71     {
72         return eina_array_push_custom_export_mono(Handle, ele);
73     }
74
75     internal IntPtr InternalPop()
76     {
77         return eina_array_pop_custom_export_mono(Handle);
78     }
79
80     internal IntPtr InternalDataGet(int idx)
81     {
82         return eina_array_data_get_custom_export_mono(Handle, (uint)idx); // TODO: Check bounds ???
83     }
84
85     internal void InternalDataSet(int idx, IntPtr ele)
86     {
87         eina_array_data_set_custom_export_mono(Handle, (uint)idx, ele); // TODO: Check bounds ???
88     }
89
90     public Array()
91     {
92         InitNew(DefaultStep);
93     }
94
95     public Array(uint step)
96     {
97         InitNew(step);
98     }
99
100     public Array(IntPtr handle, bool own)
101     {
102         Handle = handle;
103         Own = own;
104         OwnContent = own;
105     }
106
107     public Array(IntPtr handle, bool own, bool ownContent)
108     {
109         Handle = handle;
110         Own = own;
111         OwnContent = ownContent;
112     }
113
114     ~Array()
115     {
116         Dispose(false);
117     }
118
119     protected virtual void Dispose(bool disposing)
120     {
121         IntPtr h = Handle;
122         Handle = IntPtr.Zero;
123         if (h == IntPtr.Zero)
124             return;
125
126         if (OwnContent)
127         {
128             int len = (int)eina_array_count_custom_export_mono(h);
129             for(int i = 0; i < len; ++i)
130             {
131                 NativeFree<T>(eina_array_data_get_custom_export_mono(h, (uint)i));
132             }
133         }
134
135         if (Own)
136             eina_array_free(h);
137     }
138
139     public void Dispose()
140     {
141         Dispose(true);
142         GC.SuppressFinalize(this);
143     }
144
145     public void Free()
146     {
147         Dispose();
148     }
149
150     public IntPtr Release()
151     {
152         IntPtr h = Handle;
153         Handle = IntPtr.Zero;
154         return h;
155     }
156
157     private void FreeElementsIfOwned()
158     {
159         if (OwnContent)
160         {
161             int len = Length;
162             for(int i = 0; i < len; ++i)
163             {
164                 NativeFree<T>(InternalDataGet(i));
165             }
166         }
167     }
168
169     public void Clean()
170     {
171         FreeElementsIfOwned();
172         eina_array_clean_custom_export_mono(Handle);
173     }
174
175     public void Flush()
176     {
177         FreeElementsIfOwned();
178         eina_array_flush(Handle);
179     }
180
181     public int Count()
182     {
183         return (int) eina_array_count_custom_export_mono(Handle);
184     }
185
186     public void SetOwnership(bool ownAll)
187     {
188         Own = ownAll;
189         OwnContent = ownAll;
190     }
191
192     public void SetOwnership(bool own, bool ownContent)
193     {
194         Own = own;
195         OwnContent = ownContent;
196     }
197
198     public bool Push(T val)
199     {
200         IntPtr ele = ManagedToNativeAlloc(val);
201         var r = InternalPush(ele);
202         if (!r)
203             NativeFree<T>(ele);
204         return r;
205     }
206
207 // TODO ???
208 //     public void Add(T val)
209 //     {
210 //         if (!Push(val))
211 //           throw;
212 //     }
213
214     public T Pop()
215     {
216         IntPtr ele = InternalPop();
217         var r = NativeToManaged<T>(ele);
218         if (OwnContent && ele != IntPtr.Zero)
219             NativeFree<T>(ele);
220         return r;
221     }
222
223     public T DataGet(int idx)
224     {
225         IntPtr ele = InternalDataGet(idx);
226         return NativeToManaged<T>(ele);
227     }
228
229     public T At(int idx)
230     {
231         return DataGet(idx);
232     }
233
234     public void DataSet(int idx, T val)
235     {
236         IntPtr ele = InternalDataGet(idx); // TODO: check bondaries ??
237         if (OwnContent && ele != IntPtr.Zero)
238             NativeFree<T>(ele);
239         ele = ManagedToNativeAlloc(val);
240         InternalDataSet(idx, ele);
241     }
242
243     public T this[int idx]
244     {
245         get
246         {
247             return DataGet(idx);
248         }
249         set
250         {
251             DataSet(idx, value);
252         }
253     }
254
255     public T[] ToArray()
256     {
257         int len = Length;
258         var managed = new T[len];
259         for(int i = 0; i < len; ++i)
260         {
261             managed[i] = DataGet(i);
262         }
263         return managed;
264     }
265
266     public bool Append(T[] values)
267     {
268         foreach(T v in values)
269             if (!Push(v))
270                 return false;
271         return true;
272     }
273
274
275     public Eina.Iterator<T> GetIterator()
276     {
277         return new Eina.Iterator<T>(eina_array_iterator_new(Handle), true, false);
278     }
279
280     public IEnumerator<T> GetEnumerator()
281     {
282         int len = Length;
283         for(int i = 0; i < len; ++i)
284         {
285             yield return DataGet(i);
286         }
287     }
288
289     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
290     {
291         return this.GetEnumerator();
292     }
293
294     /// <summary> Gets an Accessor for this Array.</summary>
295     public Eina.Accessor<T> GetAccessor()
296     {
297         return new Eina.Accessor<T>(eina_array_accessor_new(Handle), Ownership.Managed);
298     }
299 }
300
301 }