public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var matcher = Matcher.CType(
                new TupleCType(aNativeFunction.CurrentParameterType, aNativeFunction.NextParameterType));
            if (!matcher.Match(new TupleCType(
                new PointerCType(new NamedCType("char")),
                new NamedCType("int")
                )))
            {
                return false;
            }
            if (aNativeFunction.CurrentParameter.Name != "buffer") return false;
            if (aNativeFunction.NextParameter.Name != "buffer_size") return false;

            string parameterName = aNativeFunction.CurrentParameter.Name;
            string utf8StringName = "utf8_"+parameterName;
            aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, utf8StringName + ".IntPtr");
            aAssembler.AddPInvokeParameter(new CSharpType("int"), aNativeFunction.NextParameter.Name, utf8StringName + ".BufferLength");
            aAssembler.SetManagedReturn(new CSharpType("string"));
            aAssembler.InsertAtTop(      "string returnValue;");

            aAssembler.InsertBeforeCall("using (Utf8String " + utf8StringName + " = SpotifyMarshalling.AllocBuffer(256))");
            aAssembler.InsertBeforeCall("{");
            aAssembler.IncreaseIndent();
            aAssembler.InsertAfterCall("returnValue = " + utf8StringName + ".Value;");
            aAssembler.DecreaseIndent();
            aAssembler.InsertAfterCall("}");

            aAssembler.InsertAtEnd("return returnValue;");
            aNativeFunction.ConsumeArgument();
            aNativeFunction.ConsumeArgument();
            return true;
        }
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var firstArgType = aNativeFunction.CurrentParameterType;
            var secondArgType = aNativeFunction.NextParameterType;
            bool secondArgIsInt = secondArgType.MatchToPattern(new NamedCType("int")).IsMatch;
            if (!secondArgIsInt) { return false; }

            bool firstArgIsPointer = firstArgType is PointerCType;
            if (!firstArgIsPointer) { return false; }
            var derefOnceType = firstArgType.ChildType;

            bool firstArgIsPointerToPointer = derefOnceType is PointerCType;
            if (!firstArgIsPointerToPointer) { return false; }
            var derefTwiceType = derefOnceType.ChildType;

            bool firstArgIsPointerToPointerToNamedType =  derefTwiceType is NamedCType;
            if (!firstArgIsPointerToPointerToNamedType) { return false; }
            var elementType = (NamedCType)derefTwiceType;

            bool arrayIsMutable = !derefOnceType.Qualifiers.Contains("const");

            string arg1name = aNativeFunction.CurrentParameter.Name;
            string arg2name = aNativeFunction.NextParameter.Name;
            if (arg2name != "num_" + arg1name) { return false; }
            string className;
            if (!iHandlesToClassNames.TryGetValue(elementType.Name, out className)) { return false; }

            // Finally, we are sure that this is an array of handles.
            // Now we need to marshal the cursed thing!
            string paramName = aNativeFunction.CurrentParameter.Name;

            aAssembler.AddPInvokeParameter(
                new CSharpType("IntPtr"),
                paramName,
                "array_" + paramName + ".IntPtr");
            aAssembler.AddPInvokeParameter(
                new CSharpType("int"),
                "num_" + paramName,
                "array_" + paramName + ".Length");
            aAssembler.AddManagedParameter(
                paramName,
                new CSharpType(className + "[]"));

            aAssembler.InsertBeforeCall("using (var array_" + paramName + " = SpotifyMarshalling.ArrayToNativeArray(" + paramName + ", x=>x._handle))");
            aAssembler.InsertBeforeCall("{");
            aAssembler.IncreaseIndent();
            if (arrayIsMutable)
            {
                // Unless we pass in a 'handle * const *', the function might have changed
                // the content of the array, so copy it back.
                aAssembler.InsertAfterCall("array_" + paramName + ".CopyTo(" + paramName + ", ptr => ptr == IntPtr.Zero ? null : new " + className + "(ptr));");
            }
            aAssembler.DecreaseIndent();
            aAssembler.InsertAfterCall( "}");

            aNativeFunction.ConsumeArgument();
            aNativeFunction.ConsumeArgument();
            return true;
        }
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var matcher = Matcher.CType(new TupleCType(
                aNativeFunction.CurrentParameterType,
                aNativeFunction.NextParameterType));
            if (!matcher.Match(new TupleCType(
                new PointerCType(new VariableCType("element-type")),
                new NamedCType("int"))))
            {
                return false;
            }
            var elementType = matcher.BoundVariables["element-type"] as NamedCType;
            if (elementType == null) { return false; }
            string arg1name = aNativeFunction.CurrentParameter.Name;
            string arg2name = aNativeFunction.NextParameter.Name;
            if (arg2name != "num_" + arg1name) { return false; }

            string managedType;

            switch (elementType.Name)
            {
                case "int":
                    managedType = "int";
                    break;
                default:
                    return false;
            }

            // Finally, we are sure that this is an array of handles.
            // Now we need to marshal the cursed thing!
            string paramName = aNativeFunction.CurrentParameter.Name;

            aAssembler.AddPInvokeParameter(
                new CSharpType("IntPtr"),
                paramName,
                "array_" + paramName + ".IntPtr");
            aAssembler.AddPInvokeParameter(
                new CSharpType("int"),
                "num_" + paramName,
                "array_" + paramName + ".Length");
            aAssembler.AddManagedParameter(
                paramName,
                new CSharpType(managedType + "[]"));

            aAssembler.InsertBeforeCall("using (var array_" + paramName + " = SpotifyMarshalling.ArrayToNativeArray(" + paramName + "))");
            aAssembler.InsertBeforeCall("{");
            aAssembler.IncreaseIndent();
            aAssembler.InsertAfterCall(     "Array.Copy(array_"+paramName+".Value(), "+paramName+", "+paramName+".Length);");
            aAssembler.DecreaseIndent();
            aAssembler.InsertAfterCall("}");

            aNativeFunction.ConsumeArgument();
            aNativeFunction.ConsumeArgument();
            return true;
        }
