/* * Copyright 2019 by its authors. See AUTHORS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma warning disable 1591 using System; using System.Runtime.InteropServices; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using static Eina.TraitFunctions; using static Eina.InlistNativeFunctions; using Eina.Callbacks; namespace Eina { [EditorBrowsable(EditorBrowsableState.Never)] internal static class InlistNativeFunctions { [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_append(IntPtr in_list, IntPtr in_item); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_prepend(IntPtr in_list, IntPtr in_item); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_append_relative(IntPtr in_list, IntPtr in_item, IntPtr in_relative); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_prepend_relative(IntPtr in_list, IntPtr in_item, IntPtr in_relative); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_remove(IntPtr in_list, IntPtr in_item); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_find(IntPtr in_list, IntPtr in_item); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_promote(IntPtr list, IntPtr item); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_demote(IntPtr list, IntPtr item); [DllImport(efl.Libs.Eina)] internal static extern uint eina_inlist_count(IntPtr list); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_iterator_new(IntPtr in_list); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_accessor_new(IntPtr in_list); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_sorted_insert(IntPtr list, IntPtr item, IntPtr func); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_sorted_state_new(); [DllImport(efl.Libs.Eina)] internal static extern int eina_inlist_sorted_state_init(IntPtr state, IntPtr list); [DllImport(efl.Libs.Eina)] internal static extern void eina_inlist_sorted_state_free(IntPtr state); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_sorted_state_insert(IntPtr list, IntPtr item, IntPtr func, IntPtr state); [DllImport(efl.Libs.Eina)] internal static extern IntPtr eina_inlist_sort(IntPtr head, IntPtr func); [DllImport(efl.Libs.CustomExports)] internal static extern IntPtr eina_inlist_first_custom_export_mono(IntPtr list); [DllImport(efl.Libs.CustomExports)] internal static extern IntPtr eina_inlist_last_custom_export_mono(IntPtr list); [DllImport(efl.Libs.CustomExports)] internal static extern IntPtr eina_inlist_next_custom_export_mono(IntPtr list); [DllImport(efl.Libs.CustomExports)] internal static extern IntPtr eina_inlist_prev_custom_export_mono(IntPtr list); [DllImport(efl.Libs.CustomExports)] internal static extern IntPtr eina_inlist_iterator_wrapper_new_custom_export_mono(IntPtr in_list); } /// Wrapper around an inplace list. /// Since EFL 1.23. /// [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification="This is a generalized container mapping the native one.")] public class Inlist : IEnumerable, IDisposable { [EditorBrowsable(EditorBrowsableState.Never)] public IntPtr Handle {get;set;} = IntPtr.Zero; /// Whether this wrapper owns the native buffer. /// Since EFL 1.23. /// public bool Own {get;set;} /// Who is in charge of releasing the resources wrapped by /// this instance. /// Since EFL 1.23. /// public bool OwnContent {get;set;} public int Length { get { return Count(); } } private void InitNew() { Handle = IntPtr.Zero; Own = true; OwnContent = true; } private IntPtr InternalFirst() { return eina_inlist_first_custom_export_mono(Handle); } private IntPtr InternalLast() { return eina_inlist_last_custom_export_mono(Handle); } private IntPtr InternalAt(int idx) { if (idx < 0) { return IntPtr.Zero; } IntPtr curr = Handle; for (int n = 0; n != idx && curr != IntPtr.Zero; ++n) { curr = InternalNext(curr); } return curr; } private static IntPtr InternalNext(IntPtr inlist) { return eina_inlist_next_custom_export_mono(inlist); } private static IntPtr InternalPrev(IntPtr inlist) { return eina_inlist_prev_custom_export_mono(inlist); } /// /// Default constructor. /// Since EFL 1.23. /// public Inlist() { InitNew(); } [EditorBrowsable(EditorBrowsableState.Never)] public Inlist(IntPtr handle, bool own) { Handle = handle; Own = own; OwnContent = own; } [EditorBrowsable(EditorBrowsableState.Never)] public Inlist(IntPtr handle, bool own, bool ownContent) { Handle = handle; Own = own; OwnContent = ownContent; } /// /// Finalizer to be called from the Garbage Collector. /// Since EFL 1.23. /// ~Inlist() { Dispose(false); } /// Disposes of this wrapper, releasing the native array if owned. /// Since EFL 1.23. /// /// True if this was called from public method. False if /// called from the C# finalizer. protected virtual void Dispose(bool disposing) { IntPtr h = Handle; Handle = IntPtr.Zero; if (h == IntPtr.Zero) { return; } if (OwnContent) { for (IntPtr curr = h; curr != IntPtr.Zero; curr = InternalNext(curr)) { NativeFreeInlistNodeElement(curr); } } if (Own) { while (h != IntPtr.Zero) { var aux = h; h = eina_inlist_remove(h, h); NativeFreeInlistNode(aux, false); } } } /// Releases the native resources held by this instance. /// Since EFL 1.23. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// Releases the native resources held by this instance. /// Since EFL 1.23. /// public void Free() { Dispose(); } /// /// Releases the native inlist. /// Since EFL 1.23. /// /// The native inlist. public IntPtr Release() { IntPtr h = Handle; Handle = IntPtr.Zero; return h; } /// Sets all ownership. /// Since EFL 1.23. /// /// If the hash own for all ownerships. public void SetOwnership(bool ownAll) { Own = ownAll; OwnContent = ownAll; } /// Sets own individually. /// Since EFL 1.23. /// /// If own the object. /// If own the content's object. public void SetOwnership(bool own, bool ownContent) { Own = own; OwnContent = ownContent; } /// /// Gets the count of the number of items. /// Since EFL 1.23. /// /// The number of members in the list. public int Count() { return (int)eina_inlist_count(Handle); } /// /// Cleanup the inlist. /// Since EFL 1.23. /// public void Clean() { while (Handle != IntPtr.Zero) { var aux = Handle; Handle = eina_inlist_remove(Handle, Handle); NativeFreeInlistNode(aux, OwnContent); } } /// /// Adds a new value to the end. /// Since EFL 1.23. /// /// The value to be added. public void Append(T val) { IntPtr node = ManagedToNativeAllocInlistNode(val); Handle = eina_inlist_append(Handle, node); } /// /// Adds a new value to the begin. /// Since EFL 1.23. /// /// The value to be added. public void Prepend(T val) { IntPtr node = ManagedToNativeAllocInlistNode(val); Handle = eina_inlist_prepend(Handle, node); } /// /// Removes value at the specified position from list. /// Since EFL 1.23. /// /// The given position. public void Remove(int idx) { IntPtr node = InternalAt(idx); Handle = eina_inlist_remove(Handle, node); NativeFreeInlistNode(node, OwnContent); } /// /// Returns the element of the list at the specified position. /// Since EFL 1.23. /// /// The position of the desired element. /// The element at the specified position public T At(int idx) { IntPtr node = InternalAt(idx); if (node == IntPtr.Zero) { throw new IndexOutOfRangeException(); } return NativeToManagedInlistNode(node); } /// /// Replaces the element at the specified position. /// Since EFL 1.23. /// /// The position of the desired element. /// The value of the element to be inserted. public void DataSet(int idx, T val) { IntPtr old = InternalAt(idx); if (old == IntPtr.Zero) { throw new IndexOutOfRangeException(); } IntPtr new_node = ManagedToNativeAllocInlistNode(val); Handle = eina_inlist_append_relative(Handle, new_node, old); Handle = eina_inlist_remove(Handle, old); NativeFreeInlistNode(old, OwnContent); } /// /// Accessor by index to the elements of this list. /// Since EFL 1.23. /// public T this[int idx] { get { return At(idx); } set { DataSet(idx, value); } } /// /// Returns a array containing all of the elements in proper sequence. /// Since EFL 1.23. /// /// A array public T[] ToArray() { var managed = new T[Count()]; int i = 0; for (IntPtr curr = Handle; curr != IntPtr.Zero; ++i, curr = InternalNext(curr)) { managed[i] = NativeToManagedInlistNode(curr); } return managed; } /// /// Adds a array to the end. /// Since EFL 1.23. /// /// The values to be added. public void AppendArray(T[] values) { Contract.Requires(values != null, nameof(values)); foreach (T v in values) { Append(v); } } /// Gets an Iterator for this list. /// Since EFL 1.23. /// public Eina.Iterator GetIterator() { return new Eina.Iterator(eina_inlist_iterator_wrapper_new_custom_export_mono(Handle), true); } /// Gets an Enumerator for this list. /// Since EFL 1.23. /// public IEnumerator GetEnumerator() { for (IntPtr curr = Handle; curr != IntPtr.Zero; curr = InternalNext(curr)) { yield return NativeToManagedInlistNode(curr); } } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); } /// Gets an Accessor for this List. /// Since EFL 1.23. /// public Eina.Accessor GetAccessor() { return new Eina.AccessorInList(eina_inlist_accessor_new(Handle), Ownership.Managed); } } }