-- RopeEditingAllocImpl.Mesa
-- written by Bill Paxton, March 1981
-- last edit by Bill Paxton, December 22, 1981 9:56 am
DIRECTORY
RopeEditingAlloc,
Rope,
RopeReader,
RopeFrom;
RopeEditingAllocImpl:
CEDAR MONITOR
IMPORTS RopeReader, RopeFrom
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 ← RopeFrom.pZone.NEW[CharsArray]; start ← 0;
base ← RopeReader.CharsRope[chars];
RETURN };
charsArray ← RopeFrom.pZone.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 ← RopeFrom.pZone.NEW[CharsArray]; start ← 0;
base ← RopeReader.CharsRope[chars];
RETURN };
charsArray ← RopeFrom.pZone.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 ← RopeFrom.pZone.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 };
-- ***** Initialization
Start:
PUBLIC
PROC = {
};
END.