示例#4
0
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            if (!aNativeFunction.CurrentParameterType.MatchToPattern(
                    new PointerCType(new NamedCType("char"))).IsMatch)
            {
                return(false);
            }
            if (-1 != Matcher.CType(aNativeFunction.CurrentParameterType).FirstMatch(
                    new NamedCType("size_t"),
                    new NamedCType("int")
                    ))
            {
                return(false);
            }
            if (!aNativeFunction.ReturnType.MatchToPattern(
                    new NamedCType("int")).IsMatch)
            {
                return(false);
            }
            if (aNativeFunction.CurrentParameterIndex != aNativeFunction.ParameterCount - 2)
            {
                return(false);
            }
            string lengthNativeType  = ((NamedCType)aNativeFunction.NextParameterType).Name;
            string lengthManagedType = lengthNativeType == "size_t" ? "UIntPtr" : "int";
            string parameterName     = aNativeFunction.CurrentParameter.Name;
            string utf8StringName    = "utf8_" + parameterName;

            aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, utf8StringName + ".IntPtr");
            aAssembler.AddPInvokeParameter(new CSharpType(lengthManagedType), aNativeFunction.NextParameter.Name, "(" + lengthManagedType + ")(" + utf8StringName + ".BufferLength)");
            aAssembler.SetPInvokeReturn(new CSharpType("int"), "stringLength_" + parameterName);
            aAssembler.SetManagedReturn(new CSharpType("string"));
            aAssembler.InsertAtTop("string returnValue;");
            aAssembler.InsertAtTop("int stringLength_" + parameterName + " = 256;");

            aAssembler.InsertBeforeCall("using (Utf8String " + utf8StringName + " = SpotifyMarshalling.AllocBuffer(stringLength_" + parameterName + "))");
            aAssembler.InsertBeforeCall("{");
            aAssembler.IncreaseIndent();
            aAssembler.InsertPreCall("stringLength_" + parameterName);
            aAssembler.InsertBeforeCall(utf8StringName + ".ReallocIfSmaller(stringLength_" + parameterName + " + 1);");

            aAssembler.InsertAfterCall("returnValue = " + utf8StringName + ".GetString(stringLength_" + parameterName + ");");
            aAssembler.DecreaseIndent();
            aAssembler.InsertAfterCall("}");

            aAssembler.InsertAtEnd("return returnValue;");
            aNativeFunction.ConsumeArgument();
            aNativeFunction.ConsumeArgument();
            aNativeFunction.ConsumeReturn();
            return(true);
        }
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            if (!aNativeFunction.CurrentParameterType.MatchToPattern(
                new PointerCType(new NamedCType("char"))).IsMatch)
            {
                return false;
            }
            if (-1 != Matcher.CType(aNativeFunction.CurrentParameterType).FirstMatch(
                new NamedCType("size_t"),
                new NamedCType("int")
                ))
            {
                return false;
            }
            if (!aNativeFunction.ReturnType.MatchToPattern(
                new NamedCType("int")).IsMatch)
            {
                return false;
            }
            if (aNativeFunction.CurrentParameterIndex != aNativeFunction.ParameterCount - 2)
            {
                return false;
            }
            string lengthNativeType = ((NamedCType)aNativeFunction.NextParameterType).Name;
            string lengthManagedType = lengthNativeType == "size_t" ? "UIntPtr" : "int";
            string parameterName = aNativeFunction.CurrentParameter.Name;
            string utf8StringName = "utf8_"+parameterName;
            aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, utf8StringName + ".IntPtr");
            aAssembler.AddPInvokeParameter(new CSharpType(lengthManagedType), aNativeFunction.NextParameter.Name, "(" + lengthManagedType + ")(" + utf8StringName + ".BufferLength)");
            aAssembler.SetPInvokeReturn(new CSharpType("int"), "stringLength_"+parameterName);
            aAssembler.SetManagedReturn(new CSharpType("string"));
            aAssembler.InsertAtTop(      "string returnValue;");
            aAssembler.InsertAtTop("int stringLength_" + parameterName + " = 256;");

            aAssembler.InsertBeforeCall("using (Utf8String " + utf8StringName + " = SpotifyMarshalling.AllocBuffer(stringLength_" + parameterName + "))");
            aAssembler.InsertBeforeCall("{");
            aAssembler.IncreaseIndent();
            aAssembler.InsertPreCall("stringLength_" + parameterName);
            aAssembler.InsertBeforeCall(utf8StringName + ".ReallocIfSmaller(stringLength_" + parameterName + " + 1);");

            aAssembler.InsertAfterCall("returnValue = " + utf8StringName + ".GetString(stringLength_" + parameterName + ");");
            aAssembler.DecreaseIndent();
            aAssembler.InsertAfterCall("}");

            aAssembler.InsertAtEnd("return returnValue;");
            aNativeFunction.ConsumeArgument();
            aNativeFunction.ConsumeArgument();
            aNativeFunction.ConsumeReturn();
            return true;
        }
