GtkSharp/generator/StructBase.cs
Gonzalo Paniagua Javier 3821938764 2003-04-03 Gonzalo Paniagua Javier <gonzalo@ximian.com>
* generator/CallbackGen.cs: the new generated wrappers have:
		-(optional) Field of the same type returned by the callback.
		-A call to RemoveIfNotAlive at the beginning. It returns true,
		return the dummy field.
		-Added an object to the ctor signature and pass it to the base
		class.

	* generator/Ctor.cs: added a Params property.

	* generator/Method.cs: set Static property in Parameters if the method
	is static.

	* generator/Parameters.cs: added Static property. The call creation of
	the delegate wrapper (if applicable) uses the new signature. Pass a null
	as object is the method is static.

	* generator/StructBase.cs: set Static for the parameters of the ctors.

	* glib/DelegateWrapper.cs: the ctor takes an object (the one creating
	the wrapper or null) and creates a weak reference to it. Store it in
	a static Hashtable (this way the wrapper itself is not garbage
	collected).
	(RemoveIfNotAlive): called from the native delegate callbacks. If the
	target of the weak reference has been garbage collected, removes itself
	from the hashtable to let the GC dispose this instance and returns true.

	* gdk/Pixbuf.custom:
	* gtk/Clipboard.custom:
	* gtk/GtkSharp.GtkClipboardClearFuncNative.cs:
	* gtk/GtkSharp.GtkClipboardGetFuncNative.cs:
	* glade/XML.custom: changed delegate wrappers to match the new
	signature.

svn path=/trunk/gtk-sharp/; revision=13237
2003-04-06 09:21:15 +00:00

274 lines
7.3 KiB
C#

