X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=MText.cs;h=14a0696c76691d54cc2e66f6449de490ebfbbf0f;hb=HEAD;hp=39f9359a1854e7b9a8e1f49bfb69458e2fbe0dd8;hpb=9ea91c0c5ca99a2aa11280641f36e503ea302937;p=m17n%2Fm17n-lib-cs.git diff --git a/MText.cs b/MText.cs index 39f9359..14a0696 100644 --- a/MText.cs +++ b/MText.cs @@ -115,7 +115,7 @@ namespace M17N.Core private int cache_idx; private MPlist intervals; private MPlist default_property; - private bool read_only; + private bool read_only = false; private static UTF8Encoding utf8 = new UTF8Encoding (); @@ -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; } @@ -152,6 +152,13 @@ namespace M17N.Core intervals = new MPlist (); } + public MText (byte[] str, int offset, int length) + { + sb = new StringBuilder (utf8.GetString (str, offset, length)); + nchars = count_chars (sb); + intervals = new MPlist (); + } + public MText (String str) { sb = new StringBuilder (str); @@ -166,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) @@ -212,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) @@ -243,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; @@ -364,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; } @@ -373,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 ()); @@ -433,14 +460,29 @@ namespace M17N.Core return this; } + public MText Cat (MText mt) + { + insert (nchars, mt, 0, mt.Length); + 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) { @@ -535,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) @@ -569,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 ("("); @@ -886,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; @@ -969,21 +1062,25 @@ namespace M17N.Core MInterval head = find_head (start); MInterval tail = find_tail (end); + M17n.DebugPrint ("Copying: {0}", copy); + if (! head.Stack.IsEmpty && (isSensitive && head.From < start - || isFrontSensitive && ! first)) + || (isFrontSensitive && ! first))) { + M17n.DebugPrint (" clear head"); head = copy.find_head (0); head.Stack.Clear (); } if (! tail.Stack.IsEmpty - && (isSensitive && end < head.To - || isRearSensitive && ! last)) + && (isSensitive && end < tail.To + || (isRearSensitive && ! last))) { + M17n.DebugPrint (" clear tail"); tail = copy.find_tail (copy.Length); tail.Stack.Clear (); } - M17n.DebugPrint ("Copied: {0}\n", copy); + M17n.DebugPrint ("\n"); return copy; } @@ -1315,7 +1412,7 @@ namespace M17N.Core interval = interval.Copy (mtext, start, end, front_grafted, (rear_grafted - || (next == null && end < interval.mtext.Length))); + || (next == null && end == interval.mtext.Length))); else interval = new MInterval (Key, mtext, end - start, null); @@ -1629,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);