31574d552f806b7b85388ef75383c08fa6e9c8ee
[platform/core/csapi/tizenfx.git] / internals / src / EflSharp / EflSharp / efl / eina_accessor.cs
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Runtime.InteropServices;
5
6 using static Eina.TraitFunctions;
7
8 using static Eina.AccessorNativeFunctions;
9
10 namespace Eina
11 {
12
13 internal class AccessorNativeFunctions
14 {
15     [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
16         eina_accessor_data_get(IntPtr accessor, uint position, IntPtr data);
17     [DllImport(efl.Libs.Eina)] public static extern void
18         eina_accessor_free(IntPtr accessor);
19 }
20
21 /// <summary>Accessors provide an uniform way of accessing Eina containers, similar to C++ STL's and C# IEnumerable.</summary>
22 public class Accessor<T> : IEnumerable<T>, IDisposable
23 {
24     /// <summary>Pointer to the native accessor.</summary>
25     public IntPtr Handle { get; private set; } = IntPtr.Zero;
26
27     /// <summary>Who is in charge of releasing the resources wrapped by this instance.</summary>
28     private Ownership Ownership { get; set; }
29
30     // FIXME Part of the implicit EFL Container interface. Need to make it explicit.
31     ///<summary>Whether this wrapper owns the native accessor.</summary>
32     public bool Own
33     {
34         get
35         {
36             return Ownership == Ownership.Managed;
37         }
38         set
39         {
40             Ownership = value ? Ownership.Managed : Ownership.Unmanaged;
41         }
42     }
43
44     /// <summary>Create a new accessor wrapping the given pointer.</summary>
45     /// <param name="handle">The native handle to be wrapped.</param>
46     /// <param name="owner">Whether this wrapper owns the native accessor.</param>
47     public Accessor(IntPtr handle, Ownership owner = Ownership.Managed)
48     {
49         Handle = handle;
50         Ownership = owner;
51     }
52
53     /// <summary>Create a new accessor wrapping the given pointer.</summary>
54     /// <param name="handle">The native handle to be wrapped.</param>
55     /// <param name="own">Whether this wrapper owns the native accessor.</param>
56     /// <param name="ownContent">For compatibility with other EFL# containers. Ignored in acessors.</param>
57     public Accessor(IntPtr handle, bool own, bool ownContent = false)
58         : this(handle, own ? Ownership.Managed : Ownership.Unmanaged)
59     {
60     }
61
62     /// <summary>Release the native resources held by this instance.</summary>
63     public void Dispose()
64     {
65         Dispose(true);
66     }
67
68     /// <summary>Disposes of this wrapper, releasing the native accessor if owned.</summary>
69     /// <param name="disposing">True if this was called from <see cref="Dispose()"/> public method. False if
70     /// called from the C# finalizer.</param>
71     protected virtual void Dispose(bool disposing)
72     {
73         if (Ownership == Ownership.Managed && Handle != IntPtr.Zero)
74         {
75             eina_accessor_free(Handle);
76             Handle = IntPtr.Zero;
77         }
78     }
79
80     /// <summary>Finalizer to be called from the Garbage Collector.</summary>
81     ~Accessor()
82     {
83         Dispose(false);
84     }
85
86     /// <summary>Convert the native data into managed. This is used when returning the data through a
87     /// <see cref="System.Collections.Generic.IEnumerator&lt;T&gt;"/>.</summary>
88     /// <param name="data">The data to be converted</param>
89     /// <returns>The managed data representing <c>data</c>.</returns>
90     protected virtual T Convert(IntPtr data)
91     {
92         return NativeToManaged<T>(data);
93     }
94
95     /// <summary>Returns an enumerator that iterates throught this accessor.</summary>
96     /// <returns>An enumerator to walk through the acessor items.</returns>
97     public IEnumerator<T> GetEnumerator()
98     {
99         if (Handle == IntPtr.Zero)
100         {
101             throw new ObjectDisposedException(base.GetType().Name);
102         }
103
104         IntPtr tmp = MemoryNative.Alloc(Marshal.SizeOf(typeof(IntPtr)));
105         uint position = 0;
106
107         try
108         {
109             while (eina_accessor_data_get(Handle, position, tmp))
110             {
111                 IntPtr data = (IntPtr)Marshal.PtrToStructure(tmp, typeof(IntPtr));
112                 yield return Convert(data);
113                 position += 1;
114             }
115         }
116         finally
117         {
118             MemoryNative.Free(tmp);
119         }
120     }
121
122     IEnumerator IEnumerable.GetEnumerator()
123     {
124         return this.GetEnumerator();
125     }
126 }
127
128 ///<summary>Accessor for Inlists.</summary>
129 public class AccessorInList<T> : Accessor<T>
130 {
131     /// <summary>Create a new accessor wrapping the given pointer.</summary>
132     /// <param name="handle">The native handle to be wrapped.</param>
133     /// <param name="own">Whether this wrapper owns the native accessor.</param>
134     public AccessorInList(IntPtr handle, Ownership own) : base(handle, own)
135     {
136     }
137
138     /// <summary>Convert the native data into managed. This is used when returning the data through a
139     /// <see cref="System.Collections.Generic.IEnumerator&lt;T&gt;"/>.</summary>
140     /// <param name="data">The data to be converted</param>
141     /// <returns>The managed data representing <c>data</c>.</returns>
142     protected override T Convert(IntPtr data)
143     {
144         return NativeToManagedInlistNode<T>(data);
145     }
146 }
147
148 ///<summary>Accessor for Inarrays.</summary>
149 public class AccessorInArray<T> : Accessor<T>
150 {
151     /// <summary>Create a new accessor wrapping the given pointer.</summary>
152     /// <param name="handle">The native handle to be wrapped.</param>
153     /// <param name="own">Whether this wrapper owns the native accessor.</param>
154     public AccessorInArray(IntPtr handle, Ownership own) : base(handle, own)
155     {
156     }
157
158     /// <summary>Convert the native data into managed. This is used when returning the data through a
159     /// <see cref="System.Collections.Generic.IEnumerator&lt;T&gt;"/>.</summary>
160     /// <param name="data">The data to be converted</param>
161     /// <returns>The managed data representing <c>data</c>.</returns>
162     protected override T Convert(IntPtr data)
163     {
164         return NativeToManagedInplace<T>(data);
165     }
166 }
167
168 }