* SimpleCollator.cs :
Created another struct to reduce method arguments. Created
another
flags that keeps "once-matched" state (counterpart of
checkedFlags, now neverMatchFlags).
svn path=/trunk/mcs/; revision=53029
+2005-11-14 Atsushi Enomoto <atsushi@ximian.com>
+
+ * SimpleCollator.cs :
+ Created another struct to reduce method arguments. Created another
+ flags that keeps "once-matched" state (counterpart of
+ checkedFlags, now neverMatchFlags).
+
2005-11-14 Atsushi Enomoto <atsushi@ximian.com>
* SimpleCollator.cs :
2005-11-14 Atsushi Enomoto <atsushi@ximian.com>
* SimpleCollator.cs :
{
internal class SimpleCollator
{
{
internal class SimpleCollator
{
+ unsafe internal struct Context
+ {
+ public Context (CompareOptions opt, byte* alwaysMatchFlags, byte* neverMatchFlags, byte* buffer1, byte* buffer2, byte* prev1)
+ {
+ Option = opt;
+ AlwaysMatchFlags = alwaysMatchFlags;
+ NeverMatchFlags = neverMatchFlags;
+ Buffer1 = buffer1;
+ Buffer2 = buffer2;
+ PrevSortKey = prev1;
+ PrevCode = -1;
+ }
+
+ public readonly CompareOptions Option;
+ public readonly byte* NeverMatchFlags;
+ public readonly byte* AlwaysMatchFlags;
+ public byte* Buffer1;
+ public byte* Buffer2;
+ public int PrevCode;
+ public byte* PrevSortKey;
+
+ public void ClearPrevInfo ()
+ {
+ PrevCode = -1;
+ PrevSortKey = null;
+ }
+ }
+
unsafe struct PreviousInfo
{
public int Code;
unsafe struct PreviousInfo
{
public int Code;
//
// Now that it should be thread safe, this array is allocated
// at every time.
//
// Now that it should be thread safe, this array is allocated
// at every time.
-// byte [] checkedFlags = new byte [128 / 8];
+// byte [] neverMatchFlags = new byte [128 / 8];
#region .ctor() and split functions
#region .ctor() and split functions
unsafe void GetSortKey (string s, int start, int end,
SortKeyBuffer buf, CompareOptions opt)
{
unsafe void GetSortKey (string s, int start, int end,
SortKeyBuffer buf, CompareOptions opt)
{
- PreviousInfo prev = new PreviousInfo (false);
byte* prevbuf = stackalloc byte [4];
ClearBuffer (prevbuf, 4);
byte* prevbuf = stackalloc byte [4];
ClearBuffer (prevbuf, 4);
- prev.SortKey = prevbuf;
+ Context ctx = new Context (opt, null, null, null, null, prevbuf);
for (int n = start; n < end; n++) {
int i = s [n];
ExtenderType ext = GetExtenderType (i);
if (ext != ExtenderType.None) {
for (int n = start; n < end; n++) {
int i = s [n];
ExtenderType ext = GetExtenderType (i);
if (ext != ExtenderType.None) {
- i = FilterExtender (prev.Code, ext, opt);
+ i = FilterExtender (ctx.PrevCode, ext, opt);
if (i >= 0)
FillSortKeyRaw (i, ext, buf, opt);
if (i >= 0)
FillSortKeyRaw (i, ext, buf, opt);
- else if (prev.SortKey != null) {
- byte* b = prev.SortKey;
+ else if (ctx.PrevSortKey != null) {
+ byte* b = ctx.PrevSortKey;
buf.AppendNormal (
b [0],
b [1],
buf.AppendNormal (
b [0],
b [1],
if (ct.Replacement != null) {
GetSortKey (ct.Replacement, 0, ct.Replacement.Length, buf, opt);
} else {
if (ct.Replacement != null) {
GetSortKey (ct.Replacement, 0, ct.Replacement.Length, buf, opt);
} else {
- byte* b = prev.SortKey;
+ byte* b = ctx.PrevSortKey;
for (int bi = 0; bi < ct.SortKey.Length; bi++)
b [bi] = ct.SortKey [bi];
buf.AppendNormal (
for (int bi = 0; bi < ct.SortKey.Length; bi++)
b [bi] = ct.SortKey [bi];
buf.AppendNormal (
b [1],
b [2] != 1 ? b [2] : Level2 (i, ext),
b [3] != 1 ? b [3] : Uni.Level3 (i));
b [1],
b [2] != 1 ? b [2] : Level2 (i, ext),
b [3] != 1 ? b [3] : Uni.Level3 (i));
}
n += ct.Source.Length - 1;
}
else {
if (!Uni.IsIgnorableNonSpacing (i))
}
n += ct.Source.Length - 1;
}
else {
if (!Uni.IsIgnorableNonSpacing (i))
FillSortKeyRaw (i, ExtenderType.None, buf, opt);
}
}
FillSortKeyRaw (i, ExtenderType.None, buf, opt);
}
}
return d1 [i] < d2 [i] ? -1 : 1;
return d1.Length == d2.Length ? 0 : d1.Length < d2.Length ? -1 : 1;
#else
return d1 [i] < d2 [i] ? -1 : 1;
return d1.Length == d2.Length ? 0 : d1.Length < d2.Length ? -1 : 1;
#else
- PreviousInfo prev1 = new PreviousInfo (false);
byte* sk1 = stackalloc byte [4];
byte* sk1 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
+ Context ctx = new Context (options, null, null, sk1, sk2, null);
+
- int ret = CompareInternal (options, s1, idx1, len1, s2, idx2, len2, out dummy, out dummy2, true, ref prev1, sk1, sk2);
+ int ret = CompareInternal (s1, idx1, len1, s2, idx2, len2, out dummy, out dummy2, true, false, ref ctx);
return ret == 0 ? 0 : ret < 0 ? -1 : 1;
#endif
}
return ret == 0 ? 0 : ret < 0 ? -1 : 1;
#endif
}
- unsafe int CompareInternal (COpt opt, string s1, int idx1, int len1, string s2,
+ unsafe int CompareInternal (string s1, int idx1, int len1, string s2,
int idx2, int len2,
out bool targetConsumed, out bool sourceConsumed,
int idx2, int len2,
out bool targetConsumed, out bool sourceConsumed,
- bool skipHeadingExtenders, ref PreviousInfo prev1,
- byte* charSortKey, byte* charSortKey2)
+ bool skipHeadingExtenders, bool immediatelyBreakup,
+ ref Context ctx)
int start1 = idx1;
int start2 = idx2;
int end1 = idx1 + len1;
int start1 = idx1;
int start2 = idx2;
int end1 = idx1 + len1;
// repeat the previous character.
ext1 = GetExtenderType (i1);
if (ext1 != ExtenderType.None) {
// repeat the previous character.
ext1 = GetExtenderType (i1);
if (ext1 != ExtenderType.None) {
- if (prev1.Code < 0) {
- if (prev1.SortKey == null) {
+ if (ctx.PrevCode < 0) {
+ if (ctx.PrevSortKey == null) {
// nothing to extend
idx1++;
continue;
}
// nothing to extend
idx1++;
continue;
}
- i1 = FilterExtender (prev1.Code, ext1, opt);
+ i1 = FilterExtender (ctx.PrevCode, ext1, opt);
}
ext2 = GetExtenderType (i2);
if (ext2 != ExtenderType.None) {
}
ext2 = GetExtenderType (i2);
if (ext2 != ExtenderType.None) {
// here Windows has a bug that it does
// not consider thirtiary weight.
lv5Value1 = Level1 (i1) << 8 + Uni.Level3 (i1);
// here Windows has a bug that it does
// not consider thirtiary weight.
lv5Value1 = Level1 (i1) << 8 + Uni.Level3 (i1);
idx1++;
}
if (cat2 == 6) {
idx1++;
}
if (cat2 == 6) {
else if (ct1 != null) {
offset1 = ct1.Source.Length;
if (ct1.SortKey != null) {
else if (ct1 != null) {
offset1 = ct1.Source.Length;
if (ct1.SortKey != null) {
for (int i = 0; i < ct1.SortKey.Length; i++)
sk1 [i] = ct1.SortKey [i];
for (int i = 0; i < ct1.SortKey.Length; i++)
sk1 [i] = ct1.SortKey [i];
- prev1.Code = -1;
- prev1.SortKey = sk1;
+ ctx.PrevCode = -1;
+ ctx.PrevSortKey = sk1;
}
else if (escape1.Source == null) {
escape1.Source = s1;
}
else if (escape1.Source == null) {
escape1.Source = s1;
sk1 [0] = cat1;
sk1 [1] = Level1 (i1);
if (!ignoreNonSpace && currentLevel > 1)
sk1 [0] = cat1;
sk1 [1] = Level1 (i1);
if (!ignoreNonSpace && currentLevel > 1)
if (currentLevel > 3)
special1 = Uni.HasSpecialWeight ((char) i1);
if (cat1 > 1)
if (currentLevel > 3)
special1 = Uni.HasSpecialWeight ((char) i1);
if (cat1 > 1)
}
Contraction ct2 = null;
}
Contraction ct2 = null;
else if (ct2 != null) {
idx2 += ct2.Source.Length;
if (ct2.SortKey != null) {
else if (ct2 != null) {
idx2 += ct2.Source.Length;
if (ct2.SortKey != null) {
for (int i = 0; i < ct2.SortKey.Length; i++)
sk2 [i] = ct2.SortKey [i];
prev2.Code = -1;
for (int i = 0; i < ct2.SortKey.Length; i++)
sk2 [i] = ct2.SortKey [i];
prev2.Code = -1;
sk2 [0] = cat2;
sk2 [1] = Level1 (i2);
if (!ignoreNonSpace && currentLevel > 1)
sk2 [0] = cat2;
sk2 [1] = Level1 (i2);
if (!ignoreNonSpace && currentLevel > 1)
ret = sk1 [2] - sk2 [2];
if (ret != 0) {
finalResult = ret;
ret = sk1 [2] - sk2 [2];
if (ret != 0) {
finalResult = ret;
+ if (immediatelyBreakup)
+ return -1; // different
currentLevel = frenchSort ? 2 : 1;
continue;
}
currentLevel = frenchSort ? 2 : 1;
continue;
}
ret = sk1 [3] - sk2 [3];
if (ret != 0) {
finalResult = ret;
ret = sk1 [3] - sk2 [3];
if (ret != 0) {
finalResult = ret;
+ if (immediatelyBreakup)
+ return -1; // different
currentLevel = 2;
continue;
}
if (currentLevel == 3)
continue;
if (special1 != special2) {
currentLevel = 2;
continue;
}
if (currentLevel == 3)
continue;
if (special1 != special2) {
+ if (immediatelyBreakup)
+ return -1; // different
finalResult = special1 ? 1 : -1;
currentLevel = 3;
continue;
finalResult = special1 ? 1 : -1;
currentLevel = 3;
continue;
!IsHalfKana ((char) i1, opt),
!IsHalfKana ((char) i2, opt));
if (ret != 0) {
!IsHalfKana ((char) i1, opt),
!IsHalfKana ((char) i2, opt));
if (ret != 0) {
+ if (immediatelyBreakup)
+ return -1; // different
finalResult = ret;
currentLevel = 3;
continue;
finalResult = ret;
currentLevel = 3;
continue;
{
if (target.Length == 0)
return true;
{
if (target.Length == 0)
return true;
- PreviousInfo prev = new PreviousInfo (false);
byte* sk1 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
ClearBuffer (sk1, 4);
ClearBuffer (sk2, 4);
byte* sk1 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
ClearBuffer (sk1, 4);
ClearBuffer (sk2, 4);
- return IsPrefix (opt, s, target, start, length, true, ref prev, sk1, sk2);
+ Context ctx = new Context (opt, null, null, sk1, sk2, null);
+ return IsPrefix (s, target, start, length, true, ref ctx);
- unsafe bool IsPrefix (COpt opt, string s, string target, int start, int length, bool skipHeadingExtenders, ref PreviousInfo prev, byte* sk1, byte* sk2)
+ unsafe bool IsPrefix (string s, string target, int start, int length, bool skipHeadingExtenders, ref Context ctx)
- CompareInternal (opt, s, start, length,
+ CompareInternal (s, start, length,
target, 0, target.Length,
out consumed, out dummy, skipHeadingExtenders,
target, 0, target.Length,
out consumed, out dummy, skipHeadingExtenders,
- unsafe bool IsSuffix (COpt opt, string s, string t, int start, int length, ref PreviousInfo prev, byte* sk1, byte* sk2)
+ unsafe bool IsSuffix (string s, string t, int start, int length, ref Context ctx)
+ COpt opt = ctx.Option;
+
for (;tstart < t.Length; tstart++)
if (!IsIgnorable (t [tstart], opt))
break;
for (;tstart < t.Length; tstart++)
if (!IsIgnorable (t [tstart], opt))
break;
bool sourceConsumed, targetConsumed;
int mismatchCount = 0;
for (int i = 0; i < length; i++) {
bool sourceConsumed, targetConsumed;
int mismatchCount = 0;
for (int i = 0; i < length; i++) {
- prev = new PreviousInfo (false); // prev.Reset();
- int ret = CompareInternal (opt, s, start - i, i + 1,
+ int ret = CompareInternal (s, start - i, i + 1,
t, tstart, t.Length - tstart,
out targetConsumed,
t, tstart, t.Length - tstart,
out targetConsumed,
- out sourceConsumed, true, ref prev,
- sk1, sk2);
+ // FIXME: could immediately breakup
+ out sourceConsumed, true, true, ref ctx);
if (ret == 0)
return true;
if (!sourceConsumed && targetConsumed)
if (ret == 0)
return true;
if (!sourceConsumed && targetConsumed)
public unsafe int IndexOf (string s, string target, int start, int length, CompareOptions opt)
{
public unsafe int IndexOf (string s, string target, int start, int length, CompareOptions opt)
{
- PreviousInfo prev = new PreviousInfo (false);
- byte* checkedFlags = stackalloc byte [16];
+ byte* alwaysMatchFlags = stackalloc byte [16];
+ byte* neverMatchFlags = stackalloc byte [16];
byte* targetSortKey = stackalloc byte [4];
byte* sk1 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
byte* targetSortKey = stackalloc byte [4];
byte* sk1 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
- ClearBuffer (checkedFlags, 16);
+ ClearBuffer (alwaysMatchFlags, 16);
+ ClearBuffer (neverMatchFlags, 16);
ClearBuffer (targetSortKey, 4);
ClearBuffer (sk1, 4);
ClearBuffer (sk2, 4);
ClearBuffer (targetSortKey, 4);
ClearBuffer (sk1, 4);
ClearBuffer (sk2, 4);
+ Context ctx = new Context (opt, alwaysMatchFlags, neverMatchFlags, sk1, sk2, null);
- return IndexOf (opt, s, target, start, length,
- checkedFlags, targetSortKey, ref prev, sk1, sk2);
+ return IndexOf (s, target, start, length,
+ targetSortKey, ref ctx);
}
public int IndexOf (string s, char target, CompareOptions opt)
}
public int IndexOf (string s, char target, CompareOptions opt)
public unsafe int IndexOf (string s, char target, int start, int length, CompareOptions opt)
{
public unsafe int IndexOf (string s, char target, int start, int length, CompareOptions opt)
{
- PreviousInfo prev = new PreviousInfo (false);
- byte* checkedFlags = stackalloc byte [16];
+ byte* alwaysMatchFlags = stackalloc byte [16];
+ byte* neverMatchFlags = stackalloc byte [16];
byte* targetSortKey = stackalloc byte [4];
byte* sk1 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
byte* targetSortKey = stackalloc byte [4];
byte* sk1 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
- ClearBuffer (checkedFlags, 16);
+ ClearBuffer (alwaysMatchFlags, 16);
+ ClearBuffer (neverMatchFlags, 16);
ClearBuffer (targetSortKey, 4);
ClearBuffer (sk1, 4);
ClearBuffer (sk2, 4);
ClearBuffer (targetSortKey, 4);
ClearBuffer (sk1, 4);
ClearBuffer (sk2, 4);
+ Context ctx = new Context (opt, alwaysMatchFlags, neverMatchFlags, sk1, sk2, null);
// If target is contraction, then use string search.
Contraction ct = GetContraction (target);
if (ct != null) {
if (ct.Replacement != null)
// If target is contraction, then use string search.
Contraction ct = GetContraction (target);
if (ct != null) {
if (ct.Replacement != null)
- return IndexOf (opt, s, ct.Replacement,
- start, length, checkedFlags, targetSortKey, ref prev, sk1, sk2);
+ return IndexOf (s, ct.Replacement,
+ start, length, targetSortKey, ref ctx);
else {
for (int i = 0; i < ct.SortKey.Length; i++)
sk2 [i] = ct.SortKey [i];
else {
for (int i = 0; i < ct.SortKey.Length; i++)
sk2 [i] = ct.SortKey [i];
- return IndexOfSortKey (opt, s, start, length, sk2, char.MinValue, -1, true, checkedFlags, ref prev, sk1);
+ return IndexOfSortKey (s, start, length, sk2, char.MinValue, -1, true, ref ctx);
}
} else {
int ti = FilterOptions ((int) target, opt);
}
} else {
int ti = FilterOptions ((int) target, opt);
targetSortKey [2] =
Level2 (ti, ExtenderType.None);
targetSortKey [3] = Uni.Level3 (ti);
targetSortKey [2] =
Level2 (ti, ExtenderType.None);
targetSortKey [3] = Uni.Level3 (ti);
- return IndexOfSortKey (opt, s, start, length,
+ return IndexOfSortKey (s, start, length,
targetSortKey, target, ti,
targetSortKey, target, ti,
- !Uni.HasSpecialWeight ((char) ti), checkedFlags, ref prev, sk1);
+ !Uni.HasSpecialWeight ((char) ti), ref ctx);
}
}
// Searches target byte[] keydata
}
}
// Searches target byte[] keydata
- unsafe int IndexOfSortKey (COpt opt, string s, int start, int length, byte* sortkey, char target, int ti, bool noLv4, byte* checkedFlags, ref PreviousInfo prev, byte* sk)
+ unsafe int IndexOfSortKey (string s, int start, int length, byte* sortkey, char target, int ti, bool noLv4, ref Context ctx)
{
int end = start + length;
int idx = start;
while (idx < end) {
int cur = idx;
{
int end = start + length;
int idx = start;
while (idx < end) {
int cur = idx;
- if (MatchesForward (opt, s, ref idx, end, ti, sortkey, noLv4, checkedFlags, ref prev, sk))
+ if (MatchesForward (s, ref idx, end, ti, sortkey, noLv4, ref ctx))
// Searches string. Search head character (or keydata when
// the head is contraction sortkey) and try IsPrefix().
// Searches string. Search head character (or keydata when
// the head is contraction sortkey) and try IsPrefix().
- unsafe int IndexOf (COpt opt, string s, string target, int start, int length, byte* checkedFlags, byte* targetSortKey, ref PreviousInfo prev, byte* sk1, byte* sk2)
+ unsafe int IndexOf (string s, string target, int start, int length, byte* targetSortKey, ref Context ctx)
int tidx = 0;
for (; tidx < target.Length; tidx++)
if (!IsIgnorable (target [tidx], opt))
int tidx = 0;
for (; tidx < target.Length; tidx++)
if (!IsIgnorable (target [tidx], opt))
do {
int idx = 0;
if (replace != null)
do {
int idx = 0;
if (replace != null)
- idx = IndexOf (opt, s, replace, start, length, checkedFlags, targetSortKey, ref prev, sk1, sk2);
+ idx = IndexOf (s, replace, start, length, targetSortKey, ref ctx);
- idx = IndexOfSortKey (opt, s, start, length, sk, tc, ti, noLv4, checkedFlags, ref prev, sk1);
+ idx = IndexOfSortKey (s, start, length, sk, tc, ti, noLv4, ref ctx);
if (idx < 0)
return -1;
length -= idx - start;
start = idx;
if (idx < 0)
return -1;
length -= idx - start;
start = idx;
- if (IsPrefix (opt, s, target, start, length, false, ref prev, sk1, sk2))
+ if (IsPrefix (s, target, start, length, false, ref ctx))
return idx;
Contraction cts = GetContraction (s, start, length);
if (cts != null) {
return idx;
Contraction cts = GetContraction (s, start, length);
if (cts != null) {
public unsafe int LastIndexOf (string s, string target, int start, int length, CompareOptions opt)
{
public unsafe int LastIndexOf (string s, string target, int start, int length, CompareOptions opt)
{
- PreviousInfo prev = new PreviousInfo (false);
- byte* checkedFlags = stackalloc byte [16];
+ byte* alwaysMatchFlags = stackalloc byte [16];
+ byte* neverMatchFlags = stackalloc byte [16];
byte* targetSortKey = stackalloc byte [4];
byte* sk1 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
byte* targetSortKey = stackalloc byte [4];
byte* sk1 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
- ClearBuffer (checkedFlags, 16);
+ ClearBuffer (alwaysMatchFlags, 16);
+ ClearBuffer (neverMatchFlags, 16);
ClearBuffer (targetSortKey, 4);
ClearBuffer (sk1, 4);
ClearBuffer (sk2, 4);
ClearBuffer (targetSortKey, 4);
ClearBuffer (sk1, 4);
ClearBuffer (sk2, 4);
- return LastIndexOf (opt, s, target, start, length,
- checkedFlags, targetSortKey, ref prev, sk1, sk2);
+ Context ctx = new Context (opt, alwaysMatchFlags, neverMatchFlags, sk1, sk2, null);
+ return LastIndexOf (s, target, start, length,
+ targetSortKey, ref ctx);
}
public int LastIndexOf (string s, char target, CompareOptions opt)
}
public int LastIndexOf (string s, char target, CompareOptions opt)
public unsafe int LastIndexOf (string s, char target, int start, int length, CompareOptions opt)
{
public unsafe int LastIndexOf (string s, char target, int start, int length, CompareOptions opt)
{
- PreviousInfo prev = new PreviousInfo (false);
- byte* checkedFlags = stackalloc byte [16];
+ byte* alwaysMatchFlags = stackalloc byte [16];
+ byte* neverMatchFlags = stackalloc byte [16];
byte* targetSortKey = stackalloc byte [4];
byte* sk1 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
byte* targetSortKey = stackalloc byte [4];
byte* sk1 = stackalloc byte [4];
byte* sk2 = stackalloc byte [4];
- ClearBuffer (checkedFlags, 16);
+ ClearBuffer (alwaysMatchFlags, 16);
+ ClearBuffer (neverMatchFlags, 16);
ClearBuffer (targetSortKey, 4);
ClearBuffer (sk1, 4);
ClearBuffer (sk2, 4);
ClearBuffer (targetSortKey, 4);
ClearBuffer (sk1, 4);
ClearBuffer (sk2, 4);
+ Context ctx = new Context (opt, alwaysMatchFlags, neverMatchFlags, sk1, sk2, null);
// If target is a replacement contraction, then use
// string search.
Contraction ct = GetContraction (target);
if (ct != null) {
if (ct.Replacement != null)
// If target is a replacement contraction, then use
// string search.
Contraction ct = GetContraction (target);
if (ct != null) {
if (ct.Replacement != null)
- return LastIndexOf (opt, s,
ct.Replacement, start, length,
ct.Replacement, start, length,
- checkedFlags, targetSortKey, ref prev, sk1, sk2);
+ targetSortKey, ref ctx);
else {
for (int bi = 0; bi < ct.SortKey.Length; bi++)
sk2 [bi] = ct.SortKey [bi];
else {
for (int bi = 0; bi < ct.SortKey.Length; bi++)
sk2 [bi] = ct.SortKey [bi];
- return LastIndexOfSortKey (opt, s, start,
+ return LastIndexOfSortKey (s, start,
- -1, true,
- checkedFlags, ref prev, sk1);
if ((opt & COpt.IgnoreNonSpace) == 0)
targetSortKey [2] = Level2 (ti, ExtenderType.None);
targetSortKey [3] = Uni.Level3 (ti);
if ((opt & COpt.IgnoreNonSpace) == 0)
targetSortKey [2] = Level2 (ti, ExtenderType.None);
targetSortKey [3] = Uni.Level3 (ti);
- return LastIndexOfSortKey (opt, s, start, start,
+ return LastIndexOfSortKey (s, start, start,
length, targetSortKey,
ti, !Uni.HasSpecialWeight ((char) ti),
length, targetSortKey,
ti, !Uni.HasSpecialWeight ((char) ti),
- checkedFlags, ref prev, sk1);
}
}
// Searches target byte[] keydata
}
}
// Searches target byte[] keydata
- unsafe int LastIndexOfSortKey (COpt opt, string s, int start, int orgStart, int length, byte* sortkey, int ti, bool noLv4, byte* checkedFlags, ref PreviousInfo prev, byte* sk)
+ unsafe int LastIndexOfSortKey (string s, int start, int orgStart, int length, byte* sortkey, int ti, bool noLv4, ref Context ctx)
{
int end = start - length;
int idx = start;
while (idx > end) {
int cur = idx;
{
int end = start - length;
int idx = start;
while (idx > end) {
int cur = idx;
- if (MatchesBackward (opt, s, ref idx, end, orgStart,
- ti, sortkey, noLv4, checkedFlags, ref prev, sk))
+ if (MatchesBackward (s, ref idx, end, orgStart,
+ ti, sortkey, noLv4, ref ctx))
// Searches string. Search head character (or keydata when
// the head is contraction sortkey) and try IsPrefix().
// Searches string. Search head character (or keydata when
// the head is contraction sortkey) and try IsPrefix().
- unsafe int LastIndexOf (COpt opt, string s, string target, int start, int length, byte* checkedFlags, byte* targetSortKey, ref PreviousInfo prev, byte* sk1, byte* sk2)
+ unsafe int LastIndexOf (string s, string target, int start, int length, byte* targetSortKey, ref Context ctx)
int orgStart = start;
int tidx = 0;
for (; tidx < target.Length; tidx++)
int orgStart = start;
int tidx = 0;
for (; tidx < target.Length; tidx++)
byte* sk = replace == null ? targetSortKey : null;
bool noLv4 = true;
byte* sk = replace == null ? targetSortKey : null;
bool noLv4 = true;
- char tc = char.MinValue;
int ti = -1;
if (ct != null && sk != null) {
for (int i = 0; i < ct.SortKey.Length; i++)
sk [i] = ct.SortKey [i];
} else if (sk != null) {
int ti = -1;
if (ct != null && sk != null) {
for (int i = 0; i < ct.SortKey.Length; i++)
sk [i] = ct.SortKey [i];
} else if (sk != null) {
ti = FilterOptions (target [tidx], opt);
sk [0] = Category (ti);
sk [1] = Level1 (ti);
ti = FilterOptions (target [tidx], opt);
sk [0] = Category (ti);
sk [1] = Level1 (ti);
int idx = 0;
if (replace != null)
int idx = 0;
if (replace != null)
- idx = LastIndexOf (opt, s, replace,
- start, length, checkedFlags,
- targetSortKey, ref prev, sk1, sk2);
+ idx = LastIndexOf (s, replace,
+ start, length,
+ targetSortKey, ref ctx);
- idx = LastIndexOfSortKey (opt, s, start, orgStart, length, sk, ti, noLv4, checkedFlags, ref prev, sk1);
+ idx = LastIndexOfSortKey (s, start, orgStart, length, sk, ti, noLv4, ref ctx);
if (idx < 0)
return -1;
length -= start - idx;
start = idx;
if (idx < 0)
return -1;
length -= start - idx;
start = idx;
- if (IsPrefix (opt, s, target, idx, orgStart - idx + 1, false, ref prev, sk1, sk2)) {
+ if (IsPrefix (s, target, idx, orgStart - idx + 1, false, ref ctx)) {
for (;idx < orgStart; idx++)
if (!IsIgnorable (s [idx], opt))
break;
for (;idx < orgStart; idx++)
if (!IsIgnorable (s [idx], opt))
break;
- unsafe bool MatchesForward (COpt opt, string s, ref int idx, int end, int ti, byte* sortkey, bool noLv4, byte* checkedFlags, ref PreviousInfo prev, byte* sk)
+ unsafe bool MatchesForward (string s, ref int idx, int end, int ti, byte* sortkey, bool noLv4, ref Context ctx)
- if (checkedFlags != null && si < 128 && (checkedFlags [si / 8] & (1 << (si % 8))) != 0) {
+ if (ctx.AlwaysMatchFlags != null && si < 128 && (ctx.AlwaysMatchFlags [si / 8] & (1 << (si % 8))) != 0)
+ return true;
+ if (ctx.NeverMatchFlags != null &&
+ si < 128 &&
+ (ctx.NeverMatchFlags [si / 8] & (1 << (si % 8))) != 0) {
idx++;
return false;
}
ExtenderType ext = GetExtenderType (s [idx]);
Contraction ct = null;
idx++;
return false;
}
ExtenderType ext = GetExtenderType (s [idx]);
Contraction ct = null;
- if (MatchesForwardCore (opt, s, ref idx, end, ti, sortkey, noLv4, ext, ref ct, checkedFlags, ref prev, sk))
+ if (MatchesForwardCore (s, ref idx, end, ti, sortkey, noLv4, ext, ref ct, ref ctx)) {
+ if (ctx.AlwaysMatchFlags != null && ct == null && ext == ExtenderType.None && si < 128)
+ ctx.AlwaysMatchFlags [si / 8] |= (byte) (1 << (si % 8));
- if (checkedFlags != null && ct == null && ext == ExtenderType.None && si < 128) {
- checkedFlags [si / 8] |= (byte) (1 << (si % 8));
+ if (ctx.NeverMatchFlags != null && ct == null && ext == ExtenderType.None && si < 128)
+ ctx.NeverMatchFlags [si / 8] |= (byte) (1 << (si % 8));
- unsafe bool MatchesForwardCore (COpt opt, string s, ref int idx, int end, int ti, byte* sortkey, bool noLv4, ExtenderType ext, ref Contraction ct, byte* checkedFlags, ref PreviousInfo prev, byte* charSortKey)
+ unsafe bool MatchesForwardCore (string s, ref int idx, int end, int ti, byte* sortkey, bool noLv4, ExtenderType ext, ref Contraction ct, ref Context ctx)
+ COpt opt = ctx.Option;
+ byte* charSortKey = ctx.Buffer1;
bool ignoreNonSpace = (opt & COpt.IgnoreNonSpace) != 0;
int si = -1;
if (ext == ExtenderType.None)
ct = GetContraction (s, idx, end);
bool ignoreNonSpace = (opt & COpt.IgnoreNonSpace) != 0;
int si = -1;
if (ext == ExtenderType.None)
ct = GetContraction (s, idx, end);
- else if (prev.Code < 0) {
- if (prev.SortKey == null) {
+ else if (ctx.PrevCode < 0) {
+ if (ctx.PrevSortKey == null) {
- charSortKey = prev.SortKey;
+ charSortKey = ctx.PrevSortKey;
- si = FilterExtender (prev.Code, ext, opt);
+ si = FilterExtender (ctx.PrevCode, ext, opt);
// if lv4 exists, it never matches contraction
if (ct != null) {
idx += ct.Source.Length;
// if lv4 exists, it never matches contraction
if (ct != null) {
idx += ct.Source.Length;
if (ct.SortKey != null) {
for (int i = 0; i < 4; i++)
charSortKey [i] = sortkey [i];
if (ct.SortKey != null) {
for (int i = 0; i < 4; i++)
charSortKey [i] = sortkey [i];
- prev.Code = -1;
- prev.SortKey = charSortKey;
+ ctx.PrevCode = -1;
+ ctx.PrevSortKey = charSortKey;
} else {
// Here is the core of LAMESPEC
// described at the top of the source.
int dummy = 0;
} else {
// Here is the core of LAMESPEC
// described at the top of the source.
int dummy = 0;
- return MatchesForward (opt, ct.Replacement, ref dummy,
- ct.Replacement.Length, ti, sortkey, noLv4, checkedFlags, ref prev, charSortKey);
+ return MatchesForward (ct.Replacement, ref dummy,
+ ct.Replacement.Length, ti, sortkey, noLv4, ref ctx);
}
charSortKey [3] = Uni.Level3 (si);
if (charSortKey [0] != 1)
}
charSortKey [3] = Uni.Level3 (si);
if (charSortKey [0] != 1)
}
for (; idx < end; idx++) {
if (Category (s [idx]) != 1)
}
for (; idx < end; idx++) {
if (Category (s [idx]) != 1)
- unsafe bool MatchesBackward (COpt opt, string s, ref int idx, int end, int orgStart, int ti, byte* sortkey, bool noLv4, byte* checkedFlags, ref PreviousInfo prev, byte* sk)
+ unsafe bool MatchesBackward (string s, ref int idx, int end, int orgStart, int ti, byte* sortkey, bool noLv4, ref Context ctx)
- if (checkedFlags != null && si < 128 && (checkedFlags [si / 8] & (1 << (si % 8))) != 0) {
+ if (ctx.AlwaysMatchFlags != null && si < 128 && (ctx.AlwaysMatchFlags [si / 8] & (1 << (si % 8))) != 0)
+ return true;
+ if (ctx.NeverMatchFlags != null && si < 128 && (ctx.NeverMatchFlags [si / 8] & (1 << (si % 8))) != 0) {
idx--;
return false;
}
ExtenderType ext = GetExtenderType (s [idx]);
Contraction ct = null;
idx--;
return false;
}
ExtenderType ext = GetExtenderType (s [idx]);
Contraction ct = null;
- if (MatchesBackwardCore (opt, s, ref idx, end, orgStart, ti, sortkey, noLv4, ext, ref ct, checkedFlags, ref prev, sk))
+ if (MatchesBackwardCore (s, ref idx, end, orgStart, ti, sortkey, noLv4, ext, ref ct, ref ctx)) {
+ if (ctx.AlwaysMatchFlags != null && ct == null && ext == ExtenderType.None && si < 128)
+ ctx.AlwaysMatchFlags [si / 8] |= (byte) (1 << (si % 8));
- if (checkedFlags != null && ct == null && ext == ExtenderType.None && si < 128) {
- checkedFlags [si / 8] |= (byte) (1 << (si % 8));
+ }
+ if (ctx.NeverMatchFlags != null && ct == null && ext == ExtenderType.None && si < 128) {
+ ctx.NeverMatchFlags [si / 8] |= (byte) (1 << (si % 8));
- unsafe bool MatchesBackwardCore (COpt opt, string s, ref int idx, int end, int orgStart, int ti, byte* sortkey, bool noLv4, ExtenderType ext, ref Contraction ct, byte* checkedFlags, ref PreviousInfo prev, byte* charSortKey)
+ unsafe bool MatchesBackwardCore (string s, ref int idx, int end, int orgStart, int ti, byte* sortkey, bool noLv4, ExtenderType ext, ref Contraction ct, ref Context ctx)
+ COpt opt = ctx.Option;
+ byte* charSortKey = ctx.Buffer1;
bool ignoreNonSpace = (opt & COpt.IgnoreNonSpace) != 0;
int cur = idx;
int si = -1;
bool ignoreNonSpace = (opt & COpt.IgnoreNonSpace) != 0;
int cur = idx;
int si = -1;
if (ct.SortKey != null) {
for (int i = 0; i < 4; i++)
charSortKey [i] = sortkey [i];
if (ct.SortKey != null) {
for (int i = 0; i < 4; i++)
charSortKey [i] = sortkey [i];
- prev.Code = -1;
- prev.SortKey = charSortKey;
+ ctx.PrevCode = -1;
+ ctx.PrevSortKey = charSortKey;
} else {
// Here is the core of LAMESPEC
// described at the top of the source.
int dummy = ct.Replacement.Length - 1;
} else {
// Here is the core of LAMESPEC
// described at the top of the source.
int dummy = ct.Replacement.Length - 1;
- return 0 <= LastIndexOfSortKey (opt,
+ return 0 <= LastIndexOfSortKey (
ct.Replacement, dummy, dummy,
ct.Replacement.Length, sortkey,
ct.Replacement, dummy, dummy,
ct.Replacement.Length, sortkey,
- ti, noLv4, checkedFlags,
- ref prev, charSortKey);
}
} else if (ext == ExtenderType.None) {
if (si < 0)
}
} else if (ext == ExtenderType.None) {
if (si < 0)
return false;
charSortKey [3] = Uni.Level3 (si);
if (charSortKey [0] != 1)
return false;
charSortKey [3] = Uni.Level3 (si);
if (charSortKey [0] != 1)
}
if (ext == ExtenderType.None) {
for (int tmp = cur + 1; tmp < orgStart; tmp++) {
}
if (ext == ExtenderType.None) {
for (int tmp = cur + 1; tmp < orgStart; tmp++) {