public unsafe override int GetCharCount(byte* bytes, int count, DecoderNLS decoder)
{
// Just assert, we're called internally so these should be safe, checked already
Debug.Assert(bytes != null, "[SBCSCodePageEncoding.GetCharCount]bytes is null");
Debug.Assert(count >= 0, "[SBCSCodePageEncoding.GetCharCount]byteCount is negative");
CheckMemorySection();
// See if we have best fit
bool bUseBestFit = false;
// Only need decoder fallback buffer if not using default replacement fallback or best fit fallback.
DecoderReplacementFallback fallback = null;
if (decoder == null)
{
fallback = DecoderFallback as DecoderReplacementFallback;
bUseBestFit = DecoderFallback is InternalDecoderBestFitFallback;
}
else
{
fallback = decoder.Fallback as DecoderReplacementFallback;
bUseBestFit = decoder.Fallback is InternalDecoderBestFitFallback;
Debug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
decoder.FallbackBuffer.Remaining == 0,
"[SBCSCodePageEncoding.GetChars]Expected empty fallback buffer at start");
}
if (bUseBestFit || (fallback != null && fallback.MaxCharCount == 1))
{
// Just return length, SBCS stay the same length because they don't map to surrogate
// pairs and we don't have a decoder fallback.
return count;
}
// Might need one of these later
DecoderFallbackBuffer fallbackBuffer = null;
DecoderFallbackBufferHelper fallbackHelper = new DecoderFallbackBufferHelper(fallbackBuffer);
// Have to do it the hard way.
// Assume charCount will be == count
int charCount = count;
byte[] byteBuffer = new byte[1];
// Do it our fast way
byte* byteEnd = bytes + count;
// Quick loop
while (bytes < byteEnd)
{
// Faster if don't use *bytes++;
char c;
c = _mapBytesToUnicode[*bytes];
bytes++;
// If unknown we have to do fallback count
if (c == UNKNOWN_CHAR)
{
// Must have a fallback buffer
if (fallbackBuffer == null)
{
// Need to adjust count so we get real start
if (decoder == null)
fallbackBuffer = DecoderFallback.CreateFallbackBuffer();
else
fallbackBuffer = decoder.FallbackBuffer;
fallbackHelper = new DecoderFallbackBufferHelper(fallbackBuffer);
fallbackHelper.InternalInitialize(byteEnd - count, null);
}
// Use fallback buffer
byteBuffer[0] = *(bytes - 1);
charCount--; // We'd already reserved one for *(bytes-1)
charCount += fallbackHelper.InternalFallback(byteBuffer, bytes);
}
}
// Fallback buffer must be empty
Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[SBCSEncoding.GetCharCount]Expected Empty fallback buffer at end");
// Converted sequence is same length as input
return charCount;
}