|
|
|
@ -155,49 +155,50 @@ namespace CppSharp.Types.Std |
|
|
|
return new CustomType(typePrinter.IntPtrType); |
|
|
|
return new CustomType(typePrinter.IntPtrType); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Type type = Type.Desugar(); |
|
|
|
var (enconding, _) = GetEncoding(); |
|
|
|
|
|
|
|
|
|
|
|
uint charWidth = 0; |
|
|
|
if (enconding == Encoding.ASCII) |
|
|
|
if (type is PointerType pointerType) |
|
|
|
return new CustomType("[MarshalAs(UnmanagedType.LPStr)] string"); |
|
|
|
charWidth = GetCharPtrWidth(pointerType); |
|
|
|
else if (enconding == Encoding.UTF8) |
|
|
|
else if (type.GetPointee()?.Desugar() is PointerType pointeePointerType) |
|
|
|
|
|
|
|
charWidth = GetCharPtrWidth(pointeePointerType); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (charWidth == 8) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (Context.Options.Encoding == Encoding.ASCII) |
|
|
|
|
|
|
|
return new CustomType("[MarshalAs(UnmanagedType.LPStr)] string"); |
|
|
|
|
|
|
|
return new CustomType("[MarshalAs(UnmanagedType.LPUTF8Str)] string"); |
|
|
|
return new CustomType("[MarshalAs(UnmanagedType.LPUTF8Str)] string"); |
|
|
|
} |
|
|
|
else if (enconding == Encoding.Unicode || enconding == Encoding.BigEndianUnicode) |
|
|
|
|
|
|
|
|
|
|
|
if (Context.Options.Encoding == Encoding.Unicode || |
|
|
|
|
|
|
|
Context.Options.Encoding == Encoding.BigEndianUnicode) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// NOTE: This will break if charWidth is not 16 bit which may
|
|
|
|
|
|
|
|
// happen if someone uses wchar_t on platforms where it's size is 32 bit.
|
|
|
|
|
|
|
|
// TODO: Create a custom marshaller to support that scenario.
|
|
|
|
|
|
|
|
// Once that's done consider supporting char32_t as well
|
|
|
|
|
|
|
|
return new CustomType("[MarshalAs(UnmanagedType.LPWStr)] string"); |
|
|
|
return new CustomType("[MarshalAs(UnmanagedType.LPWStr)] string"); |
|
|
|
} |
|
|
|
else if (enconding == Encoding.UTF32) |
|
|
|
|
|
|
|
return new CustomType("[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CppSharp.Runtime.UTF32Marshaller))] string"); |
|
|
|
if (Context.Options.Encoding == Encoding.UTF8 && charWidth == 16) |
|
|
|
|
|
|
|
return new CustomType("[MarshalAs(UnmanagedType.LPWStr)] string"); // fallback;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
throw new System.NotSupportedException( |
|
|
|
throw new System.NotSupportedException( |
|
|
|
$"{Context.Options.Encoding.EncodingName} is not supported yet."); |
|
|
|
$"{Context.Options.Encoding.EncodingName} is not supported yet."); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public uint GetCharWidth() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Type type = Type.Desugar(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (type is PointerType pointerType) |
|
|
|
|
|
|
|
return GetCharPtrWidth(pointerType); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (type.GetPointee()?.Desugar() is PointerType pointeePointerType) |
|
|
|
|
|
|
|
return GetCharPtrWidth(pointeePointerType); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public uint GetCharPtrWidth(PointerType pointer) |
|
|
|
public uint GetCharPtrWidth(PointerType pointer) |
|
|
|
{ |
|
|
|
{ |
|
|
|
var pointee = pointer?.Pointee?.Desugar(); |
|
|
|
var pointee = pointer?.Pointee?.Desugar(); |
|
|
|
if (pointee != null) |
|
|
|
if (pointee != null && pointee.IsPrimitiveType(out var primitiveType)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (pointee.IsPrimitiveType(PrimitiveType.Char)) |
|
|
|
switch (primitiveType) |
|
|
|
return Context.TargetInfo.CharWidth; |
|
|
|
{ |
|
|
|
if (pointee.IsPrimitiveType(PrimitiveType.WideChar)) |
|
|
|
case PrimitiveType.Char: |
|
|
|
return Context.TargetInfo.WCharWidth; |
|
|
|
return Context.TargetInfo.CharWidth; |
|
|
|
if (pointee.IsPrimitiveType(PrimitiveType.Char16)) |
|
|
|
case PrimitiveType.WideChar: |
|
|
|
return Context.TargetInfo.Char16Width; |
|
|
|
return Context.TargetInfo.WCharWidth; |
|
|
|
|
|
|
|
case PrimitiveType.Char16: |
|
|
|
|
|
|
|
return Context.TargetInfo.Char16Width; |
|
|
|
|
|
|
|
case PrimitiveType.Char32: |
|
|
|
|
|
|
|
return Context.TargetInfo.Char32Width; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
@ -224,7 +225,7 @@ namespace CppSharp.Types.Std |
|
|
|
string bytes = $"__bytes{ctx.ParameterIndex}"; |
|
|
|
string bytes = $"__bytes{ctx.ParameterIndex}"; |
|
|
|
string bytePtr = $"__bytePtr{ctx.ParameterIndex}"; |
|
|
|
string bytePtr = $"__bytePtr{ctx.ParameterIndex}"; |
|
|
|
ctx.Before.WriteLine($@"byte[] {bytes} = global::System.Text.Encoding.{
|
|
|
|
ctx.Before.WriteLine($@"byte[] {bytes} = global::System.Text.Encoding.{
|
|
|
|
GetEncodingClass(ctx.Parameter)}.GetBytes({param});");
|
|
|
|
GetEncoding().Name}.GetBytes({param});");
|
|
|
|
ctx.Before.WriteLine($"fixed (byte* {bytePtr} = {bytes})"); |
|
|
|
ctx.Before.WriteLine($"fixed (byte* {bytePtr} = {bytes})"); |
|
|
|
ctx.HasCodeBlock = true; |
|
|
|
ctx.HasCodeBlock = true; |
|
|
|
ctx.Before.WriteOpenBraceAndIndent(); |
|
|
|
ctx.Before.WriteOpenBraceAndIndent(); |
|
|
|
@ -266,50 +267,45 @@ namespace CppSharp.Types.Std |
|
|
|
textGenerator.WriteLine($"if ({ctx.ReturnVarName} == {nullPtr})"); |
|
|
|
textGenerator.WriteLine($"if ({ctx.ReturnVarName} == {nullPtr})"); |
|
|
|
textGenerator.WriteOpenBraceAndIndent(); |
|
|
|
textGenerator.WriteOpenBraceAndIndent(); |
|
|
|
textGenerator.WriteLine($"{ctx.Parameter.Name} = default({Type.Desugar()});"); |
|
|
|
textGenerator.WriteLine($"{ctx.Parameter.Name} = default({Type.Desugar()});"); |
|
|
|
textGenerator.WriteLine("return;"); |
|
|
|
textGenerator.WriteLine($"return{(ctx.Function.ReturnType.Type.IsPrimitiveType(PrimitiveType.Void) ? "" : " default")};"); |
|
|
|
textGenerator.UnindentAndWriteCloseBrace(); |
|
|
|
textGenerator.UnindentAndWriteCloseBrace(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
string encoding = GetEncodingClass(ctx.Parameter); |
|
|
|
string encoding = GetEncoding().Name; |
|
|
|
string type = GetTypeForCodePoint(encoding); |
|
|
|
string type = GetTypeForCodePoint(encoding); |
|
|
|
textGenerator.WriteLine($"var __retPtr = ({type}*) {returnVarName};"); |
|
|
|
var retPtr = Generator.GeneratedIdentifier($"retPtr{ctx.ParameterIndex}"); |
|
|
|
textGenerator.WriteLine("int __length = 0;"); |
|
|
|
var length = Generator.GeneratedIdentifier($"length{ctx.ParameterIndex}"); |
|
|
|
textGenerator.WriteLine($"while (*(__retPtr++) != 0) __length += sizeof({type});"); |
|
|
|
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.{
|
|
|
|
ctx.Return.Write($@"global::System.Text.Encoding.{
|
|
|
|
encoding}.GetString((byte*) {returnVarName}, __length)");
|
|
|
|
encoding}.GetString((byte*) {returnVarName}, {length})");
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private string GetEncodingClass(Parameter parameter) |
|
|
|
private (Encoding Encoding, string Name) GetEncoding() |
|
|
|
{ |
|
|
|
{ |
|
|
|
Type type = Type.Desugar(); |
|
|
|
switch (GetCharWidth()) |
|
|
|
Type pointee = type.GetPointee().Desugar(); |
|
|
|
{ |
|
|
|
var isChar = type.IsPointerToPrimitiveType(PrimitiveType.Char) || |
|
|
|
case 8: |
|
|
|
(pointee.IsPointerToPrimitiveType(PrimitiveType.Char) && |
|
|
|
if (Context.Options.Encoding == Encoding.ASCII) |
|
|
|
parameter != null && |
|
|
|
return (Context.Options.Encoding, nameof(Encoding.ASCII)); |
|
|
|
(parameter.IsInOut || parameter.IsOut)); |
|
|
|
if (Context.Options.Encoding == Encoding.UTF8) |
|
|
|
|
|
|
|
return (Context.Options.Encoding, nameof(Encoding.UTF8)); |
|
|
|
if (!isChar) |
|
|
|
if (Context.Options.Encoding == Encoding.UTF7) |
|
|
|
return (Context.TargetInfo.WCharWidth == 16) ? |
|
|
|
return (Context.Options.Encoding, nameof(Encoding.UTF7)); |
|
|
|
nameof(Encoding.Unicode) : nameof(Encoding.UTF32); |
|
|
|
if (Context.Options.Encoding == Encoding.BigEndianUnicode) |
|
|
|
|
|
|
|
return (Context.Options.Encoding, nameof(Encoding.BigEndianUnicode)); |
|
|
|
if (Context.Options.Encoding == Encoding.ASCII) |
|
|
|
if (Context.Options.Encoding == Encoding.Unicode) |
|
|
|
return nameof(Encoding.ASCII); |
|
|
|
return (Context.Options.Encoding, nameof(Encoding.Unicode)); |
|
|
|
|
|
|
|
if (Context.Options.Encoding == Encoding.UTF32) |
|
|
|
if (Context.Options.Encoding == Encoding.BigEndianUnicode) |
|
|
|
return (Context.Options.Encoding, nameof(Encoding.UTF32)); |
|
|
|
return nameof(Encoding.BigEndianUnicode); |
|
|
|
break; |
|
|
|
|
|
|
|
case 16: |
|
|
|
if (Context.Options.Encoding == Encoding.Unicode) |
|
|
|
return (Encoding.Unicode, nameof(Encoding.Unicode)); |
|
|
|
return nameof(Encoding.Unicode); |
|
|
|
case 32: |
|
|
|
|
|
|
|
return (Encoding.UTF32, nameof(Encoding.UTF32)); |
|
|
|
if (Context.Options.Encoding == Encoding.UTF32) |
|
|
|
} |
|
|
|
return nameof(Encoding.UTF32); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Context.Options.Encoding == Encoding.UTF7) |
|
|
|
|
|
|
|
return nameof(Encoding.UTF7); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Context.Options.Encoding == Encoding.UTF8) |
|
|
|
|
|
|
|
return nameof(Encoding.UTF8); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
throw new System.NotSupportedException( |
|
|
|
throw new System.NotSupportedException( |
|
|
|
$"{Context.Options.Encoding.EncodingName} is not supported yet."); |
|
|
|
$"{Context.Options.Encoding.EncodingName} is not supported yet."); |
|
|
|
@ -348,6 +344,12 @@ namespace CppSharp.Types.Std |
|
|
|
{ |
|
|
|
{ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[TypeMap("const char32_t*", GeneratorKind = GeneratorKind.CSharp)] |
|
|
|
|
|
|
|
[TypeMap("const char32_t*", GeneratorKind = GeneratorKind.CLI)] |
|
|
|
|
|
|
|
public class ConstChar32TPointer : ConstCharPointer |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[TypeMap("basic_string<char, char_traits<char>, allocator<char>>", GeneratorKind = GeneratorKind.CSharp)] |
|
|
|
[TypeMap("basic_string<char, char_traits<char>, allocator<char>>", GeneratorKind = GeneratorKind.CSharp)] |
|
|
|
[TypeMap("basic_string<char, char_traits<char>, allocator<char>>", GeneratorKind = GeneratorKind.CLI)] |
|
|
|
[TypeMap("basic_string<char, char_traits<char>, allocator<char>>", GeneratorKind = GeneratorKind.CLI)] |
|
|
|
public class String : TypeMap |
|
|
|
public class String : TypeMap |
|
|
|
|