DIRECTORY IO, IOClasses, IOUtils; IOClassesImpl: 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; Copy: PUBLIC PROC [ from, to: STREAM, closeFrom, closeTo: BOOL, bufferByteCount: NAT] = { DO to.PutChar[from.GetChar[! IO.EndOfStream => EXIT]]; ENDLOOP; IF closeFrom THEN from.Close[]; IF closeTo THEN to.Close[]; }; FilterCommentsStreamData: TYPE = REF FilterCommentsStreamRecord; FilterCommentsStreamRecord: TYPE = RECORD [ inStringLiteral: BOOL _ FALSE, inCharLiteral: BOOL _ FALSE, inExtendedChar: BOOL _ FALSE ]; FilterCommentsStreamProcs: REF IO.StreamProcs = IO.CreateStreamProcs[ variety: $input, class: $CommentFilter, getChar: FilterCommentsStreamGetChar ]; CreateCommentFilterStream: PUBLIC PROC [input: STREAM] RETURNS [IO.STREAM] = { RETURN[IO.CreateStream[ streamProcs: FilterCommentsStreamProcs, backingStream: input, streamData: NEW[FilterCommentsStreamRecord _ []]]]; }; FilterCommentsStreamGetChar: PROC[self: IO.STREAM] RETURNS [char: CHAR] = { data: FilterCommentsStreamData = NARROW[self.streamData]; char _ self.backingStream.GetChar[]; SELECT TRUE FROM data.inExtendedChar => { data.inExtendedChar _ FALSE; -- not really, but rest of extended char can't contain '" RETURN }; data.inCharLiteral => { data.inCharLiteral _ FALSE; IF char = '\\ THEN data.inExtendedChar _ TRUE; RETURN }; data.inStringLiteral => { SELECT char FROM '\\ => data.inExtendedChar _ TRUE; '\" => data.inStringLiteral _ FALSE; -- not really, but if following char is '" it will look like a new string literal, which is ok ENDCASE; RETURN }; ENDCASE => SELECT char FROM '\" => data.inStringLiteral _ TRUE; '\' => data.inCharLiteral _ TRUE; '- => IF NOT self.backingStream.EndOf[] AND self.backingStream.PeekChar[] = '- THEN { [] _ self.backingStream.GetChar[]; DO SELECT (char _ self.backingStream.GetChar[]) FROM '\n => EXIT; '- => IF self.backingStream.GetChar[] = '- THEN { char _ IO.SP; EXIT }; ENDCASE; ENDLOOP; } ENDCASE; }; 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; data.input1 _ data.input2; data.input2 _ temp; }; 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 data.input1.EndOf[] AND 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; }; DribbleStreamData: TYPE = REF DribbleStreamRecord; DribbleStreamRecord: TYPE = RECORD [outputStream: STREAM]; DribbleStreamProcs: REF StreamProcs _ IO.CreateStreamProcs[ variety: $output, class: $Dribble, putChar: DribbleStreamPutChar, putBlock: DribbleStreamPutBlock, unsafePutBlock: DribbleStreamUnsafePutBlock, flush: DribbleStreamFlush, eraseChar: DribbleStreamEraseChar, reset: DribbleStreamReset, close: DribbleStreamClose ]; CreateDribbleOutputStream: PUBLIC PROC [output1, output2: STREAM] RETURNS [STREAM] = { RETURN[IO.CreateStream[ streamProcs: DribbleStreamProcs, streamData: NEW[DribbleStreamRecord _ [outputStream: output2]], backingStream: output1]]; }; DribbleStreamPutChar: PROC [self: STREAM, char: CHAR] = { data: DribbleStreamData = NARROW[self.streamData]; self.backingStream.PutChar[char]; data.outputStream.PutChar[char]; }; DribbleStreamPutBlock: PROC [ self: STREAM, block: REF READONLY TEXT, startIndex: NAT, count: NAT] = { data: DribbleStreamData = NARROW[self.streamData]; self.backingStream.PutBlock[block, startIndex, count]; data.outputStream.PutBlock[block, startIndex, count]; }; DribbleStreamUnsafePutBlock: PROC [self: STREAM, block: IO.UnsafeBlock] = { data: DribbleStreamData = NARROW[self.streamData]; self.backingStream.UnsafePutBlock[block]; data.outputStream.UnsafePutBlock[block]; }; DribbleStreamFlush: PROC[self: STREAM] = { data: DribbleStreamData = NARROW[self.streamData]; self.backingStream.Flush[]; data.outputStream.Flush[]; }; DribbleStreamEraseChar: PROC [self: STREAM, char: CHAR] = { data: DribbleStreamData = NARROW[self.streamData]; self.backingStream.EraseChar[char]; data.outputStream.EraseChar[char]; }; DribbleStreamReset: PROC[self: STREAM] = { data: DribbleStreamData = NARROW[self.streamData]; self.backingStream.Reset[]; data.outputStream.Reset[]; }; DribbleStreamClose: PROC[self: STREAM, abort: BOOL] = { data: DribbleStreamData = NARROW[self.streamData]; self.backingStream.Close[abort]; data.outputStream.Close[abort]; }; END. žIOClassesImpl.mesa Last edited by: MBrown on January 13, 1984 1:32 pm Copy Interim implementation, one character at a time. Comment-filtered Input Stream May raise IO.EndOfStream. Skip over the comment. Return ending CR, or SP if ends without CR, or raise IO.EndOfStream if comment ends with end of input. Concatenated Input Stream we preserve the information for debugging purposes Dribble Output Stream Κ O– "Cedar" style˜headšœ™bodyšœ™Jšœ Οc™"——˜šΟk ˜ Jšžœ˜Jšœ ˜ Jšœ˜J˜——šΠbl œžœžœ˜Jšžœžœ˜Jšžœ ˜Jšžœžœ#˜-Jšž˜Jšžœžœžœžœ˜Jšœ žœžœ ˜#Jšœ žœžœ ˜#—™unitšΟnœžœžœ˜Jšœ žœžœžœ˜EJ™0codešž˜Nšœžœžœ˜3Nšžœ˜—Nšžœ žœ˜Nšžœ žœ ˜Jšœ˜—J˜—™Mšœžœžœ˜Ašœžœžœ˜+Jšœžœžœ˜Jšœžœžœ˜Jšœžœž˜J˜—šœžœžœ$˜EJšœ'˜'J˜$Jšœ˜—š œžœžœ žœ˜6Jšžœžœžœ˜šžœžœ˜Jšœ=˜=Jšœ žœ$˜3—Jšžœ˜—š  œžœžœžœžœžœ˜KJšœ!žœ˜9šœ$˜$Jšœ žœ ™—šžœžœž˜šœ˜Jšœžœ9˜VJšž˜Jšœ˜—šœ˜Jšœžœ˜Jšžœ žœžœ˜.Jšž˜Jšœ˜—šœ˜šžœž˜Jšœžœ˜"Jšœžœ^˜ƒJšžœ˜—Jšžœ˜ —šžœ˜ šžœž˜Jšœžœ˜#Jšœžœ˜!šœžœžœ˜'šžœ$žœ˜-Jš œ&žœžœžœ žœ/™~Jšœ"˜"šž˜šžœ'ž˜1Jšœžœ˜ šœžœ#žœ˜1Jšœžœžœžœ˜—Jšžœ˜—Jšžœ˜—J˜——Jšžœ˜———J˜——™Jšœžœžœ˜5šœžœžœ˜%Jšœž˜Jšœ˜—Jšœžœ ˜9šœžœžœ$˜?Jšœ&˜&Jšœ˜Jšœ!˜!Jšœ-˜-Jšœ%˜%Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—š  œžœžœžœžœžœ˜Ošžœžœ˜šœ.žœ˜JJšœ4˜4——Jšžœ˜—š  œžœžœžœžœ˜=Jšœžœ˜3˜šžœžœ˜/Jšžœžœžœ˜0—šžœ˜J˜Jšžœ˜J˜—J˜—J˜—š  œžœ˜0Jšœ2™2Jšœžœ˜Jšœ˜Jšœ˜J˜—š œžœžœ žœžœžœ žœ˜YJšžœžœ˜Jšœžœ˜3Jšœ<˜