コード例 #1
0
        public void BoolToIntSetForAllIntegerTypes(Type integerType)
        {
            var cppMarshallable = new CppMarshallable
            {
                TypeName       = "Integer",
                ArrayDimension = "0",
                IsArray        = true,
                Rule           = new MappingRule
                {
                    MappingType = "bool"
                }
            };

            var typeRegistry = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());

            typeRegistry.BindType("bool", typeRegistry.ImportType(typeof(bool)));
            typeRegistry.BindType("Integer", typeRegistry.ImportType(integerType));

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable);

            Assert.Equal(typeRegistry.ImportType(typeof(bool)), csMarshallable.PublicType);
            Assert.Equal(typeRegistry.ImportType(integerType), csMarshallable.MarshalType);
            Assert.True(csMarshallable.IsBoolToInt);
        }
コード例 #2
0
        public void NativeTypeTakesPrecedenceOverMarshalTypeForMappedType()
        {
            var cppMarshallable = new CppMarshallable
            {
                TypeName       = "short",
                ArrayDimension = "0",
                IsArray        = true,
                Rule           = new MappingRule
                {
                    MappingType = "bool"
                }
            };

            var typeRegistry = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());

            typeRegistry.BindType("bool", typeRegistry.ImportType(typeof(bool)), typeRegistry.ImportType(typeof(int)));
            typeRegistry.BindType("short", typeRegistry.ImportType(typeof(short)));

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable);

            Assert.Equal(typeRegistry.ImportType(typeof(bool)), csMarshallable.PublicType);
            Assert.Equal(typeRegistry.ImportType(typeof(short)), csMarshallable.MarshalType);
        }
コード例 #3
0
        public bool Apply(CppMarshallable marshallable, string name, string originalName, string originalNameLower,
                          out string[] variants)
        {
            variants = null;
            if (originalName.Length <= Prefix.Length + 1)
            {
                return(false);
            }

            if (!originalName.StartsWith(Prefix))
            {
                return(false);
            }

            if (!char.IsUpper(originalName[Prefix.Length]))
            {
                return(false);
            }

            var index = Selector(marshallable);

            if (index < 0)
            {
                return(false);
            }

            var content      = name.Substring(Prefix.Length);
            var contentLower = content.ToLowerInvariant();

            string SuffixWith(string suffix) => content + suffix;
            bool SuffixPredicate(string x) => !contentLower.Contains(x) && !originalNameLower.Contains(x);

            IEnumerable <string> preferredSuffixedVariants, secondarySuffixedVariants;

            switch (SuffixVariants.Length)
            {
            case > 0 when index >= SuffixVariants.Length:
                return(false);

            case > 0:
                preferredSuffixedVariants = new[] { SuffixVariants[index] }
                .Where(SuffixPredicate).Select(SuffixWith);
                secondarySuffixedVariants = SuffixVariants.Take(index)
                                            .Concat(SuffixVariants.Skip(index + 1))
                                            .Where(SuffixPredicate)
                                            .Select(SuffixWith);
                break;

            default:
                preferredSuffixedVariants = secondarySuffixedVariants = Enumerable.Empty <string>();
                break;
            }

            variants = new[] { content }.Concat(preferredSuffixedVariants).Concat(secondarySuffixedVariants)
            .ToArray();

            return(true);
        }
コード例 #4
0
        public void ParamWithNoTypeMappingShouldHaveMarshalTypeEqualToPublic()
        {
            var marshallable = new CppMarshallable
            {
                TypeName = "int"
            };

            var typeRegistry = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());

            typeRegistry.BindType("int", typeRegistry.ImportType(typeof(int)));

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(marshallable);

            Assert.Equal(csMarshallable.PublicType, csMarshallable.MarshalType);
        }
コード例 #5
0
        public void PointerToTypeWithMarshallingMarshalsAsUnderlyingType()
        {
            var cppMarshallable = new CppMarshallable
            {
                TypeName = "bool",
                Pointer  = "*"
            };

            var typeRegistry = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());

            typeRegistry.BindType("bool", typeRegistry.ImportType(typeof(bool)), typeRegistry.ImportType(typeof(int)));
            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable);

            Assert.Equal(typeRegistry.ImportType(typeof(int)), csMarshallable.MarshalType);
        }