示例#6
0
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var pointerType = aNativeFunction.CurrentParameterType as PointerCType;

            if (pointerType == null)
            {
                return(false);
            }
            var namedType = pointerType.BaseType as NamedCType;

            if (namedType == null)
            {
                return(false);
            }
            string className;

            if (!iHandlesToClassNames.TryGetValue(namedType.Name, out className))
            {
                return(false);
            }

            aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, aNativeFunction.CurrentParameter.Name + "._handle");
            aAssembler.AddManagedParameter(aNativeFunction.CurrentParameter.Name, new CSharpType(className));
            aNativeFunction.ConsumeArgument();
            return(true);
        }
 public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
 {
     NamedCType nativeType = aNativeFunction.CurrentParameterType as NamedCType;
     if (nativeType == null) return false;
     CSharpType pinvokeArgType;
     CSharpType managedArgType;
     switch (nativeType.Name)
     {
         case "bool":
             pinvokeArgType = new CSharpType("bool"){ Attributes = { "MarshalAs(UnmanagedType.I1)" } };
             managedArgType = new CSharpType("bool");
             break;
         case "int":
             pinvokeArgType = managedArgType = new CSharpType("int");
             break;
         case "size_t":
             pinvokeArgType = managedArgType = new CSharpType("UIntPtr");
             break;
         default:
             string managedEnumName;
             if (!iEnumNativeToManagedMappings.TryGetValue(nativeType.Name, out managedEnumName))
             {
                 return false;
             }
             pinvokeArgType = managedArgType = new CSharpType(managedEnumName);
             break;
     }
     aAssembler.AddPInvokeParameter(pinvokeArgType, aNativeFunction.CurrentParameter.Name, aNativeFunction.CurrentParameter.Name);
     aAssembler.AddManagedParameter(aNativeFunction.CurrentParameter.Name, managedArgType);
     aNativeFunction.ConsumeArgument();
     return true;
 }
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var pointerType = aNativeFunction.CurrentParameterType as PointerCType;

            if (pointerType == null)
            {
                return(false);
            }
            var namedType = pointerType.BaseType as NamedCType;

            if (namedType == null)
            {
                return(false);
            }

            switch (namedType.Name)
            {
            case "void":
                break;

            default:
                return(false);
            }

            aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, null);
            aAssembler.SuppressManagedWrapper();
            aNativeFunction.ConsumeArgument();
            return(true);
        }
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var pointerType = aNativeFunction.CurrentParameterType as PointerCType;

            if (pointerType == null)
            {
                return(false);
            }
            var namedType = pointerType.BaseType as NamedCType;

            if (namedType == null)
            {
                return(false);
            }
            string structName;

            if (!iHandlesToStructNames.TryGetValue(namedType.Name, out structName))
            {
                return(false);
            }

            aAssembler.AddPInvokeParameter(new CSharpType(structName)
            {
                IsRef = true
            }, aNativeFunction.CurrentParameter.Name, null);
            aAssembler.SuppressManagedWrapper();
            aNativeFunction.ConsumeArgument();
            return(true);
        }
