-- 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: 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];
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]] };
END.