-- 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: 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.