private char TryBestFit(byte[] bytesCheck)
{
// Need to figure out our best fit character, low is beginning of array, high is 1 AFTER end of array
int lowBound = 0;
int highBound = _oFallback.arrayBestFit.Length;
int index;
char cCheck;
// Check trivial case first (no best fit)
if (highBound == 0)
return '\0';
// If our array is too small or too big we can't check
if (bytesCheck.Length == 0 || bytesCheck.Length > 2)
return '\0';
if (bytesCheck.Length == 1)
cCheck = unchecked((char)bytesCheck[0]);
else
cCheck = unchecked((char)((bytesCheck[0] << 8) + bytesCheck[1]));
// Check trivial out of range case
if (cCheck < _oFallback.arrayBestFit[0] || cCheck > _oFallback.arrayBestFit[highBound - 2])
return '\0';
// Binary search the array
int iDiff;
while ((iDiff = (highBound - lowBound)) > 6)
{
// Look in the middle, which is complicated by the fact that we have 2 #s for each pair,
// so we don't want index to be odd because it must be word aligned.
// Also note that index can never == highBound (because diff is rounded down)
index = ((iDiff / 2) + lowBound) & 0xFFFE;
char cTest = _oFallback.arrayBestFit[index];
if (cTest == cCheck)
{
// We found it
Debug.Assert(index + 1 < _oFallback.arrayBestFit.Length,
"[InternalDecoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array");
return _oFallback.arrayBestFit[index + 1];
}
else if (cTest < cCheck)
{
// We weren't high enough
lowBound = index;
}
else
{
// We weren't low enough
highBound = index;
}
}
for (index = lowBound; index < highBound; index += 2)
{
if (_oFallback.arrayBestFit[index] == cCheck)
{
// We found it
Debug.Assert(index + 1 < _oFallback.arrayBestFit.Length,
"[InternalDecoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array");
return _oFallback.arrayBestFit[index + 1];
}
}
// Char wasn't in our table
return '\0';
}