-- RopeFrom.mesa; written by Bill Paxton, February 1981
-- last edit by Paxton, July 11, 1983 10:53 am
-- last edit by McGregor, February 8, 1983 11:04 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 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
IO,
File,
Rope;
RopeFrom: CEDAR 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
fileLen: Offset ← MaxLen]
RETURNS [ROPE];
fileLen is size of entire file in bytes, excluding leader page
let this be defaulted if you're not sure of it
Stream: PROC [stream: IO.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: NATLAST[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: BOOLEANTRUE]
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: ROPENIL,
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];
FlatReplaceByChar: PROC [
base: ROPE, char: CHAR,
start: Offset ← 0, len, baseSize: Offset ← MaxLen,
tryAppend: BOOLEANTRUE]
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: BOOLEANTRUE]
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: BOOLEANTRUE]
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: BOOLEANTRUE]
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: BOOLEANTRUE]
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: BOOLEANTRUE]
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: BOOLEANTRUE] 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]] };
END.