Beispiel #1
0
        public virtual void Generate(GenerationInfo generationInfo, string indent)
        {
            if (Ignored || Hidden)
            {
                return;
            }

            CheckGlue(generationInfo);

            GenerateImports(generationInfo, indent);

            if (Getter == null && _getterName == null && _offsetName == null &&
                Setter == null && _setterName == null)
            {
                return;
            }

            var streamWriter = generationInfo.Writer;
            var modifiers    = Element.GetAttributeAsBoolean("new_flag") ? "new " : "";

            streamWriter.WriteLine($"{indent}public {modifiers}{CsType} {Name} {{");

            var table       = SymbolTable.Table;
            var generatable = table[CType];

            if (Getter != null)
            {
                streamWriter.Write($"{indent}\tget ");
                Getter.GenerateBody(generationInfo, ContainerType, "\t");
                streamWriter.WriteLine("");
            }
            else if (_getterName != null)
            {
                streamWriter.WriteLine($"{indent}\tget {{");
                ContainerType.Prepare(streamWriter, $"{indent}\t\t");

                streamWriter.WriteLine(indent + "\t\t" + CsType + " result = " +
                                       table.FromNative(CType, _getterName + " (" + ContainerType.CallByName() + ")") +
                                       ";");

                ContainerType.Finish(streamWriter, $"{indent}\t\t");
                streamWriter.WriteLine($"{indent}\t\treturn result;");
                streamWriter.WriteLine($"{indent}\t}}");
            }
            else if (Readable && _offsetName != null)
            {
                streamWriter.WriteLine($"{indent}\tget {{");
                streamWriter.WriteLine($"{indent}\t\tunsafe {{");

                if (generatable is CallbackGen)
                {
                    streamWriter.WriteLine(indent + "\t\t\tIntPtr* raw_ptr = (IntPtr*)(((byte*)" +
                                           ContainerType.CallByName() +
                                           ") + " + _offsetName + ");");

                    streamWriter.WriteLine(
                        indent + "\t\t\t {0} del = ({0})Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof({0}));",
                        table.GetMarshalType(CType));

                    streamWriter.WriteLine($"{indent}\t\t\treturn {table.FromNative(CType, "(del)")};");
                }
                else
                {
                    streamWriter.WriteLine(indent + "\t\t\t" + table.GetMarshalType(CType) + "* raw_ptr = (" +
                                           table.GetMarshalType(CType) + "*)(((byte*)" + ContainerType.CallByName() +
                                           ") + " +
                                           _offsetName + ");");

                    streamWriter.WriteLine($"{indent}\t\t\treturn {table.FromNative(CType, "(*raw_ptr)")};");
                }

                streamWriter.WriteLine($"{indent}\t\t}}");
                streamWriter.WriteLine($"{indent}\t}}");
            }

            var toNative = generatable is IManualMarshaler marshaler
                ? marshaler.AllocNative("value")
                : generatable.CallByName("value");

            if (Setter != null)
            {
                streamWriter.Write($"{indent}\tset ");
                Setter.GenerateBody(generationInfo, ContainerType, "\t");
                streamWriter.WriteLine("");
            }
            else if (_setterName != null)
            {
                streamWriter.WriteLine($"{indent}\tset {{");
                ContainerType.Prepare(streamWriter, $"{indent}\t\t");

                streamWriter.WriteLine(
                    $"{indent}\t\t{_setterName} ({ContainerType.CallByName()}, {toNative});");

                ContainerType.Finish(streamWriter, $"{indent}\t\t");
                streamWriter.WriteLine($"{indent}\t}}");
            }
            else if (Writeable && _offsetName != null)
            {
                streamWriter.WriteLine($"{indent}\tset {{");
                streamWriter.WriteLine($"{indent}\t\tunsafe {{");

                if (generatable is CallbackGen callbackGen)
                {
                    streamWriter.WriteLine(indent + "\t\t\t{0} wrapper = new {0} (value);", callbackGen.WrapperName);
                    streamWriter.WriteLine(
                        $"{indent}\t\t\tIntPtr* raw_ptr = (IntPtr*)(((byte*){ContainerType.CallByName()}) + {_offsetName});");
                    streamWriter.WriteLine(
                        $"{indent}\t\t\t*raw_ptr = Marshal.GetFunctionPointerForDelegate (wrapper.NativeDelegate);");
                }
                else
                {
                    streamWriter.WriteLine(indent + "\t\t\t" + table.GetMarshalType(CType) + "* raw_ptr = (" +
                                           table.GetMarshalType(CType) + "*)(((byte*)" + ContainerType.CallByName() +
                                           ") + " +
                                           _offsetName + ");");
                    streamWriter.WriteLine($"{indent}\t\t\t*raw_ptr = {toNative};");
                }

                streamWriter.WriteLine($"{indent}\t\t}}");
                streamWriter.WriteLine($"{indent}\t}}");
            }

            streamWriter.WriteLine($"{indent}}}");
            streamWriter.WriteLine("");

            if ((_getterName != null || _setterName != null || GetOffsetName != null) &&
                generationInfo.GlueWriter != null)
            {
                GenerateGlue(generationInfo);
            }
        }