DIRECTORY IO, IOClasses, IOUtils; IOClassesFix: CEDAR PROGRAM IMPORTS IO, IOUtils EXPORTS IOClasses SHARES IO --for representation of StreamProcs = BEGIN STREAM: TYPE = IO.STREAM; StreamProcs: TYPE = IO.StreamProcs; UnsafeBlock: TYPE = IO.UnsafeBlock; CatInputStreamData: TYPE = REF CatInputStreamRecord; CatInputStreamRecord: TYPE = RECORD [ input1, input2: STREAM, state: CatInputStreamState]; CatInputStreamState: TYPE = { initial, swapped, closed }; CatInputStreamProcs: REF IO.StreamProcs = IO.CreateStreamProcs[ variety: $input, class: $Concatenated, getChar: CatInputStreamGetChar, getBlock: CatInputStreamGetBlock, unsafeGetBlock: CatInputStreamUnsafeGetBlock, charsAvail: CatInputStreamCharsAvail, backup: CatInputStreamBackup, endOf: CatInputStreamEndOf, reset: CatInputStreamReset, close: CatInputStreamClose ]; CreateCatInputStream: PUBLIC PROC [input1, input2: STREAM] RETURNS [STREAM] = { RETURN[IO.CreateStream[ streamProcs: CatInputStreamProcs, streamData: NEW[CatInputStreamRecord _ [ input1: input1, input2: input2, state: $initial]]]]; }; CatInputStreamGetChar: PROC [self: STREAM] RETURNS [CHAR] = { data: CatInputStreamData = NARROW[self.streamData]; { RETURN[data.input1.GetChar[ ! IO.EndOfStream => IF data.state = $initial THEN GOTO nextStream]]; EXITS nextStream => { SwapStreams[data]; RETURN[data.input1.GetChar[]]; } } }; SwapStreams: PROC [data: CatInputStreamData] = { temp: STREAM _ data.input1; IF data.state # $initial THEN ERROR; data.input1 _ data.input2; data.input2 _ temp; data.state _ $swapped; }; CatInputStreamGetBlock: PROC [self: STREAM, block: REF TEXT, startIndex: NAT, count: NAT] RETURNS [nBytesRead: NAT] = { data: CatInputStreamData = NARROW[self.streamData]; nBytesRead _ data.input1.GetBlock[block, startIndex, count]; IF nBytesRead > 0 OR data.state = $swapped THEN RETURN [nBytesRead]; SwapStreams[data]; RETURN[data.input1.GetBlock[block, startIndex, count]]; }; CatInputStreamUnsafeGetBlock: PROC [self: STREAM, block: UnsafeBlock] RETURNS [nBytesRead: INT] = TRUSTED { data: CatInputStreamData = NARROW[self.streamData]; nBytesRead _ data.input1.UnsafeGetBlock[block]; IF nBytesRead > 0 OR data.state = $swapped THEN RETURN [nBytesRead]; SwapStreams[data]; RETURN[data.input1.UnsafeGetBlock[block]]; }; CatInputStreamEndOf: PROC [self: STREAM] RETURNS [BOOL] = { data: CatInputStreamData = NARROW[self.streamData]; IF NOT data.input1.EndOf[] THEN RETURN [FALSE]; IF data.state = $swapped THEN RETURN [TRUE]; SwapStreams[data]; RETURN [data.input1.EndOf[]]; }; CatInputStreamCharsAvail: PROC [self: STREAM, wait: BOOL] RETURNS [INT] = { data: CatInputStreamData = NARROW[self.streamData]; RETURN[data.input1.CharsAvail[wait]]; }; CatInputStreamBackup: PROC [self: STREAM, char: CHAR] = { data: CatInputStreamData = NARROW[self.streamData]; data.input1.Backup[char]; }; CatInputStreamReset: PROC [self: STREAM] = { data: CatInputStreamData = NARROW[self.streamData]; data.input1.Reset[]; data.input2.Reset[]; }; CatInputStreamClose: PROC [self: STREAM, abort: BOOL] = { data: CatInputStreamData = NARROW[self.streamData]; data.input1.Close[]; data.input2.Close[]; data.state _ $closed; self.streamProcs _ IOUtils.closedStreamProcs; }; END. ΦIOClassesFix.mesa Last edited by: MBrown on January 13, 1984 1:32 pm Last Edited by: Spreitzer, September 14, 1984 9:00:07 pm PDT Concatenated Input Stream we preserve the information for debugging purposes Κw– "Cedar" style˜headšœ™bodyšœ™Jšœ Οc™"J™<——˜šΟk ˜ Jšžœ˜Jšœ ˜ Jšœ˜J˜——šΠbl œžœžœ˜Jšžœžœ˜Jšžœ ˜Jšžœžœ#˜-Jšž˜Jšžœžœžœžœ˜Jšœ žœžœ ˜#Jšœ žœžœ ˜#—™Jšœžœžœ˜5šœžœžœ˜%Jšœž˜Jšœ˜—Jšœžœ ˜9unitšœžœžœ$˜?Jšœ&˜&Jšœ˜Jšœ!˜!Jšœ-˜-Jšœ%˜%Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—š Οnœžœžœžœžœžœ˜Ošžœžœ˜šœ.žœ˜JJšœ4˜4——Jšžœ˜—š  œžœžœžœžœ˜=Jšœžœ˜3˜šžœžœ˜/Jšžœžœžœ˜0—šžœ˜J˜Jšžœ˜J˜—J˜—J˜—š  œžœ˜0Jšœ2™2Jšœžœ˜Jšžœžœžœ˜$Jšœ˜Jšœ˜J˜J˜—š œžœžœ žœžœžœ žœ˜YJšžœžœ˜Jšœžœ˜3Jšœ<˜