public unsafe override int GetByteCount(char* chars, int count, EncoderNLS encoder)
{
// Just need to ASSERT, this is called by something else internal that checked parameters already
Debug.Assert(count >= 0, "[DBCSCodePageEncoding.GetByteCount]count is negative");
Debug.Assert(chars != null, "[DBCSCodePageEncoding.GetByteCount]chars is null");
// Assert because we shouldn't be able to have a null encoder.
Debug.Assert(EncoderFallback != null, "[DBCSCodePageEncoding.GetByteCount]Attempting to use null fallback");
CheckMemorySection();
// Get any left over characters
char charLeftOver = (char)0;
if (encoder != null)
{
charLeftOver = encoder.charLeftOver;
// Only count if encoder.m_throwOnOverflow
if (encoder.InternalHasFallbackBuffer && encoder.FallbackBuffer.Remaining > 0)
throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, EncodingName, encoder.Fallback.GetType()));
}
// prepare our end
int byteCount = 0;
char* charEnd = chars + count;
// For fallback we will need a fallback buffer
EncoderFallbackBuffer fallbackBuffer = null;
EncoderFallbackBufferHelper fallbackHelper = new EncoderFallbackBufferHelper(fallbackBuffer);
// We may have a left over character from last time, try and process it.
if (charLeftOver > 0)
{
Debug.Assert(Char.IsHighSurrogate(charLeftOver), "[DBCSCodePageEncoding.GetByteCount]leftover character should be high surrogate");
Debug.Assert(encoder != null,
"[DBCSCodePageEncoding.GetByteCount]Expect to have encoder if we have a charLeftOver");
// Since left over char was a surrogate, it'll have to be fallen back.
// Get Fallback
fallbackBuffer = encoder.FallbackBuffer;
fallbackHelper = new EncoderFallbackBufferHelper(fallbackBuffer);
fallbackHelper.InternalInitialize(chars, charEnd, encoder, false);
// This will fallback a pair if *chars is a low surrogate
fallbackHelper.InternalFallback(charLeftOver, ref chars);
}
// Now we may have fallback char[] already (from the encoder)
// We have to use fallback method.
char ch;
while ((ch = (fallbackBuffer == null) ? '\0' : fallbackHelper.InternalGetNextChar()) != 0 ||
chars < charEnd)
{
// First unwind any fallback
if (ch == 0)
{
// No fallback, just get next char
ch = *chars;
chars++;
}
// get byte for this char
ushort sTemp = mapUnicodeToBytes[ch];
// Check for fallback, this'll catch surrogate pairs too.
if (sTemp == 0 && ch != (char)0)
{
if (fallbackBuffer == null)
{
// Initialize the buffer
if (encoder == null)
fallbackBuffer = EncoderFallback.CreateFallbackBuffer();
else
fallbackBuffer = encoder.FallbackBuffer;
fallbackHelper = new EncoderFallbackBufferHelper(fallbackBuffer);
fallbackHelper.InternalInitialize(charEnd - count, charEnd, encoder, false);
}
// Get Fallback
fallbackHelper.InternalFallback(ch, ref chars);
continue;
}
// We'll use this one
byteCount++;
if (sTemp >= 0x100)
byteCount++;
}
return (int)byteCount;
}