Browse Source

Fix string marshalling bug and move hard to read code to CppSharp.Runtime (#1445)

pull/1446/head
josetr 5 years ago committed by GitHub
parent
commit
0cfc060018
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 47
      src/Generator/Types/Std/Stdlib.cs
  2. 34
      src/Runtime/MarshalUtil.cs

47
src/Generator/Types/Std/Stdlib.cs

@ -242,45 +242,18 @@ namespace CppSharp.Types.Std @@ -242,45 +242,18 @@ namespace CppSharp.Types.Std
}
string returnVarName = ctx.ReturnVarName;
string nullPtr = "global::System.IntPtr.Zero";
if (ctx.Function != null)
{
Type returnType = ctx.Function.ReturnType.Type.Desugar();
if (returnType.IsAddress() &&
returnType.GetPointee().Desugar().IsAddress())
{
returnVarName = $"*{returnVarName}";
nullPtr = "null";
returnVarName = $"new global::System.IntPtr(*{returnVarName})";
}
}
TextGenerator textGenerator;
if (ctx.Parameter == null)
{
textGenerator = ctx.Before;
textGenerator.WriteLine($"if ({ctx.ReturnVarName} == {nullPtr})");
textGenerator.WriteLineIndent($"return default({ctx.ReturnType});");
}
else
{
textGenerator = ctx.Cleanup;
textGenerator.WriteLine($"if ({ctx.ReturnVarName} == {nullPtr})");
textGenerator.WriteOpenBraceAndIndent();
textGenerator.WriteLine($"{ctx.Parameter.Name} = default({Type.Desugar()});");
textGenerator.WriteLine($"return{(ctx.Function.ReturnType.Type.IsPrimitiveType(PrimitiveType.Void) ? "" : " default")};");
textGenerator.UnindentAndWriteCloseBrace();
}
string encoding = GetEncoding().Name;
string type = GetTypeForCodePoint(encoding);
var retPtr = Generator.GeneratedIdentifier($"retPtr{ctx.ParameterIndex}");
var length = Generator.GeneratedIdentifier($"length{ctx.ParameterIndex}");
textGenerator.WriteLine($"var {retPtr} = ({type}*) {returnVarName};");
textGenerator.WriteLine($"int {length} = 0;");
textGenerator.WriteLine($"while (*({retPtr}++) != 0) {length} += sizeof({type});");
ctx.Return.Write($@"global::System.Text.Encoding.{
encoding}.GetString((byte*) {returnVarName}, {length})");
var encoding = $"global::System.Text.Encoding.{GetEncoding().Name}";
ctx.Return.Write($@"CppSharp.Runtime.MarshalUtil.GetString({encoding}, {returnVarName})");
}
private (Encoding Encoding, string Name) GetEncoding()
@ -310,20 +283,6 @@ namespace CppSharp.Types.Std @@ -310,20 +283,6 @@ namespace CppSharp.Types.Std
throw new System.NotSupportedException(
$"{Context.Options.Encoding.EncodingName} is not supported yet.");
}
private static string GetTypeForCodePoint(string encoding)
{
switch (encoding)
{
case nameof(Encoding.UTF32):
return "int";
case nameof(Encoding.Unicode):
case nameof(Encoding.BigEndianUnicode):
return "short";
default:
return "byte";
}
}
}
[TypeMap("const char[]", GeneratorKind = GeneratorKind.CSharp)]

34
src/Runtime/MarshalUtil.cs

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
using System;
using System.Text;
namespace CppSharp.Runtime
{
public unsafe static class MarshalUtil
{
public static string GetString(Encoding encoding, IntPtr str)
{
if (str == IntPtr.Zero)
return null;
int byteCount = 0;
if (encoding == Encoding.UTF32)
{
var str32 = (int*)str;
while (*(str32++) != 0) byteCount += sizeof(int);
}
else if (encoding == Encoding.Unicode || encoding == Encoding.BigEndianUnicode)
{
var str16 = (short*)str;
while (*(str16++) != 0) byteCount += sizeof(short);
}
else
{
var str8 = (byte*)str;
while (*(str8++) != 0) byteCount += sizeof(byte);
}
return encoding.GetString((byte*)str, byteCount);
}
}
}
Loading…
Cancel
Save