summaryrefslogtreecommitdiff
path: root/src/bindings/mono/eina_mono/eina_hash.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bindings/mono/eina_mono/eina_hash.cs')
-rw-r--r--src/bindings/mono/eina_mono/eina_hash.cs151
1 files changed, 122 insertions, 29 deletions
diff --git a/src/bindings/mono/eina_mono/eina_hash.cs b/src/bindings/mono/eina_mono/eina_hash.cs
index 590033e..95de7c5 100644
--- a/src/bindings/mono/eina_mono/eina_hash.cs
+++ b/src/bindings/mono/eina_mono/eina_hash.cs
@@ -242,10 +242,13 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
242 242
243 public bool AddNew(TKey key, TValue val) 243 public bool AddNew(TKey key, TValue val)
244 { 244 {
245 var nk = ManagedToNativeAllocRef(key, true); 245 IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
246 var nv = ManagedToNativeAlloc(val); 246 IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
247 IntPtr gchnv = CopyNativeObject(val, false);
248 IntPtr nv = GetNativePtr<TValue>(gchnv, false);
247 var r = eina_hash_add(Handle, nk, nv); 249 var r = eina_hash_add(Handle, nk, nv);
248 NativeFreeRef<TKey>(nk); 250 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
251 FreeNativeIndirection<TValue>(gchnv, false);
249 return r; 252 return r;
250 } 253 }
251 254
@@ -256,17 +259,20 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
256 259
257 public bool DelByKey(TKey key) 260 public bool DelByKey(TKey key)
258 { 261 {
259 var nk = ManagedToNativeAllocRef(key); 262 IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
263 IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
260 var r = eina_hash_del_by_key(Handle, nk); 264 var r = eina_hash_del_by_key(Handle, nk);
261 NativeFreeRef<TKey>(nk, OwnKey && r); 265 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
266 // NativeFreeRef<TKey>(nk, OwnKey && r);
262 return r; 267 return r;
263 } 268 }
264 269
265 public bool DelByValue(TValue val) 270 public bool DelByValue(TValue val)
266 { 271 {
267 var nv = ManagedToNativeAlloc(val); 272 IntPtr gchnv = CopyNativeObject(val, false);
273 IntPtr nv = GetNativePtr<TValue>(gchnv, false);
268 var r = eina_hash_del_by_data(Handle, nv); 274 var r = eina_hash_del_by_data(Handle, nv);
269 NativeFree<TValue>(nv); 275 FreeNativeIndirection<TValue>(gchnv, false);
270 return r; 276 return r;
271 } 277 }
272 278
@@ -277,42 +283,52 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
277 283
278 public TValue Find(TKey key) 284 public TValue Find(TKey key)
279 { 285 {
280 var nk = ManagedToNativeAllocRef(key); 286 var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
287 var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
281 var found = eina_hash_find(Handle, nk); 288 var found = eina_hash_find(Handle, nk);
282 NativeFreeRef<TKey>(nk); 289 //NativeFreeRef<TKey>(nk);
290 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
283 if (found == IntPtr.Zero) 291 if (found == IntPtr.Zero)
284 throw new KeyNotFoundException(); 292 throw new KeyNotFoundException();
285 return NativeToManaged<TValue>(found); 293
294 return NativeToManaged<TValue>(IndirectNative<TValue>(found, false));
286 } 295 }
287 296
288 public bool TryGetValue(TKey key, out TValue val) 297 public bool TryGetValue(TKey key, out TValue val)
289 { 298 {
290 var nk = ManagedToNativeAllocRef(key); 299 var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
300 var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
291 var found = eina_hash_find(Handle, nk); 301 var found = eina_hash_find(Handle, nk);
292 NativeFreeRef<TKey>(nk); 302 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
293 if (found == IntPtr.Zero) 303 if (found == IntPtr.Zero)
294 { 304 {
295 val = default(TValue); 305 val = default(TValue);
296 return false; 306 return false;
297 } 307 }
298 val = NativeToManaged<TValue>(found); 308 val = NativeToManaged<TValue>(IndirectNative<TValue>(found, false));
299 return true; 309 return true;
300 } 310 }
301 311
302 public bool ContainsKey(TKey key) 312 public bool ContainsKey(TKey key)
303 { 313 {
304 var nk = ManagedToNativeAllocRef(key); 314 var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
315 var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
316 // var nk = ManagedToNativeAllocRef(key);
305 var found = eina_hash_find(Handle, nk); 317 var found = eina_hash_find(Handle, nk);
306 NativeFreeRef<TKey>(nk); 318 // NativeFreeRef<TKey>(nk);
319 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
307 return found != IntPtr.Zero; 320 return found != IntPtr.Zero;
308 } 321 }
309 322
310 public bool Modify(TKey key, TValue val) 323 public bool Modify(TKey key, TValue val)
311 { 324 {
312 var nk = ManagedToNativeAllocRef(key); 325 var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
313 var nv = ManagedToNativeAlloc(val); 326 var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
327 var gchnv = CopyNativeObject<TValue>(val, false);
328 var nv = GetNativePtr<TValue>(gchnv, false);
314 var old = eina_hash_modify(Handle, nk, nv); 329 var old = eina_hash_modify(Handle, nk, nv);
315 NativeFreeRef<TKey>(nk); 330 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
331 // NativeFreeRef<TKey>(nk);
316 if (old == IntPtr.Zero) 332 if (old == IntPtr.Zero)
317 { 333 {
318 NativeFree<TValue>(nv); 334 NativeFree<TValue>(nv);
@@ -323,13 +339,83 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
323 return true; 339 return true;
324 } 340 }
325 341
342 private static bool ForceRefKey<T>()
343 {
344 return (!typeof(T).IsValueType) && (typeof(T) != typeof(string));
345 }
346
347 private static IntPtr CopyNativeObject<T>(T value, bool forceRef)
348 {
349 if (!IsEflObject(typeof(T)) && forceRef)
350 {
351 GCHandle gch = GCHandle.Alloc(new byte[Marshal.SizeOf<T>()], GCHandleType.Pinned);
352 IntPtr pin = gch.AddrOfPinnedObject();
353
354 ManagedToNativeCopyTo(value, pin);
355
356 return GCHandle.ToIntPtr(gch);
357 }
358 else if(IsEflObject(typeof(T)) && forceRef)
359 {
360 GCHandle gch = GCHandle.Alloc(new byte[Marshal.SizeOf<IntPtr>()], GCHandleType.Pinned);
361 IntPtr pin = gch.AddrOfPinnedObject();
362
363 ManagedToNativeCopyTo(value, pin);
364
365 return GCHandle.ToIntPtr(gch);
366 }
367 else
368 {
369 return ManagedToNativeAlloc(value);
370 }
371 }
372 private static IntPtr GetNativePtr<T>(IntPtr gchptr, bool forceRef)
373 {
374 if (forceRef)
375 {
376 GCHandle gch = GCHandle.FromIntPtr(gchptr);
377 IntPtr pin = gch.AddrOfPinnedObject();
378
379 return pin;
380 }
381 else
382 {
383 return gchptr;
384 }
385 }
386 private static void FreeNativeIndirection<T>(IntPtr gchptr, bool forceRef)
387 {
388 if (forceRef)
389 {
390 GCHandle gch = GCHandle.FromIntPtr(gchptr);
391 gch.Free();
392 }
393 }
394
395 private static IntPtr IndirectNative<T>(IntPtr ptr, bool forceRef)
396 {
397 if (forceRef)
398 {
399 IntPtr val = Marshal.ReadIntPtr(ptr);
400 return val;
401 }
402 else
403 {
404 return ptr;
405 }
406 }
407
326 public void Set(TKey key, TValue val) 408 public void Set(TKey key, TValue val)
327 { 409 {
328 var nk = ManagedToNativeAllocRef(key, true); 410 IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
329 var nv = ManagedToNativeAlloc(val); 411 IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
330 var old = eina_hash_set(Handle, nk, nv); 412
331 NativeFreeRef<TKey>(nk, old != IntPtr.Zero); 413 IntPtr gchnv = CopyNativeObject(val, false);
332 if (old != IntPtr.Zero && OwnValue) 414 IntPtr nv = GetNativePtr<TValue>(gchnv, false);
415 IntPtr old = eina_hash_set(Handle, nk, nv);
416 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
417 FreeNativeIndirection<TValue>(gchnv, false);
418 if (OwnValue || old != IntPtr.Zero)
333 NativeFree<TValue>(old); 419 NativeFree<TValue>(old);
334 } 420 }
335 421
@@ -347,11 +433,17 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
347 433
348 public bool Move(TKey key_old, TKey key_new) 434 public bool Move(TKey key_old, TKey key_new)
349 { 435 {
350 var nk_old = ManagedToNativeAllocRef(key_old); 436 IntPtr gchnko = CopyNativeObject(key_old, ForceRefKey<TKey>());
351 var nk_new = ManagedToNativeAllocRef(key_new, true); 437 IntPtr nko = GetNativePtr<TKey>(gchnko, ForceRefKey<TKey>());
352 var r = eina_hash_move(Handle, nk_old, nk_new); 438 IntPtr gchnk = CopyNativeObject(key_new, ForceRefKey<TKey>());
353 NativeFreeRef<TKey>(nk_old, OwnKey && r); 439 IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
354 NativeFreeRef<TKey>(nk_new, !r); 440 // var nk_old = ManagedToNativeAllocRef(key_old);
441 // var nk_new = ManagedToNativeAllocRef(key_new, true);
442 var r = eina_hash_move(Handle, nko, nk);
443 FreeNativeIndirection<TKey>(gchnko, ForceRefKey<TKey>());
444 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
445 // NativeFreeRef<TKey>(nk_old, OwnKey && r);
446 // NativeFreeRef<TKey>(nk_new, !r);
355 return r; 447 return r;
356 } 448 }
357 449
@@ -383,7 +475,8 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
383 for (IntPtr tuplePtr; eina_iterator_next(itr, out tuplePtr);) 475 for (IntPtr tuplePtr; eina_iterator_next(itr, out tuplePtr);)
384 { 476 {
385 var tuple = Marshal.PtrToStructure<Eina.HashTupleNative>(tuplePtr); 477 var tuple = Marshal.PtrToStructure<Eina.HashTupleNative>(tuplePtr);
386 var key = NativeToManagedRef<TKey>(tuple.key); 478 IntPtr ikey = IndirectNative<TKey>(tuple.key, ForceRefKey<TKey>());
479 var key = NativeToManaged<TKey>(ikey);
387 var val = NativeToManaged<TValue>(tuple.data); 480 var val = NativeToManaged<TValue>(tuple.data);
388 yield return new KeyValuePair<TKey, TValue>(key, val); 481 yield return new KeyValuePair<TKey, TValue>(key, val);
389 } 482 }