public Rope Remove(int start, int length) { if (IsLeaf) { if (Leaf.Length < start) { throw new ArgumentOutOfRangeException("Start is after the length of this string. Cant remove"); } if (start + length < Leaf.Length) { //need to split the leaf into left and right var newRight = new Rope { Leaf = new LeafSection(Leaf.Base, Leaf.Start + start + length, Leaf.Length - (start + length)), LengthChangedAction = LengthChangedHandler }; var newLeft = new Rope { Leaf = new LeafSection(Leaf.Base, Leaf.Start, start), LengthChangedAction = LengthChangedHandler }; this.Right = newRight; this.Left = newLeft; } else if (start == 0) { //need to remove the begining Leaf.Start += length; Leaf.Length -= length; } else { //need to remove the end Leaf.Length = start; } LengthChangedAction?.Invoke(this, Length); } else { var leftLen = LeftLength(); if (start < leftLen) { var lenInLeft = Math.Min(leftLen - start, length); Left.Remove(start, lenInLeft); if (lenInLeft < length) { Right.Remove(0, length - lenInLeft); } } else { Right.Remove(start - leftLen, length); } if (Right?.Length == 0) { Right = null; } if (Left?.Length == 0) { //if left is empty then move right to left if (Right == null) { Left = null; } else { Left = Right; Right = null; } } } return(this); }
public Rope Insert(string value, int position) { if (this.IsLeaf) { if (position == 0) { //Insert before this Right = new Rope { Leaf = Leaf, LengthChangedAction = LengthChangedHandler }; Left = new Rope(value) { LengthChangedAction = LengthChangedHandler }; } else if (position == Length) { //Insert after this Left = new Rope { Leaf = Leaf, LengthChangedAction = LengthChangedHandler }; Right = new Rope(value) { LengthChangedAction = LengthChangedHandler }; } else { //its in the middle of this bit var newLeft = new Rope(); var newLeftLen = position; newLeft.Left = new Rope { Leaf = new LeafSection(Leaf.Base, Leaf.Start, newLeftLen), LengthChangedAction = LengthChangedHandler }; newLeft.Right = new Rope(value) { LengthChangedAction = LengthChangedHandler }; var newRightStart = Leaf.Start + newLeftLen; Right = new Rope { Leaf = new LeafSection(Leaf.Base, newRightStart, Leaf.Length - newRightStart), LengthChangedAction = LengthChangedHandler }; Left = newLeft; } } else { var leftLen = LeftLength(); if (position < leftLen) { Left.Insert(value, position); } else { if (Right == null) { Right = new Rope(value) { LengthChangedAction = LengthChangedHandler }; } else { Right.Insert(value, position - leftLen); } } } return(this); }