Ejemplo n.º 1
0
        protected ClassBase(XmlElement namespaceElement, XmlElement element) : base(namespaceElement, element)
        {
            IsDeprecated     = element.GetAttributeAsBoolean(Constants.Deprecated);
            IsAbstract       = element.GetAttributeAsBoolean(Constants.Abstract);
            IsAbiFieldsValid = true;

            var parentType = Element.GetAttribute(Constants.Parent);

            var abiFieldsCount = 0;

            foreach (XmlNode node in element.ChildNodes)
            {
                if (!(node is XmlElement))
                {
                    continue;
                }

                var            member   = (XmlElement)node;
                StructAbiField abiField = null;

                switch (member.Name)
                {
                // Make sure ABI fields are taken into account, even when hidden.
                case Constants.Field:
                {
                    abiFieldsCount += 1;

                    // Skip instance parent struct if present, taking into account
                    // bindinator broken behaviour concerning parent field (ie.
                    // marking it as pointer, somehow risky but good enough for now.)
                    if (abiFieldsCount != 1 || parentType == "" ||
                        member.GetAttribute(Constants.Type).Replace("*", "") != parentType)
                    {
                        abiField = new StructAbiField(member, this, "abi_info");
                        AbiFields.Add(abiField);
                    }

                    break;
                }

                case "union":
                    abiField = new UnionAbiField(member, this, "abi_info");
                    AbiFields.Add(abiField);
                    break;
                }

                if (member.GetAttributeAsBoolean(Constants.Hidden))
                {
                    continue;
                }

                string name;

                switch (member.Name)
                {
                case Constants.Method:
                    name = member.GetAttribute(Constants.Name);

                    while (Methods.ContainsKey(name))
                    {
                        name += "mangled";
                    }

                    Methods.Add(name, new Method(member, this));
                    break;

                case Constants.Property:
                    name = member.GetAttribute(Constants.Name);

                    while (Properties.ContainsKey(name))
                    {
                        name += "mangled";
                    }

                    Properties.Add(name, new Property(member, this));
                    break;

                case Constants.Field:
                    //TODO: Generate callbacks.
                    if (member.GetAttributeAsBoolean("is_callback"))
                    {
                        continue;
                    }

                    name = member.GetAttribute(Constants.Name);

                    while (_fields.ContainsKey(name))
                    {
                        name += "mangled";
                    }

                    var field = new ObjectField(member, this);
                    field.AbiField = abiField;
                    _fields.Add(name, field);
                    break;

                case Constants.Implements:
                    ParseImplements(member);
                    break;

                case Constants.Constructor:
                    Constructors.Add(new Ctor(member, this));
                    break;

                case "constant":
                    name = member.GetAttribute(Constants.Name);
                    _constants.Add(name, new Constant(member));
                    break;
                }
            }
        }
Ejemplo n.º 2
0
        protected void GenerateStructAbi(GenerationInfo generationInfo, IList <StructAbiField> fields,
                                         string infoName, string structName)
        {
            if (fields == null)
            {
                fields = AbiFields;
            }

            var logWriter = new LogWriter(QualifiedName);

            if (!CheckStructAbiParent(logWriter, out var csParentStruct))
            {
                return;
            }

            var streamWriter = generationInfo.Writer;

            streamWriter.WriteLine();
            streamWriter.WriteLine("\t\t// Internal representation of the wrapped structure ABI.");
            streamWriter.WriteLine($"\t\tstatic GLib.AbiStruct _{infoName} = null;");
            streamWriter.WriteLine(
                $"\t\tstatic public {(!string.IsNullOrEmpty(csParentStruct) ? "new " : "")}GLib.AbiStruct {infoName} {{");
            streamWriter.WriteLine("\t\t\tget {");
            streamWriter.WriteLine($"\t\t\t\tif (_{infoName} == null)");

            // Generate Tests
            var usingParentFields = false;

            if (fields.Count > 0)
            {
                streamWriter.WriteLine($"\t\t\t\t\t_{infoName} = new GLib.AbiStruct (new List<GLib.AbiField>{{ ");

                if (generationInfo.CAbiWriter != null)
                {
                    generationInfo.CAbiWriter.WriteLine(
                        "\tg_print(\"\\\"sizeof({0})\\\": \\\"%\" G_GUINT64_FORMAT \"\\\"\\n\", (guint64) sizeof({0}));",
                        structName);
                    generationInfo.AbiWriter.WriteLine(
                        "\t\t\tConsole.WriteLine(\"\\\"sizeof({0})\\\": \\\"\" + {1}.{2}.{3}.Size + \"\\\"\");",
                        structName, Namespace, Name, infoName);
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(csParentStruct))
                {
                    streamWriter.WriteLine("\t\t\t\t\t_{1} = new GLib.AbiStruct ({0}.{1}.Fields);", csParentStruct, infoName);
                    usingParentFields = true;
                }
                else
                {
                    streamWriter.WriteLine("\t\t\t\t\t_{0} = new GLib.AbiStruct (new List<GLib.AbiField>{{ ", infoName);
                }
            }

            StructAbiField previous = null;
            var            fieldAlignmentStructuresWriter = new StringWriter();

            for (var i = 0; i < fields.Count; i++)
            {
                var field = fields[i];
                var next  = fields.Count > i + 1 ? fields[i + 1] : null;

                previous = field.Generate(generationInfo, "\t\t\t\t\t", previous, next, csParentStruct,
                                          fieldAlignmentStructuresWriter);

                if (field is UnionAbiField || generationInfo.CAbiWriter == null || field.IsBitfield)
                {
                    continue;
                }

                generationInfo.CAbiWriter.WriteLine(
                    "\tg_print(\"\\\"{0}.{1}\\\": \\\"%\" G_GUINT64_FORMAT \"\\\"\\n\", (guint64) G_STRUCT_OFFSET({0}, {1}));",
                    structName, field.CName);
                generationInfo.AbiWriter.WriteLine(
                    "\t\t\tConsole.WriteLine(\"\\\"{0}.{3}\\\": \\\"\" + {1}.{2}.{4}.GetFieldOffset(\"{3}\") + \"\\\"\");",
                    structName, Namespace, Name, field.CName, infoName);
            }

            if (fields.Count > 0 && generationInfo.CAbiWriter != null)
            {
                generationInfo.AbiWriter.Flush();
                generationInfo.CAbiWriter.Flush();
            }

            if (!usingParentFields)
            {
                streamWriter.WriteLine("\t\t\t\t\t});");
            }

            streamWriter.WriteLine();
            streamWriter.WriteLine($"\t\t\t\treturn _{infoName};");
            streamWriter.WriteLine("\t\t\t}");
            streamWriter.WriteLine("\t\t}");
            streamWriter.WriteLine();

            streamWriter.WriteLine(fieldAlignmentStructuresWriter.ToString());
            streamWriter.WriteLine("\t\t// End of the ABI representation.");
            streamWriter.WriteLine();
        }