<> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<[runs, index] _ RunReader.Position[reader];>> <> <> <> <> <> <> <<[count, looks] _ RunReader.Get[reader];>> <> <> <> <> <<[count, looks] _ RunReader.Backwards[reader];>> <> <> <<[count, looks] _ RunReader.Peek[reader];>> <> <<[count, looks] _ RunReader.PeekBackwards[reader];>> <> <> <> DIRECTORY TiogaLooks, TiogaLooksSupport; RunReader: CEDAR DEFINITIONS IMPORTS TiogaLooksSupport = BEGIN <<***** RunReader Declarations>> Base: TYPE = TiogaLooks.BaseRuns; Looks: TYPE = TiogaLooks.Looks; noLooks: Looks = TiogaLooks.noLooks; Runs: TYPE = TiogaLooks.Runs; Offset: TYPE = TiogaLooks.Offset; NoMoreRuns: ERROR; -- if try to read off end Ref: TYPE = REF Body; Body: TYPE = PRIVATE RECORD [ current: NAT _ 0, -- index of current run first: NAT _ 0, -- index of first run to read after: NAT _ 0, -- index beyond last run to read base: Base, -- current array of runs changeLooks: BOOLEAN _ FALSE, -- if need to change looks from base remove, add: Looks _ noLooks, -- the change runs: Runs _ NIL, -- runs that we are reading index: Offset _ 0 -- index in runs ]; <<***** RunReader Operations>> Create: PROC RETURNS [Ref]; SetPosition: PROC [reader: Ref, runs: Runs, index: Offset _ 0] = INLINE { IF runs # GetRuns[reader] OR index # GetIndex[reader] THEN reader^ _ [0,0,0,NIL,FALSE,noLooks,noLooks,runs,index]; }; SetIndex: PROC [reader: Ref, index: Offset _ 0] = INLINE { IF index # GetIndex[reader] THEN { runs: Runs _ GetRuns[reader]; reader^ _ [0,0,0,NIL,FALSE,noLooks,noLooks,runs,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: Runs] = INLINE { RETURN [reader.runs] }; GetIndex: PROC [reader: Ref] RETURNS [index: Offset]; ReaderProc: TYPE = PROC [reader: Ref] RETURNS [count: Offset, looks: Looks]; Get: ReaderProc = INLINE { <> current: NAT; base: Base; IF (current_reader.current) >= reader.after THEN { [count, looks] _ ReadRun[reader, get]; RETURN }; reader.current _ current+1; base _ reader.base; count _ IF current=0 THEN base[0].after ELSE base[current].after-base[current-1].after; looks _ base[current].looks; IF reader.changeLooks THEN looks _ TiogaLooksSupport.ModifyLooks[looks,reader.remove,reader.add] }; Backwards: ReaderProc = INLINE { <> current: NAT; base: Base; IF (current_reader.current) <= reader.first THEN { [count, looks] _ ReadRun[reader, backwards]; RETURN }; base _ reader.base; count _ IF (reader.current _ current _ current-1)=0 THEN base[0].after ELSE base[current].after-base[current-1].after; looks _ base[current].looks; IF reader.changeLooks THEN looks _ TiogaLooksSupport.ModifyLooks[looks,reader.remove,reader.add] }; Peek: ReaderProc = INLINE { <> current: NAT; base: Base; IF (current_reader.current) >= reader.after THEN { [count, looks] _ ReadRun[reader, peek]; RETURN }; base _ reader.base; count _ IF current=0 THEN base[0].after ELSE base[current].after-base[current-1].after; looks _ base[current].looks; IF reader.changeLooks THEN looks _ TiogaLooksSupport.ModifyLooks[looks,reader.remove,reader.add] }; PeekBackwards: ReaderProc = INLINE { <> current: NAT; base: Base; IF (current_reader.current) <= reader.first THEN { [count, looks] _ ReadRun[reader, backwards]; RETURN }; base _ reader.base; count _ IF (current _ current-1)=0 THEN base[0].after ELSE base[current].after-base[current-1].after; looks _ base[current].looks; IF reader.changeLooks THEN looks _ TiogaLooksSupport.ModifyLooks[looks,reader.remove,reader.add] }; MergedGet: ReaderProc; <> <> <> <> <> <> Mode: PRIVATE TYPE = {get, backwards, peek, peekbackwards}; ReaderEscProc: TYPE = PROC [reader: Ref, mode: Mode] RETURNS [Offset, Looks]; ReadRun: PRIVATE ReaderEscProc; <> Equal: PROC [r1,r2: Runs, rdr1,rdr2: Ref] RETURNS [BOOLEAN] = INLINE { <> RETURN [EqSubstrs[r1,r2,0,0,LAST[Offset],rdr1,rdr2]] }; EqSubstrs: PROC [r1,r2: Runs, start1,start2,len: Offset, rdr1,rdr2: Ref] RETURNS [BOOLEAN]; <> <> <> <> < size[r1] or start2+len > size[r2]>> <> <> GetRunReader: PROC RETURNS [reader: Ref]; FreeRunReader: PROC [reader: Ref]; END.