示例#10
0
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var matcher = Matcher.CType(
                new TupleCType(aNativeFunction.CurrentParameterType, aNativeFunction.NextParameterType));

            if (!matcher.Match(new TupleCType(
                                   new PointerCType(new NamedCType("char")),
                                   new NamedCType("int")
                                   )))
            {
                return(false);
            }
            if (aNativeFunction.CurrentParameter.Name != "buffer")
            {
                return(false);
            }
            if (aNativeFunction.NextParameter.Name != "buffer_size")
            {
                return(false);
            }

            string parameterName  = aNativeFunction.CurrentParameter.Name;
            string utf8StringName = "utf8_" + parameterName;

            aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, utf8StringName + ".IntPtr");
            aAssembler.AddPInvokeParameter(new CSharpType("int"), aNativeFunction.NextParameter.Name, utf8StringName + ".BufferLength");
            aAssembler.SetManagedReturn(new CSharpType("string"));
            aAssembler.InsertAtTop("string returnValue;");

            aAssembler.InsertBeforeCall("using (Utf8String " + utf8StringName + " = SpotifyMarshalling.AllocBuffer(256))");
            aAssembler.InsertBeforeCall("{");
            aAssembler.IncreaseIndent();
            aAssembler.InsertAfterCall("returnValue = " + utf8StringName + ".Value;");
            aAssembler.DecreaseIndent();
            aAssembler.InsertAfterCall("}");

            aAssembler.InsertAtEnd("return returnValue;");
            aNativeFunction.ConsumeArgument();
            aNativeFunction.ConsumeArgument();
            return(true);
        }
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var pointerType = aNativeFunction.CurrentParameterType as PointerCType;
            if (pointerType == null) return false;
            var namedType = pointerType.BaseType as NamedCType;
            if (namedType == null) return false;

            // Accept anything.

            aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, null);
            aAssembler.SuppressManagedWrapper();
            aNativeFunction.ConsumeArgument();
            return true;
        }
 public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
 {
     if (aNativeFunction.CurrentParameterIndex != 0)
     {
         return(false);
     }
     if (!aNativeFunction.CurrentParameterType.MatchToPattern(new PointerCType(new NamedCType(HandleType))).IsMatch)
     {
         return(false);
     }
     aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, "this._handle");
     aAssembler.IsStatic = false;
     aNativeFunction.ConsumeArgument();
     return(true);
 }
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var pointerType = aNativeFunction.CurrentParameterType as PointerCType;
            if (pointerType == null) return false;
            var namedType = pointerType.BaseType as NamedCType;
            if (namedType == null) return false;
            string structName;
            if (!iHandlesToStructNames.TryGetValue(namedType.Name, out structName))
            {
                return false;
            }

            aAssembler.AddPInvokeParameter(new CSharpType(structName) { IsRef = true }, aNativeFunction.CurrentParameter.Name, null);
            aAssembler.SuppressManagedWrapper();
            aNativeFunction.ConsumeArgument();
            return true;
        }
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var pointerType = aNativeFunction.CurrentParameterType as PointerCType;
            if (pointerType == null) return false;
            var namedType = pointerType.BaseType as NamedCType;
            if (namedType == null) return false;
            string className;
            if (!iHandlesToClassNames.TryGetValue(namedType.Name, out className))
            {
                return false;
            }

            aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, aNativeFunction.CurrentParameter.Name + "._handle");
            aAssembler.AddManagedParameter(aNativeFunction.CurrentParameter.Name, new CSharpType(className));
            aNativeFunction.ConsumeArgument();
            return true;
        }
 public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
 {
     var matcher = Matcher.CType(aNativeFunction.CurrentParameterType);
     if (!matcher.Match(new PointerCType(new NamedCType("char") { Qualifiers = { "const" } })))
     {
         return false;
     }
     string utf8StringName = "utf8_" + aNativeFunction.CurrentParameter.Name;
     aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, utf8StringName + ".IntPtr");
     aAssembler.AddManagedParameter(aNativeFunction.CurrentParameter.Name, new CSharpType("string"));
     aAssembler.InsertBeforeCall("using (Utf8String " + utf8StringName + " = SpotifyMarshalling.StringToUtf8(" + aNativeFunction.CurrentParameter.Name + "))");
     aAssembler.InsertBeforeCall("{");
     aAssembler.IncreaseIndent();
     aAssembler.DecreaseIndent();
     aAssembler.InsertAfterCall("}");
     aNativeFunction.ConsumeArgument();
     return true;
 }
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            PointerCType pointer1Type = aNativeFunction.CurrentParameterType as PointerCType;
            if (pointer1Type == null) return false;
            PointerCType pointer2Type = pointer1Type.BaseType as PointerCType;
            if (pointer2Type == null) return false;
            NamedCType nativeType = pointer2Type.BaseType as NamedCType;
            if (nativeType == null) return false;
            if (!iHandleNames.Contains(nativeType.Name)) return false;

            aAssembler.AddPInvokeParameter(
                new CSharpType("IntPtr") { IsRef = true },
                aNativeFunction.CurrentParameter.Name,
                null);
            aAssembler.SuppressManagedWrapper();
            aNativeFunction.ConsumeArgument();
            return true;
        }
