-- PGStreams.Mesa -- written by Paxton. February 1981 -- last written by Paxton. February 20, 1981 2:46 PM -- Uses FileByteStream to create special streams for Put/Get. DIRECTORY FileOps: FROM "TiogaFileOps" USING [Byte], FileByteStream: FROM "TiogaFBS" USING [ Transaction, CreateOptions, AccessOptions, Handle], InlineDefs: FROM "InlineDefs" USING [LowHalf], Rope: FROM "Rope" USING [Ref], RopeReader: FROM "RopeReader" USING [Ref]; PGStreams: DEFINITIONS IMPORTS InlineDefs = BEGIN Card: TYPE = LONG CARDINAL; PGStreamMode: TYPE = {read, write}; PGStream: TYPE = REF PGStreamBody; PGStreamBody: PRIVATE TYPE = RECORD [ loc: NAT _ 0, -- index in block of next character to read or write after: NAT _ 0, -- index beyond last character to read or write block: Block, -- block of chars for current read/write blockSeq: REF BlockSeq, -- sequence of text blocks blockNum: NAT _ 0, -- index in blockSeq of next block file: FileByteStream.Handle, reader: RopeReader.Ref, -- for use in moving characters from ropes pgm: PGM, -- ref to monitored record for reading/writing process: PROCESS, -- process doing reads/writes with pgm other: PGStream, -- text and control streams point to each other mode: PGStreamMode, -- read/write kind: OfBlock -- text/control ]; OfBlock: TYPE = {control, text}; Block: TYPE = REF BlockBody; BlockBody: TYPE = TEXT--[blockSize]--; blockSize: NAT = 1024; BlockSeq: TYPE = RECORD[SEQUENCE length:NAT OF Block]; OpenPGStreams: PROC [ filename: Rope.Ref, transaction: FileByteStream.Transaction _ NIL, createOptions: FileByteStream.CreateOptions _ none, accessOptions: FileByteStream.AccessOptions _ write] RETURNS [control, text: PGStream]; ClosePGStreams: PROC [str: PGStream]; ReadChar: PROC [str: PGStream] RETURNS [char: CHARACTER] = INLINE BEGIN loc: CARDINAL; IF (loc_str.loc) >= str.after THEN RETURN[ReadCharSupport[str]]; str.loc _ loc+1; RETURN[str.block[loc]]; END; ReadCharSupport: PRIVATE PROC [str: PGStream] RETURNS [char: CHARACTER]; SkipChar: PROC [str: PGStream] = INLINE BEGIN loc: CARDINAL; IF (loc_str.loc) >= str.after THEN RETURN--[SkipCharSupport[str]]--; str.loc _ loc+1; END; SkipCharSupport: PRIVATE PROC [str: PGStream]; ReadByte: PROC [str: PGStream] RETURNS [[0..255]] = INLINE { RETURN[LOOPHOLE[ReadChar[str], TiogaFileOps.Byte]]}; ReadWord: PROC [str: PGStream] RETURNS [CARDINAL]; ReadDoubleWord: PROC [str: PGStream] RETURNS [Card]; MakeRope: PROC [len: Card, str: PGStream] RETURNS [rope: Rope.Ref]; WriteChar: PROC [char: CHARACTER, str: PGStream] = INLINE BEGIN loc: CARDINAL; IF (loc_str.loc) >= str.after THEN { WriteCharSupport[char, str]; RETURN }; str.loc _ loc+1; str.block[loc] _ char; END; WriteCharSupport: PRIVATE PROC [char: CHARACTER, str: PGStream]; WriteByte: PROC [byte: [0..255], str: PGStream] = INLINE { WriteChar[LOOPHOLE[byte], str]}; WriteWord: PROC [wd: CARDINAL, str: PGStream]; WriteDoubleWord: PROC [dwd: Card, str: PGStream]; WriteRope: PROC [rope: Rope.Ref, str: PGStream]; PutRope: PROC [ rope: Rope.Ref, size: Card, str1, str2: PGStream] = INLINE { WriteByte[LOOPHOLE[InlineDefs.LowHalf[size]], str1]; WriteRope[rope, str2]}; PutLongRope: PROC [ rope: Rope.Ref, size: Card, str1, str2: PGStream] = INLINE { WriteWord[InlineDefs.LowHalf[size], str1]; WriteRope[rope, str2]}; PutVeryLongRope: PROC [ rope: Rope.Ref, size: Card, str1, str2: PGStream] = INLINE { WriteDoubleWord[size, str1]; WriteRope[rope, str2]}; -- following implemented by TiogaPGMonitorImpl PGM: TYPE = REF PGMBody; PGMBody: TYPE; -- the monitored record CreatePGM: PROC [PGStreamMode] RETURNS [PGM]; -- creates monitored record for use in put/get AddToControlList: PROC [pgm: PGM, block: Block]; -- adds block to end of control read list GetFromControlList: PROC [pgm: PGM] RETURNS [Block]; -- removes first block from control read list -- returns NIL when certain that nothing more to read -- i.e., after there has been a call on ControlReadsDone ControlReadsDone: PROC [pgm: PGM]; -- promises that there will be no more calls on AddToControlList TextReadsDone: PROC [pgm: PGM]; -- informs world that have finished reading text WriteTextBlock: PROC [pgm: PGM, block: Block]; --puts text block at end of write list WriteControlBlock: PROC [pgm: PGM, block: Block]; --puts control block at end of deferred list GetFromWriteList: PROC [pgm: PGM] RETURNS [Block]; -- call this to get a block to write -- returns NIL when certain that nothing more to write -- i.e., after there has been a call on WritesDone WritesDone: PROC [pgm: PGM]; -- promises that there will be no more calls on AddToWriteList END. LOG added formals ids to PROC definitions. Pier, 12/7/80 added inlines for ReadChar/WriteChar. Paxton, 2/2/81 changed to use TiogaFBS. Pier, 2/11/81 fixed up to compile properly. Pier 2/20/81 (635)