public unsafe String ToTitleCase(String str) {
if (str==null)
{
throw new ArgumentNullException("str");
}
int len = str.Length;
if (len == 0) {
return (str);
}
int i;
StringBuilder result = new StringBuilder();
String lowercaseData = null;
for (i = 0; i < len; i++) {
UnicodeCategory charType;
int charLen;
charType = CharUnicodeInfo.InternalGetUnicodeCategory(str, i, out charLen);
if (Char.CheckLetter(charType))
{
// Do the uppercasing for the first character of the word.
// There are titlecase characters that need to be special treated.
if (charLen == 1) {
result.Append(nativeGetTitleCaseChar(m_pNativeTextInfo, str[i]));
} else {
//
// ASSUMPTION: There is no titlecase char in the surrogate.
//
char resultHighSurrogate;
char resultLowSurrogate;
ChangeCaseSurrogate(str[i], str[i+1], out resultHighSurrogate, out resultLowSurrogate, true);
result.Append(resultHighSurrogate);
result.Append(resultLowSurrogate);
}
i+= charLen;
//
// Convert the characters until the end of the this word
// to lowercase.
//
int lowercaseStart = i;
//
// Use hasLowerCase flag to prevent from lowercasing acronyms (like "URT", "USA", etc)
// This is in line with Word 2000 behavior of titilecasing.
//
bool hasLowerCase = (charType == UnicodeCategory.LowercaseLetter);
// Use a loop to find all of the other letters following this letter.
while (i < len) {
charType = CharUnicodeInfo.InternalGetUnicodeCategory(str, i, out charLen);
if (IsLetterCategory(charType)) {
if (charType == UnicodeCategory.LowercaseLetter) {
hasLowerCase = true;
}
i += charLen;
} else if (str[i] == '\'') {
// Special case for APOSTROPHE. It should be considered part of the word. E.g. "can't".
i++;
if (hasLowerCase) {
if (lowercaseData==null) {
lowercaseData = this.ToLower(str);
}
result.Append(lowercaseData, lowercaseStart, i - lowercaseStart);
} else {
result.Append(str, lowercaseStart, i - lowercaseStart);
}
lowercaseStart = i;
hasLowerCase = true;
} else if (!IsWordSeparator(charType)) {
// This category is considered to be part of the word.
// This is any category that is marked as false in wordSeprator array.
i+= charLen;
} else {
// A word separator. Break out of the loop.
break;
}
}
int count = i - lowercaseStart;
if (count>0) {
if (hasLowerCase) {
if (lowercaseData==null) {
lowercaseData = this.ToLower(str);
}
result.Append(lowercaseData, lowercaseStart, count);
} else {
result.Append(str, lowercaseStart, count);
}
}
if (i < len) {
// Add the non-letter character.
if (charLen == 1) {
result.Append(str[i]);
} else {
// Surrogate.
result.Append(str[i++]);
result.Append(str[i]);
}
}
} else {
//
// Not a letter, just append them.
//
if (charLen == 1) {
result.Append(str[i]);
} else {
// Surrogate.
result.Append(str[i++]);
result.Append(str[i]);
}
}
}
return (result.ToString());
}