lauromoura pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=e973b87bf845bc6375b7608be40ba9a0851cd4e6

commit e973b87bf845bc6375b7608be40ba9a0851cd4e6
Author: Lauro Moura <[email protected]>
Date:   Fri Sep 13 19:22:39 2019 -0300

    csharp: Fix Hash.DelByValue
    
    Summary:
    The C function `eina_hash_del_by_data` requires the same value that was
    passed to the `add` function. As C# hashes store stuff through pointers
    due to marshalling, this makes it hard to pass the same pointer for it.
    
    So this functionality is implemented at C# level instead of relying on
    the native function directly.
    
    Fixes T8198
    
    Thanks to @brunobelo and @singh.amitesh for the test case.
    
    Reviewers: singh.amitesh, felipealmeida, brunobelo
    
    Reviewed By: brunobelo
    
    Subscribers: cedric, #reviewers, #committers, singh.amitesh, brunobelo
    
    Tags: #efl
    
    Maniphest Tasks: T8198
    
    Differential Revision: https://phab.enlightenment.org/D9853
---
 src/bindings/mono/eina_mono/eina_hash.cs | 26 +++++++++++----
 src/tests/efl_mono/Hash.cs               | 55 ++++++++++++++++++++++++++++++++
 src/tests/efl_mono/meson.build           |  1 +
 3 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/src/bindings/mono/eina_mono/eina_hash.cs 
b/src/bindings/mono/eina_mono/eina_hash.cs
index 38522dc0e3..dc5c0fd294 100644
--- a/src/bindings/mono/eina_mono/eina_hash.cs
+++ b/src/bindings/mono/eina_mono/eina_hash.cs
@@ -278,17 +278,31 @@ public class Hash<TKey, TValue> : 
IEnumerable<KeyValuePair<TKey, TValue>>, IDi
         IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
         var r = eina_hash_del_by_key(Handle, nk);
         FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
-        // NativeFreeRef<TKey>(nk, OwnKey && r);
         return r;
     }
 
+    /// <summary>Searches this hash for <c>val</c> and deletes it from the 
hash, also deleting it.</summary>
+    /// <returns><c>true</c> if the value was found and deleted, false if it 
was <c>null</c> or not found.</returns>
     public bool DelByValue(TValue val)
     {
-        IntPtr gchnv = CopyNativeObject(val, false);
-        IntPtr nv = GetNativePtr<TValue>(gchnv, false);
-        var r = eina_hash_del_by_data(Handle, nv);
-        FreeNativeIndirection<TValue>(gchnv, false);
-        return r;
+        // We don't use the C version of `eina_hash_del_by_data` because it 
requires the exact pointer
+        // we passed to add(). As our hashes store the data by pointer, this 
makes it harder to pass the
+        // same value.
+        if (val == null)
+        {
+            return false;
+        }
+
+        foreach (var pair in this)
+        {
+            if (pair.Value != null && val.Equals(pair.Value))
+            {
+                return this.DelByKey(pair.Key);
+            }
+        }
+
+        return false;
+
     }
 
     public void Remove(TKey key)
diff --git a/src/tests/efl_mono/Hash.cs b/src/tests/efl_mono/Hash.cs
new file mode 100644
index 0000000000..e064e47a13
--- /dev/null
+++ b/src/tests/efl_mono/Hash.cs
@@ -0,0 +1,55 @@
+using System;
+
+namespace TestSuite {
+
+class TestHash
+{
+
+    public static void test_del_value()
+    {
+        var hash = new Eina.Hash<int, int>();
+        Test.AssertEquals(hash.Count, 0);
+        hash.Add(0, 1);
+        Test.Assert(hash.DelByValue(1));
+        Test.AssertEquals(hash.Count, 0);
+
+        hash.Add(0, 1);
+        hash.Add(1, 100);
+        hash.Add(2, 101);
+
+        Test.Assert(hash.DelByValue(100));
+        Test.AssertEquals(hash.Count, 2);
+
+        Test.Assert(!hash.DelByValue(200));
+    }
+
+    public static void test_del_value_string()
+    {
+        var hash = new Eina.Hash<int, string>();
+        Test.AssertEquals(hash.Count, 0);
+        hash.Add(0, "E F L");
+        Test.Assert(hash.DelByValue("E F L"));
+        Test.AssertEquals(hash.Count, 0);
+
+        hash.Add(0, "Eina");
+        hash.Add(1, "Eo");
+        hash.Add(2, "Ecore");
+
+        Test.Assert(hash.DelByValue("Ecore"));
+        Test.AssertEquals(hash.Count, 2);
+
+        Test.Assert(!hash.DelByValue("Elementary"));
+    }
+
+    public static void test_del_key()
+    {
+        var hash = new Eina.Hash<int, int>();
+        hash.Add(0, 1);
+        hash.Add(1, 100);
+        hash.Add(2, 101);
+
+        hash.DelByKey(1);
+        Test.AssertEquals(hash.Count, 2);
+    }
+}
+} // namespace TestSuite
diff --git a/src/tests/efl_mono/meson.build b/src/tests/efl_mono/meson.build
index 445c823caa..8dedc3e543 100644
--- a/src/tests/efl_mono/meson.build
+++ b/src/tests/efl_mono/meson.build
@@ -81,6 +81,7 @@ efl_mono_src = [
      'Value.cs',
      'ValueEolian.cs',
      'Inheritance.cs',
+     'Hash.cs'
 ]
 
 efl_mono_suite = executable('efl-mono-suite',

-- 


Reply via email to