From 850b7309b061551eeee34891f40d4820da495b0f Mon Sep 17 00:00:00 2001 From: Lauro Moura Date: Fri, 1 Mar 2019 19:17:16 -0300 Subject: [PATCH] efl-csharp: Fix Eina.Value containing arrays and lists Summary: It was marshalling erroneously data into and out of arrays and lists. Instead of passing data by value (or by address of correct size), it was stuffing data into IntPtr and trying to parse out afterwards. This commit changes the binding to use the same approach of plain Get/Set, with proper overloads. Reviewers: vitor.sousa, segfaultxavi, felipealmeida Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8057 --- src/bindings/mono/eina_mono/eina_value.cs | 425 ++++++++++++++++----- src/lib/efl_mono/efl_custom_exports_mono.c | 57 +++ src/tests/efl_mono/Value.cs | 109 +++++- 3 files changed, 497 insertions(+), 94 deletions(-) diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs index 6fae14b022..edb1ab7b77 100644 --- a/src/bindings/mono/eina_mono/eina_value.cs +++ b/src/bindings/mono/eina_mono/eina_value.cs @@ -178,7 +178,47 @@ static internal class UnsafeNativeMethods { [DllImport(efl.Libs.CustomExports)] [return: MarshalAsAttribute(UnmanagedType.U1)] - internal static extern bool eina_value_array_append_wrapper(IntPtr handle, IntPtr data); + internal static extern bool eina_value_container_append_wrapper_string(IntPtr handle, string data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_append_wrapper_char(IntPtr handle, sbyte data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_append_wrapper_uchar(IntPtr handle, byte data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_append_wrapper_short(IntPtr handle, short data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_append_wrapper_ushort(IntPtr handle, ushort data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_append_wrapper_int(IntPtr handle, int data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_append_wrapper_uint(IntPtr handle, uint data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_append_wrapper_long(IntPtr handle, long data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_append_wrapper_ulong(IntPtr handle, ulong data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_append_wrapper_float(IntPtr handle, float data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_append_wrapper_double(IntPtr handle, double data); [DllImport(efl.Libs.CustomExports)] [return: MarshalAsAttribute(UnmanagedType.U1)] @@ -186,7 +226,47 @@ static internal class UnsafeNativeMethods { [DllImport(efl.Libs.CustomExports)] [return: MarshalAsAttribute(UnmanagedType.U1)] - internal static extern bool eina_value_array_get_wrapper(IntPtr handle, int index, out IntPtr output); + internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out IntPtr output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out sbyte output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out byte output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out short output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out ushort output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out int output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out uint output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out long output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out ulong output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out float output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out double output); [DllImport(efl.Libs.CustomExports)] [return: MarshalAsAttribute(UnmanagedType.U1)] @@ -194,11 +274,47 @@ static internal class UnsafeNativeMethods { [DllImport(efl.Libs.CustomExports)] [return: MarshalAsAttribute(UnmanagedType.U1)] - internal static extern bool eina_value_array_set_wrapper(IntPtr handle, int index, IntPtr value); + internal static extern bool eina_value_container_set_wrapper_string(IntPtr handle, int index, string value); [DllImport(efl.Libs.CustomExports)] [return: MarshalAsAttribute(UnmanagedType.U1)] - internal static extern bool eina_value_list_set_wrapper(IntPtr handle, int index, IntPtr value); + internal static extern bool eina_value_container_set_wrapper_uchar(IntPtr handle, int index, byte value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_set_wrapper_char(IntPtr handle, int index, sbyte value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_set_wrapper_short(IntPtr handle, int index, short value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_set_wrapper_ushort(IntPtr handle, int index, ushort value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_set_wrapper_int(IntPtr handle, int index, int value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_set_wrapper_uint(IntPtr handle, int index, uint value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_set_wrapper_long(IntPtr handle, int index, long value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_set_wrapper_ulong(IntPtr handle, int index, ulong value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_set_wrapper_float(IntPtr handle, int index, float value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_container_set_wrapper_double(IntPtr handle, int index, double value); [DllImport(efl.Libs.CustomExports)] internal static extern IntPtr eina_value_array_subtype_get_wrapper(IntPtr handle); @@ -1747,13 +1863,70 @@ public class Value : IDisposable, IComparable, IEquatable } public bool Append(object o) { ContainerSanityChecks(); - using (DisposableIntPtr marshalled_value = MarshalValue(o)) { - switch (GetValueType()) { - case ValueType.Array: - return eina_value_array_append_wrapper(this.Handle, marshalled_value.Handle); - case ValueType.List: - return eina_value_list_append_wrapper(this.Handle, marshalled_value.Handle); - } + + switch (GetValueSubType()) { + case ValueType.SByte: + { + sbyte b = Convert.ToSByte(o); + return eina_value_container_append_wrapper_char(this.Handle, b); + } + case ValueType.Byte: + { + byte b = Convert.ToByte(o); + return eina_value_container_append_wrapper_uchar(this.Handle, b); + } + + case ValueType.Short: + { + short b = Convert.ToInt16(o); + return eina_value_container_append_wrapper_short(this.Handle, b); + } + case ValueType.UShort: + { + ushort b = Convert.ToUInt16(o); + return eina_value_container_append_wrapper_ushort(this.Handle, b); + } + + case ValueType.Int32: + { + int x = Convert.ToInt32(o); + return eina_value_container_append_wrapper_int(this.Handle, x); + } + case ValueType.UInt32: + { + uint x = Convert.ToUInt32(o); + return eina_value_container_append_wrapper_uint(this.Handle, x); + } + + case ValueType.Long: + case ValueType.Int64: + { + long x = Convert.ToInt64(o); + return eina_value_container_append_wrapper_long(this.Handle, x); + } + case ValueType.ULong: + case ValueType.UInt64: + { + ulong x = Convert.ToUInt64(o); + return eina_value_container_append_wrapper_ulong(this.Handle, x); + } + + case ValueType.Float: + { + float x = Convert.ToSingle(o); + return eina_value_container_append_wrapper_float(this.Handle, x); + } + case ValueType.Double: + { + double x = Convert.ToDouble(o); + return eina_value_container_append_wrapper_double(this.Handle, x); + } + + case ValueType.String: + { + string x = Convert.ToString(o); + return eina_value_container_append_wrapper_string(this.Handle, x); + } } return false; } @@ -1763,49 +1936,163 @@ public class Value : IDisposable, IComparable, IEquatable get { ContainerSanityChecks(i); - IntPtr output = IntPtr.Zero; - switch (GetValueType()) { - case ValueType.Array: - if (!eina_value_array_get_wrapper(this.Handle, i, out output)) - return null; - break; - case ValueType.List: - if (!eina_value_list_get_wrapper(this.Handle, i, out output)) - return null; - break; + switch (GetValueSubType()) { + case ValueType.SByte: + { + sbyte ret = default(sbyte); + eina_value_container_get_wrapper(this.Handle, i, out ret); + return ret; + } + case ValueType.Byte: + { + byte ret = default(byte); + eina_value_container_get_wrapper(this.Handle, i, out ret); + return ret; + } + + case ValueType.Short: + { + short ret = default(short); + eina_value_container_get_wrapper(this.Handle, i, out ret); + return ret; + } + case ValueType.UShort: + { + ushort ret = default(ushort); + eina_value_container_get_wrapper(this.Handle, i, out ret); + return ret; + } + + case ValueType.Int32: + { + int ret = default(int); + eina_value_container_get_wrapper(this.Handle, i, out ret); + return ret; + } + case ValueType.UInt32: + { + uint ret = default(uint); + eina_value_container_get_wrapper(this.Handle, i, out ret); + return ret; + } + + case ValueType.Long: + case ValueType.Int64: + { + long ret = default(long); + eina_value_container_get_wrapper(this.Handle, i, out ret); + return ret; + } + case ValueType.ULong: + case ValueType.UInt64: + { + ulong ret = default(ulong); + eina_value_container_get_wrapper(this.Handle, i, out ret); + return ret; + } + + case ValueType.Float: + { + float ret = default(float); + eina_value_container_get_wrapper(this.Handle, i, out ret); + return ret; + } + case ValueType.Double: + { + double ret = default(double); + eina_value_container_get_wrapper(this.Handle, i, out ret); + return ret; + } + + case ValueType.String: + { + // Using intptr as using string as the arg type in the DllImport'd function would + // make mono take ownership of the string. + IntPtr ptr = IntPtr.Zero; + eina_value_container_get_wrapper(this.Handle, i, out ptr); + return Eina.StringConversion.NativeUtf8ToManagedString(ptr); + } + default: + throw new InvalidOperationException("Subtype not supported."); } - return UnMarshalPtr(output); } set { ContainerSanityChecks(i); - switch (GetValueType()) { - case ValueType.Array: - ArraySet(i, value); + switch (GetValueSubType()) { + case ValueType.SByte: + { + sbyte v = Convert.ToSByte(value); + eina_value_container_set_wrapper_char(this.Handle, i, v); + } break; - case ValueType.List: - ListSet(i, value); + case ValueType.Byte: + { + byte v = Convert.ToByte(value); + eina_value_container_set_wrapper_uchar(this.Handle, i, v); + } break; - } - } - } - private void ArraySet(int i, object value) { - using (DisposableIntPtr marshalled_value = MarshalValue(value)) - { - if (!eina_value_array_set_wrapper(this.Handle, i, - marshalled_value.Handle)) { - throw new SetItemFailedException($"Failed to set item at index {i}"); - } - } - } + case ValueType.Short: + { + short x = Convert.ToInt16(value); + eina_value_container_set_wrapper_short(this.Handle, i, x); + } + break; + case ValueType.UShort: + { + ushort x = Convert.ToUInt16(value); + eina_value_container_set_wrapper_ushort(this.Handle, i, x); + } + break; - private void ListSet(int i, object value) { - using (DisposableIntPtr marshalled_value = MarshalValue(value)) - { - if (!eina_value_list_set_wrapper(this.Handle, i, - marshalled_value.Handle)) { - throw new SetItemFailedException($"Failed to set item at index {i}"); + case ValueType.Int32: + { + int x = Convert.ToInt32(value); + eina_value_container_set_wrapper_int(this.Handle, i, x); + } + break; + case ValueType.UInt32: + { + uint x = Convert.ToUInt32(value); + eina_value_container_set_wrapper_uint(this.Handle, i, x); + } + break; + + case ValueType.Long: + case ValueType.Int64: + { + long x = Convert.ToInt64(value); + eina_value_container_set_wrapper_long(this.Handle, i, x); + } + break; + case ValueType.ULong: + case ValueType.UInt64: + { + ulong x = Convert.ToUInt64(value); + eina_value_container_set_wrapper_ulong(this.Handle, i, x); + } + break; + + case ValueType.Float: + { + float x = Convert.ToSingle(value); + eina_value_container_set_wrapper_float(this.Handle, i, x); + } + break; + case ValueType.Double: + { + double x = Convert.ToDouble(value); + eina_value_container_set_wrapper_double(this.Handle, i, x); + } + break; + + case ValueType.String: + { + string x = Convert.ToString(value); + eina_value_container_set_wrapper_string(this.Handle, i, x); + } + break; } } } @@ -1826,54 +2113,6 @@ public class Value : IDisposable, IComparable, IEquatable } return ValueTypeBridge.GetManaged(native_subtype); } - - private DisposableIntPtr MarshalValue(object value) - { - IntPtr ret = IntPtr.Zero; - bool shouldFree = false; - switch(GetValueSubType()) { - case ValueType.Int32: - { - int x = Convert.ToInt32(value); - ret = new IntPtr(x); - } - break; - case ValueType.UInt32: - { - uint x = Convert.ToUInt32(value); - ret = new IntPtr((int)x); - } - break; - case ValueType.String: - { - string x = value as string; - if (x == null) - ret = IntPtr.Zero; - else { - ret = StringConversion.ManagedStringToNativeUtf8Alloc(x); - shouldFree = true; - } - } - break; - } - - return new DisposableIntPtr(ret, shouldFree); - } - - private object UnMarshalPtr(IntPtr data) - { - switch(GetValueSubType()) { - case ValueType.Int32: - return Convert.ToInt32(data.ToInt32()); - case ValueType.UInt32: - return Convert.ToUInt32(data.ToInt32()); - case ValueType.String: - return StringConversion.NativeUtf8ToManagedString(data); - default: - return null; - } - } - } /// Custom marshaler to convert value pointers to managed values and back, diff --git a/src/lib/efl_mono/efl_custom_exports_mono.c b/src/lib/efl_mono/efl_custom_exports_mono.c index 246a7bcf71..fce3a43a1e 100644 --- a/src/lib/efl_mono/efl_custom_exports_mono.c +++ b/src/lib/efl_mono/efl_custom_exports_mono.c @@ -349,6 +349,63 @@ EINA_SET_WRAPPER(double, double) EINA_SET_WRAPPER(string, const char *) EINA_SET_WRAPPER(ptr, void *) +#define EINA_CONTAINER_SET_WRAPPER(N, T) EAPI Eina_Bool eina_value_container_set_wrapper_##N(Eina_Value *value, int i, T new_value) \ +{ \ + const Eina_Value_Type *tp = eina_value_type_get(value); \ + if (tp == EINA_VALUE_TYPE_ARRAY) \ + return eina_value_array_set(value, i, new_value); \ + else if (tp == EINA_VALUE_TYPE_LIST) \ + return eina_value_list_set(value, i, new_value); \ + else \ + return EINA_FALSE; \ +} + +EINA_CONTAINER_SET_WRAPPER(char, char) +EINA_CONTAINER_SET_WRAPPER(uchar, unsigned char) +EINA_CONTAINER_SET_WRAPPER(short, short) +EINA_CONTAINER_SET_WRAPPER(ushort, unsigned short) +EINA_CONTAINER_SET_WRAPPER(int, int) +EINA_CONTAINER_SET_WRAPPER(uint, unsigned int) +EINA_CONTAINER_SET_WRAPPER(long, long) +EINA_CONTAINER_SET_WRAPPER(ulong, unsigned long) +EINA_CONTAINER_SET_WRAPPER(float, float) +EINA_CONTAINER_SET_WRAPPER(double, double) +EINA_CONTAINER_SET_WRAPPER(string, const char *) +EINA_CONTAINER_SET_WRAPPER(ptr, void *) + +#define EINA_CONTAINER_APPEND_WRAPPER(N, T) EAPI Eina_Bool eina_value_container_append_wrapper_##N(Eina_Value *value, T new_value) \ +{ \ + const Eina_Value_Type *tp = eina_value_type_get(value); \ + if (tp == EINA_VALUE_TYPE_ARRAY) \ + return eina_value_array_append(value, new_value); \ + else if (tp == EINA_VALUE_TYPE_LIST) \ + return eina_value_list_append(value, new_value); \ + else \ + return EINA_FALSE; \ +} + +EINA_CONTAINER_APPEND_WRAPPER(char, char) +EINA_CONTAINER_APPEND_WRAPPER(uchar, unsigned char) +EINA_CONTAINER_APPEND_WRAPPER(short, short) +EINA_CONTAINER_APPEND_WRAPPER(ushort, unsigned short) +EINA_CONTAINER_APPEND_WRAPPER(int, int) +EINA_CONTAINER_APPEND_WRAPPER(uint, unsigned int) +EINA_CONTAINER_APPEND_WRAPPER(long, long) +EINA_CONTAINER_APPEND_WRAPPER(ulong, unsigned long) +EINA_CONTAINER_APPEND_WRAPPER(float, float) +EINA_CONTAINER_APPEND_WRAPPER(double, double) +EINA_CONTAINER_APPEND_WRAPPER(string, const char *) +EINA_CONTAINER_APPEND_WRAPPER(ptr, void *) + +EAPI void eina_value_container_get_wrapper(const Eina_Value *value, int i, void *output) +{ + const Eina_Value_Type *tp = eina_value_type_get(value); + if (tp == EINA_VALUE_TYPE_ARRAY) + eina_value_array_get(value, i, output); + else if (tp == EINA_VALUE_TYPE_LIST) + eina_value_list_get(value, i, output); +} + EAPI Eina_Bool eina_value_setup_wrapper(Eina_Value *value, const Eina_Value_Type *type) { diff --git a/src/tests/efl_mono/Value.cs b/src/tests/efl_mono/Value.cs index 6f2c5799b5..2c5e3115f0 100644 --- a/src/tests/efl_mono/Value.cs +++ b/src/tests/efl_mono/Value.cs @@ -604,7 +604,74 @@ public static class TestEinaValue { } } - public static void TestValueArray() { + public static void TestValueArrayOfSByte() + { + using(Eina.Value array = new Eina.Value(Eina.ValueType.Array, Eina.ValueType.SByte)) { + Test.AssertEquals(0, array.Count()); + Test.Assert(array.Append(0)); + Test.AssertEquals(1, array.Count()); + Test.Assert(array.Append(1)); + Test.AssertEquals(2, array.Count()); + Test.Assert(array.Append(5)); + Test.AssertEquals(3, array.Count()); + Test.Assert(array.Append(42)); + Test.AssertEquals(4, array.Count()); + + + Test.AssertEquals((sbyte)array[0], 0); + Test.AssertEquals((sbyte)array[1], 1); + Test.AssertEquals((sbyte)array[2], 5); + Test.AssertEquals((sbyte)array[3], 42); + + array[0] = 120; + array[1] = -42; + Test.AssertEquals(4, array.Count()); + + Test.AssertEquals((sbyte)array[0], 120); + Test.AssertEquals((sbyte)array[1], -42); + Test.AssertEquals((sbyte)array[2], 5); + Test.AssertEquals((sbyte)array[3], 42); + + Test.AssertEquals("[120, -42, 5, 42]", array.ToString()); + } + } + + public static void TestValueArrayOfByte() + { + using(Eina.Value array = new Eina.Value(Eina.ValueType.Array, Eina.ValueType.Byte)) { + Test.AssertEquals(0, array.Count()); + Test.Assert(array.Append(0)); + Test.AssertEquals(1, array.Count()); + Test.Assert(array.Append(1)); + Test.AssertEquals(2, array.Count()); + Test.Assert(array.Append(5)); + Test.AssertEquals(3, array.Count()); + Test.Assert(array.Append(42)); + Test.AssertEquals(4, array.Count()); + + + Test.AssertEquals((byte)array[0], 0); + Test.AssertEquals((byte)array[1], 1); + Test.AssertEquals((byte)array[2], 5); + Test.AssertEquals((byte)array[3], 42); + + array[0] = 155; + array[1] = 42; + Test.AssertEquals(4, array.Count()); + + Test.AssertEquals((byte)array[0], 155); + Test.AssertEquals((byte)array[1], 42); + Test.AssertEquals((byte)array[2], 5); + Test.AssertEquals((byte)array[3], 42); + + Test.AssertEquals("[155, 42, 5, 42]", array.ToString()); + + Test.AssertRaises(() => array[0] = 123214); + } + } + + public static void TestValueArrayOfInts() + { using(Eina.Value array = new Eina.Value(Eina.ValueType.Array, Eina.ValueType.Int32)) { Test.AssertEquals(0, array.Count()); Test.Assert(array.Append(0)); @@ -633,12 +700,52 @@ public static class TestEinaValue { Test.AssertEquals("[1984, -42, 5, 42]", array.ToString()); } + } + + public static void TestValueArrayOfInt64s() + { + using(Eina.Value array = new Eina.Value(Eina.ValueType.Array, Eina.ValueType.Int64)) { + Test.AssertEquals(0, array.Count()); + Test.Assert(array.Append(0)); + Test.AssertEquals(1, array.Count()); + Test.Assert(array.Append(10000000000)); + Test.AssertEquals(2, array.Count()); + Test.Assert(array.Append(5)); + Test.AssertEquals(3, array.Count()); + Test.Assert(array.Append(42)); + Test.AssertEquals(4, array.Count()); + + + Test.AssertEquals((long)array[0], 0); + Test.AssertEquals((long)array[1], 10000000000); + Test.AssertEquals((long)array[2], 5); + Test.AssertEquals((long)array[3], 42); + + array[0] = 1984; + array[1] = -42; + Test.AssertEquals(4, array.Count()); + + Test.AssertEquals((long)array[0], 1984); + Test.AssertEquals((long)array[1], -42); + Test.AssertEquals((long)array[2], 5); + Test.AssertEquals((long)array[3], 42); + + Test.AssertEquals("[1984, -42, 5, 42]", array.ToString()); + } + } + + public static void TestValueArrayOfUInts() + { using(Eina.Value array = new Eina.Value(Eina.ValueType.Array, Eina.ValueType.UInt32)) { Test.Assert(array.Append(2)); Test.AssertEquals((uint)array[0], (uint)2); Test.AssertRaises(() => array[0] = -1); } + } + + public static void TestValueArrayOfStrings() + { using(Eina.Value array = new Eina.Value(Eina.ValueType.Array, Eina.ValueType.String)) {