-- RopeEditingAllocImpl.Mesa; written by Bill Paxton, March 1981
-- edited by Bill Paxton, July 11, 1983 10:58 am
-- edited by McGregor, February 8, 1983 11:07 am
DIRECTORY
RopeEditingAlloc,
Rope,
RopeReader,
RopeFrom;
RopeEditingAllocImpl:
CEDAR MONITOR
IMPORTS RopeReader
EXPORTS RopeEditingAlloc =
BEGIN OPEN RopeEditingAlloc;
charsPerArray: NAT = RopeReader.charsPerArray;
wordsPerArray: NAT = charsPerArray/2;
charsArray: Chars ← NIL; -- current shared array of chars
charsRemaining: NAT ← 0; -- amount of room remaining in current chars array
charsRope: ROPE; -- rope pointing to current chars array
AllocChars:
PUBLIC
ENTRY
PROC [len:
NAT]
RETURNS [chars: Chars, start: NAT, base: ROPE] = {
-- returns chars array & starting index to fill with characters
-- and a rope that points to that substring of the chars array
IF len > charsRemaining
THEN {
IF len > charsPerArray THEN ERROR;
IF charsPerArray-len < charsRemaining
THEN {
-- keep the current one
chars ← NEW[CharsArray]; start ← 0;
base ← RopeReader.CharsRope[chars];
RETURN };
charsArray ← NEW[CharsArray]; charsRemaining ← charsPerArray;
charsRope ← RopeReader.CharsRope[charsArray] };
chars ← charsArray;
start ← charsPerArray-charsRemaining;
charsRemaining ← charsRemaining-len;
base ← charsRope };
AllocWords:
PUBLIC
ENTRY
PROC [nwords:
NAT]
RETURNS [chars: Chars, start: NAT, base: ROPE] = {
-- ensures that start is even, i.e., start on word boundary
wordsRemaining: NAT;
IF nwords > (wordsRemaining ← charsRemaining/2)
THEN {
IF nwords > wordsPerArray THEN ERROR;
IF wordsPerArray-nwords < wordsRemaining
THEN {
chars ← NEW[CharsArray]; start ← 0;
base ← RopeReader.CharsRope[chars];
RETURN };
charsArray ← NEW[CharsArray];
wordsRemaining ← wordsPerArray;
charsRope ← RopeReader.CharsRope[charsArray] };
chars ← charsArray;
start ← (wordsPerArray-wordsRemaining)*2;
charsRemaining ← (wordsRemaining-nwords)*2;
base ← charsRope };
TryAllocAdjacent:
PUBLIC
ENTRY
PROC [base:
ROPE, start:
NAT, len:
NAT]
RETURNS [ok: BOOLEAN, chars: Chars] = {
IF base=charsRope
AND
start=charsPerArray-charsRemaining
AND
charsRemaining >= len THEN {
charsRemaining ← charsRemaining-len; RETURN [TRUE, charsArray]};
RETURN [FALSE, charsArray]};
-- ***** buffer cache
blockSize: NAT = 512;
blk1, blk2: REF TEXT; -- shared buffers
GetBlock:
PUBLIC
ENTRY
PROC
RETURNS [blk:
REF
TEXT] = {
IF blk2 # NIL THEN { blk ← blk2; blk2 ← NIL }
ELSE IF blk1 # NIL THEN { blk ← blk1; blk1 ← NIL }
ELSE blk ← NEW[TEXT[blockSize]];
blk.length ← 0 };
FreeBlock:
PUBLIC
ENTRY
PROC [blk:
REF
TEXT] = {
IF blk2 = NIL THEN blk2 ← blk ELSE IF blk1 = NIL THEN blk1 ← blk };
END.