<> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<[runs, index] _ LooksReader.Position[reader];>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> DIRECTORY TiogaLooks, RunReader; LooksReader: CEDAR DEFINITIONS IMPORTS RunReader = BEGIN Offset: TYPE = TiogaLooks.Offset; Looks: TYPE = TiogaLooks.Looks; noLooks: Looks = TiogaLooks.noLooks; Runs: TYPE = TiogaLooks.Runs; Ref: TYPE = REF Body; Body: TYPE = PRIVATE RECORD [ rem: NAT, -- remainder of current run len: NAT, -- length of current run looks: Looks, -- looks for current run runreader: RunReader.Ref -- reader for runs ]; Create: PROC [] RETURNS [Ref]; <> SetPosition: PROC [reader: Ref, runs: Runs, index: Offset _ 0] = INLINE { <> reader.rem _ reader.len _ 0; RunReader.SetPosition[reader.runreader, runs, index] }; SetIndex: PROC [reader: Ref, index: Offset _ 0] = INLINE { reader.rem _ reader.len _ 0; RunReader.SetIndex[reader.runreader, index] }; BackupIndex: PROC [reader: Ref, amount: Offset] = INLINE { SetIndex[reader, GetIndex[reader]-amount] }; BumpIndex: PROC [reader: Ref, amount: Offset] = INLINE { SetIndex[reader, GetIndex[reader]+amount] }; Position: PROC [reader: Ref] RETURNS [runs: Runs, index: Offset] = <> INLINE { RETURN [GetRuns[reader], GetIndex[reader]] }; GetRuns: PROC [reader: Ref] RETURNS [Runs] = INLINE { RETURN [RunReader.GetRuns[reader.runreader]] }; GetIndex: PROC [reader: Ref] RETURNS [index: Offset] = INLINE { RETURN [ RunReader.GetIndex[reader.runreader]-reader.rem]}; ReaderProc: TYPE = PROC [reader: Ref] RETURNS [Looks]; Get: ReaderProc = INLINE { <> rem: NAT; IF (rem_reader.rem) = 0 THEN { -- go to the next run len: Offset; [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: ReaderProc = INLINE { <> rem: NAT; IF (rem_reader.rem) >= reader.len THEN { -- go to the previous run len: Offset; [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: ReaderProc = INLINE { <> looks: Looks; IF reader.rem = 0 THEN [,looks] _ RunReader.Peek[reader.runreader] ELSE looks _ reader.looks; RETURN [looks]}; PeekBackwards: ReaderProc = INLINE { <> looks: Looks; IF reader.rem >= reader.len THEN [,looks] _ RunReader.PeekBackwards[reader.runreader] ELSE looks _ reader.looks; RETURN [looks]}; <> <> <> <> <> GetLooksReader: PROC RETURNS [Ref]; FreeLooksReader: PROC[Ref]; END.