diff InteropCodeGen/gendotnet.cs @ 0:e1ec7bf71313

Initial commit
author Ivo Smits
date Wed, 04 May 2011 00:59:43 +0200
parents
children f1deea9c97a0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/InteropCodeGen/gendotnet.cs	Wed May 04 00:59:43 2011 +0200
@@ -0,0 +1,407 @@
+//+reference System.dll
+//+reference System.Xml.dll
+using System;
+using System.Xml.XPath;
+using System.IO;
+using System.Collections.Generic;
+class Program {
+	enum ParameterType {
+		In,
+		Out,
+		Reference,
+		Return,
+		Param,
+	}
+	class TypeInfo {
+		public String Name { get; private set; }
+		public String[] Attributes { get; private set; }
+		//public Boolean InputOnly { get; private set; }
+		public String Members { get; set; }
+
+		public TypeInfo(String name, params String[] attributes) {
+			this.Name = name;
+			this.Attributes = attributes;
+		}
+		/*public TypeInfo(String name, bool inputOnly, params String[] attributes)
+			: this(name, attributes) {
+			this.InputOnly = inputOnly;
+		}*/
+		/*public static TypeInfo CreateInterfaceWithMembers(String name, String members) {
+			TypeInfo ret = new TypeInfo(name, "MarshalAs(UnmanagedType.Interface)");
+			ret.Members = members;
+			return ret;
+		}*/
+		//Todo: if attribute mod="string"/"ptr" ...
+		public void WriteDeclaration(TextWriter o, ParameterType vartype) {
+			WriteAttributes(o, vartype);
+			o.Write(Name);
+		}
+		public void WriteAttributes(TextWriter o, ParameterType vartype) {
+			//if (InputOnly && vartype != ParameterType.In) {
+			foreach (String attribute in Attributes) {
+				o.Write("[");
+				if (vartype == ParameterType.Return) o.Write("return: ");
+				else if (vartype == ParameterType.Param) o.Write("param: ");
+				o.Write(attribute);
+				o.Write("] ");
+			}
+			if (vartype == ParameterType.Out) o.Write("out ");
+			else if (vartype == ParameterType.Reference) o.Write("ref ");
+		}
+	}
+	static Dictionary<String, TypeInfo> Types = new Dictionary<string, TypeInfo>();
+	static void InitTypes() {
+		Types.Add("short", new TypeInfo("Int16"));
+		Types.Add("unsigned short", new TypeInfo("UInt16"));
+		Types.Add("unsigned long", new TypeInfo("UInt32"));
+		Types.Add("long long", new TypeInfo("Int64"));
+		Types.Add("long", new TypeInfo("Int32"));
+		Types.Add("octet", new TypeInfo("Byte"));
+		Types.Add("unsigned long long", new TypeInfo("UInt32"));
+		//Types.Add("boolean", new TypeInfo("Boolean", "MarshalAs(UnmanagedType.Bool)"));
+		Types.Add("boolean", new TypeInfo("Int32"));
+		Types.Add("wstring", new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)"));
+		//Types.Add("uuid", new TypeInfo("Guid", true, "MarshalAs(UnmanagedType.LPStruct)"));
+		Types.Add("uuid", new TypeInfo("Guid", "MarshalAs(UnmanagedType.LPStruct)"));
+
+		Types.Add("IMachine", new TypeInfo("IMachine", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("ISession", new TypeInfo("ISession", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IVirtualBox", new TypeInfo("IVirtualBox", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IHost", new TypeInfo("IHost", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IConsole", new TypeInfo("IConsole", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("ISystemProperties", new TypeInfo("ISystemProperties", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IProgress", new TypeInfo("IProgress", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IDisplay", new TypeInfo("IDisplay", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IMouse", new TypeInfo("IMouse", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IKeyboard", new TypeInfo("IKeyboard", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IFramebuffer", new TypeInfo("IFramebuffer", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IFramebufferOverlay", new TypeInfo("IFramebufferOverlay", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IMachineDebugger", new TypeInfo("IMachineDebugger", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IVirtualBoxErrorInfo", new TypeInfo("IVirtualBoxErrorInfo", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IEventSource", new TypeInfo("IEventSource", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IEventListener", new TypeInfo("IEventListener", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IEventContext", new TypeInfo("IEventContext", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IConsoleCallback", new TypeInfo("IConsoleCallback", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("IEvent", new TypeInfo("IEvent", "MarshalAs(UnmanagedType.Interface)"));
+
+		Types.Add("LockType", new TypeInfo("LockType"));
+		Types.Add("MediumVariant", new TypeInfo("MediumVariant"));
+		Types.Add("AccessMode", new TypeInfo("AccessMode"));
+		Types.Add("NATProtocol", new TypeInfo("NATProtocol"));
+		Types.Add("FirmwareType", new TypeInfo("FirmwareType"));
+		Types.Add("StorageControllerType", new TypeInfo("StorageControllerType"));
+		Types.Add("StorageBus", new TypeInfo("StorageBus"));
+		Types.Add("SessionType", new TypeInfo("SessionType"));
+		Types.Add("SessionState", new TypeInfo("SessionState"));
+		Types.Add("USBDeviceState", new TypeInfo("USBDeviceState"));
+		Types.Add("USBDeviceFilterAction", new TypeInfo("USBDeviceFilterAction"));
+		Types.Add("AudioControllerType", new TypeInfo("AudioControllerType"));
+		Types.Add("AudioDriverType", new TypeInfo("AudioDriverType"));
+		Types.Add("VRDPAuthType", new TypeInfo("VRDPAuthType"));
+		Types.Add("MachineState", new TypeInfo("MachineState"));
+		Types.Add("NetworkAdapterType", new TypeInfo("NetworkAdapterType"));
+		Types.Add("NetworkAttachmentType", new TypeInfo("NetworkAttachmentType"));
+		Types.Add("PortMode", new TypeInfo("PortMode"));
+		Types.Add("DeviceType", new TypeInfo("DeviceType"));
+		Types.Add("MediumState", new TypeInfo("MediumState"));
+		Types.Add("MediumType", new TypeInfo("MediumType"));
+		Types.Add("HostNetworkInterfaceType", new TypeInfo("HostNetworkInterfaceType"));
+		Types.Add("DeviceActivity", new TypeInfo("DeviceActivity"));
+		Types.Add("HostNetworkInterfaceMediumType", new TypeInfo("HostNetworkInterfaceMediumType"));
+		Types.Add("HostNetworkInterfaceStatus", new TypeInfo("HostNetworkInterfaceStatus"));
+		Types.Add("ProcessorFeature", new TypeInfo("ProcessorFeature"));
+		Types.Add("VFSType", new TypeInfo("VFSType"));
+		Types.Add("BIOSBootMenuMode", new TypeInfo("BIOSBootMenuMode"));
+		Types.Add("VirtualSystemDescriptionType", new TypeInfo("VirtualSystemDescriptionType"));
+		Types.Add("VirtualSystemDescriptionValueType", new TypeInfo("VirtualSystemDescriptionValueType"));
+		Types.Add("KeyboardHidType", new TypeInfo("KeyboardHidType"));
+		Types.Add("ClipboardMode", new TypeInfo("ClipboardMode"));
+		Types.Add("PointingHidType", new TypeInfo("PointingHidType"));
+		Types.Add("CPUPropertyType", new TypeInfo("CPUPropertyType"));
+		Types.Add("HWVirtExPropertyType", new TypeInfo("HWVirtExPropertyType"));
+		Types.Add("Scope", new TypeInfo("Scope"));
+		Types.Add("ChipsetType", new TypeInfo("ChipsetType"));
+		Types.Add("FaultToleranceState", new TypeInfo("FaultToleranceState"));
+		Types.Add("BandwidthGroupType", new TypeInfo("BandwidthGroupType"));
+		Types.Add("VBoxEventType", new TypeInfo("VBoxEventType"));
+		Types.Add("GuestMonitorChangedEventType", new TypeInfo("GuestMonitorChangedEventType"));
+		Types.Add("AuthType", new TypeInfo("AuthType"));
+		Types.Add("NetworkAdapterPromiscModePolicy", new TypeInfo("NetworkAdapterPromiscModePolicy"));
+		Types.Add("ExecuteProcessStatus", new TypeInfo("ExecuteProcessStatus"));
+		Types.Add("AdditionsRunLevelType", new TypeInfo("AdditionsRunLevelType"));
+		Types.Add("AdditionsFacilityStatus", new TypeInfo("AdditionsFacilityStatus"));
+		Types.Add("AdditionsFacilityType", new TypeInfo("AdditionsFacilityType"));
+		Types.Add("AdditionsFacilityClass", new TypeInfo("AdditionsFacilityClass"));
+		Types.Add("CleanupMode", new TypeInfo("CleanupMode"));
+		Types.Add("DataType", new TypeInfo("DataType"));
+
+		Types.Add("IBandwidthControl", new TypeInfo("IntPtr"));
+		Types.Add("IVRDEServerInfo", new TypeInfo("IntPtr"));
+		Types.Add("IAdditionsFacility", new TypeInfo("IntPtr"));
+		Types.Add("IExtPackPlugIn", new TypeInfo("IntPtr"));
+		Types.Add("IExtPackFile", new TypeInfo("IntPtr"));
+		Types.Add("IExtPack", new TypeInfo("IntPtr"));
+		Types.Add("IBIOSSettings", new TypeInfo("IntPtr"));
+		Types.Add("IVFSExplorer", new TypeInfo("IntPtr"));
+		Types.Add("IUSBController", new TypeInfo("IntPtr"));
+		Types.Add("IStorageController", new TypeInfo("IntPtr"));
+		Types.Add("IVRDPServer", new TypeInfo("IntPtr"));
+		Types.Add("ISnapshot", new TypeInfo("IntPtr"));
+		Types.Add("INATEngine", new TypeInfo("IntPtr"));
+		Types.Add("IUSBDeviceFilter", new TypeInfo("IntPtr"));
+		Types.Add("IMediumAttachment", new TypeInfo("IntPtr"));
+		Types.Add("IUSBDevice", new TypeInfo("IntPtr"));
+		Types.Add("IParallelPort", new TypeInfo("IntPtr"));
+		Types.Add("ISerialPort", new TypeInfo("IntPtr"));
+		Types.Add("INetworkAdapter", new TypeInfo("IntPtr"));
+		Types.Add("IMedium", new TypeInfo("IntPtr"));
+		Types.Add("IGuestOSType", new TypeInfo("IntPtr"));
+		Types.Add("ISharedFolder", new TypeInfo("IntPtr"));
+		Types.Add("IPerformanceCollector", new TypeInfo("IntPtr"));
+		Types.Add("IDHCPServer", new TypeInfo("IntPtr"));
+		Types.Add("IAppliance", new TypeInfo("IntPtr"));
+		Types.Add("IVirtualBoxCallback", new TypeInfo("IntPtr"));
+		Types.Add("IPerformanceMetric", new TypeInfo("IntPtr"));
+		Types.Add("IMediumFormat", new TypeInfo("IntPtr"));
+		Types.Add("IHostUSBDevice", new TypeInfo("IntPtr"));
+		Types.Add("IHostNetworkInterface", new TypeInfo("IntPtr"));
+		Types.Add("IHostUSBDeviceFilter", new TypeInfo("IntPtr"));
+		Types.Add("IRemoteDisplayInfo", new TypeInfo("IntPtr"));
+		Types.Add("IGuest", new TypeInfo("IntPtr"));
+		Types.Add("IVirtualSystemDescription", new TypeInfo("IntPtr"));
+		Types.Add("IAudioAdapter", new TypeInfo("IntPtr"));
+		Types.Add("IExtPackManager", new TypeInfo("IntPtr"));
+		Types.Add("IVRDEServer", new TypeInfo("IntPtr"));
+		Types.Add("IPciDeviceAttachment", new TypeInfo("IntPtr"));
+		Types.Add("IBandwidthGroup", new TypeInfo("IntPtr"));
+
+		Types.Add("$unknown", new TypeInfo("IntPtr"));
+	}
+	static void Main(string[] args) {
+		InitTypes();
+
+		XPathDocument doc = new XPathDocument("VirtualBox.xidl");
+		XPathNavigator nav = doc.CreateNavigator();
+		nav = nav.SelectSingleNode("/idl/library[@name='VirtualBox']");
+		TextWriter o = Console.Out;
+		o.WriteLine("using System;");
+		o.WriteLine("using System.Runtime.CompilerServices;");
+		o.WriteLine("using System.Runtime.InteropServices;");
+		o.WriteLine("namespace VirtualBox {");
+		foreach (XPathNavigator intf in nav.Select("interface")) {
+			ProcessInterface(intf, o, nav);
+		}
+		foreach (XPathNavigator intf in nav.Select("enum")) {
+			ProcessEnum(intf, o);
+		}
+		o.WriteLine("}");
+	}
+	static void ProcessEnum(XPathNavigator nav, TextWriter o) {
+		String typeName = nav.SelectSingleNode("@name").Value;
+		if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName));
+		o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value);
+		o.WriteLine("enum " + typeName + " {");
+		foreach (XPathNavigator member in nav.SelectChildren(XPathNodeType.Element)) {
+			switch (member.Name) {
+				case "desc":
+					break;
+				case "const":
+					o.WriteLine("\t{0} = {1},", member.SelectSingleNode("@name").Value, member.SelectSingleNode("@value").Value);
+					break;
+				default:
+					Console.Error.WriteLine("Unknown member type {0}", member.Name);
+					break;
+			}
+		}
+		o.WriteLine("}");
+	}
+	static void ProcessInterface(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) {
+		String typeName = nav.SelectSingleNode("@name").Value;
+		if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName, "MarshalAs(UnmanagedType.Interface)"));
+		o.WriteLine("[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]");
+		o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value);
+		o.WriteLine("[ComImport()]");
+		o.Write("interface " + typeName);
+		o.WriteLine(" {");
+		ProcessInterfaceMembersAndInherited(nav, o, parentNav);
+		o.WriteLine("}");
+	}
+	static void ProcessInterfaceMembersAndInherited(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) {
+		XPathItem item = nav.SelectSingleNode("@extends");
+		if (item != null && item.Value[0] != '$') {
+			XPathNavigator inav = parentNav.SelectSingleNode("interface[@name='" + item.Value + "']");
+			ProcessInterfaceMembersAndInherited(inav, o, parentNav);
+		}
+		ProcessInterfaceMembers(nav.SelectChildren(XPathNodeType.Element), o);
+	}
+	static void ProcessInterfaceMembers(XPathNodeIterator members, TextWriter oattribute) {
+		XPathItem item;
+		StringWriter omethod = new StringWriter();
+		foreach (XPathNavigator member in members) {
+			switch (member.Name) {
+				case "desc":
+					break;
+				case "attribute": {
+						String mName = member.SelectSingleNode("@name").Value;
+						//String mType = member.SelectSingleNode("@type").Value;
+						item = member.SelectSingleNode("@readonly");
+						Boolean mReadOnly = item == null ? false : item.Value == "yes";
+						//item = member.SelectSingleNode("@mod");
+						//String mMod = item == null ? null : item.Value;
+						mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1);
+						oattribute.Write("\t");
+						/*TypeInfo t;
+						if (mMod == "ptr") {
+							t = new TypeInfo("IntPtr");
+						} else if (mMod == "string") {
+							t = new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)");
+						} else if (mMod == null) {
+							if (!Types.TryGetValue(mType, out t)) {
+								Console.Error.WriteLine("Type {0} is not supported", mType);
+								t = new TypeInfo("void");
+							}
+						} else {
+							Console.Error.WriteLine("Type modifier {0} is not supported", mMod);
+							t = new TypeInfo("void");
+						}*/
+						TypeInfo t = GetTypeDeclaration(member);
+						oattribute.Write(t.Name);
+						oattribute.Write(" ");
+						oattribute.Write(mName);
+						oattribute.WriteLine(" {");
+						oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] ");
+						t.WriteAttributes(oattribute, ParameterType.Return);
+						oattribute.WriteLine("get;");
+						if (!mReadOnly) {
+							oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] ");
+							t.WriteAttributes(oattribute, ParameterType.Param);
+							oattribute.WriteLine("set;");
+						}
+						oattribute.WriteLine("\t}");
+					} break;
+				case "method": {
+						String mName = member.SelectSingleNode("@name").Value;
+						XPathNodeIterator mParamReturn = member.Select("param[@dir='return']");
+						omethod.WriteLine("\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]");
+						omethod.Write("\t");
+						bool mReturn = false;
+						if (mParamReturn == null || mParamReturn.Count != 1) {
+							omethod.Write("void");
+						} else {
+							mParamReturn.MoveNext();
+							mReturn = true;
+							TypeInfo t = GetTypeDeclaration(mParamReturn.Current);
+							/*String mType = mParamReturn.Current.SelectSingleNode("@type").Value;
+							TypeInfo t;
+							if (!Types.TryGetValue(mType, out t)) {
+								Console.Error.WriteLine("Type {0} is not supported", mType);
+								t = new TypeInfo("void");
+								mReturn = false;
+							}*/
+							t.WriteDeclaration(omethod, ParameterType.Return);
+						}
+						mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1);
+						omethod.Write(" ");
+						omethod.Write(mName);
+						omethod.Write("(");
+						XPathNodeIterator mParams = member.Select("param");
+						bool first = true;
+						if (mParams.MoveNext()) {
+							while (true) {
+								XPathNavigator mParam = mParams.Current;
+								String pDir = mParam.SelectSingleNode("@dir").Value;
+								//item = mParam.SelectSingleNode("@safearray");
+								//Boolean pArray = item == null ? false : item.Value == "yes";
+								//item = mParam.SelectSingleNode("@mod");
+								//String pMod = item == null ? null : item.Value;
+								if (pDir == "return" && mReturn) {
+									if (mParams.MoveNext()) {
+										continue;
+									} else {
+										break;
+									}
+								} else if (pDir == "in") {
+								} else if (pDir == "out") {
+								} else {
+									Console.Error.WriteLine("Unsupported parameter direction {0}", pDir);
+								}
+								if (first) {
+									first = false;
+								} else {
+									omethod.Write(", ");
+								}
+								ParameterType pt = ParameterType.In;
+								if (pDir == "out") pt = ParameterType.Out;
+								TypeInfo t = GetTypeDeclaration(mParam, ref pt);
+								t.WriteDeclaration(omethod, pt);
+								/*if (pArray) {
+									omethod.Write("[MarshalAs(UnmanagedType.SafeArray)] ");
+									if (pDir == "out") omethod.Write("out ");
+									else omethod.Write("ref ");
+									omethod.Write("System.Array");
+								} else {
+									String pType = mParam.SelectSingleNode("@type").Value;
+									TypeInfo t;
+									if (!Types.TryGetValue(pType, out t)) {
+										Console.Error.WriteLine("Type {0} is not supported", pType);
+										t = new TypeInfo("IntPtr");
+										mReturn = false;
+									}
+									if (pMod == "ptr") {
+										t.WriteDeclaration(omethod, ParameterType.Reference);
+									} else if (pDir == "out") {
+										t.WriteDeclaration(omethod, ParameterType.Out);
+									} else {
+										t.WriteDeclaration(omethod, ParameterType.In);
+									}
+								}*/
+								omethod.Write(" p");
+								omethod.Write(mParam.SelectSingleNode("@name").Value);
+								if (!mParams.MoveNext()) break;
+							}
+						}
+						omethod.WriteLine(");");
+					} break;
+				default:
+					Console.Error.WriteLine("Unknown member type {0}", member.Name);
+					break;
+			}
+		}
+		oattribute.Write((omethod as StringWriter).ToString());
+	}
+	private static TypeInfo GetTypeDeclaration(XPathNavigator nav) {
+		ParameterType pt = ParameterType.Param;
+		return GetTypeDeclaration(nav, ref pt);
+	}
+	private static TypeInfo GetTypeDeclaration(XPathNavigator nav, ref ParameterType paramType) {
+		String mType = nav.SelectSingleNode("@type").Value;
+		XPathItem item;
+		item = nav.SelectSingleNode("@mod");
+		String mMod = item == null ? null : item.Value;
+		item = nav.SelectSingleNode("@safearray");
+		Boolean pArray = item == null ? false : item.Value == "yes";
+
+		TypeInfo t;
+		if (!Types.TryGetValue(mType, out t)) {
+			Console.Error.WriteLine("Type {0} is not supported", mType);
+			t = new TypeInfo("void");
+		}
+		if (mMod == "ptr") {
+			if (paramType == ParameterType.In) {
+				paramType = ParameterType.Reference;
+			} else {
+				t = new TypeInfo("IntPtr");
+			}
+		} else if (mMod == "string") {
+			t = new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)");
+		} else if (mMod != null) {
+			Console.Error.WriteLine("Type modifier {0} is not supported", mMod);
+			t = new TypeInfo("void");
+		}
+		if (pArray) {
+			t = new TypeInfo("Array", "MarshalAs(UnmanagedType.SafeArray)");
+			if (paramType == ParameterType.In || paramType == ParameterType.Out) paramType = ParameterType.Reference;
+		}
+		return t;
+	}
+}