// Fallback the current byte by sticking it into the remaining char buffer.
// This can only be called by our encodings (other have to use the public fallback methods), so
// we can use our DecoderNLS here too (except we don't).
// Returns true if we are successful, false if we can't fallback the character (no buffer space)
// So the caller needs to throw buffer space if the method returns false.
// Right now this has both bytes and bytes[], since we might have extra bytes, hence the
// array, and we might need the index, hence the byte*
// Don't touch ref chars unless we succeed
internal bool InternalFallback(byte[] bytes, byte *pBytes, ref char *chars)
{
Debug.Assert(byteStart != null, "[DecoderFallback.InternalFallback]Used InternalFallback without calling InternalInitialize");
// See if there's a fallback character and we have an output buffer then copy our string.
if (_fallbackBuffer.Fallback(bytes, (int)(pBytes - byteStart - bytes.Length)))
{
// Copy the chars to our output
char ch;
char *charTemp = chars;
bool bHighSurrogate = false;
while ((ch = _fallbackBuffer.GetNextChar()) != 0)
{
// Make sure no mixed up surrogates
if (Char.IsSurrogate(ch))
{
if (Char.IsHighSurrogate(ch))
{
// High Surrogate
if (bHighSurrogate)
{
throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
}
bHighSurrogate = true;
}
else
{
// Low surrogate
if (bHighSurrogate == false)
{
throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
}
bHighSurrogate = false;
}
}
if (charTemp >= charEnd)
{
// No buffer space
return(false);
}
*(charTemp++) = ch;
}
// Need to make sure that bHighSurrogate isn't true
if (bHighSurrogate)
{
throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
}
// Now we aren't going to be false, so its OK to update chars
chars = charTemp;
}
return(true);
}