unsafe public int GetChars(byte[] bytes, int byteIndex, int byteCount, byte[] chars, int charIndex)
{
if (bytes == null)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(bytes)));
if (byteIndex < 0)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteIndex), SR.Format(SR.ValueMustBeNonNegative)));
if (byteIndex > bytes.Length)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteIndex), SR.Format(SR.OffsetExceedsBufferSize, bytes.Length)));
if (byteCount < 0)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteCount), SR.Format(SR.ValueMustBeNonNegative)));
if (byteCount > bytes.Length - byteIndex)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteCount), SR.Format(SR.SizeExceedsRemainingBufferSpace, bytes.Length - byteIndex)));
int charCount = GetCharCount(bytes, byteIndex, byteCount);
if (chars == null)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(chars)));
if (charIndex < 0)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charIndex), SR.Format(SR.ValueMustBeNonNegative)));
if (charIndex > chars.Length)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charIndex), SR.Format(SR.OffsetExceedsBufferSize, chars.Length)));
if (charCount < 0 || charCount > chars.Length - charIndex)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.XmlArrayTooSmall), nameof(chars)));
// We've computed exactly how many chars there are and verified that
// there's enough space in the char buffer, so we can proceed without
// checking the charCount.
if (byteCount > 0)
{
fixed (byte* _val2byte = s_val2byte)
{
fixed (byte* _bytes = &bytes[byteIndex])
{
fixed (byte* _chars = &chars[charIndex])
{
byte* pb = _bytes;
byte* pbMax = pb + byteCount - 3;
byte* pch = _chars;
// Convert chunks of 3 bytes to 4 chars
while (pb <= pbMax)
{
// 76543210 76543210 76543210
// xx765432 xx107654 xx321076 xx543210
// Inspect the code carefully before you change this
pch[0] = _val2byte[(pb[0] >> 2)];
pch[1] = _val2byte[((pb[0] & 0x03) << 4) | (pb[1] >> 4)];
pch[2] = _val2byte[((pb[1] & 0x0F) << 2) | (pb[2] >> 6)];
pch[3] = _val2byte[pb[2] & 0x3F];
pb += 3;
pch += 4;
}
// Handle 1 or 2 trailing bytes
if (pb - pbMax == 2)
{
// 1 trailing byte
// 76543210 xxxxxxxx xxxxxxxx
// xx765432 xx10xxxx xxxxxxxx xxxxxxxx
pch[0] = _val2byte[(pb[0] >> 2)];
pch[1] = _val2byte[((pb[0] & 0x03) << 4)];
pch[2] = (byte)'=';
pch[3] = (byte)'=';
}
else if (pb - pbMax == 1)
{
// 2 trailing bytes
// 76543210 76543210 xxxxxxxx
// xx765432 xx107654 xx3210xx xxxxxxxx
pch[0] = _val2byte[(pb[0] >> 2)];
pch[1] = _val2byte[((pb[0] & 0x03) << 4) | (pb[1] >> 4)];
pch[2] = _val2byte[((pb[1] & 0x0F) << 2)];
pch[3] = (byte)'=';
}
else
{
// 0 trailing bytes
DiagnosticUtility.DebugAssert(pb - pbMax == 3, "");
}
}
}
}
}
return charCount;
}
}