1 // GtkSharp.Generation.StructField.cs - The Structure Field generation 2 // Class. 3 // 4 // Author: Mike Kestner <mkestner@ximian.com> 5 // 6 // Copyright (c) 2004-2005 Novell, Inc. 7 // 8 // This program is free software; you can redistribute it and/or 9 // modify it under the terms of version 2 of the GNU General Public 10 // License as published by the Free Software Foundation. 11 // 12 // This program is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 // General Public License for more details. 16 // 17 // You should have received a copy of the GNU General Public 18 // License along with this program; if not, write to the 19 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 // Boston, MA 02111-1307, USA. 21 22 23 namespace GtkSharp.Generation { 24 25 using System; 26 using System.IO; 27 using System.Xml; 28 29 public class StructField : FieldBase { 30 31 public static int bitfields; 32 StructField(XmlElement elem, ClassBase container_type)33 public StructField (XmlElement elem, ClassBase container_type) : base (elem, container_type) {} 34 35 protected override string DefaultAccess { 36 get { 37 if (IsPadding) 38 return "private"; 39 40 return "public"; 41 } 42 } 43 44 int ArrayLength { 45 get { 46 if (!IsArray) 47 return 0; 48 49 int result; 50 try { 51 result = Int32.Parse (elem.GetAttribute("array_len")); 52 } catch (Exception) { 53 Console.Write ("Non-numeric array_len: " + elem.GetAttribute("array_len")); 54 Console.WriteLine (" warning: array field {0} incorrectly generated", Name); 55 result = 0; 56 } 57 return result; 58 } 59 } 60 61 bool IsNullTermArray { 62 get { return elem.GetAttributeAsBoolean ("null_term_array"); } 63 } 64 65 public new string CSType { 66 get { 67 string type = base.CSType; 68 if (IsArray) 69 type += "[]"; 70 else if ((IsPointer || SymbolTable.Table.IsOpaque (CType)) && type != "string") 71 type = "IntPtr"; 72 73 return type; 74 } 75 } 76 77 bool visible = false; 78 internal bool Visible { 79 get { 80 return visible; 81 } 82 } 83 84 public string EqualityName { 85 get { 86 SymbolTable table = SymbolTable.Table; 87 string wrapped_name = SymbolTable.Table.MangleName (CName); 88 IGeneratable gen = table [CType]; 89 90 if (IsArray || gen is IAccessor) 91 return StudlyName; 92 else if (IsBitfield) 93 return Name; 94 else if (IsPointer && (gen is StructGen || gen is BoxedGen || gen is UnionGen)) 95 return Access != "private" ? wrapped_name : Name; 96 else if (IsPointer && CSType != "string") 97 return Name; 98 else 99 return Access == "public" ? StudlyName : Name; 100 } 101 } 102 103 public bool IsPadding { 104 get { 105 return (CName.StartsWith ("dummy") || CName.StartsWith ("padding")); 106 } 107 } 108 109 public bool IsPointer { 110 get { 111 return (CType.EndsWith ("*") || CType.EndsWith ("pointer")); 112 } 113 } 114 115 public new string Name { 116 get { 117 string result = ""; 118 if ((IsPointer || SymbolTable.Table.IsOpaque (CType)) && CSType != "string") 119 result = "_"; 120 result += SymbolTable.Table.MangleName (CName); 121 122 return result; 123 } 124 } 125 126 public string StudlyName { 127 get { 128 string studly = base.Name; 129 if (studly == "") 130 throw new Exception ("API file must be regenerated with a current version of the GAPI parser. It is incompatible with this version of the GAPI code generator."); 131 132 return studly; 133 } 134 } 135 Generate(GenerationInfo gen_info, string indent)136 public override void Generate (GenerationInfo gen_info, string indent) 137 { 138 if (Hidden) 139 return; 140 141 visible = Access != "private"; 142 143 StreamWriter sw = gen_info.Writer; 144 SymbolTable table = SymbolTable.Table; 145 146 string wrapped = table.GetCSType (CType); 147 string wrapped_name = SymbolTable.Table.MangleName (CName); 148 IGeneratable gen = table [CType]; 149 150 if (IsArray && !IsNullTermArray) { 151 sw.WriteLine (indent + "[MarshalAs (UnmanagedType.ByValArray, SizeConst=" + ArrayLength + ")]"); 152 sw.WriteLine (indent + "{0} {1} {2};", Access, CSType, StudlyName); 153 } else if (IsArray && IsNullTermArray) { 154 sw.WriteLine (indent + "private {0} {1};", "IntPtr", StudlyName+ "Ptr"); 155 if ((Readable || Writable) && Access == "public") { 156 sw.WriteLine (indent + "public {0} {1} {{", CSType, StudlyName); 157 if (Readable) 158 sw.WriteLine (indent + "\tget {{ return GLib.Marshaller.StructArrayFromNullTerminatedIntPtr<{0}> ({1}); }}", 159 base.CSType, StudlyName + "Ptr"); 160 if (Writable) 161 sw.WriteLine (indent + "\tset {{ {0} = GLib.Marshaller.StructArrayToNullTerminatedStructArrayIntPtr<{1}> (value); }}", 162 StudlyName + "Ptr", base.CSType); 163 sw.WriteLine (indent + "}"); 164 } 165 } else if (IsBitfield) { 166 base.Generate (gen_info, indent); 167 } else if (gen is IAccessor) { 168 sw.WriteLine (indent + "private {0} {1};", gen.MarshalType, Name); 169 170 if (Access != "private") { 171 IAccessor acc = table [CType] as IAccessor; 172 sw.WriteLine (indent + Access + " " + wrapped + " " + StudlyName + " {"); 173 acc.WriteAccessors (sw, indent + "\t", Name); 174 sw.WriteLine (indent + "}"); 175 } 176 } else if (IsPointer && (gen is StructGen || gen is BoxedGen || gen is UnionGen)) { 177 sw.WriteLine (indent + "private {0} {1};", CSType, Name); 178 sw.WriteLine (); 179 if (Access != "private") { 180 sw.WriteLine (indent + Access + " " + wrapped + " " + wrapped_name + " {"); 181 sw.WriteLine (indent + "\tget { return " + table.FromNative (CType, Name) + "; }"); 182 sw.WriteLine (indent + "}"); 183 } 184 } else if (IsPointer && CSType != "string") { 185 // FIXME: probably some fields here which should be visible. 186 visible = false; 187 sw.WriteLine (indent + "private {0} {1};", CSType, Name); 188 } else { 189 sw.WriteLine (indent + "{0} {1} {2};", Access, CSType, Access == "public" ? StudlyName : Name); 190 } 191 } 192 } 193 } 194 195