summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2017-07-07 17:38:54 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2017-07-07 19:42:06 -0300
commit45bb858b493bc5fac4ddbdc023c6513d4ce143f2 (patch)
treeabad5787ad3db4d1e2ac0e69c33e51d813da7bf0
parent8c73e94cdf4af2a33afa95eeec31495650863c8e (diff)
eina_mono: Use DisposableIntPtr to free array datadevs/felipealmeida/csharp-norebase
Plus minor fixes (integer size, support types other than ints in arrays, etc)
-rw-r--r--src/bindings/mono/eina_mono/eina_value.cs59
-rw-r--r--src/lib/efl_mono/efl_custom_exports_mono.c2
-rw-r--r--src/tests/efl_mono/Value.cs29
3 files changed, 62 insertions, 28 deletions
diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs
index 574d513f8c..8b9643318d 100644
--- a/src/bindings/mono/eina_mono/eina_value.cs
+++ b/src/bindings/mono/eina_mono/eina_value.cs
@@ -66,7 +66,7 @@ static internal class UnsafeNativeMethods {
66 66
67 [DllImport("eflcustomexportsmono")] 67 [DllImport("eflcustomexportsmono")]
68 [return: MarshalAsAttribute(UnmanagedType.U1)] 68 [return: MarshalAsAttribute(UnmanagedType.U1)]
69 internal static extern bool eina_value_array_append_wrapper(IntPtr handle, int data); 69 internal static extern bool eina_value_array_append_wrapper(IntPtr handle, IntPtr data);
70 70
71 [DllImport("eflcustomexportsmono")] 71 [DllImport("eflcustomexportsmono")]
72 [return: MarshalAsAttribute(UnmanagedType.U1)] 72 [return: MarshalAsAttribute(UnmanagedType.U1)]
@@ -535,7 +535,9 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
535 // Array methods 535 // Array methods
536 public bool Append(object o) { 536 public bool Append(object o) {
537 SanityChecks(); 537 SanityChecks();
538 return eina_value_array_append_wrapper(this.Handle, (int)o); 538 using (DisposableIntPtr marshalled_value = MarshalValue(o)) {
539 return eina_value_array_append_wrapper(this.Handle, marshalled_value.Handle);
540 }
539 } 541 }
540 542
541 public object this[int i] 543 public object this[int i]
@@ -551,23 +553,19 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
551 } 553 }
552 set { 554 set {
553 SanityChecks(); 555 SanityChecks();
554 IntPtr marshalled_value = MarshalValue(value); 556 using (DisposableIntPtr marshalled_value = MarshalValue(value))
555 557 {
556 if (!eina_value_array_set_wrapper(this.Handle, i, marshalled_value)) { 558 if (!eina_value_array_set_wrapper(this.Handle, i, marshalled_value.Handle)) {
557
558 if (GetValueSubType().IsString())
559 Marshal.FreeHGlobal(marshalled_value);
560 559
561 uint size = eina_value_array_count_wrapper(this.Handle); 560 uint size = eina_value_array_count_wrapper(this.Handle);
562 561
563 if (i >= size) 562 if (i >= size)
564 throw new System.ArgumentOutOfRangeException($"Index {i} is larger than max array index {size-1}"); 563 throw new System.ArgumentOutOfRangeException(
564 $"Index {i} is larger than max array index {size-1}");
565 565
566 throw new SetItemFailedException($"Failed to set item at index {i}"); 566 throw new SetItemFailedException($"Failed to set item at index {i}");
567 }
567 } 568 }
568
569 if (GetValueSubType().IsString())
570 Marshal.FreeHGlobal(marshalled_value);
571 } 569 }
572 } 570 }
573 571
@@ -579,39 +577,46 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
579 return ValueTypeBridge.GetManaged(native_subtype); 577 return ValueTypeBridge.GetManaged(native_subtype);
580 } 578 }
581 579
582 private IntPtr MarshalValue(object value) 580 private DisposableIntPtr MarshalValue(object value)
583 { 581 {
582 IntPtr ret = IntPtr.Zero;
583 bool shouldFree = false;
584 switch(GetValueSubType()) { 584 switch(GetValueSubType()) {
585 case ValueType.Int32: 585 case ValueType.Int32:
586 { 586 {
587 int x = (int)value; 587 int x = Convert.ToInt32(value);
588 return new IntPtr(x); 588 ret = new IntPtr(x);
589 } 589 }
590 break;
590 case ValueType.UInt32: 591 case ValueType.UInt32:
591 { 592 {
592 uint x = (uint)value; 593 uint x = Convert.ToUInt32(value);
593 return new IntPtr((int)x); 594 ret = new IntPtr((int)x);
594 } 595 }
596 break;
595 case ValueType.String: 597 case ValueType.String:
596 { 598 {
597 string x = value as string; 599 string x = value as string;
598 if (x == null) 600 if (x == null)
599 return IntPtr.Zero; 601 ret = IntPtr.Zero;
600 // Warning: Caller will have ownership of this memory. 602 else {
601 return Marshal.StringToHGlobalAnsi(x); 603 ret = Marshal.StringToHGlobalAnsi(x);
604 shouldFree = true;
605 }
602 } 606 }
603 default: 607 break;
604 return IntPtr.Zero;
605 } 608 }
609
610 return new DisposableIntPtr(ret, shouldFree);
606 } 611 }
607 612
608 private object UnMarshalPtr(IntPtr data) 613 private object UnMarshalPtr(IntPtr data)
609 { 614 {
610 switch(GetValueSubType()) { 615 switch(GetValueSubType()) {
611 case ValueType.Int32: 616 case ValueType.Int32:
612 return Convert.ToInt32(data.ToInt64()); 617 return Convert.ToInt32(data.ToInt32());
613 case ValueType.UInt32: 618 case ValueType.UInt32:
614 return Convert.ToUInt32(data.ToInt64()); 619 return Convert.ToUInt32(data.ToInt32());
615 case ValueType.String: 620 case ValueType.String:
616 return Marshal.PtrToStringAuto(data); 621 return Marshal.PtrToStringAuto(data);
617 default: 622 default:
diff --git a/src/lib/efl_mono/efl_custom_exports_mono.c b/src/lib/efl_mono/efl_custom_exports_mono.c
index dc6bb81bd0..4b66ac55f3 100644
--- a/src/lib/efl_mono/efl_custom_exports_mono.c
+++ b/src/lib/efl_mono/efl_custom_exports_mono.c
@@ -332,7 +332,7 @@ EAPI Eina_Bool eina_value_array_get_wrapper(const Eina_Value *array, int i, void
332 return eina_value_array_get(array, i, output); 332 return eina_value_array_get(array, i, output);
333} 333}
334 334
335EAPI Eina_Bool eina_value_array_set_wrapper(const Eina_Value *array, int i, void *value) 335EAPI Eina_Bool eina_value_array_set_wrapper(Eina_Value *array, int i, void *value)
336{ 336{
337 return eina_value_array_set(array, i, value); 337 return eina_value_array_set(array, i, value);
338} 338}
diff --git a/src/tests/efl_mono/Value.cs b/src/tests/efl_mono/Value.cs
index 4a7aaf06ec..c49514c51b 100644
--- a/src/tests/efl_mono/Value.cs
+++ b/src/tests/efl_mono/Value.cs
@@ -336,6 +336,35 @@ public static class TestEinaValue {
336 Test.AssertEquals((int)array[1], 1); 336 Test.AssertEquals((int)array[1], 1);
337 Test.AssertEquals((int)array[2], 5); 337 Test.AssertEquals((int)array[2], 5);
338 Test.AssertEquals((int)array[3], 42); 338 Test.AssertEquals((int)array[3], 42);
339
340 array[0] = 1984;
341 array[1] = -42;
342
343 Test.AssertEquals((int)array[0], 1984);
344 Test.AssertEquals((int)array[1], -42);
345 Test.AssertEquals((int)array[2], 5);
346 Test.AssertEquals((int)array[3], 42);
347 }
348
349 using(eina.Value array = new eina.Value(eina.ValueType.Array, eina.ValueType.UInt32)) {
350 Test.Assert(array.Append(2));
351 Test.AssertEquals((uint)array[0], (uint)2);
352 Test.AssertRaises<OverflowException>(() => array[0] = -1);
353 }
354
355 using(eina.Value array = new eina.Value(eina.ValueType.Array, eina.ValueType.String)) {
356
357 Test.Assert(array.Append("hello"));
358 Test.Assert(array.Append("world"));
359
360 Test.AssertEquals((string)array[0], "hello");
361 Test.AssertEquals((string)array[1], "world");
362
363 array[0] = "efl";
364 array[1] = "rocks";
365
366 Test.AssertEquals((string)array[0], "efl");
367 Test.AssertEquals((string)array[1], "rocks");
339 } 368 }
340 369
341 Test.AssertRaises<ArgumentException>(() => { 370 Test.AssertRaises<ArgumentException>(() => {