internal static int GetCurrentTextElementLen(String str, int index, int len, ref UnicodeCategory ucCurrent, ref int currentCharCount)
{
BCLDebug.Assert(index >= 0 && len >= 0, "StringInfo.GetCurrentTextElementLen() : index = " + index + ", len = " + len);
BCLDebug.Assert(index < len, "StringInfo.GetCurrentTextElementLen() : index = " + index + ", len = " + len);
if (index + currentCharCount == len)
{
// This is the last character/surrogate in the string.
return (currentCharCount);
}
// Call an internal GetUnicodeCategory, which will tell us both the unicode category, and also tell us if it is a surrogate pair or not.
int nextCharCount;
UnicodeCategory ucNext = CharUnicodeInfo.InternalGetUnicodeCategory(str, index + currentCharCount, out nextCharCount);
if (CharUnicodeInfo.IsCombiningCategory(ucNext)) {
// The next element is a combining class.
// Check if the current text element to see if it is a valid base category (i.e. it should not be a combining category,
// not a format character, and not a control character).
if (CharUnicodeInfo.IsCombiningCategory(ucCurrent)
|| (ucCurrent == UnicodeCategory.Format)
|| (ucCurrent == UnicodeCategory.Control)
|| (ucCurrent == UnicodeCategory.OtherNotAssigned)
|| (ucCurrent == UnicodeCategory.Surrogate)) // An unpair high surrogate or low surrogate
{
// Will fall thru and return the currentCharCount
} else {
int startIndex = index; // Remember the current index.
// We have a valid base characters, and we have a character (or surrogate) that is combining.
// Check if there are more combining characters to follow.
// Check if the next character is a nonspacing character.
index += currentCharCount + nextCharCount;
while (index < len)
{
ucNext = CharUnicodeInfo.InternalGetUnicodeCategory(str, index, out nextCharCount);
if (!CharUnicodeInfo.IsCombiningCategory(ucNext)) {
ucCurrent = ucNext;
currentCharCount = nextCharCount;
break;
}
index += nextCharCount;
}
return (index - startIndex);
}
}
// The return value will be the currentCharCount.
int ret = currentCharCount;
ucCurrent = ucNext;
// Update currentCharCount.
currentCharCount = nextCharCount;
return (ret);
}