public override int NextCodePoint() { int c; for (; ;) { if (state == State.IterCheckFwd) { c = iter.Next(); if (c < 0) { return(c); } if (CollationFCD.HasTccc(c)) { if (CollationFCD.MaybeTibetanCompositeVowel(c) || CollationFCD.HasLccc(iter.Current)) { iter.Previous(); if (!NextSegment()) { return(Collation.SENTINEL_CP); } continue; } } if (IsLeadSurrogate(c)) { int trail = iter.Next(); if (IsTrailSurrogate(trail)) { return(Character.ToCodePoint((char)c, (char)trail)); } else if (trail >= 0) { iter.Previous(); } } return(c); } else if (state == State.IterInFCDSegment && pos != limit) { c = iter.NextCodePoint(); pos += Character.CharCount(c); Debug.Assert(c >= 0); return(c); } else if (state.CompareTo(State.InNormIterAtLimit) >= 0 && pos != normalized.Length) { c = normalized.CodePointAt(pos); pos += Character.CharCount(c); return(c); } else { SwitchToForward(); } } }
/// <summary> /// Extend the FCD text segment backward or normalize around pos. /// To be called when checkDir < 0 && pos != start. /// Returns with checkDir == 0 and pos != start. /// </summary> private void PreviousSegment() { Debug.Assert(checkDir < 0 && seq == rawSeq && pos != start); // The input text [pos..segmentLimit[ passes the FCD check. int p = pos; int nextCC = 0; for (; ;) { // Fetch the previous character's fcd16 value. int q = p; int c = Character.CodePointBefore(seq, p); p -= Character.CharCount(c); int fcd16 = nfcImpl.GetFCD16(c); int trailCC = fcd16 & 0xff; if (trailCC == 0 && q != pos) { // FCD boundary after the [p, q[ character. start = segmentStart = q; break; } if (trailCC != 0 && ((nextCC != 0 && trailCC > nextCC) || CollationFCD.IsFCD16OfTibetanCompositeVowel(fcd16))) { // Fails FCD check. Find the previous FCD boundary and normalize. do { q = p; if (fcd16 <= 0xff || p == rawStart) { break; } c = Character.CodePointBefore(seq, p); p -= Character.CharCount(c); } while ((fcd16 = nfcImpl.GetFCD16(c)) != 0); Normalize(q, pos); pos = limit; break; } nextCC = fcd16 >> 8; if (p == rawStart || nextCC == 0) { // FCD boundary before the following character. start = segmentStart = p; break; } } Debug.Assert(pos != start); checkDir = 0; }
protected override long HandleNextCE32() { int c; for (; ;) { if (state == State.IterCheckFwd) { c = iter.Next(); if (c < 0) { return(NO_CP_AND_CE32); } if (CollationFCD.HasTccc(c)) { if (CollationFCD.MaybeTibetanCompositeVowel(c) || CollationFCD.HasLccc(iter.Current)) { iter.Previous(); if (!NextSegment()) { c = Collation.SENTINEL_CP; return(Collation.FALLBACK_CE32); } continue; } } break; } else if (state == State.IterInFCDSegment && pos != limit) { c = iter.Next(); ++pos; Debug.Assert(c >= 0); break; } else if (state.CompareTo(State.InNormIterAtLimit) >= 0 && pos != normalized.Length) { c = normalized[pos++]; break; } else { SwitchToForward(); } } return(MakeCodePointAndCE32Pair(c, trie.GetFromU16SingleLead((char)c))); }
/// <summary> /// Extend the FCD text segment forward or normalize around pos. /// To be called when checkDir > 0 && pos != limit. /// Returns with checkDir == 0 and pos != limit. /// </summary> private void NextSegment() { Debug.Assert(checkDir > 0 && seq == rawSeq && pos != limit); // The input text [segmentStart..pos[ passes the FCD check. int p = pos; int prevCC = 0; for (; ;) { // Fetch the next character's fcd16 value. int q = p; int c = Character.CodePointAt(seq, p); p += Character.CharCount(c); int fcd16 = nfcImpl.GetFCD16(c); int leadCC = fcd16 >> 8; if (leadCC == 0 && q != pos) { // FCD boundary before the [q, p[ character. limit = segmentLimit = q; break; } if (leadCC != 0 && (prevCC > leadCC || CollationFCD.IsFCD16OfTibetanCompositeVowel(fcd16))) { // Fails FCD check. Find the next FCD boundary and normalize. do { q = p; if (p == rawLimit) { break; } c = Character.CodePointAt(seq, p); p += Character.CharCount(c); } while (nfcImpl.GetFCD16(c) > 0xff); Normalize(pos, q); pos = start; break; } prevCC = fcd16 & 0xff; if (p == rawLimit || prevCC == 0) { // FCD boundary after the last character. limit = segmentLimit = p; break; } } Debug.Assert(pos != limit); checkDir = 0; }
public override int PreviousCodePoint() { char c; for (; ;) { if (checkDir < 0) { if (pos == start) { return(Collation.SentinelCodePoint); } c = seq[--pos]; if (CollationFCD.HasLccc(c)) { if (CollationFCD.MaybeTibetanCompositeVowel(c) || (pos != start && CollationFCD.HasTccc(seq[pos - 1]))) { ++pos; PreviousSegment(); c = seq[--pos]; } } break; } else if (checkDir == 0 && pos != start) { c = seq[--pos]; break; } else { SwitchToBackward(); } } char lead; if (char.IsLowSurrogate(c) && pos != start && char.IsHighSurrogate(lead = seq[pos - 1])) { --pos; return(Character.ToCodePoint(lead, c)); } else { return(c); } }
public override int NextCodePoint() { char c; for (; ;) { if (checkDir > 0) { if (pos == limit) { return(Collation.SentinelCodePoint); } c = seq[pos++]; if (CollationFCD.HasTccc(c)) { if (CollationFCD.MaybeTibetanCompositeVowel(c) || (pos != limit && CollationFCD.HasLccc(seq[pos]))) { --pos; NextSegment(); c = seq[pos++]; } } break; } else if (checkDir == 0 && pos != limit) { c = seq[pos++]; break; } else { SwitchToForward(); } } char trail; if (char.IsHighSurrogate(c) && pos != limit && char.IsLowSurrogate(trail = seq[pos])) { ++pos; return(Character.ToCodePoint(c, trail)); } else { return(c); } }
protected override long HandleNextCE32() { char c; for (; ;) { if (checkDir > 0) { if (pos == limit) { return(NoCodePointAndCE32); } c = seq[pos++]; if (CollationFCD.HasTccc(c)) { if (CollationFCD.MaybeTibetanCompositeVowel(c) || (pos != limit && CollationFCD.HasLccc(seq[pos]))) { --pos; NextSegment(); c = seq[pos++]; } } break; } else if (checkDir == 0 && pos != limit) { c = seq[pos++]; break; } else { SwitchToForward(); } } return(MakeCodePointAndCE32Pair(c, trie.GetFromU16SingleLead(c))); }
/// <summary> /// Extends the FCD text segment backward or normalizes around pos. /// </summary> /// <returns><c>true</c> if success.</returns> private bool PreviousSegment() { Debug.Assert(state == State.IterCheckBwd); // The input text [(iter index)..limit[ passes the FCD check. pos = iter.Index; // Collect the characters being checked, in case they need to be normalized. if (s == null) { s = new StringBuilder(); } else { s.Length = 0; } int nextCC = 0; for (; ;) { // Fetch the previous character and its fcd16 value. int c = iter.PreviousCodePoint(); if (c < 0) { break; } int fcd16 = nfcImpl.GetFCD16(c); int trailCC = fcd16 & 0xff; if (trailCC == 0 && s.Length != 0) { // FCD boundary after this character. iter.NextCodePoint(); break; } s.AppendCodePoint(c); if (trailCC != 0 && ((nextCC != 0 && trailCC > nextCC) || CollationFCD.IsFCD16OfTibetanCompositeVowel(fcd16))) { // Fails FCD check. Find the previous FCD boundary and normalize. while (fcd16 > 0xff) { c = iter.PreviousCodePoint(); if (c < 0) { break; } fcd16 = nfcImpl.GetFCD16(c); if (fcd16 == 0) { iter.NextCodePoint(); break; } s.AppendCodePoint(c); } s.Reverse(); Normalize(s); limit = pos; start = pos - s.Length; state = State.InNormIterAtStart; pos = normalized.Length; return(true); } nextCC = fcd16 >> 8; if (nextCC == 0) { // FCD boundary before the following character. break; } } start = pos - s.Length; Debug.Assert(pos != start); iter.MoveIndex(s.Length); state = State.IterInFCDSegment; return(true); }
/// <summary> /// Extends the FCD text segment forward or normalizes around pos. /// </summary> /// <returns><c>true</c> if success.</returns> private bool NextSegment() { Debug.Assert(state == State.IterCheckFwd); // The input text [start..(iter index)[ passes the FCD check. pos = iter.Index; // Collect the characters being checked, in case they need to be normalized. if (s == null) { s = new StringBuilder(); } else { s.Length = 0; } int prevCC = 0; for (; ;) { // Fetch the next character and its fcd16 value. int c = iter.NextCodePoint(); if (c < 0) { break; } int fcd16 = nfcImpl.GetFCD16(c); int leadCC = fcd16 >> 8; if (leadCC == 0 && s.Length != 0) { // FCD boundary before this character. iter.PreviousCodePoint(); break; } s.AppendCodePoint(c); if (leadCC != 0 && (prevCC > leadCC || CollationFCD.IsFCD16OfTibetanCompositeVowel(fcd16))) { // Fails FCD check. Find the next FCD boundary and normalize. for (; ;) { c = iter.NextCodePoint(); if (c < 0) { break; } if (nfcImpl.GetFCD16(c) <= 0xff) { iter.PreviousCodePoint(); break; } s.AppendCodePoint(c); } Normalize(s); start = pos; limit = pos + s.Length; state = State.InNormIterAtLimit; pos = 0; return(true); } prevCC = fcd16 & 0xff; if (prevCC == 0) { // FCD boundary after the last character. break; } } limit = pos + s.Length; Debug.Assert(pos != limit); iter.MoveIndex(-s.Length); state = State.IterInFCDSegment; return(true); }
public override int PreviousCodePoint() { int c; for (; ;) { if (state == State.IterCheckBwd) { c = iter.Previous(); if (c < 0) { start = pos = 0; state = State.IterInFCDSegment; return(Collation.SENTINEL_CP); } if (CollationFCD.HasLccc(c)) { int prev = Collation.SENTINEL_CP; if (CollationFCD.MaybeTibetanCompositeVowel(c) || CollationFCD.HasTccc(prev = iter.Previous())) { iter.Next(); if (prev >= 0) { iter.Next(); } if (!PreviousSegment()) { return(Collation.SENTINEL_CP); } continue; } // hasLccc(trail)=true for all trail surrogates if (IsTrailSurrogate(c)) { if (prev < 0) { prev = iter.Previous(); } if (IsLeadSurrogate(prev)) { return(Character.ToCodePoint((char)prev, (char)c)); } } if (prev >= 0) { iter.Next(); } } return(c); } else if (state == State.IterInFCDSegment && pos != start) { c = iter.PreviousCodePoint(); pos -= Character.CharCount(c); Debug.Assert(c >= 0); return(c); } else if (state.CompareTo(State.InNormIterAtLimit) >= 0 && pos != 0) { c = normalized.CodePointBefore(pos); pos -= Character.CharCount(c); return(c); } else { SwitchToBackward(); } } }