X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=MText.cs;h=b28180898a25d02e4266c77f10df1f3d6c90327d;hb=948496e0c55cfffced24b1053d17b19a9369f747;hp=5c916f171f361a026c461fe9963a977630c7c2af;hpb=3ae490784a2d2a150d2f918edf52586681e256b3;p=m17n%2Fm17n-lib-cs.git diff --git a/MText.cs b/MText.cs index 5c916f1..b281808 100644 --- a/MText.cs +++ b/MText.cs @@ -124,7 +124,7 @@ namespace M17N.Core int len = str.Length, n = 0; for (int i = 0; i < len; i++, n++) - if (surrogate_high_p (str[i])) + if (Char.IsHighSurrogate (str[i])) i++; return n; } @@ -134,7 +134,7 @@ namespace M17N.Core int len = str.Length, n = 0; for (int i = 0; i < len; i++, n++) - if (surrogate_high_p (str[i])) + if (Char.IsHighSurrogate (str[i])) i++; return n; } @@ -173,6 +173,14 @@ namespace M17N.Core intervals = new MPlist (); } + public MText (int c, int len) : this () + { + while (len-- > 0) + this.Cat (c); + } + + public MText (int c) : this (c, 1) { } + public static MText operator+ (object obj, MText mt) { if (obj is string) @@ -219,24 +227,24 @@ namespace M17N.Core public override string ToString () { return sb.ToString (); } - private static bool surrogate_high_p (char c) + public static implicit operator MText (string str) { - return (c >= 0xD800 && c < 0xDC00); + return new MText (str); } - private static bool surrogate_low_p (char c) + public static explicit operator string (MText mt) { - return (c >= 0xDC00 && c < 0xE000); + return mt.ToString (); } private static int inc_idx (StringBuilder sb, int i) { - return (i + (surrogate_high_p (sb[i]) ? 2 : 1)); + return (i + (Char.IsHighSurrogate (sb[i]) ? 2 : 1)); } private static int dec_idx (StringBuilder sb, int i) { - return (i - (surrogate_low_p (sb[i - 1]) ? 2 : 1)); + return (i - (Char.IsLowSurrogate (sb[i - 1]) ? 2 : 1)); } private static int pos_to_idx (MText mt, int pos) @@ -250,7 +258,7 @@ namespace M17N.Core if (pos < mt.cache_pos) { if (mt.cache_pos == mt.cache_idx) - return mt.cache_idx; + return pos; if (pos < mt.cache_pos - pos) { p = i = 0; @@ -371,7 +379,7 @@ namespace M17N.Core i = pos_to_idx (this, i); if (value < 0x10000) { - if (surrogate_high_p (sb[i])) + if (Char.IsHighSurrogate (sb[i])) sb.Remove (i, 1); sb[i] = (char) value; } @@ -380,20 +388,32 @@ namespace M17N.Core char high = (char) (0xD800 + ((value - 0x10000) >> 10)); char low = (char) (0xDC00 + ((value - 0x10000) & 0x3FF)); - if (! surrogate_high_p (sb[i])) + if (! Char.IsHighSurrogate (sb[i])) sb.Insert (i, 0); sb[i] = high; sb[i + 1] = low; } + PopProp (i, i + 1); } get { i = pos_to_idx (this, i); - return (surrogate_high_p (sb[i]) + return (Char.IsHighSurrogate (sb[i]) ? ((sb[i] - 0xD800) << 10) + (sb[i + 1] - 0xDC00) + 0x10000 : sb[i]); } } + public MText this[int from, int to] + { + set { + if (from < to) + Del (from, to); + if (value != null) + Ins (from, value); + } + get { return Dup (from, to); } + } + public MText Dup () { MText mt = new MText (sb.ToString ()); @@ -446,14 +466,23 @@ namespace M17N.Core return this; } + public MText Cat (MText mt, int from, int to) + { + insert (nchars, mt, from, to); + return this; + } + + public MText Del () + { + return Del (0, Length); + } + public MText Del (int from, int to) { if (check_range (from, to, true)) return this; - sb.Remove (from, pos_to_idx (this, to) - pos_to_idx (this, from)); nchars -= to - from; - if (nchars > 0) foreach (MPlist plist in intervals) { @@ -548,6 +577,29 @@ namespace M17N.Core } } + public void PopProp (int from, int to) + { + if (from < 0) + { + default_property = null; + } + else + { + if (check_range (from, to, true)) + return; + for (MPlist p = intervals; ! p.IsEmpty; p = p.next) + { + MInterval root = (MInterval) p.Val; + root.PopAll (from, to); + root = (MInterval) p.Val; + if (M17n.debug) + DumpPropNested (); + root.MergeAfterChange (from, to); + root.Balance (); + } + } + } + public void PopProp (int from, int to, MSymbol key) { if (from < 0) @@ -582,6 +634,19 @@ namespace M17N.Core } } + public object FindProp (MSymbol key, int pos, out int from, out int to) + { + from = 0; + to = Length; + check_pos (pos, false); + + MInterval i = (MInterval) intervals.Get (key); + if (i != null + && (i = i.Find (pos, out from, out to)) != null) + return GetProp (from, key); + return null; + } + public void DumpProp () { Console.Write ("("); @@ -899,6 +964,21 @@ namespace M17N.Core return Parent; } + public MInterval Find (int pos, out int from, out int to) + { + MInterval i = find_head (pos); + + from = to = pos; + if (i.Stack.IsEmpty) + i = i.Next; + if (i != null) + { + from = i.From; + to = i.To; + } + return i; + } + public MInterval Balance () { MInterval i = this; @@ -1646,6 +1726,46 @@ namespace M17N.Core Pop (head.From, tail.To); } + public void PopAll (int start, int end) + { + update_from_to (); + M17n.DebugPrint ("popall({0} {1}) at {2}\n", start, end, this); + if (start < From) + { + if (end <= From) + { + Left.PopAll (start, end); + return; + } + Left.PopAll (start, From); + start = From; + } + if (end > To) + { + if (start >= To) + { + Right.PopAll (start, end); + return; + } + Right.PopAll (To, end); + end = To; + } + + if (! Stack.IsEmpty) + { + if (isSensitive) + Stack.Clear (); + else + { + if (start > From) + divide_left (start); + if (end < To) + divide_right (end); + Stack.Clear (); + } + } + } + public override string ToString () { string str = String.Format ("#{0}({1} {2} {3} [", ID, Length, From, To);