コード例 #6
0
        public void CharPointerMappedToStringMarshalledWithIntPtr()
        {
            var cppMarshallable = new CppMarshallable
            {
                TypeName = "char",
                Pointer  = "*"
            };

            var typeRegistry = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable);

            Assert.Equal(typeRegistry.ImportType(typeof(string)), csMarshallable.PublicType);
            Assert.Equal(typeRegistry.ImportType(typeof(IntPtr)), csMarshallable.MarshalType);
            Assert.True(csMarshallable.HasPointer);
        }
コード例 #7
0
        public void ZeroDimensionArrayMappedAsSingleElement()
        {
            var cppMarshallable = new CppMarshallable
            {
                TypeName       = "int",
                ArrayDimension = "0",
                IsArray        = true
            };

            var typeRegistry = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());

            typeRegistry.BindType("int", typeRegistry.ImportType(typeof(int)));

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable);

            Assert.False(csMarshallable.IsArray);
        }
コード例 #8
0
        public void CharArrayMappedToStringMarshalledWithByte()
        {
            var cppMarshallable = new CppMarshallable
            {
                TypeName       = "char",
                IsArray        = true,
                ArrayDimension = "10"
            };

            var typeRegistry = new TypeRegistry(Logger, A.Fake <IDocumentationLinker>());

            var marshalledElementFactory = new MarshalledElementFactory(Logger, new GlobalNamespaceProvider(), typeRegistry);

            var csMarshallable = marshalledElementFactory.Create(cppMarshallable);

            Assert.Equal(typeRegistry.ImportType(typeof(string)), csMarshallable.PublicType);
            Assert.Equal(typeRegistry.ImportType(typeof(byte)), csMarshallable.MarshalType);
            Assert.Equal(10, csMarshallable.ArrayDimensionValue);
            Assert.True(csMarshallable.IsArray);
        }
コード例 #9
0
 protected CsMarshalCallableBase(Ioc ioc, CppMarshallable cppElement, string name) : base(ioc, cppElement, name)
 {
 }
コード例 #10
0
 protected CsMarshalCallableBase(CppMarshallable cppElement, string name) : base(cppElement, name)
 {
 }
