diff --git a/ChangeLog b/ChangeLog index 1817cffd3..596b7ae50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2004-02-04 Mike Kestner + + * generator/CustomMarshalerGen.cs : impl MarshalReturnType. + * generator/Method.cs : add CustomMarshalerGen return type handling. + * generator/Property.cs : rework property type selection. + * generator/SymbolTable.cs : add time_t mapping + * glib/time_t_CustomMarshaler.cs : impl native to managed methods. + * glue/time_t.c : remove debugging code. + 2004-02-03 Mike Kestner * glib/List.cs : add a ctor overload to create empty lists with diff --git a/generator/CustomMarshalerGen.cs b/generator/CustomMarshalerGen.cs index c913c8def..cc9c92415 100644 --- a/generator/CustomMarshalerGen.cs +++ b/generator/CustomMarshalerGen.cs @@ -46,7 +46,7 @@ namespace GtkSharp.Generation { } public virtual string MarshalReturnType { get { - return String.Empty; + return "[return:MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(" + marshaler + "))]"; } } diff --git a/generator/Method.cs b/generator/Method.cs index 6e40ba9ca..03442c189 100644 --- a/generator/Method.cs +++ b/generator/Method.cs @@ -270,7 +270,10 @@ namespace GtkSharp.Generation { import_sig += !IsShared && parms != null ? ", " : ""; import_sig += isig.ToString(); sw.WriteLine("\t\t[DllImport(\"" + libname + "\")]"); - sw.WriteLine("\t\tstatic extern " + safety + m_ret + " " + cname + "(" + import_sig + ");"); + if (m_ret.StartsWith ("[return:")) + sw.WriteLine("\t\t" + m_ret + " static extern " + safety + s_ret + " " + cname + "(" + import_sig + ");"); + else + sw.WriteLine("\t\tstatic extern " + safety + m_ret + " " + cname + "(" + import_sig + ");"); sw.WriteLine(); } @@ -349,26 +352,25 @@ namespace GtkSharp.Generation { body.Initialize(gen_info, is_get, is_set, indent); SymbolTable table = SymbolTable.Table; + IGeneratable ret_igen = table [rettype]; sw.Write(indent + "\t\t\t"); if (m_ret == "void") { sw.WriteLine(cname + call + ";"); + } else if (ret_igen is ObjectGen || ret_igen is OpaqueGen) { + sw.WriteLine(m_ret + " raw_ret = " + cname + call + ";"); + sw.WriteLine(indent +"\t\t\t" + s_ret + " ret = " + table.FromNativeReturn(rettype, "raw_ret") + ";"); + if (table.IsOpaque (rettype)) + sw.WriteLine(indent + "\t\t\tif (ret == null) ret = new " + s_ret + "(raw_ret);"); + } else if (ret_igen is CustomMarshalerGen) { + sw.WriteLine(s_ret + " ret = " + cname + call + ";"); } else { - if (table.IsObject (rettype) || table.IsOpaque (rettype)) - { - sw.WriteLine(m_ret + " raw_ret = " + cname + call + ";"); - sw.WriteLine(indent +"\t\t\t" + s_ret + " ret = " + table.FromNativeReturn(rettype, "raw_ret") + ";"); - if (table.IsOpaque (rettype)) - sw.WriteLine(indent + "\t\t\tif (ret == null) ret = new " + s_ret + "(raw_ret);"); - } - else { - sw.WriteLine(m_ret + " raw_ret = " + cname + call + ";"); - sw.Write(indent + "\t\t\t"); - string raw_parms = "raw_ret"; - if (element_type != null) - raw_parms += ", typeof (" + element_type + ")"; - sw.WriteLine(s_ret + " ret = " + table.FromNativeReturn(rettype, raw_parms) + ";"); - } + sw.WriteLine(m_ret + " raw_ret = " + cname + call + ";"); + sw.Write(indent + "\t\t\t"); + string raw_parms = "raw_ret"; + if (element_type != null) + raw_parms += ", typeof (" + element_type + ")"; + sw.WriteLine(s_ret + " ret = " + table.FromNativeReturn(rettype, raw_parms) + ";"); } body.Finish (sw, indent); diff --git a/generator/Property.cs b/generator/Property.cs index d752d2dc6..1b5c5335d 100644 --- a/generator/Property.cs +++ b/generator/Property.cs @@ -91,22 +91,37 @@ namespace GtkSharp.Generation { bool has_getter = false; bool has_setter = false; + string getter_type = String.Empty; + string setter_type = String.Empty; + Method getter = container_type.GetMethod("Get" + Name); + if (getter != null && getter.Validate () && getter.IsGetter) + getter_type = getter.ReturnType; + Method setter = container_type.GetMethod("Set" + Name); + if (setter != null && setter.Validate () && setter.IsSetter) + setter_type = setter.Signature.Types; - if (getter != null && getter.Validate() && getter.IsGetter && getter.ReturnType == cs_type) { - has_getter = true; - getter.GenerateImport(sw); - } - if (setter != null && setter.Validate() && setter.IsSetter) { - has_setter = true; - setter.GenerateImport(sw); - } + if (getter_type != String.Empty && getter_type == setter_type) { + has_getter = has_setter = true; + getter.GenerateImport (sw); + setter.GenerateImport (sw); + cs_type = getter_type; + } else { + if (getter_type == cs_type) { + has_getter = true; + getter.GenerateImport(sw); + } + if (setter_type != String.Empty) { + has_setter = true; + setter.GenerateImport(sw); + } - if (has_setter && setter.Signature.Types != cs_type) - cs_type = setter.Signature.Types; - else if (has_getter && getter.ReturnType != cs_type) - cs_type = getter.ReturnType; + if (has_setter && setter_type != cs_type) + cs_type = setter_type; + else if (has_getter && getter_type != cs_type) + cs_type = getter_type; + } sw.WriteLine(); diff --git a/generator/SymbolTable.cs b/generator/SymbolTable.cs index 09c2a594f..1c0520c78 100644 --- a/generator/SymbolTable.cs +++ b/generator/SymbolTable.cs @@ -91,7 +91,7 @@ namespace GtkSharp.Generation { AddType (new SimpleGen ("GParamSpec", "IntPtr")); AddType (new SimpleGen ("gconstpointer", "IntPtr")); - // AddType (new CustomMarshalerGen ("time_t", "System.DateTime", "GLib.time_t_CustomMarshaler")); + AddType (new CustomMarshalerGen ("time_t", "System.DateTime", "GLib.time_t_CustomMarshaler")); AddType (new ManualGen ("GSList", "GLib.SList")); AddType (new ManualGen ("GList", "GLib.List")); AddType (new ManualGen ("GValue", "GLib.Value")); diff --git a/glib/time_t_CustomMarshaler.cs b/glib/time_t_CustomMarshaler.cs index 3128ef504..5f18d37e8 100644 --- a/glib/time_t_CustomMarshaler.cs +++ b/glib/time_t_CustomMarshaler.cs @@ -29,23 +29,19 @@ namespace GLib { return marshaler; } - [DllImport ("gtksharpglue")] - static extern int gtksharp_time_t_sizeof (); - - [DllImport ("gtksharpglue")] - static extern void gtksharp_time_t_print (int time_t); - public IntPtr MarshalManagedToNative (object obj) { DateTime dt = (DateTime) obj; - int size = Marshal.SizeOf (typeof (int)) + gtksharp_time_t_sizeof (); + int size = Marshal.SizeOf (typeof (int)) + GetNativeDataSize (); IntPtr ptr = Marshal.AllocCoTaskMem (size); IntPtr time_t_ptr = new IntPtr (ptr.ToInt32 () + Marshal.SizeOf (typeof(int))); - int secs = dt.Subtract (local_epoch).Seconds + utc_offset; - Console.WriteLine ("Marshaling DateTime: " + dt); - Marshal.WriteInt32 (time_t_ptr, secs); - gtksharp_time_t_print (secs); + if (GetNativeDataSize () == 4) + Marshal.WriteInt32 (time_t_ptr, secs); + else if (GetNativeDataSize () == 8) + Marshal.WriteInt64 (time_t_ptr, secs); + else + throw new Exception ("Unexpected native size for time_t."); return time_t_ptr; } @@ -57,14 +53,26 @@ namespace GLib { public object MarshalNativeToManaged (IntPtr data) { - throw new NotImplementedException (); + int secs; + if (GetNativeDataSize () == 4) + secs = Marshal.ReadInt32 (data); + else if (GetNativeDataSize () == 8) + secs = (int) Marshal.ReadInt64 (data); + else + throw new Exception ("Unexpected native size for time_t."); + + TimeSpan span = new TimeSpan (secs - utc_offset); + return local_epoch.Add (span); } public void CleanUpManagedData (object obj) {} + [DllImport ("gtksharpglue")] + static extern int gtksharp_time_t_sizeof (); + public int GetNativeDataSize () { - throw new NotImplementedException (); + return gtksharp_time_t_sizeof (); } } } diff --git a/glue/time_t.c b/glue/time_t.c index bf0a85709..6ac4474c3 100644 --- a/glue/time_t.c +++ b/glue/time_t.c @@ -11,7 +11,6 @@ /* Forward declarations */ gint gtksharp_time_t_sizeof (void); -void gtksharp_time_t_print (time_t t); gint gtksharp_time_t_sizeof () @@ -19,8 +18,3 @@ gtksharp_time_t_sizeof () return sizeof (time_t); } -void -gtksharp_time_t_print (time_t t) -{ - printf ("%s\n", ctime (&t)); -}