DIRECTORY Basics, Rope, RuntimeError, TextNode, TiogaRopes; TiogaRopesImpl: CEDAR PROGRAM IMPORTS Rope, RuntimeError, TextNode EXPORTS TiogaRopes = BEGIN OPEN TiogaRopes; Location: TYPE = TextNode.Location; TiogaRope: TYPE = REF TiogaRopePrivate; TiogaRopePrivate: TYPE = RECORD [ node: Node, start, length: INT, skipCommentNode: BOOL, curNode: Node ¬ NIL, curNodeStart, curNodeLength: INT ¬ 0, curRope: ROPE ]; RopeFromTioga: PUBLIC PROC [node: Node, start: INT ¬ 0, length: INT ¬ LAST[INT], skipCommentNode: BOOL ¬ FALSE] RETURNS [asRope: ROPE] = { end: Location = DocEnd[node, skipCommentNode]; nodeLoc: Location = [node, 0]; remSize: INT = TextNode.LocOffset[nodeLoc, end, 1, skipCommentNode]; IF start >= remSize THEN RETURN [NIL]; {curRope: ROPE = node.rope; tr: TiogaRope = NEW [TiogaRopePrivate ¬ [ node: node, start: start, length: MIN[length, remSize - start], skipCommentNode: skipCommentNode, curNode: node, curNodeStart: 0, curNodeLength: curRope.Length[], curRope: curRope ]]; asRope ¬ Rope.MakeRope[tr, tr.length, FetchFromTiogaRope, NIL, MoveFromTiogaRope]; }}; JumpTo: PROC [tr: TiogaRope, index: INT] = { newOffset: INT = tr.start+index; here: Location = IF newOffset >= tr.curNodeStart/2 THEN LocRelative[[tr.curNode, 0], newOffset-tr.curNodeStart, 1, tr.skipCommentNode] ELSE LocRelative[[tr.node, 0], newOffset, 1, tr.skipCommentNode]; tr.curNode ¬ here.node; tr.curNodeStart ¬ newOffset - here.where; tr.curRope ¬ tr.curNode.rope; tr.curNodeLength ¬ tr.curRope.Length[]; }; LocRelative: PROC [location: Location, count: INT, break: NAT ¬ 1, skipCommentNodes: BOOL ¬ FALSE] RETURNS [rel: Location] = { SELECT count FROM =0 => rel ¬ location --avoid the bogosity in TextNodeImpl.LocRelative--; >0 => rel ¬ TextNode.LocRelative[location, count, break, skipCommentNodes]; <0 => {--TextNodeImpl.LocRelative won't backup over node boundaries backParent: Node ¬ NIL; rel ¬ location; WHILE count + rel.where < 0 DO count ¬ count + rel.where; [rel.node, backParent, ] ¬ TextNode.Backward[rel.node, backParent]; rel.where ¬ IF (NOT skipCommentNodes) OR (NOT rel.node.comment) THEN rel.node.rope.Length[] + break ELSE 0; ENDLOOP; rel.where ¬ count + rel.where; }; ENDCASE => ERROR; rel ¬ rel; }; FetchFromTiogaRope: PROC [data: REF, index: INT] RETURNS [CHAR] --Rope.FetchType-- = { tr: TiogaRope = NARROW[data]; IF NOT index IN [0 .. tr.length) THEN ERROR RuntimeError.BoundsFault; {rel: INT ¬ index+tr.start - tr.curNodeStart; {IF rel<0 THEN GOTO Fixit; SELECT tr.curNodeLength FROM >rel => GOTO TakeIt; =rel => RETURN ['\n]; ENDCASE => GOTO Fixit; EXITS Fixit => { JumpTo[tr, index]; rel ¬ index+tr.start - tr.curNodeStart; IF rel=tr.curNodeLength THEN RETURN ['\n]}; TakeIt => NULL}; RETURN [tr.curRope.Fetch[rel]]}}; MoveFromTiogaRope: UNSAFE PROC [block: Basics.UnsafeBlock, data: REF ANY, start: INT] RETURNS [charsMoved: INT ¬ 0] ~ CHECKED { tr: TiogaRope = NARROW[data]; IF NOT start IN [0 .. tr.length) THEN ERROR RuntimeError.BoundsFault; WHILE block.count>0 DO rel: INT ¬ start + tr.start - tr.curNodeStart; IF rel NOT IN [0 .. tr.curNodeLength] THEN {JumpTo[tr, start]; rel ¬ start + tr.start - tr.curNodeStart}; IF rel < tr.curNodeLength THEN { n: INT; TRUSTED {n ¬ Rope.UnsafeMoveChars[block: block, rope: tr.curRope, start: rel]}; start ¬ start + n; charsMoved ¬ charsMoved + n; block.startIndex ¬ block.startIndex + n; block.count ¬ block.count - n; }; IF block.count # 0 THEN { TRUSTED {LOOPHOLE[block.base, LONG POINTER TO Basics.RawChars][block.startIndex] ¬ '\n}; start ¬ start + 1; charsMoved ¬ charsMoved + 1; block.startIndex ¬ block.startIndex + 1; block.count ¬ block.count - 1; }; ENDLOOP; RETURN}; DocEnd: PROC [node: Node, skipCommentNode: BOOL] RETURNS [endLoc: Location] = { endNode: Node ¬ TextNode.Root[node]; IF endNode = NIL THEN ERROR; DO next: Node ¬ TextNode.LastChild[endNode]; IF next = NIL THEN EXIT; endNode ¬ next; ENDLOOP; IF skipCommentNode THEN WHILE endNode.comment DO endNode ¬ TextNode.StepBackward[endNode] ENDLOOP; endLoc ¬ [endNode, endNode.rope.Length[]+1]; }; END. μ TiogaRopesImpl.mesa Copyright Σ 1992 by Xerox Corporation. All rights reserved. Mike Spreitzer August 5, 1986 4:26:06 pm PDT Last tweaked by Mike Spreitzer on November 30, 1987 3:50:09 pm PST Willie-s, April 3, 1992 5:29 pm PST Κ–(cedarcode) style•NewlineDelimiter ™code™Kšœ Οeœ1™