From 18fc769c0976a57459232311917d9a4c0b9ad849 Mon Sep 17 00:00:00 2001 From: handa Date: Wed, 1 Apr 2009 12:52:47 +0000 Subject: [PATCH] *** empty log message *** --- MText.cs | 235 ++++++++++++++++++++++++++++++++++++++++------------------- textprop.cs | 15 ++-- 2 files changed, 171 insertions(+), 79 deletions(-) diff --git a/MText.cs b/MText.cs index ad343f1..cfa688b 100644 --- a/MText.cs +++ b/MText.cs @@ -67,6 +67,11 @@ namespace M17N.Core if (sensitive) flags |= Flag.Sensitive; } + + public override string ToString () + { + return key.ToString () + ":" + val; + } } public class MText : IEnumerable, IEquatable, IComparable @@ -228,8 +233,23 @@ namespace M17N.Core return i; } + private void check_pos (int pos, bool tail_ok) + { + if (pos < 0 || (tail_ok ? pos > nchars : pos >= nchars)) + throw new Exception ("Invalid MText position:" + pos); + } + + private void check_range (int from, int to, bool zero_ok) + { + if (from < 0 || (zero_ok ? from > to : from >= to) + || to > nchars) + throw new Exception ("Invalid MText range"); + } + private void insert (int pos, MText mt2, int from, int to) { + check_pos (pos, true); + int pos_idx = pos_to_idx (this, pos); int from_idx = pos_to_idx (mt2, from); int to_idx = pos_to_idx (mt2, to); @@ -249,7 +269,7 @@ namespace M17N.Core interval = new MInterval (plist.Key, to - from); else interval = ((MInterval) p.Val).copy (from, to); - ((MInterval) plist.Val).insert (pos, interval); + ((MInterval) plist.Val).Insert (pos, interval); } } @@ -301,16 +321,23 @@ namespace M17N.Core public MText Del (int from, int to) { + check_range (from, to, true); + sb.Remove (from, pos_to_idx (this, to) - pos_to_idx (this, from)); nchars -= to - from; - foreach (MPlist plist in intervals) - ((MInterval) plist.Val).Delete (from, to); + if (nchars > 0) + foreach (MPlist plist in intervals) + ((MInterval) plist.Val).Delete (from, to); + else + intervals = new MPlist (); return this; } public object GetProp (int pos, MSymbol key) { + check_pos (pos, false); + MInterval i = (MInterval) intervals.Find (key).Val; if (i == null) @@ -322,6 +349,8 @@ namespace M17N.Core public object GetProp (int pos, MSymbol key, out MTextProperty prop) { + check_pos (pos, false); + MInterval i = (MInterval) intervals.Find (key).Val; if (i == null) @@ -332,6 +361,8 @@ namespace M17N.Core public object GetProp (int pos, MSymbol key, out MTextProperty[] array) { + check_pos (pos, false); + MInterval i = (MInterval) intervals.Find (key).Val; if (i == null) @@ -342,6 +373,8 @@ namespace M17N.Core public void PushProp (int from, int to, MSymbol key, object val) { + check_range (from, to, false); + PushProp (from, to, new MTextProperty (key, val)); } @@ -368,8 +401,10 @@ namespace M17N.Core public void DumpProp () { + Console.Write ("("); foreach (MPlist p in intervals) ((MInterval) p.Val).Dump (); + Console.WriteLine (")"); } private class MInterval @@ -383,6 +418,9 @@ namespace M17N.Core // [7 (3 4)] // [3 (1 2)] [3 (4 6)] // [1 (0 1)] [2 (2 3)] [1 (6 7)] + // + private static int count = 0; + private int id; private int total_length; private int from, to; private MSymbol key; @@ -397,6 +435,7 @@ namespace M17N.Core this.key = key; total_length = length; stack = new MPlist (); + id = count++; } public MInterval (MSymbol key, MText mt) @@ -407,6 +446,7 @@ namespace M17N.Core from = 0; to = total_length; stack = new MPlist (); + id = count++; } public MTextProperty Get (int pos) @@ -441,15 +481,26 @@ namespace M17N.Core from = 0; to = total_length; this.stack = stack.Clone (); + id = count++; } private void update_from_to () { - if (parent != null) + if (parent == null) + { + from = LeftLength; + to = total_length - RightLength; + } + else if (parent.left == this) { from = parent.from - total_length + LeftLength; to = parent.from - RightLength; } + else + { + from = parent.to + LeftLength; + to = parent.to + total_length - RightLength; + } } private int LeftLength @@ -633,14 +684,13 @@ namespace M17N.Core // right private MInterval divide_right (int pos) { - update_from_to (); - MInterval interval = new MInterval (key, to - pos, stack); - total_length -= to - pos; + Console.Write ("divide-right({0}) at ", pos); DumpOne (false, true); to = pos; if (right != null) { + interval.right = right; right.parent = interval; interval.total_length += right.total_length; } @@ -654,14 +704,13 @@ namespace M17N.Core // left private MInterval divide_left (int pos) { - update_from_to (); - - MInterval interval = new MInterval (key, to - pos, stack); + MInterval interval = new MInterval (key, pos - from, stack); - total_length -= to - pos; + Console.Write ("divide-reft({0}) at ", pos); DumpOne (false, true); from = pos; if (left != null) { + interval.left = left; left.parent = interval; interval.total_length += left.total_length; } @@ -683,39 +732,58 @@ namespace M17N.Core } } - private void merge_properties (MPlist plist, MTextProperty.Flag flags) + private void merge_front_properties (MPlist plist) { - if (left != null) - left.merge_properties (plist, flags); - if (right != null) - right.merge_properties (plist, flags); - for (MPlist p = plist; ! p.IsEmpty; p = p.Next) + for (MInterval i = left_most_node; i != null; i = i.next) { - MTextProperty prop = (MTextProperty) p.Val; + if (! stack.IsEmpty) + break; + for (MPlist p = plist; ! p.IsEmpty; p = p.Next) + { + MTextProperty prop = (MTextProperty) p.Val; - if ((prop.flags & flags) == flags - && stack.Get (prop.Key) == null) - stack.Push (prop.key, prop); + if ((prop.flags & MTextProperty.Flag.RearSticky) + == MTextProperty.Flag.RearSticky) + i.stack.Push (prop.key, prop); + } } } - public void insert (int pos, MInterval interval) + private void merge_rear_properties (MPlist plist) + { + for (MInterval i = right_most_node; i != null; i = i.prev) + { + if (! stack.IsEmpty) + break; + for (MPlist p = plist; ! p.IsEmpty; p = p.Next) + { + MTextProperty prop = (MTextProperty) p.Val; + + if ((prop.flags & MTextProperty.Flag.FrontSticky) + == MTextProperty.Flag.FrontSticky) + i.stack.Push (prop.key, prop); + } + } + } + + public void Insert (int pos, MInterval interval) { update_from_to (); + Console.Write ("insert({0}) at ", pos); DumpOne (false, true); if (pos < from || (pos == from && left == null && pos > 0)) { - prev.insert (pos, interval); + prev.Insert (pos, interval); return; } if (pos > to || (pos == to && right == null && next != null)) { - next.insert (pos, interval); + next.Insert (pos, interval); return; } if (pos > from && pos < to) { remove_properties (MTextProperty.Flag.Sensitive); - divide_right (pos).insert (pos, interval); + divide_right (pos).Insert (pos, interval); return; } if (pos == from) @@ -724,13 +792,11 @@ namespace M17N.Core { prev.remove_properties (MTextProperty.Flag.Sensitive|MTextProperty.Flag.RearSticky); - interval.merge_properties - (prev.stack, MTextProperty.Flag.RearSticky); + interval.merge_front_properties (prev.stack); } remove_properties (MTextProperty.Flag.Sensitive|MTextProperty.Flag.FrontSticky); - interval.merge_properties - (stack, MTextProperty.Flag.FrontSticky); + interval.merge_rear_properties (stack); // INTERVAL is ready to insert. // @@ -764,13 +830,11 @@ namespace M17N.Core left_most.remove_properties (MTextProperty.Flag.Sensitive|MTextProperty.Flag.FrontSticky); - interval.merge_properties - (stack, MTextProperty.Flag.FrontSticky); + interval.merge_rear_properties (left_most.stack); } remove_properties (MTextProperty.Flag.Sensitive|MTextProperty.Flag.RearSticky); - interval.merge_properties - (stack, MTextProperty.Flag.RearSticky); + interval.merge_front_properties (stack); // INTERVAL is ready to insert. // @@ -798,32 +862,34 @@ namespace M17N.Core } } - private void update_parent (MInterval i) + private void vacate_node (MInterval interval) { + Console.WriteLine ("vacate #{0} to #{1}", id, interval.id); + if (interval != null) + interval.parent = parent; if (parent == null) - mtext.intervals.Put (key, i); + { + mtext.intervals.Put (key, interval); + } else { - int diff; - - if (parent.right == i) - { - diff = parent.right.total_length - i.total_length; - parent.right = i; - } + if (this == parent.right) + parent.right = interval; else - { - diff = parent.left.total_length - i.total_length; - parent.left = i; - } - for (i = parent; i != null; i = i.parent) - i.total_length += diff; + parent.left = interval; + + int diff = total_length; + if (interval != null) + diff -= interval.total_length; + for (MInterval i = parent; i != null; i = i.parent) + i.total_length -= diff; } } public void Delete (int start, int end) { update_from_to (); + Console.Write ("delete({0} {1}) at ", start, end); DumpOne (false, true); if (start < from) { if (end <= from) @@ -832,9 +898,11 @@ namespace M17N.Core return; } left.Delete (start, from); - start = from; + to -= from - start; + end -= from - start; + from = start; } - else if (end > to) + if (end > to) { if (start >= to) { @@ -846,19 +914,23 @@ namespace M17N.Core } if (start == from && end == to) { - if (left == null) - update_parent (right); - else if (right == null) - update_parent (left); + if (right == null) + { + vacate_node (left); + } else { - MInterval i; + if (left != null) + { + MInterval i; - for (i = right; i.left != null; i = i.left) - i.total_length += left.total_length; - i.total_length += left.total_length; - i.left = left; - update_parent (right); + for (i = right; i.left != null; i = i.left) + i.total_length += left.total_length; + i.total_length += left.total_length; + i.left = left; + left.parent = i; + } + vacate_node (right); } } else @@ -870,43 +942,58 @@ namespace M17N.Core } } - public MTextProperty Push (int start, int end, MTextProperty prop) + public void Push (int start, int end, MTextProperty prop) { update_from_to (); + Console.Write ("push({0} {1}) at ", start, end); DumpOne (false, true); if (start < from) { - left.Push (start, end, prop); if (end <= from) - return prop; + { + left.Push (start, end, prop); + return; + } + left.Push (start, from, prop); start = from; } - else if (end > to) + if (end > to) { - right.Push (start, end, prop); if (start >= to) - return prop; + { + right.Push (start, end, prop); + return; + } + right.Push (to, end, prop); end = to; } if (start > from) - divide_left (from); + divide_left (start); if (end < to) divide_right (end); stack.Push (prop.key, prop); - Console.WriteLine ("push({0},{1})", from, to); - return prop; } - public Dump () + private void DumpOne (bool with_prop, bool newline) + { + Console.Write ("#{0}({1} {2} {3}", id, total_length, from, to); + if (with_prop) + foreach (MPlist p in stack) + Console.Write (" " + p.Val); + Console.Write (")"); + if (newline) + Console.WriteLine (); + } + + public void Dump () { update_from_to (); if (left != null) left.Dump (); - if (stack.IsEmpty) - Console.WriteLine ("({0} {1})", from, to); - else - Console.WriteLine ("({0} {1} {2})", from, to, stack.Val); + if (from > 0) + Console.Write (" "); + DumpOne (true, false); if (right != null) right.Dump (); } diff --git a/textprop.cs b/textprop.cs index 29652d8..3131817 100644 --- a/textprop.cs +++ b/textprop.cs @@ -9,11 +9,16 @@ public class Test String str = "0123456789"; MText mt = new MText (str); MSymbol sym = new MSymbol ("sym"); - MTextProperty prop = new MTextProperty (sym, "test"); + MTextProperty prop1 = new MTextProperty (sym, "test1"); + MTextProperty prop2 = new MTextProperty (sym, "test2"); - mt.PushProp (2, 4, prop); - Console.WriteLine (mt.GetProp (7, sym)); - mt.Del (2, 4); - Console.WriteLine (mt.GetProp (3, sym)); + mt.PushProp (2, 5, prop1); + mt.DumpProp (); + mt.PushProp (3, 6, prop2); + mt.DumpProp (); + mt.Del (4, 9); + mt.DumpProp (); + mt.Ins (4, new MText ("45678")); + mt.DumpProp (); } } -- 1.7.10.4