-- RopeFrom.mesa
-- written by Bill Paxton, February 1981
-- last edit by Bill Paxton, March 25, 1981 11:11 AM

-- 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 TiogaRopeReader’s

-- 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
--
File USING [Capability],
Rope USING [Ref];

RopeFrom: DEFINITIONS
IMPORTS Rope =
BEGIN OPEN r:Rope;

Card: TYPE = LONG CARDINAL;
Char: TYPE = CHARACTER;
MaxLen: Card = LAST[Card];
Rope: TYPE = r.Ref;

qZone: ZONE; -- quantized zone for allocating rope pieces
-- replace this eventually by zone Russ uses

FileCapability: TYPE = Rope; -- temp
File: PROC [
file: FileCapability,
start: Card ← 0, -- byte address in file where rope will start
length: Card ← MaxLen, -- defaults to rest of file
activate: BOOLEAN ← FALSE]
RETURNS [Rope];
-- if activate is true, the system will start swapping the
-- characters into real memory

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];

Substr: PROC [rope: Rope, start, len: Card] RETURNS [Rope];

Concat: PROC [base, rest: Rope, baseSize, restSize: Card] RETURNS [Rope];
-- returns the concatenation of two ropes

Replace: PROC
[base, replace: Rope, start, len, size, baseSize, repSize: Card]
RETURNS [Rope];
-- returns a new rope with the given range replaced
-- size = baseSize+repSize-len

Delete: PROC [base: Rope, start, len, baseSize: Card] RETURNS [Rope] = INLINE
{ RETURN [Replace[base, NIL, start, len, baseSize-len, baseSize, 0]] };

Copy: PROC [base: Rope, baseSize, dest, start, len: Card] RETURNS [Rope];

Move: PROC [base: Rope, baseSize, dest, start, len: Card] RETURNS [Rope];
-- dest must not be in [start..start+len)

Transpose: PROC [base: Rope, baseSize, astart, alen, bstart, blen: Card]
RETURNS [Rope];
-- [astart..astart+alen) must not intersect [bstart..bstart+blen)

AppendChar: PROC [base: Rope, char: Char, baseSize: Card] RETURNS [Rope];

AppendString: PROC [base: Rope, string: REF READONLY TEXT,
stringStart, stringNum: NAT, baseSize: Card] RETURNS [Rope];

ReplaceByChar: PROC [base: Rope, char: Char, start, len, baseSize: Card]
RETURNS [new: Rope];

InsertChar: PROC [base: Rope, char: Char, baseSize, loc: Card]
RETURNS [Rope] =
-- char is inserted at loc
INLINE { RETURN [ReplaceByChar[base, char, loc, 0, baseSize]] };

ReplaceByString: PROC [base: Rope, string: REF READONLY TEXT,
stringStart, stringNum: NAT, start, len, baseSize: Card]
RETURNS [new: Rope];

InsertString: PROC [
base: Rope, baseSize, loc: Card, string: REF READONLY TEXT,
stringStart, stringNum: NAT] RETURNS [Rope] = INLINE { RETURN [
-- string is inserted at loc
-- inserts stringNum chars starting with stringStart
ReplaceByString[base, string, stringStart, stringNum, loc, 0, baseSize]] };

InsertRope: PROC [base, insert: Rope, dest, baseSize, insertSize: Card]
RETURNS [Rope] = INLINE { RETURN [
Replace[base,insert,dest,0,baseSize+insertSize,baseSize,insertSize]] };

END.