コード例 #11
0
        /// <summary>
        /// Gets the C# type from a C++ type.
        /// </summary>
        /// <typeparam name="T">The C# type to return</typeparam>
        /// <param name="marshallable">The marshallable element to create the C# type from.</param>
        /// <returns>An instantiated C# type</returns>
        private T CreateCore <T>(CppMarshallable marshallable) where T : CsMarshalBase, new()
        {
            CsTypeBase publicType     = null;
            CsTypeBase marshalType    = null;
            var        csMarshallable = new T
            {
                CppElement = marshallable,
                IsArray    = marshallable.IsArray,
                HasPointer = !string.IsNullOrEmpty(marshallable.Pointer) && (marshallable.Pointer.Contains("*") || marshallable.Pointer.Contains("&")),
            };

            // TODO: handle multidimensional arrays
            // Calculate ArrayDimension
            int arrayDimensionValue = 0;

            if (marshallable.IsArray)
            {
                if (string.IsNullOrEmpty(marshallable.ArrayDimension))
                {
                    arrayDimensionValue = 0;
                }
                else if (!int.TryParse(marshallable.ArrayDimension, out arrayDimensionValue))
                {
                    arrayDimensionValue = 1;
                }
            }

            // If array Dimension is 0, then it is not an array
            if (arrayDimensionValue == 0)
            {
                marshallable.IsArray   = false;
                csMarshallable.IsArray = false;
            }
            csMarshallable.ArrayDimensionValue = arrayDimensionValue;

            string publicTypeName = marshallable.GetTypeNameWithMapping();

            switch (publicTypeName)
            {
            case "char":
                publicType = typeRegistry.ImportType(typeof(byte));
                if (csMarshallable.HasPointer)
                {
                    publicType = typeRegistry.ImportType(typeof(string));
                }
                if (csMarshallable.IsArray)
                {
                    publicType  = typeRegistry.ImportType(typeof(string));
                    marshalType = typeRegistry.ImportType(typeof(byte));
                }
                break;

            case "wchar_t":
                publicType = typeRegistry.ImportType(typeof(char));
                csMarshallable.IsWideChar = true;
                if (csMarshallable.HasPointer)
                {
                    publicType = typeRegistry.ImportType(typeof(string));
                }
                if (csMarshallable.IsArray)
                {
                    publicType  = typeRegistry.ImportType(typeof(string));
                    marshalType = typeRegistry.ImportType(typeof(char));
                }
                break;

            default:

                // If CppType is an array, try first to get the binding for this array
                if (marshallable.IsArray)
                {
                    publicType = typeRegistry.FindBoundType(publicTypeName + "[" + marshallable.ArrayDimension + "]");
                }

                // Else get the typeName
                if (publicType == null)
                {
                    // Try to get a declared type
                    // If it fails, then this type is unknown
                    publicType = typeRegistry.FindBoundType(publicTypeName);
                    if (publicType == null)
                    {
                        logger.Fatal("Unknown type found [{0}]", publicTypeName);
                    }
                }
                else
                {
                    csMarshallable.ArrayDimensionValue = 0;
                    csMarshallable.IsArray             = false;
                }

                // By default, use the underlying native type as the marshal type
                // if it differs from the public type.
                marshalType = typeRegistry.FindBoundType(marshallable.TypeName);
                if (publicType == marshalType)
                {
                    marshalType = null;
                }

                if (marshalType == null)
                {
                    // Otherwise, get the registered marshal type if one exists
                    marshalType = typeRegistry.FindBoundMarshalType(publicTypeName);
                }

                if (publicType is CsStruct csStruct)
                {
                    // If a structure was not already parsed, then parse it before going further
                    if (!csStruct.IsFullyMapped)
                    {
                        RequestStructProcessing?.Invoke(csStruct);
                    }

                    if (!csStruct.IsFullyMapped)     // No one tried to map the struct so we can't continue.
                    {
                        logger.Fatal($"No struct processor processed {csStruct.QualifiedName}. Cannot continue processing");
                    }

                    // If referenced structure has a specialized marshalling, then use the structure's built-in marshalling
                    if (csStruct.HasMarshalType && !csMarshallable.HasPointer)
                    {
                        marshalType = publicType;
                    }
                }
                else if (publicType is CsEnum referenceEnum)
                {
                    marshalType = null;     // enums don't need a marshal type. They can always marshal as their underlying type.
                }
                break;
            }

            // Set bool to int conversion case
            csMarshallable.IsBoolToInt =
                marshalType is CsFundamentalType marshalFundamental && IsIntegerFundamentalType(marshalFundamental) &&
                publicType is CsFundamentalType publicFundamental && publicFundamental.Type == typeof(bool);

            if (publicType.QualifiedName == globalNamespace.GetTypeName(WellKnownName.PointerSize))
            {
                marshalType = typeRegistry.ImportType(typeof(IntPtr));
            }

            // Present void* elements as IntPtr. Marshal strings as IntPtr
            if (csMarshallable.HasPointer)
            {
                if (publicTypeName == "void")
                {
                    publicType  = typeRegistry.ImportType(typeof(IntPtr));
                    marshalType = typeRegistry.ImportType(typeof(IntPtr));
                }
                else if (publicType == typeRegistry.ImportType(typeof(string)))
                {
                    marshalType = typeRegistry.ImportType(typeof(IntPtr));
                }
            }

            csMarshallable.PublicType  = publicType;
            csMarshallable.MarshalType = marshalType ?? publicType;

            csMarshallable.Relations = RelationParser.ParseRelation(marshallable.GetMappingRule().Relation, logger);

            return(csMarshallable);
        }
コード例 #12
0
 public CsMarshalBase Create(CppMarshallable cppMarshallable)
 {
     return(CreateCore <CsMarshalBase>(cppMarshallable));
 }