/// <summary> /// Implements the "Before_Dot" condition /// /// Specification: C is followed by <code>U+0307 COMBINING DOT ABOVE</code>. /// Any sequence of characters with a combining class that is /// neither 0 nor 230 may intervene between the current character /// and the combining dot above. /// /// Regular Expression: /// After C: ([{cc!=230}&{cc!=0}])*[\u0307] /// </summary> private static bool IsBeforeDot(String src, int index) { int ch; int cc; int len = src.Length(); // Look for a following COMBINING DOT ABOVE for (int i = index + Character.CharCount(src.CodePointAt(index)); i < len; i += Character.CharCount(ch)) { ch = src.CodePointAt(i); if (ch == '\u0307') { return(true); } else { cc = Normalizer.getCombiningClass(ch); if ((cc == 0) || (cc == COMBINING_CLASS_ABOVE)) { return(false); } } } return(false); }
/// <summary> /// Implements the "Final_Cased" condition /// /// Specification: Within the closest word boundaries containing C, there is a cased /// letter before C, and there is no cased letter after C. /// /// Regular Expression: /// Before C: [{cased==true}][{wordBoundary!=true}]* /// After C: !([{wordBoundary!=true}]*[{cased}]) /// </summary> private static bool IsFinalCased(String src, int index, Locale locale) { BreakIterator wordBoundary = BreakIterator.GetWordInstance(locale); wordBoundary.SetText(src); int ch; // Look for a preceding 'cased' letter for (int i = index; (i >= 0) && !wordBoundary.IsBoundary(i); i -= Character.CharCount(ch)) { ch = src.CodePointBefore(i); if (IsCased(ch)) { int len = src.Length(); // Check that there is no 'cased' letter after the index for (i = index + Character.CharCount(src.CodePointAt(index)); (i < len) && !wordBoundary.IsBoundary(i); i += Character.CharCount(ch)) { ch = src.CodePointAt(i); if (IsCased(ch)) { return(false); } } return(true); } } return(false); }
private static char[] LookUpTable(String src, int index, Locale locale, bool bLowerCasing) { HashSet <Entry> set = EntryTable[new Integer(src.CodePointAt(index))]; char[] ret = null; if (set != null) { IEnumerator <Entry> iter = set.GetEnumerator(); String currentLang = locale.Language; while (iter.MoveNext()) { Entry entry = iter.Current; String conditionLang = entry.Language; if (((conditionLang == null) || (conditionLang.Equals(currentLang))) && IsConditionMet(src, index, locale, entry.Condition)) { ret = bLowerCasing ? entry.LowerCase : entry.UpperCase; if (conditionLang != null) { break; } } } } return(ret); }
internal static char[] ToUpperCaseCharArray(String src, int index, Locale locale) { char[] result = LookUpTable(src, index, locale, false); if (result != null) { return(result); } else { return(Character.ToUpperCaseCharArray(src.CodePointAt(index))); } }
/// <summary> /// Implements the "More_Above" condition /// /// Specification: C is followed by one or more characters of combining /// class 230 (ABOVE) in the combining character sequence. /// /// Regular Expression: /// After C: [{cc!=0}]*[{cc==230}] /// </summary> private static bool IsMoreAbove(String src, int index) { int ch; int cc; int len = src.Length(); // Look for a following ABOVE combining class character for (int i = index + Character.CharCount(src.CodePointAt(index)); i < len; i += Character.CharCount(ch)) { ch = src.CodePointAt(i); cc = Normalizer.getCombiningClass(ch); if (cc == COMBINING_CLASS_ABOVE) { return(true); } else if (cc == 0) { return(false); } } return(false); }
internal static int ToLowerCaseEx(String src, int index, Locale locale) { char[] result = LookUpTable(src, index, locale, true); if (result != null) { if (result.Length == 1) { return(result[0]); } else { return(Character.ERROR); } } else { // default to Character class' one return(char.ToLower(src.CodePointAt(index))); } }