Imported Upstream version 5.4.0.167

Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-08-21 15:34:15 +00:00
parent e49d6f06c0
commit 536cd135cc
12856 changed files with 563812 additions and 223249 deletions

View File

@ -126,6 +126,117 @@ namespace System.StubHelpers {
}
} // class CSTRMarshaler
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class UTF8Marshaler
{
const int MAX_UTF8_CHAR_SIZE = 3;
[System.Security.SecurityCritical]
static internal unsafe IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer)
{
if (null == strManaged)
{
return IntPtr.Zero;
}
StubHelpers.CheckStringLength(strManaged.Length);
int nb;
byte* pbNativeBuffer = (byte*)pNativeBuffer;
// If we are marshaling into a stack buffer allocated by the ILStub
// we will use a "1-pass" mode where we convert the string directly into the unmanaged buffer.
// else we will allocate the precise native heap memory.
if (pbNativeBuffer != null)
{
// this is the number of bytes allocated by the ILStub.
nb = (strManaged.Length + 1) * MAX_UTF8_CHAR_SIZE;
// nb is the actual number of bytes written by Encoding.GetBytes.
// use nb to de-limit the string since we are allocating more than
// required on stack
nb = strManaged.GetBytesFromEncoding(pbNativeBuffer, nb, Encoding.UTF8);
}
// required bytes > 260 , allocate required bytes on heap
else
{
nb = Encoding.UTF8.GetByteCount(strManaged);
// + 1 for the null character.
pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 1);
strManaged.GetBytesFromEncoding(pbNativeBuffer, nb, Encoding.UTF8);
}
pbNativeBuffer[nb] = 0x0;
return (IntPtr)pbNativeBuffer;
}
[System.Security.SecurityCritical]
static internal unsafe string ConvertToManaged(IntPtr cstr)
{
if (IntPtr.Zero == cstr)
return null;
int nbBytes = StubHelpers.strlen((sbyte*)cstr);
return String.CreateStringFromEncoding((byte*)cstr, nbBytes, Encoding.UTF8);
}
[System.Security.SecurityCritical]
static internal void ClearNative(IntPtr pNative)
{
if (pNative != IntPtr.Zero)
{
Win32Native.CoTaskMemFree(pNative);
}
}
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class UTF8BufferMarshaler
{
[System.Security.SecurityCritical]
static internal unsafe IntPtr ConvertToNative(StringBuilder sb, IntPtr pNativeBuffer, int flags)
{
if (null == sb)
{
return IntPtr.Zero;
}
// Convert to string first
string strManaged = sb.ToString();
// Get byte count
int nb = Encoding.UTF8.GetByteCount(strManaged);
// EmitConvertSpaceCLRToNative allocates memory
byte* pbNativeBuffer = (byte*)pNativeBuffer;
nb = strManaged.GetBytesFromEncoding(pbNativeBuffer, nb, Encoding.UTF8);
pbNativeBuffer[nb] = 0x0;
return (IntPtr)pbNativeBuffer;
}
[System.Security.SecurityCritical]
static internal unsafe void ConvertToManaged(StringBuilder sb, IntPtr pNative)
{
if (pNative == null)
return;
int nbBytes = StubHelpers.strlen((sbyte*)pNative);
int numChar = Encoding.UTF8.GetCharCount((byte*)pNative, nbBytes);
// +1 GetCharCount return 0 if the pNative points to a
// an empty buffer.We still need to allocate an empty
// buffer with a '\0' to distingiush it from null.
// Note that pinning on (char *pinned = new char[0])
// return null and Encoding.UTF8.GetChars do not like
// null argument.
char[] cCharBuffer = new char[numChar + 1];
cCharBuffer[numChar] = '\0';
fixed (char* pBuffer = cCharBuffer)
{
numChar = Encoding.UTF8.GetChars((byte*)pNative, nbBytes, pBuffer, numChar);
// replace string builder internal buffer
sb.ReplaceBufferInternal(pBuffer, numChar);
}
}
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class BSTRMarshaler
{
@ -147,7 +258,7 @@ namespace System.StubHelpers {
if (hasTrailByte)
{
// this is an odd-sized string with a trailing byte stored in its [....] block
// this is an odd-sized string with a trailing byte stored in its sync block
lengthInBytes++;
}
@ -231,7 +342,7 @@ namespace System.StubHelpers {
if ((length & 1) == 1)
{
// odd-sized strings need to have the trailing byte saved in their [....] block
// odd-sized strings need to have the trailing byte saved in their sync block
ret.SetTrailByte(((byte *)bstr.ToPointer())[length - 1]);
}