DIRECTORY LooksReader USING [Body, Looks, noLooks, Ref, Runs], RunReader USING [BackupIndex, Backwards, BumpIndex, Create, Get, GetIndex, GetRuns, Peek, PeekBackwards, Ref, Runs, SetIndex, SetPosition]; LooksReaderImpl: CEDAR MONITOR IMPORTS RunReader EXPORTS LooksReader = BEGIN OPEN LooksReader; Create: PUBLIC PROC [] RETURNS [new: Ref] = { 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] = { 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] = { 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] = { 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] = { 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. δLooksReaderImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. written by Bill Paxton, March 1981 last edit by Bill Paxton, December 22, 1981 1:30 pm Michael Plass, March 21, 1985 1:58:49 pm PST Doug Wyatt, August 28, 1986 4:44:08 pm PDT create a reader for chars and looks get looks, then increment reader location decrement reader location, then get looks get looks without incrementing reader location like Backwards, but doesn't change position Κ˜codešœ™Kšœ Οmœ7™BKšœ#™#Kšœ3™3Kšœ,™,Kšœ*™*K™—šΟk ˜ Kšœ žœ#˜4Kšœ žœ|˜‹—K˜KšΟnœžœž˜Kšžœ ˜Kšžœ ˜Kšœžœžœ ˜K˜šŸœžœžœžœ˜-Kšœ#™#Kšœžœ˜K˜(K˜—K˜šŸ œžœžœ"žœ ˜FK˜K˜5K˜—K˜šŸœžœžœžœ ˜7K˜K˜,K˜—K˜šŸ œžœžœžœ˜7K˜*K˜—K˜šŸ œžœžœžœ˜5K˜*K˜—K˜š Ÿœžœžœžœžœ˜HKšžœ$˜*Kšœ˜—K˜šŸœžœžœžœ ˜5Kšžœ'˜-K˜—K˜š Ÿœžœžœžœ žœžœ˜EK˜0K˜—K˜šŸœžœžœžœ ˜2Kšœ)™)Kšœžœ˜ šžœžœΟc˜4Kšœžœ˜ K˜6šžœžœžœžœ˜Kšœ+žœžœ˜6Kšœžœžœ˜K˜—K˜K˜—K˜Kšžœ˜K˜—K˜šŸ œžœžœžœ ˜8Kšœ)™)Kšœžœ˜ šžœ žœ ˜BKšœžœ˜ K˜<šžœžœžœžœ˜Kšœ)žœžœ˜4Kšœžœžœ˜K˜—K˜K˜—K˜Kšžœ˜K˜—K˜šŸœžœžœžœ ˜3Kšœ.™.K˜ Kšžœžœ˜˜+Kšžœ˜—Kšžœ˜K˜—K˜šŸ œžœžœžœ ˜Kš žœžœ žœžœžœ˜>Kšžœ˜K˜—K˜šŸœžœžœžœ˜4Kšœžœ˜Kš žœžœžœžœžœ˜Gšžœ žœžœ˜&Kšžœžœ žœžœ˜+Kšžœžœ žœžœ˜,—K˜—K˜Kšžœ˜—…— ¨