// GtkSharp.Generation.StructBase.cs - The Structure/Object Base Class.
//
// Author: Mike Kestner <mkestner@speakeasy.net>
//
// (c) 2001 Mike Kestner
namespace GtkSharp.Generation {
using System;
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
public class StructBase : ClassBase {
ArrayList fields = new ArrayList ();
uint bitfields;
public StructBase (XmlElement ns, XmlElement elem) : base (ns, elem)
{
hasDefaultConstructor = false;
foreach (XmlNode node in elem.ChildNodes) {
if (!(node is XmlElement)) continue;
XmlElement member = (XmlElement) node;
switch (node.Name) {
case "field":
fields.Add (member);
break;
case "callback":
Statistics.IgnoreCount++;
break;
default:
if (!IsNodeNameHandled (node.Name))
Console.WriteLine ("Unexpected node " + node.Name + " in " + CName);
break;
}
}
}
public override String MarshalType {
get
{
return "ref " + QualifiedName;
}
}
public override String MarshalReturnType {
get
{
return "IntPtr";
}
}
public override String CallByName (String var_name)
{
return "ref " + var_name;
}
public override String CallByName ()
{
return "ref this";
}
public override String AssignToName {
get { return "raw"; }
}
public override String FromNative(String var)
{
return var;
}
public override String FromNativeReturn(String var)
{
return QualifiedName + ".New (" + var + ")";
}
bool IsBit (XmlElement field)
{
return (field.HasAttribute("bits") && (field.GetAttribute("bits") == "1"));
}
bool IsPointer (XmlElement field)
{
string c_type = field.GetAttribute("type");
return (c_type[c_type.Length - 1] == '*');
}
protected void GenFields (StreamWriter sw)
{
bitfields = 0;
bool need_field = true;
foreach (XmlElement field in fields) {
if (IsBit (field)) {
if (need_field)
need_field = false;
else
continue;
} else
need_field = true;
GenField (field, sw);
}
}
protected bool GetFieldInfo (XmlElement field, out string c_type, out string type, out string name)
{
name = "";
c_type = field.GetAttribute ("type");
type = SymbolTable.GetCSType (c_type);
if (IsBit (field)) {
type = "uint";
} else if ((IsPointer (field) || SymbolTable.IsOpaque (c_type)) && type != "string") {
type = "IntPtr";
name = "_";
} else if (SymbolTable.IsCallback (c_type)) {
type = "IntPtr";
} else {
if (type == "") {
Console.WriteLine ("Field has unknown Type {0}", c_type);
Statistics.ThrottledCount++;
return false;
}
}
// FIXME: marshalling not implemented here in mono
if (field.HasAttribute("array_len"))
type = "IntPtr";
if (IsBit (field))
name = String.Format ("_bitfield{0}", bitfields++);
else
name += MangleName (field.GetAttribute ("cname"));
return true;
}
protected bool GenField (XmlElement field, StreamWriter sw)
{
string c_type, type, name;
if (!GetFieldInfo (field, out c_type, out type, out name))
return false;
sw.WriteLine ("\t\tpublic {0} {1};", type, name);
if (field.HasAttribute("array_len"))
Console.WriteLine ("warning: array field {0}.{1} probably incorrectly generated", QualifiedName, name);
string wrapped = SymbolTable.GetCSType (c_type);
string wrapped_name = MangleName (field.GetAttribute ("cname"));
if (SymbolTable.IsObject (c_type)) {
sw.WriteLine ();
sw.WriteLine ("\t\tpublic " + wrapped + " " + wrapped_name + " {");
sw.WriteLine ("\t\t\tget { ");
sw.WriteLine ("\t\t\t\t" + wrapped + " ret = " + SymbolTable.FromNativeReturn(c_type, name) + ";");
sw.WriteLine ("\t\t\t\tret.Ref ();");
sw.WriteLine ("\t\t\t\treturn ret;");
sw.WriteLine ("\t\t\t}");
sw.WriteLine ("\t\t\tset { " + name + " = " + SymbolTable.CallByName (c_type, "value") + "; }");
sw.WriteLine ("\t\t}");
} else if (SymbolTable.IsOpaque (c_type)) {
sw.WriteLine ();
sw.WriteLine ("\t\tpublic " + wrapped + " " + wrapped_name + " {");
sw.WriteLine ("\t\t\tget { ");
sw.WriteLine ("\t\t\t\t" + wrapped + " ret = " + SymbolTable.FromNativeReturn(c_type, name) + ";");
sw.WriteLine ("\t\t\t\tif (ret == null) ret = new " + wrapped + "(" + name + ");");
sw.WriteLine ("\t\t\t\treturn ret;");
sw.WriteLine ("\t\t\t}");
sw.WriteLine ("\t\t\tset { " + name + " = " + SymbolTable.CallByName (c_type, "value") + "; }");
sw.WriteLine ("\t\t}");
} else if (IsPointer (field) && (SymbolTable.IsStruct (c_type) || SymbolTable.IsBoxed (c_type))) {
sw.WriteLine ();
sw.WriteLine ("\t\tpublic " + wrapped + " " + wrapped_name + " {");
sw.WriteLine ("\t\t\tget { return " + SymbolTable.FromNativeReturn (c_type, name) + "; }");
sw.WriteLine ("\t\t}");
}
return true;
}
private String MangleName(String name)
{
if (name == "string") {
return "str1ng";
} else if (name == "event") {
return "evnt";
} else if (name == "null") {
return "is_null";
} else if (name == "object") {
return "objekt";
} else if (name == "ref") {
return "reference";
} else if (name == "params") {
return "parms";
} else if (name == "fixed") {
return "mfixed";
} else if (name == "in") {
return "inn";
} else {
return name;
}
}
public virtual void Generate ()
{
StreamWriter sw = CreateWriter ();
sw.WriteLine ("\tusing System;");
sw.WriteLine ("\tusing System.Collections;");
sw.WriteLine ("\tusing System.Runtime.InteropServices;");
sw.WriteLine ();
sw.WriteLine("\t\t/// <summary> " + Name + " Struct </summary>");
sw.WriteLine("\t\t/// <remarks>");
sw.WriteLine("\t\t/// </remarks>");
sw.WriteLine ("#region Autogenerated code");
sw.WriteLine ("\t[StructLayout(LayoutKind.Sequential)]");
sw.WriteLine ("\tpublic struct " + Name + " {");
sw.WriteLine ();
GenFields (sw);
sw.WriteLine ();
GenCtors (sw);
GenMethods (sw, null, null, true);
sw.WriteLine ("#endregion");
AppendCustom(sw);
sw.WriteLine ("\t}");
CloseWriter (sw);
}
protected override void GenCtors (StreamWriter sw)
{
sw.WriteLine ("\t\tpublic static {0} Zero = new {0} ();", QualifiedName);
sw.WriteLine();
sw.WriteLine ("\t\tpublic static " + QualifiedName + " New(IntPtr raw) {");
sw.WriteLine ("\t\t\tif (raw == IntPtr.Zero) {");
sw.WriteLine ("\t\t\t\treturn {0}.Zero;", QualifiedName);
sw.WriteLine ("\t\t\t}");
sw.WriteLine ("\t\t\t{0} self = new {0}();", QualifiedName);
sw.WriteLine ("\t\t\tself = ({0}) Marshal.PtrToStructure (raw, self.GetType ());", QualifiedName);
sw.WriteLine ("\t\t\treturn self;");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
sw.WriteLine ("\t\tpublic static bool operator == ({0} a, {0} b)", QualifiedName);
sw.WriteLine ("\t\t{");
sw.WriteLine ("\t\t\treturn a.Equals (b);");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
sw.WriteLine ("\t\tpublic static bool operator != ({0} a, {0} b)", QualifiedName);
sw.WriteLine ("\t\t{");
sw.WriteLine ("\t\t\treturn ! a.Equals (b);");
sw.WriteLine ("\t\t}");
sw.WriteLine();
foreach (Ctor ctor in Ctors) {
ctor.ForceStatic = true;
if (ctor.Params != null)
ctor.Params.Static = true;
}
base.GenCtors (sw);
}
}
}