private bool TestChar(char input, int position, out MaskedTextResultHint resultHint)
{
// boundary checks are performed in the public methods.
Debug.Assert(position >= 0 && position < _testString.Length, "Position out of range.");
if (!IsPrintableChar(input))
{
resultHint = MaskedTextResultHint.InvalidInput;
return false;
}
// Get the character info from the char descriptor table.
CharDescriptor charDex = _stringDescriptor[position];
// Test if character should be escaped.
// Test literals first - See VSW#454461. See commented-out method SynchronizeInputOptions()
if (IsLiteralPosition(charDex))
{
if (SkipLiterals && (input == _testString[position]))
{
resultHint = MaskedTextResultHint.CharacterEscaped;
return true;
}
resultHint = MaskedTextResultHint.NonEditPosition;
return false;
}
if (input == _promptChar)
{
if (ResetOnPrompt)
{
if (IsEditPosition(charDex) && charDex.IsAssigned) // Position would be reset.
{
resultHint = MaskedTextResultHint.SideEffect;
}
else
{
resultHint = MaskedTextResultHint.CharacterEscaped;
}
return true; // test does not fail for prompt when it is to be scaped.
}
// Escaping precedes AllowPromptAsInput. Now test for it.
if (!AllowPromptAsInput)
{
resultHint = MaskedTextResultHint.PromptCharNotAllowed;
return false;
}
}
if (input == spaceChar && ResetOnSpace)
{
if (IsEditPosition(charDex) && charDex.IsAssigned) // Position would be reset.
{
resultHint = MaskedTextResultHint.SideEffect;
}
else
{
resultHint = MaskedTextResultHint.CharacterEscaped;
}
return true;
}
// Character was not escaped, now test it against the mask.
// Test the character against the mask constraints. The switch tests false conditions.
// Space char succeeds the test if the char type is optional.
switch (_mask[charDex.MaskPosition])
{
case '#': // digit or plus/minus sign optional.
if (!Char.IsDigit(input) && (input != '-') && (input != '+') && input != spaceChar)
{
resultHint = MaskedTextResultHint.DigitExpected;
return false;
}
break;
case '0': // digit required.
if (!Char.IsDigit(input))
{
resultHint = MaskedTextResultHint.DigitExpected;
return false;
}
break;
case '9': // digit optional.
if (!Char.IsDigit(input) && input != spaceChar)
{
resultHint = MaskedTextResultHint.DigitExpected;
return false;
}
break;
case 'L': // letter required.
if (!Char.IsLetter(input))
{
resultHint = MaskedTextResultHint.LetterExpected;
return false;
}
if (!IsAsciiLetter(input) && AsciiOnly)
{
resultHint = MaskedTextResultHint.AsciiCharacterExpected;
return false;
}
break;
case '?': // letter optional.
if (!Char.IsLetter(input) && input != spaceChar)
{
resultHint = MaskedTextResultHint.LetterExpected;
return false;
}
if (!IsAsciiLetter(input) && AsciiOnly)
{
resultHint = MaskedTextResultHint.AsciiCharacterExpected;
return false;
}
break;
case '&': // any character required.
if (!IsAscii(input) && AsciiOnly)
{
resultHint = MaskedTextResultHint.AsciiCharacterExpected;
return false;
}
break;
case 'C': // any character optional.
if ((!IsAscii(input) && AsciiOnly) && input != spaceChar)
{
resultHint = MaskedTextResultHint.AsciiCharacterExpected;
return false;
}
break;
case 'A': // Alphanumeric required.
if (!IsAlphanumeric(input))
{
resultHint = MaskedTextResultHint.AlphanumericCharacterExpected;
return false;
}
if (!IsAciiAlphanumeric(input) && AsciiOnly)
{
resultHint = MaskedTextResultHint.AsciiCharacterExpected;
return false;
}
break;
case 'a': // Alphanumeric optional.
if (!IsAlphanumeric(input) && input != spaceChar)
{
resultHint = MaskedTextResultHint.AlphanumericCharacterExpected;
return false;
}
if (!IsAciiAlphanumeric(input) && AsciiOnly)
{
resultHint = MaskedTextResultHint.AsciiCharacterExpected;
return false;
}
break;
default:
Debug.Fail("Invalid mask language character.");
break;
}
// Test passed.
if (input == _testString[position] && charDex.IsAssigned) // setting char would not make any difference
{
resultHint = MaskedTextResultHint.NoEffect;
}
else
{
resultHint = MaskedTextResultHint.Success;
}
return true;
}