示例#17
0
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            NamedCType nativeType = aNativeFunction.CurrentParameterType as NamedCType;

            if (nativeType == null)
            {
                return(false);
            }
            CSharpType pinvokeArgType;
            CSharpType managedArgType;

            switch (nativeType.Name)
            {
            case "bool":
                pinvokeArgType = new CSharpType("bool")
                {
                    Attributes = { "MarshalAs(UnmanagedType.I1)" }
                };
                managedArgType = new CSharpType("bool");
                break;

            case "int":
                pinvokeArgType = managedArgType = new CSharpType("int");
                break;

            case "size_t":
                pinvokeArgType = managedArgType = new CSharpType("UIntPtr");
                break;

            default:
                string managedEnumName;
                if (!iEnumNativeToManagedMappings.TryGetValue(nativeType.Name, out managedEnumName))
                {
                    return(false);
                }
                pinvokeArgType = managedArgType = new CSharpType(managedEnumName);
                break;
            }
            aAssembler.AddPInvokeParameter(pinvokeArgType, aNativeFunction.CurrentParameter.Name, aNativeFunction.CurrentParameter.Name);
            aAssembler.AddManagedParameter(aNativeFunction.CurrentParameter.Name, managedArgType);
            aNativeFunction.ConsumeArgument();
            return(true);
        }
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var arrayType = aNativeFunction.CurrentParameterType as ArrayCType;
            if (arrayType == null) return false;
            var namedType = arrayType.BaseType as NamedCType;
            if (namedType == null) return false;

            switch (namedType.Name)
            {
                case "byte":
                    break;
                default:
                    return false;
            }

            aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, null);
            aAssembler.SuppressManagedWrapper();
            aNativeFunction.ConsumeArgument();
            return true;
        }
