Fix TextBufferSerializeFunc signature
* generator/CallbackGen.cs: connect return value count parameters * generator/ManagedCallString.cs: out count params aren't special * generator/MethodBody.cs: don't finish hidden params * generator/Parameters.cs: explicit IsCount setting support, with Parameters.GetCountParameter(name) interface. Clear IsCount values during validation if they have no associated array. Any remaining count params must be associated with a retval, so hide them. * generator/ReturnValue.cs: support array_length_param attribute to associate a return value with a "count" param. Use new helper methods to marshal these array retvals to IntPtr and back. * glib/Marshaller.cs: support for byte[] marshaling to and from IntPtr using a count and type in the from native direction. * gtk/Gtk.metadata: mark TextBufferSerializeFunc return type as an array with the length specific in the length param.
This commit is contained in:
parent
2e115e2aff
commit
c6a3bf4b73
7 changed files with 83 additions and 18 deletions
|
@ -54,6 +54,9 @@ namespace GtkSharp.Generation {
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrEmpty (retval.CountParameterName))
|
||||||
|
retval.CountParameter = parms.GetCountParameter (retval.CountParameterName);
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +221,9 @@ namespace GtkSharp.Generation {
|
||||||
if (finish.Length > 0)
|
if (finish.Length > 0)
|
||||||
sw.WriteLine (finish);
|
sw.WriteLine (finish);
|
||||||
sw.WriteLine ("\t\t\t\tif (release_on_call)\n\t\t\t\t\tgch.Free ();");
|
sw.WriteLine ("\t\t\t\tif (release_on_call)\n\t\t\t\t\tgch.Free ();");
|
||||||
|
Parameter cnt = retval.CountParameter;
|
||||||
|
if (cnt != null)
|
||||||
|
sw.WriteLine ("\t\t\t\t{0} = {1}{2};", cnt.Name, cnt.CSType == "int" ? String.Empty : "(" + cnt.MarshalType + ")(" + cnt.CSType + ")", "__ret.Length");
|
||||||
if (retval.CSType != "void")
|
if (retval.CSType != "void")
|
||||||
sw.WriteLine ("\t\t\t\treturn {0};", retval.ToNative ("__ret"));
|
sw.WriteLine ("\t\t\t\treturn {0};", retval.ToNative ("__ret"));
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace GtkSharp.Generation {
|
||||||
user_data_param = parms[i+1].Name;
|
user_data_param = parms[i+1].Name;
|
||||||
destroy_param = parms[i+2].Name;
|
destroy_param = parms[i+2].Name;
|
||||||
i += 2;
|
i += 2;
|
||||||
} else if (p.IsUserData && parms.IsHidden (p)) {
|
} else if ((p.IsCount || p.IsUserData) && parms.IsHidden (p)) {
|
||||||
user_data_param = p.Name;
|
user_data_param = p.Name;
|
||||||
continue;
|
continue;
|
||||||
} else if (p is ErrorParameter) {
|
} else if (p is ErrorParameter) {
|
||||||
|
|
|
@ -140,9 +140,12 @@ namespace GtkSharp.Generation {
|
||||||
|
|
||||||
public void Finish (StreamWriter sw, string indent)
|
public void Finish (StreamWriter sw, string indent)
|
||||||
{
|
{
|
||||||
foreach (Parameter p in parameters)
|
foreach (Parameter p in parameters) {
|
||||||
|
if (parameters.IsHidden (p))
|
||||||
|
continue;
|
||||||
foreach (string s in p.Finish)
|
foreach (string s in p.Finish)
|
||||||
sw.WriteLine(indent + "\t\t\t" + s);
|
sw.WriteLine(indent + "\t\t\t" + s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FinishAccessor (StreamWriter sw, Signature sig, string indent)
|
public void FinishAccessor (StreamWriter sw, Signature sig, string indent)
|
||||||
|
|
|
@ -91,8 +91,12 @@ namespace GtkSharp.Generation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_count;
|
||||||
|
bool is_count_set;
|
||||||
public bool IsCount {
|
public bool IsCount {
|
||||||
get {
|
get {
|
||||||
|
if (is_count_set)
|
||||||
|
return is_count;
|
||||||
|
|
||||||
if (Name.StartsWith("n_"))
|
if (Name.StartsWith("n_"))
|
||||||
switch (CSType) {
|
switch (CSType) {
|
||||||
|
@ -109,6 +113,10 @@ namespace GtkSharp.Generation {
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
set {
|
||||||
|
is_count_set = true;
|
||||||
|
is_count = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDestroyNotify {
|
public bool IsDestroyNotify {
|
||||||
|
@ -119,7 +127,6 @@ namespace GtkSharp.Generation {
|
||||||
|
|
||||||
public bool IsLength {
|
public bool IsLength {
|
||||||
get {
|
get {
|
||||||
|
|
||||||
if (Name.EndsWith("len") || Name.EndsWith("length"))
|
if (Name.EndsWith("len") || Name.EndsWith("length"))
|
||||||
switch (CSType) {
|
switch (CSType) {
|
||||||
case "int":
|
case "int":
|
||||||
|
@ -529,9 +536,7 @@ namespace GtkSharp.Generation {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Count {
|
public int Count {
|
||||||
get {
|
get { return param_list.Count; }
|
||||||
return param_list.Count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int VisibleCount {
|
public int VisibleCount {
|
||||||
|
@ -558,8 +563,7 @@ namespace GtkSharp.Generation {
|
||||||
if (idx > 0 && p.IsLength && p.PassAs == String.Empty && this [idx - 1].IsString)
|
if (idx > 0 && p.IsLength && p.PassAs == String.Empty && this [idx - 1].IsString)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (p.IsCount && ((idx > 0 && this [idx - 1].IsArray) ||
|
if (p.IsCount)
|
||||||
(idx < Count - 1 && this [idx + 1].IsArray)))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (p.CType == "GError**")
|
if (p.CType == "GError**")
|
||||||
|
@ -608,6 +612,16 @@ namespace GtkSharp.Generation {
|
||||||
set { is_static = value; }
|
set { is_static = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Parameter GetCountParameter (string param_name)
|
||||||
|
{
|
||||||
|
foreach (Parameter p in this)
|
||||||
|
if (p.Name == param_name) {
|
||||||
|
p.IsCount = true;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
void Clear ()
|
void Clear ()
|
||||||
{
|
{
|
||||||
elem = null;
|
elem = null;
|
||||||
|
@ -663,13 +677,16 @@ namespace GtkSharp.Generation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (p.IsCount && i < elem.ChildNodes.Count - 1) {
|
} else if (p.IsCount) {
|
||||||
XmlElement next = elem.ChildNodes [i + 1] as XmlElement;
|
p.IsCount = false;
|
||||||
if (next != null || next.Name == "parameter") {
|
if (i < elem.ChildNodes.Count - 1) {
|
||||||
Parameter a = new Parameter (next);
|
XmlElement next = elem.ChildNodes [i + 1] as XmlElement;
|
||||||
if (a.IsArray) {
|
if (next != null || next.Name == "parameter") {
|
||||||
p = new ArrayCountPair (next, parm, true);
|
Parameter a = new Parameter (next);
|
||||||
i++;
|
if (a.IsArray) {
|
||||||
|
p = new ArrayCountPair (next, parm, true);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (p.CType == "GError**")
|
} else if (p.CType == "GError**")
|
||||||
|
|
|
@ -31,15 +31,18 @@ namespace GtkSharp.Generation {
|
||||||
bool is_array;
|
bool is_array;
|
||||||
bool elements_owned;
|
bool elements_owned;
|
||||||
bool owned;
|
bool owned;
|
||||||
|
string array_length_param = String.Empty;
|
||||||
string ctype = String.Empty;
|
string ctype = String.Empty;
|
||||||
string default_value = String.Empty;
|
string default_value = String.Empty;
|
||||||
string element_ctype = String.Empty;
|
string element_ctype = String.Empty;
|
||||||
|
Parameter count_param;
|
||||||
|
|
||||||
public ReturnValue (XmlElement elem)
|
public ReturnValue (XmlElement elem)
|
||||||
{
|
{
|
||||||
if (elem != null) {
|
if (elem != null) {
|
||||||
is_null_term = elem.HasAttribute ("null_term_array");
|
is_null_term = elem.HasAttribute ("null_term_array");
|
||||||
is_array = elem.HasAttribute ("array");
|
is_array = elem.HasAttribute ("array") || elem.HasAttribute ("array_length_param");
|
||||||
|
array_length_param = elem.GetAttribute ("array_length_param");
|
||||||
elements_owned = elem.GetAttribute ("elements_owned") == "true";
|
elements_owned = elem.GetAttribute ("elements_owned") == "true";
|
||||||
owned = elem.GetAttribute ("owned") == "true";
|
owned = elem.GetAttribute ("owned") == "true";
|
||||||
ctype = elem.GetAttribute("type");
|
ctype = elem.GetAttribute("type");
|
||||||
|
@ -48,6 +51,15 @@ namespace GtkSharp.Generation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Parameter CountParameter {
|
||||||
|
get { return count_param; }
|
||||||
|
set { count_param = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CountParameterName {
|
||||||
|
get { return array_length_param; }
|
||||||
|
}
|
||||||
|
|
||||||
public string CType {
|
public string CType {
|
||||||
get {
|
get {
|
||||||
return ctype;
|
return ctype;
|
||||||
|
@ -104,9 +116,9 @@ namespace GtkSharp.Generation {
|
||||||
get {
|
get {
|
||||||
if (IGen == null)
|
if (IGen == null)
|
||||||
return String.Empty;
|
return String.Empty;
|
||||||
else if (is_null_term)
|
else if (is_array || is_null_term)
|
||||||
return "IntPtr";
|
return "IntPtr";
|
||||||
return IGen.MarshalType + (is_array ? "[]" : String.Empty);
|
return IGen.MarshalType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +145,8 @@ namespace GtkSharp.Generation {
|
||||||
return ((IOwnable)IGen).FromNative (var, owned);
|
return ((IOwnable)IGen).FromNative (var, owned);
|
||||||
else if (is_null_term)
|
else if (is_null_term)
|
||||||
return String.Format ("GLib.Marshaller.NullTermPtrToStringArray ({0}, {1})", var, owned ? "true" : "false");
|
return String.Format ("GLib.Marshaller.NullTermPtrToStringArray ({0}, {1})", var, owned ? "true" : "false");
|
||||||
|
else if (is_array)
|
||||||
|
return String.Format ("({0}) GLib.Marshaller.ArrayPtrToArray ({1}, typeof ({2}), (int){3}native_{4}, true)", CSType, var, IGen.QualifiedName, CountParameter.CSType == "int" ? String.Empty : "(" + CountParameter.CSType + ")", CountParameter.Name);
|
||||||
else
|
else
|
||||||
return IGen.FromNative (var);
|
return IGen.FromNative (var);
|
||||||
}
|
}
|
||||||
|
@ -147,6 +161,8 @@ namespace GtkSharp.Generation {
|
||||||
var = "new " + IGen.QualifiedName + "(" + var + args + ")";
|
var = "new " + IGen.QualifiedName + "(" + var + args + ")";
|
||||||
} else if (is_null_term)
|
} else if (is_null_term)
|
||||||
return String.Format ("GLib.Marshaller.StringArrayToNullTermPointer ({0})", var);
|
return String.Format ("GLib.Marshaller.StringArrayToNullTermPointer ({0})", var);
|
||||||
|
else if (is_array)
|
||||||
|
return String.Format ("GLib.Marshaller.ArrayToArrayPtr ({0})", var);
|
||||||
|
|
||||||
if (IGen is IManualMarshaler)
|
if (IGen is IManualMarshaler)
|
||||||
return (IGen as IManualMarshaler).AllocNative (var);
|
return (IGen as IManualMarshaler).AllocNative (var);
|
||||||
|
|
|
@ -402,6 +402,28 @@ namespace GLib {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IntPtr ArrayToArrayPtr (byte[] array)
|
||||||
|
{
|
||||||
|
IntPtr ret = Malloc ((ulong) array.Length);
|
||||||
|
Marshal.Copy (array, 0, ret, array.Length);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Array ArrayPtrToArray (IntPtr array_ptr, Type element_type, int length, bool owned)
|
||||||
|
{
|
||||||
|
Array result = null;
|
||||||
|
if (element_type == typeof (byte)) {
|
||||||
|
byte[] ret = new byte [length];
|
||||||
|
Marshal.Copy (array_ptr, ret, 0, length);
|
||||||
|
result = ret;
|
||||||
|
} else {
|
||||||
|
throw new InvalidOperationException ("Marshaling of " + element_type + " arrays is not supported");
|
||||||
|
}
|
||||||
|
if (owned)
|
||||||
|
Free (array_ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public static Array ListPtrToArray (IntPtr list_ptr, Type list_type, bool owned, bool elements_owned, Type elem_type)
|
public static Array ListPtrToArray (IntPtr list_ptr, Type list_type, bool owned, bool elements_owned, Type elem_type)
|
||||||
{
|
{
|
||||||
Type array_type = elem_type == typeof (ListBase.FilenameString) ? typeof (string) : elem_type;
|
Type array_type = elem_type == typeof (ListBase.FilenameString) ? typeof (string) : elem_type;
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
<attr path="/api/namespace/boxed[@cname='GtkTreeRowReference']/method[@name='Free']" name="deprecated">1</attr>
|
<attr path="/api/namespace/boxed[@cname='GtkTreeRowReference']/method[@name='Free']" name="deprecated">1</attr>
|
||||||
<attr path="/api/namespace/boxed[@cname='GtkTreeRowReference']/method[@name='GetPath']/return-type" name="owned">true</attr>
|
<attr path="/api/namespace/boxed[@cname='GtkTreeRowReference']/method[@name='GetPath']/return-type" name="owned">true</attr>
|
||||||
<attr path="/api/namespace/callback[@cname='GtkClipboardRichTextReceivedFunc']" name="hidden">1</attr>
|
<attr path="/api/namespace/callback[@cname='GtkClipboardRichTextReceivedFunc']" name="hidden">1</attr>
|
||||||
|
<attr path="/api/namespace/callback[@cname='GtkTextBufferSerializeFunc']/return-type" name="array_length_param">length</attr>
|
||||||
<attr path="/api/namespace/callback[@cname='GtkTextBufferDeserializeFunc']/*/*[@name='data']" name="array">1</attr>
|
<attr path="/api/namespace/callback[@cname='GtkTextBufferDeserializeFunc']/*/*[@name='data']" name="array">1</attr>
|
||||||
<attr path="/api/namespace/callback[@cname='GtkTreeModelFilterModifyFunc']/parameters/parameter[@name='value']" name="pass_as">ref</attr>
|
<attr path="/api/namespace/callback[@cname='GtkTreeModelFilterModifyFunc']/parameters/parameter[@name='value']" name="pass_as">ref</attr>
|
||||||
<attr path="/api/namespace/callback[@cname='GtkModuleDisplayInitFunc']" name="hidden">1</attr>
|
<attr path="/api/namespace/callback[@cname='GtkModuleDisplayInitFunc']" name="hidden">1</attr>
|
||||||
|
|
Loading…
Reference in a new issue