summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2017-07-05 21:50:58 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2017-07-13 19:00:53 -0300
commit7cc5a2224c9bd74394c75f4d04cf0bb626471eed (patch)
tree2b3d8414d606801e55049504067836ac7b2387c4
parent4502ce658f8fd6717ee5c98d488539a7f3a1b2cf (diff)
eina_mono: Add first iteration of Eina.Value
Currently supporting native types int(32), uint(32), string and array. To be implemented: - Other value types (char, etc) - List - Hash - Structs - Blob
-rw-r--r--src/Makefile_Efl_Mono.am6
-rw-r--r--src/bindings/mono/eina_mono/eina_value.cs623
-rw-r--r--src/lib/efl_mono/efl_custom_exports_mono.c82
-rw-r--r--src/tests/efl_mono/Value.cs403
4 files changed, 1112 insertions, 2 deletions
diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am
index 14edee9649..4e5639834b 100644
--- a/src/Makefile_Efl_Mono.am
+++ b/src/Makefile_Efl_Mono.am
@@ -141,7 +141,8 @@ efl_eina_mono_files = \
141 bindings/mono/eina_mono/eina_binbuf.cs \ 141 bindings/mono/eina_mono/eina_binbuf.cs \
142 bindings/mono/eina_mono/eina_slice.cs \ 142 bindings/mono/eina_mono/eina_slice.cs \
143 bindings/mono/eina_mono/eina_stringshare.cs \ 143 bindings/mono/eina_mono/eina_stringshare.cs \
144 bindings/mono/eina_mono/eina_error.cs 144 bindings/mono/eina_mono/eina_error.cs \
145 bindings/mono/eina_mono/eina_value.cs
145 146
146lib_efl_mono_libefl_mono_dll_SOURCES = \ 147lib_efl_mono_libefl_mono_dll_SOURCES = \
147 bindings/mono/efl_mono/efl_all.cs \ 148 bindings/mono/efl_mono/efl_all.cs \
@@ -196,7 +197,8 @@ tests_efl_mono_efl_mono_exe_SOURCES = \
196 tests/efl_mono/Events.cs \ 197 tests/efl_mono/Events.cs \
197 tests/efl_mono/FunctionPointers.cs \ 198 tests/efl_mono/FunctionPointers.cs \
198 tests/efl_mono/Strings.cs \ 199 tests/efl_mono/Strings.cs \
199 tests/efl_mono/TestUtils.cs 200 tests/efl_mono/TestUtils.cs \
201 tests/efl_mono/Value.cs
200 202
201 203
202tests/efl_mono/efl_mono.exe$(EXEEXT): $(tests_efl_mono_efl_mono_exe_SOURCES) tests/efl_mono/$(am__dirstamp) lib/efl_mono/libefl_mono.dll tests/efl_mono/libefl_mono_test.dll 204tests/efl_mono/efl_mono.exe$(EXEEXT): $(tests_efl_mono_efl_mono_exe_SOURCES) tests/efl_mono/$(am__dirstamp) lib/efl_mono/libefl_mono.dll tests/efl_mono/libefl_mono_test.dll
diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs
new file mode 100644
index 0000000000..574d513f8c
--- /dev/null
+++ b/src/bindings/mono/eina_mono/eina_value.cs
@@ -0,0 +1,623 @@
1#define CODE_ANALYSIS
2
3using System;
4using System.Runtime.InteropServices;
5using System.Collections.Generic;
6using System.Security.Permissions;
7using System.Security;
8using System.Diagnostics.CodeAnalysis;
9using System.Runtime.Serialization;
10
11using static eina.EinaNative.UnsafeNativeMethods;
12using static eina.TraitFunctions;
13
14
15namespace eina {
16
17namespace EinaNative {
18
19[SuppressUnmanagedCodeSecurityAttribute]
20static internal class UnsafeNativeMethods {
21
22 [DllImport("eina")]
23 [return: MarshalAsAttribute(UnmanagedType.U1)]
24 internal static extern bool eina_value_convert(IntPtr handle, IntPtr convert);
25
26 // Wrapped and helper methods
27 [DllImport("eflcustomexportsmono")]
28 [return: MarshalAsAttribute(UnmanagedType.U1)]
29 internal static extern int eina_value_sizeof();
30
31 [DllImport("eflcustomexportsmono", CharSet=CharSet.Auto)]
32 [return: MarshalAsAttribute(UnmanagedType.U1)]
33 internal static extern bool eina_value_set_wrapper(IntPtr handle, string value);
34
35 [DllImport("eflcustomexportsmono")]
36 [return: MarshalAsAttribute(UnmanagedType.U1)]
37 internal static extern bool eina_value_set_wrapper(IntPtr handle, int value);
38
39 [DllImport("eflcustomexportsmono")]
40 [return: MarshalAsAttribute(UnmanagedType.U1)]
41 internal static extern bool eina_value_set_wrapper(IntPtr handle, uint value);
42
43 [DllImport("eflcustomexportsmono")]
44 [return: MarshalAsAttribute(UnmanagedType.U1)]
45 internal static extern bool eina_value_setup_wrapper(IntPtr handle, IntPtr type);
46
47 [DllImport("eflcustomexportsmono")]
48 internal static extern void eina_value_flush_wrapper(IntPtr handle);
49
50 [DllImport("eflcustomexportsmono")]
51 internal static extern IntPtr eina_value_type_get_wrapper(IntPtr handle);
52
53 [DllImport("eflcustomexportsmono")]
54 [return: MarshalAsAttribute(UnmanagedType.U1)]
55 internal static extern bool eina_value_get_wrapper(IntPtr handle, out IntPtr output);
56
57 [DllImport("eflcustomexportsmono")]
58 internal static extern int eina_value_compare_wrapper(IntPtr handle, IntPtr other);
59
60 [DllImport("eina", CharSet=CharSet.Auto)]
61 internal static extern String eina_value_to_string(IntPtr handle); // We take ownership of the returned string.
62
63 [DllImport("eflcustomexportsmono")]
64 [return: MarshalAsAttribute(UnmanagedType.U1)]
65 internal static extern bool eina_value_array_setup_wrapper(IntPtr handle, IntPtr subtype, uint step);
66
67 [DllImport("eflcustomexportsmono")]
68 [return: MarshalAsAttribute(UnmanagedType.U1)]
69 internal static extern bool eina_value_array_append_wrapper(IntPtr handle, int data);
70
71 [DllImport("eflcustomexportsmono")]
72 [return: MarshalAsAttribute(UnmanagedType.U1)]
73 internal static extern bool eina_value_array_get_wrapper(IntPtr handle, int index, out IntPtr output);
74
75 [DllImport("eflcustomexportsmono")]
76 [return: MarshalAsAttribute(UnmanagedType.U1)]
77 internal static extern bool eina_value_array_set_wrapper(IntPtr handle, int index, IntPtr value);
78
79 [DllImport("eflcustomexportsmono")]
80 internal static extern IntPtr eina_value_array_subtype_get_wrapper(IntPtr handle);
81
82 [DllImport("eflcustomexportsmono")]
83 internal static extern uint eina_value_array_count_wrapper(IntPtr handle);
84
85 // Supported types
86 [DllImport("eflcustomexportsmono")]
87 internal static extern IntPtr type_int32();
88 [DllImport("eflcustomexportsmono")]
89 internal static extern IntPtr type_uint32();
90 [DllImport("eflcustomexportsmono")]
91 internal static extern IntPtr type_string();
92 [DllImport("eflcustomexportsmono")]
93 internal static extern IntPtr type_array();
94}
95}
96
97/// <summary>Exception for trying to access flushed values.</summary>
98[Serializable]
99public class ValueFlushedException : Exception
100{
101 /// <summary> Default constructor.</summary>
102 public ValueFlushedException() : base () { }
103 /// <summary> Most commonly used contructor.</summary>
104 public ValueFlushedException(string msg) : base(msg) { }
105 /// <summary> Wraps an inner exception.</summary>
106 public ValueFlushedException(string msg, Exception inner) : base(msg, inner) { }
107 /// <summary> Serializable constructor.</summary>
108 protected ValueFlushedException(SerializationInfo info, StreamingContext context) : base(info, context) { }
109}
110
111/// <summary>Exception for failures when setting an container item.</summary>
112[Serializable]
113public class SetItemFailedException : Exception
114{
115 /// <summary> Default constructor.</summary>
116 public SetItemFailedException() : base () { }
117 /// <summary> Most commonly used contructor.</summary>
118 public SetItemFailedException(string msg) : base(msg) { }
119 /// <summary> Wraps an inner exception.</summary>
120 public SetItemFailedException(string msg, Exception inner) : base(msg, inner) { }
121 /// <summary> Serializable constructor.</summary>
122 protected SetItemFailedException(SerializationInfo info, StreamingContext context) : base(info, context) { }
123}
124
125/// <summary>Managed-side Enum to represent Eina_Value_Type constants</summary>
126public enum ValueType {
127 /// <summary>Signed 32 bit integer. Same as 'int'</summary>
128 Int32,
129 /// <summary>Unsigned 32 bit integer. Same as 'uint'</summary>
130 UInt32,
131 /// <summary>Strings</summary>
132 String,
133 /// <summary>Array of Value items.</summary>
134 Array,
135 /// <summary>Linked list of Value items.</summary>
136 List,
137 /// <summary>Map of string keys to Value items.</summary>
138 Hash,
139}
140
141static class ValueTypeMethods {
142 public static bool IsNumeric(this ValueType val)
143 {
144 switch (val) {
145 case ValueType.Int32:
146 case ValueType.UInt32:
147 return true;
148 default:
149 return false;
150 }
151 }
152
153 public static bool IsString(this ValueType val)
154 {
155 switch(val) {
156 case ValueType.String:
157 return true;
158 default:
159 return false;
160 }
161 }
162
163 public static bool IsContainer(this ValueType val)
164 {
165 switch(val) {
166 case ValueType.Array:
167 case ValueType.List:
168 case ValueType.Hash:
169 return true;
170 default:
171 return false;
172 }
173 }
174}
175static class ValueTypeBridge
176{
177 private static Dictionary<ValueType, IntPtr> ManagedToNative = new Dictionary<ValueType, IntPtr>();
178 private static Dictionary<IntPtr, ValueType> NativeToManaged = new Dictionary<IntPtr, ValueType>();
179 private static bool TypesLoaded; // CLR defaults to false;
180
181 public static ValueType GetManaged(IntPtr native)
182 {
183 if (!TypesLoaded)
184 LoadTypes();
185
186 return NativeToManaged[native];
187 }
188
189 public static IntPtr GetNative(ValueType valueType)
190 {
191 if (!TypesLoaded)
192 LoadTypes();
193
194 return ManagedToNative[valueType];
195 }
196
197 private static void LoadTypes()
198 {
199 ManagedToNative.Add(ValueType.Int32, type_int32());
200 NativeToManaged.Add(type_int32(), ValueType.Int32);
201
202 ManagedToNative.Add(ValueType.UInt32, type_uint32());
203 NativeToManaged.Add(type_uint32(), ValueType.UInt32);
204
205 ManagedToNative.Add(ValueType.String, type_string());
206 NativeToManaged.Add(type_string(), ValueType.String);
207
208 ManagedToNative.Add(ValueType.Array, type_array());
209 NativeToManaged.Add(type_array(), ValueType.Array);
210
211 TypesLoaded = true;
212 }
213}
214
215/// <summary>Wrapper around Eina_Value generic storage.
216///
217/// <para>Eina_Value is EFL's main workhorse to deal with storing generic data in
218/// an uniform way.</para>
219///
220/// <para>It comes with predefined types for numbers, strings, array, list, hash,
221/// blob and structs. It is able to convert between data types, including
222/// to string.</para>
223/// </summary>
224public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
225{
226
227 // Unmanaged type - Managed type mapping
228 // EINA_VALUE_TYPE_UCHAR: unsigned char -- byte
229 // EINA_VALUE_TYPE_USHORT: unsigned short -- ushort
230 // Ok EINA_VALUE_TYPE_UINT: unsigned int -- uint
231 // EINA_VALUE_TYPE_ULONG: unsigned long -- ulong
232 // EINA_VALUE_TYPE_UINT64: uint64_t -- ulong
233 // EINA_VALUE_TYPE_CHAR: char -- sbyte
234 // EINA_VALUE_TYPE_SHORT: short -- short
235 // Ok EINA_VALUE_TYPE_INT: int -- int
236 // EINA_VALUE_TYPE_LONG: long -- long
237 // EINA_VALUE_TYPE_INT64: int64_t -- long
238 // EINA_VALUE_TYPE_FLOAT: float -- float
239 // EINA_VALUE_TYPE_DOUBLE: double -- double
240 // EINA_VALUE_TYPE_STRINGSHARE: const char * -- string
241 // Ok EINA_VALUE_TYPE_STRING: const char * -- string
242 // EINA_VALUE_TYPE_ARRAY: Eina_Value_Array -- eina.Array?
243 // EINA_VALUE_TYPE_LIST: Eina_Value_List -- eina.List?
244 // EINA_VALUE_TYPE_HASH: Eina_Value_Hash -- eina.Hash?
245 // EINA_VALUE_TYPE_TIMEVAL: struct timeval -- FIXME
246 // EINA_VALUE_TYPE_BLOB: Eina_Value_Blob -- FIXME
247 // EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct -- FIXME
248
249
250 private IntPtr Handle;
251 private bool Disposed;
252 private bool Flushed;
253
254 /// <summary>Create a wrapper around the given value storage.</summary>
255 /* public Value(IntPtr Ptr) */
256 /* { */
257 /* if (!TypesLoaded) */
258 /* LoadTypes(); */
259
260 /* this.Handle = Ptr; */
261 /* } */
262
263 /// <summary>Creates a new value storage for values of type 'type'.</summary>
264 public Value(ValueType type)
265 {
266 if (type.IsContainer())
267 throw new ArgumentException("To use container types you must provide a subtype");
268 this.Handle = Marshal.AllocHGlobal(eina_value_sizeof());
269 Setup(type);
270 }
271
272 /// <summary>Constructor for container values, like Array, Hash.</summary>
273 public Value(ValueType containerType, ValueType subtype, uint step=0)
274 {
275 if (!containerType.IsContainer())
276 throw new ArgumentException("First type must be a container type.");
277
278 this.Handle = Marshal.AllocHGlobal(eina_value_sizeof());
279
280 Setup(containerType, subtype, step);
281 }
282
283 /// <summary>Public method to explicitly free the wrapped eina value.</summary>
284 public void Dispose()
285 {
286 Dispose(true);
287 GC.SuppressFinalize(this);
288 }
289
290 /// <summary>Actually free the wrapped eina value. Can be called from Dispose() or through the GC.</summary>
291 protected virtual void Dispose(bool disposing)
292 {
293 if (!Disposed && (Handle != IntPtr.Zero)) {
294 if (!Flushed)
295 eina_value_flush_wrapper(this.Handle);
296
297 Marshal.FreeHGlobal(this.Handle);
298 }
299 Disposed = true;
300 }
301
302 /// <summary>Finalizer to be called from the Garbage Collector.</summary>
303 ~Value()
304 {
305 Dispose(false);
306 }
307
308 /// <summary>Returns the native handle wrapped by this object.</summary>
309 public IntPtr NativeHandle()
310 {
311 if (Disposed)
312 throw new ObjectDisposedException(base.GetType().Name);
313 return this.Handle;
314 }
315
316 /// <summary>Converts this storage to type 'type'</summary>
317 public bool Setup(ValueType type)
318 {
319 if (Disposed)
320 throw new ObjectDisposedException(base.GetType().Name);
321
322 if (type.IsContainer())
323 throw new ArgumentException("To setup a container you must provide a subtype.");
324
325 bool ret = eina_value_setup_wrapper(this.Handle, ValueTypeBridge.GetNative(type));
326 if (ret)
327 Flushed = false;
328 return ret;
329 }
330
331 public bool Setup(ValueType containerType, ValueType subtype, uint step=0) {
332 IntPtr native_subtype = ValueTypeBridge.GetNative(subtype);
333 bool ret = false;
334 switch (containerType) {
335 case ValueType.Array:
336 ret = eina_value_array_setup_wrapper(this.Handle, native_subtype, step);
337 break;
338 }
339
340 if (ret)
341 Flushed = false;
342
343 return ret;
344 }
345
346 private void SanityChecks()
347 {
348 if (Disposed)
349 throw new ObjectDisposedException(GetType().Name);
350 if (Flushed)
351 throw new ValueFlushedException("Trying to use value that has been flushed. Setup it again.");
352 }
353
354 /// <summary>Releases the memory stored by this value. It can be reused by calling setup again.
355 /// </summary>
356 public void Flush()
357 {
358 if (Disposed)
359 throw new ObjectDisposedException(GetType().Name);
360 eina_value_flush_wrapper(this.Handle);
361 Flushed = true;
362 }
363
364 /// <summary>Stores the given uint value.</summary>
365 public bool Set(uint value)
366 {
367 SanityChecks();
368 if (!GetValueType().IsNumeric())
369 throw (new ArgumentException(
370 "Trying to set numeric value on a non-numeric eina.Value"));
371 return eina_value_set_wrapper(this.Handle, value);
372 }
373
374 /// <summary>Stores the given int value.</summary>
375 public bool Set(int value)
376 {
377 SanityChecks();
378 if (!GetValueType().IsNumeric())
379 throw (new ArgumentException(
380 "Trying to set numeric value on a non-numeric eina.Value"));
381 return eina_value_set_wrapper(this.Handle, value);
382 }
383
384 /// <summary>Stores the given string value.</summary>
385 public bool Set(string value)
386 {
387 SanityChecks();
388 if (!GetValueType().IsString())
389 throw (new ArgumentException(
390 "Trying to set non-string value on a string eina.Value"));
391 // No need to worry about ownership as eina_value_set will copy the passed string.
392 return eina_value_set_wrapper(this.Handle, value);
393 }
394
395 /// <summary>Gets the currently stored value as an int.</summary>
396 public bool Get(out int value)
397 {
398 SanityChecks();
399 IntPtr output = IntPtr.Zero;
400 if (!eina_value_get_wrapper(this.Handle, out output)) {
401 value = 0;
402 return false;
403 }
404 value = Convert.ToInt32(output.ToInt64());
405 return true;
406 }
407
408 /// <summary>Gets the currently stored value as an uint.</summary>
409 public bool Get(out uint value)
410 {
411 SanityChecks();
412 IntPtr output = IntPtr.Zero;
413 if (!eina_value_get_wrapper(this.Handle, out output)) {
414 value = 0;
415 return false;
416 }
417 value = Convert.ToUInt32(output.ToInt64());
418 return true;
419 }
420
421 /// <summary>Gets the currently stored value as a string.</summary>
422 public bool Get(out string value)
423 {
424 SanityChecks();
425 IntPtr output = IntPtr.Zero;
426 if (!eina_value_get_wrapper(this.Handle, out output)) {
427 value = String.Empty;
428 return false;
429 }
430 value = Marshal.PtrToStringAuto(output);
431 return true;
432 }
433
434 /// <summary>Gets the 'Type' this value is currently configured to store.</summary>
435 public ValueType GetValueType()
436 {
437 if (Disposed)
438 throw new ObjectDisposedException(base.GetType().Name);
439 IntPtr native_type = eina_value_type_get_wrapper(this.Handle);
440 return ValueTypeBridge.GetManaged(native_type);
441 }
442
443 /// <summary>Converts the value on this storage to the type of 'target' and stores
444 /// the result in 'target'.</summary>
445 public bool ConvertTo(Value target)
446 {
447 if (target == null)
448 return false;
449
450 SanityChecks();
451
452 return eina_value_convert(this.Handle, target.Handle);
453 }
454
455 /// <summary>Compare two eina values.</summary>
456 public int CompareTo(Value other)
457 {
458 if (other == null)
459 return 1;
460 SanityChecks();
461 other.SanityChecks();
462 return eina_value_compare_wrapper(this.Handle, other.Handle);
463 }
464
465 public int Compare(Value other)
466 {
467 return this.CompareTo(other);
468 }
469
470 public override bool Equals(object obj)
471 {
472 if (obj == null)
473 return false;
474
475 Value v = obj as Value;
476 if (v == null)
477 return false;
478
479 return this.Equals(v);
480 }
481
482 public bool Equals(Value other)
483 {
484 try {
485 return this.CompareTo(other) == 0;
486 } catch (ObjectDisposedException) {
487 return false;
488 } catch (ValueFlushedException) {
489 return false;
490 }
491 }
492
493 public override int GetHashCode()
494 {
495 return this.Handle.ToInt32();
496 }
497
498 public static bool operator==(Value x, Value y)
499 {
500 if (object.ReferenceEquals(x, null))
501 return object.ReferenceEquals(y, null);
502
503 return x.Equals(y);
504 }
505
506 public static bool operator!=(Value x, Value y)
507 {
508 if (object.ReferenceEquals(x, null))
509 return !object.ReferenceEquals(y, null);
510 return !x.Equals(y);
511 }
512
513 public static bool operator>(Value x, Value y)
514 {
515 if (object.ReferenceEquals(x, null) || object.ReferenceEquals(y, null))
516 return false;
517 return x.CompareTo(y) > 0;
518 }
519
520 public static bool operator<(Value x, Value y)
521 {
522 if (object.ReferenceEquals(x, null) || object.ReferenceEquals(y, null))
523 return false;
524 return x.CompareTo(y) < 0;
525 }
526
527
528 /// <summary>Converts value to string.</summary>
529 public override String ToString()
530 {
531 SanityChecks();
532 return eina_value_to_string(this.Handle);
533 }
534
535 // Array methods
536 public bool Append(object o) {
537 SanityChecks();
538 return eina_value_array_append_wrapper(this.Handle, (int)o);
539 }
540
541 public object this[int i]
542 {
543 get {
544 SanityChecks();
545
546 IntPtr output = IntPtr.Zero;
547 // FIXME Support other integer-addressable containers (list)
548 if (!eina_value_array_get_wrapper(this.Handle, i, out output))
549 return null;
550 return UnMarshalPtr(output);
551 }
552 set {
553 SanityChecks();
554 IntPtr marshalled_value = MarshalValue(value);
555
556 if (!eina_value_array_set_wrapper(this.Handle, i, marshalled_value)) {
557
558 if (GetValueSubType().IsString())
559 Marshal.FreeHGlobal(marshalled_value);
560
561 uint size = eina_value_array_count_wrapper(this.Handle);
562
563 if (i >= size)
564 throw new System.ArgumentOutOfRangeException($"Index {i} is larger than max array index {size-1}");
565
566 throw new SetItemFailedException($"Failed to set item at index {i}");
567 }
568
569 if (GetValueSubType().IsString())
570 Marshal.FreeHGlobal(marshalled_value);
571 }
572 }
573
574 public ValueType GetValueSubType()
575 {
576 SanityChecks();
577
578 IntPtr native_subtype = eina_value_array_subtype_get_wrapper(this.Handle);
579 return ValueTypeBridge.GetManaged(native_subtype);
580 }
581
582 private IntPtr MarshalValue(object value)
583 {
584 switch(GetValueSubType()) {
585 case ValueType.Int32:
586 {
587 int x = (int)value;
588 return new IntPtr(x);
589 }
590 case ValueType.UInt32:
591 {
592 uint x = (uint)value;
593 return new IntPtr((int)x);
594 }
595 case ValueType.String:
596 {
597 string x = value as string;
598 if (x == null)
599 return IntPtr.Zero;
600 // Warning: Caller will have ownership of this memory.
601 return Marshal.StringToHGlobalAnsi(x);
602 }
603 default:
604 return IntPtr.Zero;
605 }
606 }
607
608 private object UnMarshalPtr(IntPtr data)
609 {
610 switch(GetValueSubType()) {
611 case ValueType.Int32:
612 return Convert.ToInt32(data.ToInt64());
613 case ValueType.UInt32:
614 return Convert.ToUInt32(data.ToInt64());
615 case ValueType.String:
616 return Marshal.PtrToStringAuto(data);
617 default:
618 return null;
619 }
620 }
621
622}
623}
diff --git a/src/lib/efl_mono/efl_custom_exports_mono.c b/src/lib/efl_mono/efl_custom_exports_mono.c
index 27fe157a56..dc6bb81bd0 100644
--- a/src/lib/efl_mono/efl_custom_exports_mono.c
+++ b/src/lib/efl_mono/efl_custom_exports_mono.c
@@ -267,3 +267,85 @@ EAPI Eina_Iterator *eina_hash_iterator_ptr_key_wrapper_new_custom_export_mono(co
267 return eina_iterator_wrapper_new_mono(eina_hash_iterator_key_new(hash), FUNC_ITERATOR_NEXT(eina_hash_iterator_ptr_key_wrapper_next_mono)); 267 return eina_iterator_wrapper_new_mono(eina_hash_iterator_key_new(hash), FUNC_ITERATOR_NEXT(eina_hash_iterator_ptr_key_wrapper_next_mono));
268} 268}
269 269
270// Eina Value //
271EAPI const Eina_Value_Type *type_int32() {
272 return EINA_VALUE_TYPE_INT;
273}
274EAPI const Eina_Value_Type *type_uint32() {
275 return EINA_VALUE_TYPE_UINT;
276}
277EAPI const Eina_Value_Type *type_string() {
278 return EINA_VALUE_TYPE_STRING;
279}
280EAPI const Eina_Value_Type *type_array() {
281 return EINA_VALUE_TYPE_ARRAY;
282}
283
284EAPI size_t eina_value_sizeof()
285{
286 return sizeof(Eina_Value);
287}
288
289EAPI Eina_Bool eina_value_set_wrapper(Eina_Value *value, va_list argp)
290{
291 return eina_value_set(value, argp);
292}
293
294EAPI Eina_Bool eina_value_setup_wrapper(Eina_Value *value,
295 const Eina_Value_Type *type)
296{
297 return eina_value_setup(value, type);
298}
299
300EAPI void eina_value_flush_wrapper(Eina_Value *value)
301{
302 eina_value_flush(value);
303}
304
305EAPI const Eina_Value_Type *eina_value_type_get_wrapper(const Eina_Value *value)
306{
307 return eina_value_type_get(value);
308}
309
310EAPI Eina_Bool eina_value_get_wrapper(const Eina_Value *value, void *output)
311{
312 return eina_value_get(value, output);
313}
314
315EAPI int eina_value_compare_wrapper(const Eina_Value *this, const Eina_Value *other)
316{
317 return eina_value_compare(this, other);
318}
319
320EAPI Eina_Bool eina_value_array_setup_wrapper(Eina_Value *array, const Eina_Value_Type *subtype, unsigned int step)
321{
322 return eina_value_array_setup(array, subtype, step);
323}
324
325EAPI Eina_Bool eina_value_array_append_wrapper(Eina_Value *array, va_list argp)
326{
327 return eina_value_array_append(array, argp);
328}
329
330EAPI Eina_Bool eina_value_array_get_wrapper(const Eina_Value *array, int i, void *output)
331{
332 return eina_value_array_get(array, i, output);
333}
334
335EAPI Eina_Bool eina_value_array_set_wrapper(const Eina_Value *array, int i, void *value)
336{
337 return eina_value_array_set(array, i, value);
338}
339
340// Not actually a wrapper, but keeping the naming convention for functions on this file.
341EAPI const Eina_Value_Type* eina_value_array_subtype_get_wrapper(const Eina_Value *array)
342{
343 Eina_Value_Array array_value;
344 eina_value_get(array, &array_value);
345 return array_value.subtype;
346}
347
348EAPI unsigned int eina_value_array_count_wrapper(const Eina_Value *array)
349{
350 return eina_value_array_count(array);
351}
diff --git a/src/tests/efl_mono/Value.cs b/src/tests/efl_mono/Value.cs
new file mode 100644
index 0000000000..4a7aaf06ec
--- /dev/null
+++ b/src/tests/efl_mono/Value.cs
@@ -0,0 +1,403 @@
1#define CODE_ANALYSIS
2
3#pragma warning disable 1591
4
5using System;
6using System.Diagnostics.CodeAnalysis;
7
8namespace TestSuite {
9
10
11[SuppressMessage("Gendarme.Rules.Portability", "DoNotHardcodePathsRule")]
12public static class TestEinaValue {
13 public static void TestIntSimple()
14 {
15 using (eina.Value v = new eina.Value(eina.ValueType.Int32)) {
16 Test.Assert(v.Set(32));
17 int x;
18 Test.Assert(v.Get(out x));
19 Test.AssertEquals(32, x);
20 }
21 }
22
23 public static void TestUIntSimple()
24 {
25 using (eina.Value v = new eina.Value(eina.ValueType.Int32)) {
26 Test.Assert(v.Set(0xdeadbeef));
27 uint x = 0;
28 Test.Assert(v.Get(out x));
29 Test.AssertEquals(0xdeadbeef, x);
30 }
31 }
32
33 public static void TestStringSimple()
34 {
35 using (eina.Value v = new eina.Value(eina.ValueType.String)) {
36 string expected_str = "Hello";
37 Test.Assert(v.Set(expected_str));
38 string str = null;
39 Test.Assert(v.Get(out str));
40 Test.AssertEquals(expected_str, str);
41 }
42 }
43
44 public static void TestSetWrongType()
45 {
46 using (eina.Value v = new eina.Value(eina.ValueType.String)) {
47 Test.AssertRaises<ArgumentException>(() => v.Set(42));
48 Test.AssertNotRaises<ArgumentException>(() => v.Set("Wumpus"));
49 Test.Assert(v.Setup(eina.ValueType.Int32));
50 Test.AssertRaises<ArgumentException>(() => v.Set("Wat?"));
51 Test.AssertNotRaises<ArgumentException>(() => v.Set(1984));
52 }
53 }
54
55 public static void TestValueSetup()
56 {
57 using (eina.Value v = new eina.Value(eina.ValueType.Int32)) {
58 Test.Assert(v.Set(44));
59 int x = 0;
60 Test.Assert(v.Get(out x));
61 Test.AssertEquals(44, x);
62 v.Setup(eina.ValueType.String);
63
64 string str = "Hello";
65 Test.Assert(v.Get(out str));
66 Test.AssertNull(str);
67 }
68 }
69
70 public static void TestValueFlush()
71 {
72 using (eina.Value v = new eina.Value(eina.ValueType.Int32)) {
73 Test.Assert(v.Set(44));
74 v.Flush();
75
76 int x;
77 Test.AssertRaises<eina.ValueFlushedException>(() => v.Get(out x));
78 x = 42;
79 Test.AssertRaises<eina.ValueFlushedException>(() => v.Set(x));
80
81 v.Setup(eina.ValueType.String);
82 Test.AssertNotRaises<eina.ValueFlushedException>(() => v.Set("Hello, EFL"));
83
84 string y = String.Empty;
85 Test.AssertNotRaises<eina.ValueFlushedException>(() => v.Get(out y));
86 v.Flush();
87 Test.AssertRaises<eina.ValueFlushedException>(() => v.Get(out y));
88
89 v.Setup(eina.ValueType.Array, eina.ValueType.UInt32);
90
91 Test.AssertNotRaises<eina.ValueFlushedException>(() =>
92 v.Append(42));
93 v.Flush();
94 Test.AssertRaises<eina.ValueFlushedException>(() =>
95 v.Append(42));
96
97 Test.AssertRaises<eina.ValueFlushedException>(() => v.GetValueSubType());
98
99 }
100 }
101
102 public static void TestValueCompareInts()
103 {
104 using (eina.Value a = new eina.Value(eina.ValueType.Int32))
105 using (eina.Value b = new eina.Value(eina.ValueType.Int32)) {
106 Test.Assert(a.Set(123));
107 Test.Assert(b.Set(123));
108 Test.AssertEquals(0, a.CompareTo(b));
109
110 Test.Assert(a.Set(-10));
111 Test.AssertLessThan(a, b);
112
113 Test.Assert(a.Set(123));
114 Test.Assert(b.Set(10));
115 Test.AssertGreaterThan(a, b);
116 }
117 }
118
119 public static void TestValueComparisonEquals()
120 {
121 using (eina.Value a = new eina.Value(eina.ValueType.Int32))
122 using (eina.Value b = new eina.Value(eina.ValueType.Int32))
123 using (eina.Value c = new eina.Value(eina.ValueType.Int32)) {
124 Test.Assert(a.Set(1));
125 Test.Assert(b.Set(1));
126 Test.Assert(c.Set(1));
127
128 Test.Assert(a.Equals(a), "A equals A");
129 Test.Assert(a.Equals(b) == b.Equals(a), "A equals B == B equals A");
130 Test.Assert(a.Equals(b) == b.Equals(c) == a.Equals(c));
131
132 Test.Assert(b.Set(0));
133 Test.Assert(a.Equals(b) == b.Equals(a), "A equals B == B equals A");
134
135 Test.Assert(a.Equals(null) == false, "A == null");
136 }
137 }
138
139 public static void TestValueComparisonOverloadEquals()
140 {
141 using (eina.Value a = new eina.Value(eina.ValueType.Int32))
142 using (eina.Value b = new eina.Value(eina.ValueType.Int32)) {
143 Test.Assert(a.Set(1));
144 Test.Assert(b.Set(1));
145
146 Test.Assert(a == b);
147 Test.Assert(!(a != b));
148 Test.Assert(b == a);
149 Test.Assert(!(b != a));
150
151 Test.Assert(b.Set(42));
152
153 Test.Assert(a != b);
154 Test.Assert(!(a == b));
155 Test.Assert(b != a);
156 Test.Assert(!(b == a));
157
158 Test.Assert(b.Set(42));
159
160 }
161 }
162
163 public static void TestValueComparisonOverloadLessMore()
164 {
165 using (eina.Value a = new eina.Value(eina.ValueType.Int32))
166 using (eina.Value b = new eina.Value(eina.ValueType.Int32)) {
167 Test.Assert(a.Set(1));
168 Test.Assert(b.Set(0));
169
170 Test.Assert(a > b);
171 Test.Assert(!(a < b));
172 Test.Assert(b < a);
173 Test.Assert(!(b > a));
174 }
175 }
176
177 public static void TestValueCompareStrings()
178 {
179 using (eina.Value a = new eina.Value(eina.ValueType.String))
180 using (eina.Value b = new eina.Value(eina.ValueType.String)) {
181 Test.Assert(a.Set("aaa"));
182 Test.Assert(b.Set("aaa"));
183 Test.AssertEquals(0, a.CompareTo(b));
184
185 Test.Assert(a.Set("abc"));
186 Test.Assert(b.Set("acd"));
187 Test.AssertLessThan(a, b);
188
189 Test.Assert(a.Set("acd"));
190 Test.Assert(b.Set("abc"));
191 Test.AssertGreaterThan(a, b);
192 }
193 }
194
195 public static void TestValueCompareArray()
196 {
197 using(eina.Value a = new eina.Value(eina.ValueType.Array, eina.ValueType.Int32))
198 using(eina.Value b = new eina.Value(eina.ValueType.Array, eina.ValueType.Int32)) {
199
200 Test.AssertEquals(a, b);
201
202 Test.Assert(a.Append(0));
203 Test.Assert(a.Append(1));
204 Test.Assert(a.Append(5));
205 Test.Assert(a.Append(42));
206
207 Test.Assert(b.Append(0));
208 Test.Assert(b.Append(1));
209 Test.Assert(b.Append(5));
210 Test.Assert(b.Append(42));
211
212 Test.AssertEquals(a, b);
213
214 a[0] = -1;
215 Test.Assert(!a.Equals(b));
216 Test.AssertLessThan(a, b);
217
218 a[0] = 10;
219 Test.AssertGreaterThan(a, b);
220
221 a[0] = 0;
222 Test.AssertEquals(a, b);
223
224 // bigger arrays are greater
225 Test.Assert(b.Append(0));
226 Test.AssertLessThan(a, b);
227
228 Test.Assert(a.Append(0));
229 Test.Assert(a.Append(0));
230 Test.AssertGreaterThan(a, b);
231
232 // bigger arrays are greater, unless an element says other wise
233 b[0] = 10;
234 Test.AssertGreaterThan(b, a);
235 }
236 }
237
238 /* public static void TestValueCompareList() */
239 /* { */
240 /* Test.Assert(false, "Implement me."); */
241 /* } */
242
243 /* public static void TestValueCompareHash() */
244 /* { */
245 /* Test.Assert(false, "Implement me."); */
246 /* } */
247
248 public static void TestValueToString()
249 {
250 using(eina.Value a = new eina.Value(eina.ValueType.Int32)) {
251 int i = -12345;
252 string x = $"{i}";
253 Test.Assert(a.Set(i));
254 Test.AssertEquals(x, a.ToString());
255
256 uint u = 0xdeadbeef;
257 x = $"{u}";
258 Test.Assert(a.Setup(eina.ValueType.UInt32));
259 Test.Assert(a.Set(u));
260 Test.AssertEquals(x, a.ToString());
261
262 string s = "Hello, Johnny!";
263 x = s;
264 Test.Assert(a.Setup(eina.ValueType.String));
265 Test.Assert(a.Set(s));
266 Test.AssertEquals(x, a.ToString());
267 }
268 }
269
270 public static void TestValueConvertInt()
271 {
272 using(eina.Value from = new eina.Value(eina.ValueType.Int32))
273 using(eina.Value to = new eina.Value(eina.ValueType.UInt32)) {
274 int source = 0x7FFFFFFF;
275 uint target_uint;
276 int target_int;
277 string target_str;
278 string source_str = $"{source}";
279
280 Test.Assert(from.Set(source));
281 Test.Assert(from.ConvertTo(to));
282 Test.Assert(to.Get(out target_uint));
283 Test.AssertEquals(target_uint, (uint)source);
284
285 Test.Assert(to.Setup(eina.ValueType.Int32));
286 Test.Assert(from.ConvertTo(to));
287 Test.Assert(to.Get(out target_int));
288 Test.AssertEquals(target_int, source);
289
290 Test.Assert(to.Setup(eina.ValueType.String));
291 Test.Assert(from.ConvertTo(to));
292 Test.Assert(to.Get(out target_str));
293 Test.AssertEquals(target_str, source_str);
294
295 // FIXME Add tests for failing ConvertTo() calls when downcasting
296 // to smaller types
297 }
298 }
299
300 public static void TestValueConvertUInt()
301 {
302 using(eina.Value from = new eina.Value(eina.ValueType.UInt32))
303 using(eina.Value to = new eina.Value(eina.ValueType.UInt32)) {
304 uint source = 0xFFFFFFFF;
305 uint target_uint;
306 string target_str;
307 string source_str = $"{source}";
308
309 Test.Assert(from.Set(source));
310 Test.Assert(from.ConvertTo(to));
311 Test.Assert(to.Get(out target_uint));
312 Test.AssertEquals(target_uint, source);
313
314 Test.Assert(to.Setup(eina.ValueType.Int32));
315 Test.Assert(!from.ConvertTo(to));
316
317 Test.Assert(to.Setup(eina.ValueType.String));
318 Test.Assert(from.ConvertTo(to));
319 Test.Assert(to.Get(out target_str));
320 Test.AssertEquals(target_str, source_str);
321
322 // FIXME Add tests for failing ConvertTo() calls when downcasting
323 // to smaller types
324 }
325 }
326
327 public static void TestValueArray() {
328 using(eina.Value array = new eina.Value(eina.ValueType.Array, eina.ValueType.Int32)) {
329 Test.Assert(array.Append(0));
330 Test.Assert(array.Append(1));
331 Test.Assert(array.Append(5));
332 Test.Assert(array.Append(42));
333
334
335 Test.AssertEquals((int)array[0], 0);
336 Test.AssertEquals((int)array[1], 1);
337 Test.AssertEquals((int)array[2], 5);
338 Test.AssertEquals((int)array[3], 42);
339 }
340
341 Test.AssertRaises<ArgumentException>(() => {
342 using(eina.Value array = new eina.Value(eina.ValueType.String, eina.ValueType.String)) { }
343 });
344 }
345
346 public static void TestArrayOutOfBounds() {
347 using(eina.Value array = new eina.Value(eina.ValueType.Array, eina.ValueType.Int32)) {
348 Test.AssertRaises<System.ArgumentOutOfRangeException>(() => array[0] = 1);
349 Test.Assert(array.Append(0));
350 Test.AssertNotRaises<System.ArgumentOutOfRangeException>(() => array[0] = 1);
351 Test.AssertRaises<System.ArgumentOutOfRangeException>(() => array[1] = 1);
352 Test.Assert(array.Append(0));
353 Test.AssertNotRaises<System.ArgumentOutOfRangeException>(() => array[1] = 1);
354
355 }
356 }
357
358 public static void TestValueArraySubType() {
359 using(eina.Value array = new eina.Value(eina.ValueType.Array, eina.ValueType.Int32))
360 Test.AssertEquals(eina.ValueType.Int32, array.GetValueSubType());
361
362 using(eina.Value array = new eina.Value(eina.ValueType.Array, eina.ValueType.UInt32))
363 Test.AssertEquals(eina.ValueType.UInt32, array.GetValueSubType());
364 }
365
366 /* public static void TestValueList() { */
367 /* Test.Assert(false, "Implement me."); */
368 /* } */
369
370 /* public static void TestValueHash() { */
371 /* Test.Assert(false, "Implement me."); */
372 /* } */
373
374 /* public static void TestValueTimeVal() { */
375 /* Test.Assert(false, "Implement me."); */
376 /* } */
377
378 /* public static void TestValueBlob() { */
379 /* Test.Assert(false, "Implement me."); */
380 /* } */
381
382 /* public static void TestValueStruct() { */
383 /* Test.Assert(false, "Implement me."); */
384 /* } */
385
386 /* public static void TestValueArrayOfStructs() { */
387 /* Test.Assert(false, "Implement me."); */
388 /* } */
389
390 /* public static void TestValueOptionalInt() { */
391 /* Test.Assert(false, "Implement me."); */
392 /* } */
393
394 /* public static void TestValueOptionalString() { */
395 /* Test.Assert(false, "Implement me."); */
396 /* } */
397
398 /* public static void TestValueOptionalStructMembers() { */
399 /* Test.Assert(false, "Implement me."); */
400 /* } */
401}
402#pragma warning restore 1591
403}