示例#19
0
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var matcher = Matcher.CType(aNativeFunction.CurrentParameterType);

            if (!matcher.Match(new PointerCType(new NamedCType("char")
            {
                Qualifiers = { "const" }
            })))
            {
                return(false);
            }
            string utf8StringName = "utf8_" + aNativeFunction.CurrentParameter.Name;

            aAssembler.AddPInvokeParameter(new CSharpType("IntPtr"), aNativeFunction.CurrentParameter.Name, utf8StringName + ".IntPtr");
            aAssembler.AddManagedParameter(aNativeFunction.CurrentParameter.Name, new CSharpType("string"));
            aAssembler.InsertBeforeCall("using (Utf8String " + utf8StringName + " = SpotifyMarshalling.StringToUtf8(" + aNativeFunction.CurrentParameter.Name + "))");
            aAssembler.InsertBeforeCall("{");
            aAssembler.IncreaseIndent();
            aAssembler.DecreaseIndent();
            aAssembler.InsertAfterCall("}");
            aNativeFunction.ConsumeArgument();
            return(true);
        }
示例#20
0
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            PointerCType pointer1Type = aNativeFunction.CurrentParameterType as PointerCType;

            if (pointer1Type == null)
            {
                return(false);
            }
            PointerCType pointer2Type = pointer1Type.BaseType as PointerCType;

            if (pointer2Type == null)
            {
                return(false);
            }
            NamedCType nativeType = pointer2Type.BaseType as NamedCType;

            if (nativeType == null)
            {
                return(false);
            }
            if (!iHandleNames.Contains(nativeType.Name))
            {
                return(false);
            }

            aAssembler.AddPInvokeParameter(
                new CSharpType("IntPtr")
            {
                IsRef = true
            },
                aNativeFunction.CurrentParameter.Name,
                null);
            aAssembler.SuppressManagedWrapper();
            aNativeFunction.ConsumeArgument();
            return(true);
        }
