void FillSurrogateSortKeyRaw (int i, SortKeyBuffer buf) { int diffbase = 0; int segment = 0; byte lower = 0; if (i < 0xD840) { diffbase = 0xD800; segment = 0x41; lower = (byte) ((i == 0xD800) ? 0x3E : 0x3F); } else if (0xD840 <= i && i < 0xD880) { diffbase = 0xD840; segment = 0xF2; lower = 0x3E; } else if (0xDB80 <= i && i < 0xDC00) { diffbase = 0xDB80 - 0x40; segment = 0xFE; lower = 0x3E; } else { diffbase = 0xDC00 - 0xF8 + 2; segment = 0x41; lower = 0x3F; } int diff = i - diffbase; buf.AppendNormal ( (byte) (segment + diff / 254), (byte) (diff % 254 + 2), lower, lower); }
unsafe void GetSortKey (string s, int start, int end, SortKeyBuffer buf, CompareOptions opt) { byte* prevbuf = stackalloc byte [4]; ClearBuffer (prevbuf, 4); Context ctx = new Context (opt, null, null, null, null, prevbuf, false); for (int n = start; n < end; n++) { int i = s [n]; ExtenderType ext = GetExtenderType (i); if (ext != ExtenderType.None) { i = FilterExtender (ctx.PrevCode, ext, opt); if (i >= 0) FillSortKeyRaw (i, ext, buf, opt); else if (ctx.PrevSortKey != null) { byte* b = ctx.PrevSortKey; buf.AppendNormal ( b [0], b [1], b [2] != 1 ? b [2] : Level2 (i, ext), b [3] != 1 ? b [3] : Uni.Level3 (i)); } // otherwise do nothing. // (if the extender is the first char // in the string, then just ignore.) continue; } if (IsIgnorable (i, opt)) continue; i = FilterOptions (i, opt); Contraction ct = GetContraction (s, n, end); if (ct != null) { if (ct.Replacement != null) { GetSortKey (ct.Replacement, 0, ct.Replacement.Length, buf, opt); } else { byte* b = ctx.PrevSortKey; for (int bi = 0; bi < ct.SortKey.Length; bi++) b [bi] = ct.SortKey [bi]; buf.AppendNormal ( b [0], b [1], b [2] != 1 ? b [2] : Level2 (i, ext), b [3] != 1 ? b [3] : Uni.Level3 (i)); ctx.PrevCode = -1; } n += ct.Source.Length - 1; } else { if (!Uni.IsIgnorableNonSpacing (i)) ctx.PrevCode = i; FillSortKeyRaw (i, ExtenderType.None, buf, opt); } } }
void FillSortKeyRaw (int i, ExtenderType ext, SortKeyBuffer buf, CompareOptions opt) { if (0x3400 <= i && i <= 0x4DB5) { int diff = i - 0x3400; buf.AppendCJKExtension ( (byte) (0x10 + diff / 254), (byte) (diff % 254 + 2)); return; } UnicodeCategory uc = char.GetUnicodeCategory ((char) i); switch (uc) { case UnicodeCategory.PrivateUse: int diff = i - 0xE000; buf.AppendNormal ( (byte) (0xE5 + diff / 254), (byte) (diff % 254 + 2), 0, 0); return; case UnicodeCategory.Surrogate: FillSurrogateSortKeyRaw (i, buf); return; } byte level2 = Level2 (i, ext); if (Uni.HasSpecialWeight ((char) i)) { byte level1 = Level1 (i); buf.AppendKana ( Category (i), level1, level2, Uni.Level3 (i), Uni.IsJapaneseSmallLetter ((char) i), ToDashTypeValue (ext, opt), !Uni.IsHiragana ((char) i), IsHalfKana ((char) i, opt) ); if ((opt & COpt.IgnoreNonSpace) == 0 && ext == ExtenderType.Voiced) // Append voice weight buf.AppendNormal (1, 1, 1, 0); } else buf.AppendNormal ( Category (i), Level1 (i), level2, Uni.Level3 (i)); }
public SortKey GetSortKey (string s, int start, int length, CompareOptions options) { SortKeyBuffer buf = new SortKeyBuffer (lcid); buf.Initialize (options, lcid, s, frenchSort); int end = start + length; GetSortKey (s, start, end, buf, options); return buf.GetResultAndReset (); }