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