示例#21
0
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var matcher = Matcher.CType(new TupleCType(
                                            aNativeFunction.CurrentParameterType,
                                            aNativeFunction.NextParameterType));

            if (!matcher.Match(new TupleCType(
                                   new PointerCType(new VariableCType("element-type")),
                                   new NamedCType("int"))))
            {
                return(false);
            }
            var elementType = matcher.BoundVariables["element-type"] as NamedCType;

            if (elementType == null)
            {
                return(false);
            }
            string arg1name = aNativeFunction.CurrentParameter.Name;
            string arg2name = aNativeFunction.NextParameter.Name;

            if (arg2name != "num_" + arg1name)
            {
                return(false);
            }

            string managedType;

            switch (elementType.Name)
            {
            case "int":
                managedType = "int";
                break;

            default:
                return(false);
            }

            // Finally, we are sure that this is an array of handles.
            // Now we need to marshal the cursed thing!
            string paramName = aNativeFunction.CurrentParameter.Name;

            aAssembler.AddPInvokeParameter(
                new CSharpType("IntPtr"),
                paramName,
                "array_" + paramName + ".IntPtr");
            aAssembler.AddPInvokeParameter(
                new CSharpType("int"),
                "num_" + paramName,
                "array_" + paramName + ".Length");
            aAssembler.AddManagedParameter(
                paramName,
                new CSharpType(managedType + "[]"));

            aAssembler.InsertBeforeCall("using (var array_" + paramName + " = SpotifyMarshalling.ArrayToNativeArray(" + paramName + "))");
            aAssembler.InsertBeforeCall("{");
            aAssembler.IncreaseIndent();
            aAssembler.InsertAfterCall("Array.Copy(array_" + paramName + ".Value(), " + paramName + ", " + paramName + ".Length);");
            aAssembler.DecreaseIndent();
            aAssembler.InsertAfterCall("}");

            aNativeFunction.ConsumeArgument();
            aNativeFunction.ConsumeArgument();
            return(true);
        }
        public bool Apply(IFunctionSpecificationAnalyser aNativeFunction, IFunctionAssembler aAssembler)
        {
            var  firstArgType   = aNativeFunction.CurrentParameterType;
            var  secondArgType  = aNativeFunction.NextParameterType;
            bool secondArgIsInt = secondArgType.MatchToPattern(new NamedCType("int")).IsMatch;

            if (!secondArgIsInt)
            {
                return(false);
            }

            bool firstArgIsPointer = firstArgType is PointerCType;

            if (!firstArgIsPointer)
            {
                return(false);
            }
            var derefOnceType = firstArgType.ChildType;

            bool firstArgIsPointerToPointer = derefOnceType is PointerCType;

            if (!firstArgIsPointerToPointer)
            {
                return(false);
            }
            var derefTwiceType = derefOnceType.ChildType;

            bool firstArgIsPointerToPointerToNamedType = derefTwiceType is NamedCType;

            if (!firstArgIsPointerToPointerToNamedType)
            {
                return(false);
            }
            var elementType = (NamedCType)derefTwiceType;

            bool arrayIsMutable = !derefOnceType.Qualifiers.Contains("const");

            string arg1name = aNativeFunction.CurrentParameter.Name;
            string arg2name = aNativeFunction.NextParameter.Name;

            if (arg2name != "num_" + arg1name)
            {
                return(false);
            }
            string className;

            if (!iHandlesToClassNames.TryGetValue(elementType.Name, out className))
            {
                return(false);
            }

            // Finally, we are sure that this is an array of handles.
            // Now we need to marshal the cursed thing!
            string paramName = aNativeFunction.CurrentParameter.Name;

            aAssembler.AddPInvokeParameter(
                new CSharpType("IntPtr"),
                paramName,
                "array_" + paramName + ".IntPtr");
            aAssembler.AddPInvokeParameter(
                new CSharpType("int"),
                "num_" + paramName,
                "array_" + paramName + ".Length");
            aAssembler.AddManagedParameter(
                paramName,
                new CSharpType(className + "[]"));

            aAssembler.InsertBeforeCall("using (var array_" + paramName + " = SpotifyMarshalling.ArrayToNativeArray(" + paramName + ", x=>x._handle))");
            aAssembler.InsertBeforeCall("{");
            aAssembler.IncreaseIndent();
            if (arrayIsMutable)
            {
                // Unless we pass in a 'handle * const *', the function might have changed
                // the content of the array, so copy it back.
                aAssembler.InsertAfterCall("array_" + paramName + ".CopyTo(" + paramName + ", ptr => ptr == IntPtr.Zero ? null : new " + className + "(ptr));");
            }
            aAssembler.DecreaseIndent();
            aAssembler.InsertAfterCall("}");

            aNativeFunction.ConsumeArgument();
            aNativeFunction.ConsumeArgument();
            return(true);
        }