LooksReaderImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
written by Bill Paxton, March 1981
last edit by Bill Paxton, December 22, 1981 1:30 pm
Doug Wyatt, March 3, 1985 4:33:03 pm PST
Michael Plass, March 21, 1985 1:58:49 pm PST
DIRECTORY
LooksReader,
RunReader;
LooksReaderImpl: CEDAR MONITOR
IMPORTS RunReader
EXPORTS LooksReader
= BEGIN OPEN LooksReader;
Create: PUBLIC PROC [] RETURNS [new: Ref] = {
create a reader for chars and looks
new ← NEW[Body];
new^ ← [0,0,noLooks,RunReader.Create[]];
};
SetPosition: PUBLIC PROC [reader: Ref, runs: Runs, index: INT ← 0] = {
reader.rem ← reader.len ← 0;
RunReader.SetPosition[reader.runreader, runs, index]
};
SetIndex: PUBLIC PROC [reader: Ref, index: INT ← 0] = {
reader.rem ← reader.len ← 0;
RunReader.SetIndex[reader.runreader, index]
};
BackupIndex: PUBLIC PROC [reader: Ref, amount: INT] = {
SetIndex[reader, GetIndex[reader]-amount]
};
BumpIndex: PUBLIC PROC [reader: Ref, amount: INT] = {
SetIndex[reader, GetIndex[reader]+amount]
};
Position: PUBLIC PROC [reader: Ref] RETURNS [runs: Runs, index: INT] = {
RETURN [GetRuns[reader], GetIndex[reader]]
};
GetRuns: PUBLIC PROC [reader: Ref] RETURNS [Runs] = {
RETURN [RunReader.GetRuns[reader.runreader]]
};
GetIndex: PUBLIC PROC [reader: Ref] RETURNS [index: INT] = { RETURN [
RunReader.GetIndex[reader.runreader]-reader.rem]
};
Get: PUBLIC PROC [reader: Ref] RETURNS [Looks] = {
get looks, then increment reader location
rem: NAT;
IF (rem←reader.rem) = 0 THEN { -- go to the next run
len: INT;
[len, reader.looks] ← RunReader.Get[reader.runreader];
IF len > LAST[NAT] THEN {
RunReader.BackupIndex[reader.runreader,len-LAST[NAT]];
len ← LAST[NAT]
};
reader.len ← rem ← len
};
reader.rem ← rem-1;
RETURN[reader.looks]
};
Backwards: PUBLIC PROC [reader: Ref] RETURNS [Looks] = {
decrement reader location, then get looks
rem: NAT;
IF (rem←reader.rem) >= reader.len THEN { -- go to the previous run
len: INT;
[len, reader.looks] ← RunReader.Backwards[reader.runreader];
IF len > LAST[NAT] THEN {
RunReader.BumpIndex[reader.runreader,len-LAST[NAT]];
len ← LAST[NAT]
};
reader.len ← len; rem ← 0
};
reader.rem ← rem+1;
RETURN[reader.looks]
};
Peek: PUBLIC PROC [reader: Ref] RETURNS [Looks] = {
get looks without incrementing reader location
looks: Looks;
IF reader.rem = 0 THEN
[,looks] ← RunReader.Peek[reader.runreader]
ELSE looks ← reader.looks;
RETURN [looks]
};
PeekBackwards: PUBLIC PROC [reader: Ref] RETURNS [Looks] = {
like Backwards, but doesn't change position
looks: Looks;
IF reader.rem >= reader.len THEN
[,looks] ← RunReader.PeekBackwards[reader.runreader]
ELSE looks ← reader.looks;
RETURN [looks]
};
lksrdr1, lksrdr2, lksrdr3: Ref; -- shared looks readers
GetLooksReader: PUBLIC ENTRY PROC RETURNS [reader: Ref] = {
IF lksrdr3 # NIL THEN { reader ← lksrdr3; lksrdr3 ← NIL }
ELSE IF lksrdr2 # NIL THEN { reader ← lksrdr2; lksrdr2 ← NIL }
ELSE IF lksrdr1 # NIL THEN { reader ← lksrdr1; lksrdr1 ← NIL }
ELSE reader ← Create[];
};
FreeLooksReader: PUBLIC ENTRY PROC [reader: Ref] = {
SetPosition[reader, NIL];
IF lksrdr3 = reader OR lksrdr2 = reader OR lksrdr1 = reader THEN ERROR;
IF lksrdr3 = NIL THEN lksrdr3 ← reader
ELSE IF lksrdr2 = NIL THEN lksrdr2 ← reader
ELSE IF lksrdr1 = NIL THEN lksrdr1 ← reader;
};
END.