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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
protected CsMarshalCallableBase(Ioc ioc, CppMarshallable cppElement, string name) : base(ioc, cppElement, name) { }
protected CsMarshalCallableBase(CppMarshallable cppElement, string name) : base(cppElement, name) { }
/// <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); }
public CsMarshalBase Create(CppMarshallable cppMarshallable) { return(CreateCore <CsMarshalBase>(cppMarshallable)); }