DIRECTORY RopeFrom, RopeEdit, RopeEditingAlloc, RopeReader, Rope, RopePrivate; RopeFromEditImpl: CEDAR MONITOR IMPORTS Rope, RopeEdit, RopeEditingAlloc, RopeFrom, RopePrivate, RopeReader EXPORTS RopeFrom SHARES Rope = BEGIN OPEN RopeFrom, RopePrivate; CharsArray: TYPE = RopeReader.CharsArray; Chars: TYPE = REF CharsArray; charsPerArray: NAT = RopeReader.charsPerArray; FlatSubstr: PUBLIC PROC [rope: ROPE, start: Offset _ 0, len: Offset _ MaxLen] RETURNS [ROPE] = TRUSTED { chars: Chars; loc, num: NAT; base: ROPE; substr: BOOLEAN _ FALSE; size: Offset _ Rope.InlineSize[rope]; reader: RopeReader.Ref; IF len=MaxLen THEN { IF start >= size THEN RETURN [NIL]; len _ MIN[len,size-start] }; IF len=0 OR rope=NIL THEN RETURN [NIL]; IF len > charsPerArray THEN { -- split into balanced parts front, back: ROPE; half: Offset _ len/2; half _ ((half+charsPerArray-1)/charsPerArray)*charsPerArray; -- round up front _ FlatSubstr[rope, start, half]; back _ FlatSubstr[rope, start+half, len-half]; RETURN [qZone.NEW[Tconcat _ [node[concat[len,front,back,half, 1+MAX[RopeEdit.Depth[front],RopeEdit.Depth[back]]]]]]] }; WITH x:rope SELECT FROM node => WITH x:x SELECT FROM substr => substr _ TRUE; object => IF x.size=charsPerArray THEN WITH x.base SELECT FROM z: Chars => -- don't need to move the characters IF len=charsPerArray AND start=0 THEN RETURN [rope] ELSE RETURN [qZone.NEW[Tsubstr _ [node[substr[len,rope,start,1+RopeEdit.Depth[rope]]]]]]; ENDCASE; ENDCASE; ENDCASE; [chars,loc,base] _ RopeEditingAlloc.AllocChars[num _ Short[len]]; reader _ RopeReader.GetRopeReader[]; RopeReader.SetPosition[reader, rope, start]; IF RopeReader.GetChars[reader, chars, num, loc] # num THEN ERROR; RopeReader.FreeRopeReader[reader]; IF substr AND start=0 AND len=size THEN -- just flattening an existing substr WITH x:rope SELECT FROM node => WITH x:x SELECT FROM substr => { x.base _ base; x.start _ loc; RETURN [@x] }; ENDCASE; ENDCASE; RETURN [qZone.NEW[Tsubstr _ [node[substr[len,base,loc,1+RopeEdit.Depth[base]]]]]]}; FlatConcat: PUBLIC PROC [base, rest: ROPE, baseSize, restSize: Offset _ MaxLen, tryAppend: BOOLEAN _ TRUE] RETURNS [new: ROPE] = { chars: Chars; loc, baseNum, restNum: NAT; reader: RopeReader.Ref; charsRope: ROPE; size: Offset; IF baseSize=MaxLen THEN baseSize _ Rope.InlineSize[base]; IF restSize=MaxLen THEN restSize _ Rope.InlineSize[rest]; IF (size _ baseSize+restSize) > charsPerArray THEN -- treat separately RETURN [qZone.NEW[Tconcat _ [node[concat[size,base,rest,baseSize, 1+MAX[RopeEdit.Depth[base],RopeEdit.Depth[rest]]]]]]]; IF size=0 THEN RETURN[NIL]; IF tryAppend AND (new _ TryAppendConcat[base, rest, baseSize, restSize]) # NIL THEN RETURN; baseNum _ Short[baseSize]; restNum _ Short[restSize]; [chars, loc, charsRope] _ RopeEditingAlloc.AllocChars[Short[size]]; reader _ RopeReader.GetRopeReader[]; RopeReader.SetPosition[reader, base]; IF RopeReader.GetChars[reader, chars, baseNum, loc] # baseNum THEN ERROR; RopeReader.SetPosition[reader, rest]; IF RopeReader.GetChars[reader, chars, restNum, loc+baseNum] # restNum THEN ERROR; RopeReader.FreeRopeReader[reader]; RETURN [qZone.NEW[Tsubstr _ [node[substr[size,charsRope,loc,1+RopeEdit.Depth[charsRope]]]]]]}; TryAppendConcat: PUBLIC PROC [base, rest: ROPE, baseSize, restSize: Offset _ MaxLen] RETURNS [ROPE] = TRUSTED { chars: Chars; size: Offset; IF baseSize=MaxLen THEN baseSize _ Rope.InlineSize[base]; IF restSize=MaxLen THEN restSize _ Rope.InlineSize[rest]; IF (size _ baseSize+restSize) > charsPerArray THEN -- treat separately RETURN [qZone.NEW[Tconcat _ [node[concat[size,base,rest,baseSize, 1+MAX[RopeEdit.Depth[base],RopeEdit.Depth[rest]]]]]]]; IF size=0 THEN RETURN[NIL]; IF base#NIL AND rest#NIL THEN WITH--1-- x:base SELECT FROM node => WITH--2-- x:x SELECT FROM substr => WITH--3-- z:x.base SELECT FROM node => WITH--4-- z:z SELECT FROM object => IF z.size=charsPerArray THEN WITH--5-- z.base SELECT FROM w: Chars => { -- base is a substr of a charsarray WITH--6-- y:rest SELECT FROM node => WITH--7-- y:y SELECT FROM substr => IF x.base=y.base AND x.start+x.size=y.start THEN WITH--8-- z:x.base SELECT FROM node => WITH--9-- z:z SELECT FROM object => IF z.size=charsPerArray THEN WITH--10-- z.base SELECT FROM w: Chars => -- don't need to move the characters RETURN [qZone.NEW[Tsubstr _ [node[substr[x.size+y.size,x.base,x.start, 1+RopeEdit.Depth[x.base]]]]]]; ENDCASE; ENDCASE; ENDCASE; ENDCASE; ENDCASE; --6..10-- { -- try to allocate room adjacent to base ok: BOOLEAN; loc: NAT; newbase: ROPE _ x.base; xstart: Offset _ x.start; count: NAT _ Short[restSize]; baseNum: NAT _ Short[baseSize]; [ok,chars] _ RopeEditingAlloc.TryAllocAdjacent[newbase, loc_baseNum+Short[xstart],count]; IF ok THEN { -- transfer the chars reader: RopeReader.Ref _ RopeReader.GetRopeReader[]; RopeReader.SetPosition[reader,rest]; IF RopeReader.GetChars[reader,chars,count,loc] # count THEN ERROR; RopeReader.FreeRopeReader[reader]; RETURN [qZone.NEW[Tsubstr _ [node[substr[size,newbase,xstart,1+RopeEdit.Depth[newbase]]]]]] }}}; ENDCASE; ENDCASE; ENDCASE; ENDCASE; ENDCASE; --1..5-- RETURN [NIL] }; FlatReplace: PUBLIC PROC [ base: ROPE, start: Offset _ 0, len: Offset _ MaxLen, replace: ROPE _ NIL, size, baseSize, repSize: Offset _ MaxLen] RETURNS [ROPE] = { chars: Chars; charsRope: ROPE; initloc, loc, tailsize, sze: NAT; reader: RopeReader.Ref; oldpos: Offset; Get: PROC [r: ROPE, begin: Offset, count: NAT] = { IF count > 0 THEN { RopeReader.SetPosition[reader,r,begin]; IF RopeReader.GetChars[reader,chars,count,loc] # count THEN ERROR; loc _ loc+count}}; IF baseSize=MaxLen THEN baseSize _ Rope.InlineSize[base]; IF start >= baseSize THEN RETURN [FlatConcat[base,replace,baseSize,repSize]]; IF len=MaxLen THEN len _ MIN[len,baseSize-start]; IF repSize=MaxLen THEN repSize _ Rope.InlineSize[replace]; IF size=MaxLen THEN size _ baseSize-len+repSize; IF size=0 THEN RETURN [NIL]; IF size > charsPerArray THEN -- treat separately RETURN [Rope.Replace[base, start, len, replace]]; tailsize _ Short[baseSize-(oldpos_len+start)]; [chars,loc,charsRope] _ RopeEditingAlloc.AllocChars[sze_Short[size]]; initloc _ loc; reader _ RopeReader.GetRopeReader[]; Get[base,0,Short[start]]; Get[replace,0,Short[repSize]]; Get[base,oldpos,tailsize]; RopeReader.FreeRopeReader[reader]; IF loc-initloc#sze THEN ERROR; RETURN [qZone.NEW[Tsubstr _ [node[substr[size,charsRope,initloc,1+RopeEdit.Depth[charsRope]]]]]]}; FlatCopy: PUBLIC PROC [ dest: ROPE, destLoc: Offset _ 0, source: ROPE, start: Offset _ 0, len: Offset _ MaxLen, destSize: Offset _ MaxLen] RETURNS [ROPE] = { chars: Chars; charsRope: ROPE; size: Offset; initloc, loc, dst, sze: NAT; reader: RopeReader.Ref; Get: PROC [base: ROPE, begin, count: NAT] = { IF count > 0 THEN { RopeReader.SetPosition[reader,base,begin]; IF RopeReader.GetChars[reader,chars,count,loc] # count THEN ERROR; loc _ loc+count}}; IF len=MaxLen THEN { sourceSize: Offset _ Rope.InlineSize[source]; IF start >= sourceSize THEN RETURN [dest]; len _ MIN[len,sourceSize-start] }; IF destSize=MaxLen THEN destSize _ Rope.InlineSize[dest]; IF destLoc > destSize THEN destLoc _ destSize; IF (size_destSize+len) > charsPerArray THEN -- treat separately RETURN [FlatInsert[dest,destLoc,FlatSubstr[source,start,len],destSize,len]]; IF size=0 THEN RETURN[NIL]; [chars, loc, charsRope] _ RopeEditingAlloc.AllocChars[sze _ Short[size]]; initloc _ loc; reader _ RopeReader.GetRopeReader[]; Get[dest,0,dst_Short[destLoc]]; Get[source,Short[start],Short[len]]; Get[dest,dst,Short[destSize]-dst]; RopeReader.FreeRopeReader[reader]; IF loc-initloc # sze THEN ERROR; RETURN [qZone.NEW[Tsubstr _ [node[substr[size,charsRope,initloc,1+RopeEdit.Depth[charsRope]]]]]]}; StartRopeFromEdit: PUBLIC PROC = { }; END. RopeFromEditImpl.Mesa written by Bill Paxton, February 1981 Bill Paxton, August 11, 1982 10:32 am Maxwell, January 5, 1983 12:09 pm Russ Atkinson, July 22, 1983 4:24 pm Paul Rovner, August 10, 1983 4:23 pm -- Editing Operations -- ***** Initialization ÊؘšÏc™Jš&™&Jš%™%J™!J™$J™$J™—šÏk ˜ J˜ J˜ J˜J˜ J˜J˜ J˜—šœž ˜JšžœD˜KJšžœ ˜Jšžœ˜ Jšœž œ˜#—J˜Jšœ žœ˜)Jšœžœžœ ˜Jšœžœ˜.J˜Jš™J˜šÏn œžœž˜Jš œžœ+žœžœžœ˜PJ˜ Jšœ žœ˜Jšœžœ˜ Jšœžœžœ˜J˜%J˜šžœ žœ˜Jšžœžœžœžœ˜#Jšœžœ˜—Jš žœžœžœžœžœžœ˜'šžœžœ˜:Jšœ žœ˜J˜Jšœ= ˜HJ˜&J˜.šžœžœ,˜=Jšœžœ4˜9——šžœžœž˜šœžœžœž˜Jšœžœ˜šœ žœž˜&šžœžœž˜šœ $˜0Jšžœžœ žœžœ˜3šžœžœžœ ˜ J˜8——Jšžœ˜——Jšžœžœ˜——J˜AJ˜$J˜,Jšžœ4žœžœ˜AJ˜"š žœžœ žœ žœ%˜Mšžœžœž˜šœžœžœž˜Jšœ*žœ˜8—Jšžœžœ˜——šžœžœ ˜J˜7J˜——šŸ œžœž˜Jšœ žœ2žœžœ˜RJšžœžœ˜J˜ Jšœžœ˜J˜Jšœ žœ˜J˜ Jšžœžœ"˜9Jšžœžœ"˜9šžœ,žœ˜Fšžœžœ0˜AJšœžœ1˜6——Jšžœžœžœžœ˜šžœ žœ;ž˜NJšžœžœ˜ —J˜J˜J˜CJ˜$J˜%Jšžœ<žœžœ˜IJ˜%JšžœDžœžœ˜QJ˜"JšžœžœM˜^J˜—šŸœžœžœžœ&˜TJšžœžœžœ˜J˜ J˜ Jšžœžœ"˜9Jšžœžœ"˜9šžœ,žœ˜Fšžœžœ0˜AJšœžœ1˜6——Jšžœžœžœžœ˜šžœžœžœžœžœžœžœžœ žœžœž˜\šœ žœ žœžœ žœžœž˜Jš œ žœžœžœžœž˜Cšœ#˜1š žœžœžœ žœžœž˜>šœ žœžœž˜:š žœ žœžœ žœžœž˜@šœ žœž˜&šžœžœž˜Jšœ $˜0šžœžœ ˜˜*J˜——Jš žœžœžœžœžœ ˜6—————Jšœ(˜*Jšœžœ˜ Jšœžœ˜ Jšœ žœ ˜J˜Jšœžœ˜Jšœ žœ˜˜7J˜!—šžœžœ˜#J˜4J˜$Jšžœ5žœžœ˜BJ˜"šžœžœ ˜J˜D——Jš žœžœžœžœžœ˜5————Jšžœžœ˜J˜—šŸ œžœžœ˜Jšœžœ4žœžœ˜I˜)Jšžœžœ˜—J˜ Jšœ žœ˜Jšœžœ˜!J˜Jšœ˜šŸœžœžœžœ˜2šžœ žœ˜J˜'Jšžœ5žœžœ˜BJ˜——Jšžœžœ"˜9šžœž˜Jšžœ-˜3—Jšžœ žœžœ˜1Jšžœžœ$˜:Jšžœ žœ˜0Jšžœžœžœžœ˜šžœžœ˜0Jšžœ+˜1—J˜.J˜EJ˜J˜$J˜J˜J˜J˜"Jšžœžœžœ˜JšžœžœQ˜bJ˜—šŸœžœžœ˜Jšœžœ˜ Jšœžœ*˜6J˜Jšžœžœ˜J˜ Jšœ žœ˜J˜ Jšœžœ˜J˜šŸœžœžœžœ˜-šžœ žœ˜J˜*Jšžœ5žœžœ˜BJ˜——šžœ žœ˜J˜-Jšžœžœžœ˜*Jšœžœ˜"—Jšžœžœ"˜9Jšžœžœ˜.šžœ%žœ˜?JšžœF˜L—Jšžœžœžœžœ˜J˜IJ˜J˜$J˜J˜$J˜"J˜"Jšžœžœžœ˜ JšžœžœQ˜bJ˜—Jš™J˜šŸœžœžœ˜"J˜J˜—Jšžœ˜J˜—…—'î