private static IEnumerator <T> Enumerate(RopeNode <T> node) { var stack = new Stack <RopeNode <T> >(); while (node != null) { // go to leftmost node, pushing the right parts that we'll have to visit later while (node.contents == null) { if (node.height == 0) { // go down into function nodes node = node.GetContentNode(); continue; } Debug.Assert(node.right != null); stack.Push(node.right); node = node.left; } // yield contents of leaf node for (var i = 0; i < node.length; i++) { yield return(node.contents[i]); } // go up to the next node not visited yet if (stack.Count > 0) { node = stack.Pop(); } else { node = null; } } }
internal static void WriteTo(this RopeNode <char> node, int index, TextWriter output, int count) { if (node.height == 0) { if (node.contents == null) { // function node node.GetContentNode().WriteTo(index, output, count); } else { // leaf node: append data output.Write(node.contents, index, count); } } else { // concat node: do recursive calls if (index + count <= node.left.length) { node.left.WriteTo(index, output, count); } else if (index >= node.left.length) { node.right.WriteTo(index - node.left.length, output, count); } else { var amountInLeft = node.left.length - index; node.left.WriteTo(index, output, amountInLeft); node.right.WriteTo(0, output, count - amountInLeft); } } }
private void GoToLeftMostLeaf() { while (currentNode.contents == null) { if (currentNode.height == 0) { // this is a function node - move to its contained rope currentNode = currentNode.GetContentNode(); continue; } Debug.Assert(currentNode.right != null); stack.Push(currentNode.right); currentNode = currentNode.left; } Debug.Assert(currentNode.height == 0); }