-- RopeFrom.mesa -- written by Bill Paxton, February 1981 -- last edit by Bill Paxton, 17-Jan-82 15:51:32 -- routines for creating ropes from files, strings, and characters -- also for creating flat ropes from other ones -- characters go into CharsArrays so get fast access via RopeReader's (q.v.) -- a shared CharsArray is used to hold text for chars, strings, and ropes -- it is also used for short files -- long files are mapped into their own CharsArray's -- using Pilot spaces so don't actually read the chars at all DIRECTORY IOStream, File, Rope; RopeFrom: DEFINITIONS IMPORTS Rope = BEGIN OPEN fI:File; Offset: TYPE = INT; MaxLen: Offset = LAST[Offset]; MaxNat: NAT = LAST[NAT]; ROPE: TYPE = Rope.ROPE; File: PROC [ file: fI.Capability, start: Offset ← 0, -- byte address in file where rope will start -- 0 means first page after leader page length: Offset ← MaxLen, -- defaults to rest of file beyond start activate: BOOLEAN ← FALSE, fileLen: Offset ← MaxLen, okToMapFile: BOOLEAN ← FALSE] RETURNS [ROPE]; -- if activate is true, the system will start swapping the -- characters into real memory -- fileLen is size of entire file in bytes, excluding leader page -- let this be defaulted if you're not sure of it -- set okToMapFile to FALSE if you will want to overwrite the contents later Stream: PROC [stream: IOStream.Handle, length: Offset ← MaxLen] RETURNS [rope: ROPE]; -- reads length chars from stream and puts them in a rope String: PROC [ string: REF READONLY TEXT, start: NAT ← 0, len: NAT ← LAST[NAT]] RETURNS [ROPE]; -- copies len characters from string starting at start Character: PROC [char: CHAR] RETURNS [ROPE]; Byte: PROC [x: UNSPECIFIED] RETURNS [ROPE] = INLINE { RETURN [Character[LOOPHOLE[x,CHAR]]] }; FlatSubstr: PROC [rope: ROPE, start: Offset ← 0, len: Offset ← MaxLen] RETURNS [ROPE]; FlatConcat: PROC [base, rest: ROPE, baseSize, restSize: Offset ← MaxLen, tryAppend: BOOLEAN ← TRUE] RETURNS [ROPE]; TryAppendConcat: PROC [base, rest: ROPE, baseSize, restSize: Offset ← MaxLen] RETURNS [ROPE]; -- tries to append rest by copying to buffer directly after base -- returns NIL if cannot FlatReplace: PROC [ base: ROPE, start: Offset ← 0, len: Offset ← MaxLen, replace: ROPE ← NIL, size, baseSize, repSize: Offset ← MaxLen] RETURNS [ROPE]; -- returns a new rope with the given range replaced FlatDelete: PROC [base: ROPE, start: Offset ← 0, len, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [ FlatReplace[base, start, len, NIL, MaxLen, baseSize, 0]] }; FlatInsert: PROC [ dest: ROPE, destLoc: Offset ← 0, source: ROPE, destSize, sourceSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [ FlatReplace[dest, destLoc, 0, source, MaxLen, destSize, sourceSize]] }; FlatCopy: PROC [ dest: ROPE, destLoc: Offset ← 0, source: ROPE, start: Offset ← 0, len: Offset ← MaxLen, destSize: Offset ← MaxLen] RETURNS [ROPE]; FlatMove: PROC [ base: ROPE, destLoc, start: Offset ← 0, len, baseSize: Offset ← MaxLen] RETURNS [ROPE]; FlatTranspose: PROC [ base: ROPE, astart, alen, bstart, blen: Offset, baseSize: Offset ← MaxLen] RETURNS [ROPE]; -- [astart..astart+alen) must not intersect [bstart..bstart+blen) FlatReplaceByChar: PROC [ base: ROPE, char: CHAR, start: Offset ← 0, len, baseSize: Offset ← MaxLen, tryAppend: BOOLEAN ← TRUE] RETURNS [new: ROPE]; TryAppendReplaceByChar: PROC [ base: ROPE, char: CHAR, start: Offset ← 0, len, baseSize: Offset ← MaxLen] RETURNS [new: ROPE]; FlatInsertChar: PROC [ base: ROPE, char: CHAR, loc: Offset ← 0, baseSize: Offset ← MaxLen, tryAppend: BOOLEAN ← TRUE] RETURNS [ROPE] = INLINE { RETURN [FlatReplaceByChar[base,char,loc,0,baseSize,tryAppend]] }; TryFlatInsertChar: PROC [ base: ROPE, char: CHAR, loc: Offset ← 0, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [TryAppendReplaceByChar[base,char,loc,0,baseSize]] }; FlatAppendChar: PROC [base: ROPE, char: CHAR, baseSize: Offset ← MaxLen, tryAppend: BOOLEAN ← TRUE] RETURNS [ROPE] = INLINE { RETURN [FlatReplaceByChar[base,char,MaxLen,0,baseSize,tryAppend]] }; TryFlatAppendChar: PROC [base: ROPE, char: CHAR, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [TryAppendReplaceByChar[base,char,MaxLen,0,baseSize]] }; FlatAppendByte: PROC [base: ROPE, x: UNSPECIFIED, baseSize: Offset ← MaxLen, tryAppend: BOOLEAN ← TRUE] RETURNS [ROPE] = INLINE { RETURN [FlatAppendChar[base,LOOPHOLE[x,CHAR],baseSize,tryAppend]] }; TryFlatAppendByte: PROC [base: ROPE, x: UNSPECIFIED, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [TryFlatAppendChar[base,LOOPHOLE[x,CHAR],baseSize]] }; FlatReplaceByString: PROC [ base: ROPE, string: REF READONLY TEXT, stringStart: NAT ← 0, stringNum: NAT ← MaxNat, start: Offset ← 0, len, baseSize: Offset ← MaxLen, tryAppend: BOOLEAN ← TRUE] RETURNS [new: ROPE]; TryAppendReplaceByString: PROC [ base: ROPE, string: REF READONLY TEXT, stringStart: NAT ← 0, stringNum: NAT ← MaxNat, start: Offset ← 0, len, baseSize: Offset ← MaxLen] RETURNS [new: ROPE]; FlatInsertString: PROC [ base: ROPE, string: REF READONLY TEXT, stringStart: NAT ← 0, stringNum: NAT ← MaxNat, loc: Offset ← 0, baseSize: Offset ← MaxLen, tryAppend: BOOLEAN ← TRUE] RETURNS [ROPE] = INLINE { RETURN [ -- string is inserted at loc -- inserts stringNum chars from string starting with stringStart FlatReplaceByString[base,string,stringStart,stringNum,loc,0,baseSize,tryAppend]] }; TryFlatInsertString: PROC [ base: ROPE, string: REF READONLY TEXT, stringStart: NAT ← 0, stringNum: NAT ← MaxNat, loc: Offset ← 0, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [ -- string is inserted at loc -- inserts stringNum chars from string starting with stringStart TryAppendReplaceByString[base,string,stringStart,stringNum,loc,0,baseSize]] }; FlatAppendString: PROC [ base: ROPE, string: REF READONLY TEXT, stringStart: NAT ← 0, stringNum: NAT ← MaxNat, baseSize: Offset ← MaxLen, tryAppend: BOOLEAN ← TRUE] RETURNS [ROPE] = INLINE { RETURN [ FlatReplaceByString[base,string,stringStart,stringNum,MaxLen,0,baseSize,tryAppend]] }; TryFlatAppendString: PROC [ base: ROPE, string: REF READONLY TEXT, stringStart: NAT ← 0, stringNum: NAT ← MaxNat, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [ TryAppendReplaceByString[base,string,stringStart,stringNum,MaxLen,0,baseSize]] }; -- ***** miscellaneous internal stuff StartRopeFrom, StartRopeFromEdit, StartRopeFromFile: PROC; -- for initialization only qZone: ZONE; -- quantized zone for use within RopeEditing config pZone: ZONE; -- prefixed zone for use within RopeEditing config END.