SharpGen/Generator/Marshallers/MarshallerBase.CopyMemory.cs (89 lines of code) (raw):

using System; using System.Linq; using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using SharpGen.Model; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace SharpGen.Generator.Marshallers { internal abstract partial class MarshallerBase { protected static readonly PredefinedTypeSyntax TypeInt32 = PredefinedType(Token(SyntaxKind.IntKeyword)); protected static readonly PredefinedTypeSyntax TypeUInt32 = PredefinedType(Token(SyntaxKind.UIntKeyword)); protected const string FromIdentifier = "__from"; protected const string ToIdentifier = "__to"; protected ExpressionStatementSyntax GenerateCopyMemoryInvocation(ExpressionSyntax numBytesExpression, bool castTo = true, bool castFrom = true) => GenerateCopyMemoryInvocation( IntPtrArgumentWithOptionalCast(IdentifierName(ToIdentifier), castTo), IntPtrArgumentWithOptionalCast(IdentifierName(FromIdentifier), castFrom), numBytesExpression ); protected static ExpressionSyntax IntPtrArgumentWithOptionalCast(ExpressionSyntax name, bool cast) => cast ? GeneratorHelpers.CastExpression(IntPtrType, name) : name; protected ExpressionStatementSyntax GenerateCopyMemoryInvocation( ExpressionSyntax destination, ExpressionSyntax source, ExpressionSyntax numBytesExpression ) => ExpressionStatement( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GlobalNamespace.GetTypeNameSyntax(WellKnownName.MemoryHelpers), IdentifierName("CopyMemory") ), ArgumentList( SeparatedList( new[] { Argument(destination), Argument(source), Argument(numBytesExpression) } ) ) ) ); protected ExpressionSyntax SizeOf(TypeSyntax elementType) { if (elementType is PredefinedTypeSyntax {Keyword: var predefinedType}) { static LiteralExpressionSyntax LiteralSizeOf(uint size) => LiteralExpression( SyntaxKind.NumericLiteralExpression, Literal(size) ); bool CheckKinds(params SyntaxKind[] kinds) => kinds.Any(x => predefinedType.IsKind(x)); if (CheckKinds(SyntaxKind.ByteKeyword, SyntaxKind.SByteKeyword)) return LiteralSizeOf(1); if (CheckKinds(SyntaxKind.ShortKeyword, SyntaxKind.UShortKeyword)) return LiteralSizeOf(2); if (CheckKinds(SyntaxKind.IntKeyword, SyntaxKind.UIntKeyword)) return LiteralSizeOf(4); if (CheckKinds(SyntaxKind.LongKeyword, SyntaxKind.ULongKeyword)) return LiteralSizeOf(8); } ExpressionSyntax value = elementType switch { QualifiedNameSyntax qualifiedName when qualifiedName.IsEquivalentTo(GeneratorHelpers.IntPtrType) => MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, qualifiedName, IdentifierName(nameof(IntPtr.Size)) ), QualifiedNameSyntax qualifiedName when qualifiedName.IsEquivalentTo(GeneratorHelpers.UIntPtrType) => MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, qualifiedName, IdentifierName(nameof(UIntPtr.Size)) ), _ => InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GlobalNamespace.GetTypeNameSyntax(BuiltinType.Unsafe), GenericName( Identifier(nameof(Unsafe.SizeOf)), TypeArgumentList(SingletonSeparatedList(elementType)) ) ) ) }; return GeneratorHelpers.CastExpression(TypeUInt32, value); } protected ExpressionSyntax SizeOf(CsTypeBase elementType) => SizeOf(ParseTypeName(elementType.QualifiedName)); } }