diff options
author | Owen Fraser-Green <owen@discobabe.net> | 2004-03-23 12:10:32 +0000 |
---|---|---|
committer | Owen Fraser-Green <owen@discobabe.net> | 2004-03-23 12:10:32 +0000 |
commit | c916037773d7d3d8d37ca2c5a8899b7b728e377d (patch) | |
tree | 21c37372ab9795583e724e8459578b7fe0be330b /mono/DBusType/Array.cs | |
parent | 2195cf0dbde2ae26b5a684c6d914c1711f44c28d (diff) |
First checkin of the Mono bindings.
Diffstat (limited to 'mono/DBusType/Array.cs')
-rw-r--r-- | mono/DBusType/Array.cs | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/mono/DBusType/Array.cs b/mono/DBusType/Array.cs new file mode 100644 index 00000000..3bce3afa --- /dev/null +++ b/mono/DBusType/Array.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections; +using System.Runtime.InteropServices; +using System.Reflection.Emit; + +using DBus; + +namespace DBus.DBusType +{ + /// <summary> + /// Array. + /// </summary> + public class Array : IDBusType + { + public const char Code = 'a'; + private System.Array val; + private ArrayList elements; + private Type elementType; + + private Array() + { + } + + public Array(System.Array val) + { + this.val = val; + this.elementType = Arguments.MatchType(val.GetType().UnderlyingSystemType); + } + + public Array(IntPtr iter) + { + IntPtr arrayIter = Marshal.AllocCoTaskMem(Arguments.DBusMessageIterSize); + + int elementTypeCode; + dbus_message_iter_init_array_iterator(iter, arrayIter, out elementTypeCode); + this.elementType = (Type) Arguments.DBusTypes[(char) elementTypeCode]; + + elements = new ArrayList(); + + do { + object [] pars = new Object[1]; + pars[0] = arrayIter; + DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(elementType, pars); + elements.Add(dbusType); + } while (dbus_message_iter_next(arrayIter)); + + Marshal.FreeCoTaskMem(arrayIter); + } + + public void Append(IntPtr iter) + { + IntPtr arrayIter = Marshal.AllocCoTaskMem(Arguments.DBusMessageIterSize); + + if (!dbus_message_iter_append_array(iter, + arrayIter, + (int) Arguments.GetCode(this.elementType))) { + throw new ApplicationException("Failed to append INT32 argument:" + val); + } + + foreach (object element in this.val) { + object [] pars = new Object[1]; + pars[0] = element; + DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(elementType, pars); + dbusType.Append(arrayIter); + } + + Marshal.FreeCoTaskMem(arrayIter); + } + + public static bool Suits(System.Type type) + { + if (type.IsArray) { + return true; + } + + return false; + } + + public static void EmitMarshalIn(ILGenerator generator, Type type) + { + if (type.IsByRef) { + generator.Emit(OpCodes.Ldind_Ref); + } + } + + public static void EmitMarshalOut(ILGenerator generator, Type type, bool isReturn) + { + generator.Emit(OpCodes.Castclass, type); + if (!isReturn) { + generator.Emit(OpCodes.Stind_Ref); + } + } + + public object Get() + { + throw new ArgumentException("Cannot call Get on an Array without specifying type."); + } + + public object Get(System.Type type) + { + if (Arguments.Suits(elementType, type.UnderlyingSystemType)) { + this.val = System.Array.CreateInstance(type.UnderlyingSystemType, elements.Count); + int i = 0; + foreach (DBusType.IDBusType element in elements) { + this.val.SetValue(element.Get(type.UnderlyingSystemType), i++); + } + } else { + throw new ArgumentException("Cannot cast DBus.Type.Array to type '" + type.ToString() + "'"); + } + + return this.val; + } + + [DllImport("dbus-1")] + private extern static void dbus_message_iter_init_array_iterator(IntPtr iter, + IntPtr arrayIter, + out int elementType); + + [DllImport("dbus-1")] + private extern static bool dbus_message_iter_append_array(IntPtr iter, + IntPtr arrayIter, + int elementType); + + [DllImport("dbus-1")] + private extern static bool dbus_message_iter_has_next(IntPtr iter); + + [DllImport("dbus-1")] + private extern static bool dbus_message_iter_next(IntPtr iter); + } +} |