-- CGBandStreamImpl.mesa Cedar 3.4 -- Last changed by Ken Pier, October 8, 1982 3:32 pm DIRECTORY CGBandStream, ConvertUnsafe USING [ToRope], UnsafeStorage USING [GetSystemUZone], Rope USING[ROPE], Runtime USING[CallDebugger], IO USING [UnsafeBlock, UnsafePutBlock, UnsafeGetBlock, Close, Signal, Error, PutFR, rope, card, SetIndex, GetIndex], CGStorage USING [pZone], Environment USING[wordsPerPage], Inline USING [LongCOPY, LowHalf], FileIO USING [AccessOptions, Open]; CGBandStreamImpl: PROGRAM IMPORTS Runtime, IO, FileIO, ConvertUnsafe, Inline, CGStorage, UnsafeStorage EXPORTS CGBandStream = { OPEN IO, FIO: FileIO, CGBandStream; uz: UNCOUNTED ZONE _ UnsafeStorage.GetSystemUZone[]; pZone: ZONE = CGStorage.pZone; keepPagesOnClose: CARDINAL = 0; --OpenBand takes a prefix string (usually PBAND.) and an index (i). Opens a --FileIO stream on file PBAND.i, returning a handle OpenBand: PUBLIC PROC[name: BandPrefix, index: BandIndex, access: FIO.AccessOptions _ read] RETURNS [bStream: BandStreamHandle] = { rFile: Rope.ROPE; rFile _ IF index#LAST[BandIndex] THEN IO.PutFR[ , IO.rope[ConvertUnsafe.ToRope[name]], IO.card[index]] ELSE IO.PutFR[ , IO.rope[ConvertUnsafe.ToRope[name]]]; bStream _ FIO.Open[fileName: rFile, accessOptions: access, closeOptions: keepPagesOnClose ! IO.Error, IO.Signal => TRUSTED {Runtime.CallDebugger["BSOpenFailed"L]}]; };--OpenBand PutBand: PUBLIC PROC[band: BandStreamHandle, from: LONG POINTER, words: LONG INTEGER] = { --send words to the bandstream bytes: LONG INTEGER _ words*2; uBlock: IO.UnsafeBlock; uBlock _ [base: from, startIndex: 0, stopIndexPlusOne: bytes]; IO.UnsafePutBlock[band, uBlock]; };--PutBand StartGetBand: PUBLIC PROC[band: BandStreamHandle] = { IO.SetIndex[band, 0]; wordsLeft _ 0; bRef _ bStart; };--StartBand GetBand: PUBLIC PROC[band: BandStreamHandle, to: LONG POINTER, words: LONG INTEGER] RETURNS [LONG INTEGER] = { --get the incoming block and deliver to client nWords, wordsRead, temp: LONG INTEGER _ 0; cWords: CARDINAL _ 0; uBlock: IO.UnsafeBlock; DO nWords _ IF words <= wordsLeft THEN words ELSE wordsLeft; --LongMIN[words, wordsLeft] cWords _ Inline.LowHalf[nWords]; Inline.LongCOPY[from: bRef, nwords: cWords, to: to]; wordsRead _ wordsRead+nWords; temp _ words-wordsLeft; IF nWords=words THEN {--buffer had all the words wordsLeft _ -temp; --wordsLeft-words bRef _ bRef+words; IF (bEnd - bRef) < 0 THEN ERROR; EXIT; }; --buffer empty and more to COPY. temp contains remaining word count bRef _ bStart; words _ temp; to _ to+wordsLeft; uBlock _ [base: LOOPHOLE[bStart], startIndex: 0, stopIndexPlusOne: bufferBytes]; wordsLeft _ (IO.UnsafeGetBlock[band, uBlock])/2; IF wordsLeft=0 THEN EXIT; ENDLOOP; RETURN[wordsRead]; };--GetBand SkipBand: PUBLIC PROC [band: BandStreamHandle, words: LONG INTEGER] RETURNS [wordsSkipped: LONG INTEGER] = { temp: LONG INTEGER; temp _ words-wordsLeft; IF temp <= 0 THEN {--buffer had all the words wordsLeft _ -temp; --wordsLeft-words bRef _ bRef+words; IF (bEnd - bRef) < 0 THEN ERROR; wordsSkipped _ words; RETURN}; --buffer empty and more to SKIP. temp contains skip count --skip ahead in stream: IO.SetIndex[band, IO.GetIndex[band]+temp*2]; wordsSkipped _ words; wordsLeft _ 0; bRef _ bStart; };--SkipBand CloseBand: PUBLIC PROC[b: BandStreamHandle] = { IO.Close[b ! IO.Error, IO.Signal => TRUSTED {Runtime.CallDebugger["BSCloseFailed"L]}]; };--CloseBand SetBufferPages: PUBLIC PROC[bP: CARDINAL _ 1] = { IF bP = bufferPages THEN RETURN; bufferPages _ bP; bufferWords _ bP*Environment.wordsPerPage; bufferBytes _ bufferWords*2; IF bStart#NIL THEN uz.FREE[@bStart]; bStart _ uz.NEW[Buffer[bufferWords]]; bEnd _ bStart+bufferWords; };--SetBufferPages --global storage bufferPages: PUBLIC CARDINAL _ 1; bufferWords: CARDINAL _ bufferPages*Environment.wordsPerPage; bufferBytes: CARDINAL _ bufferWords*2; wordsLeft: LONG INTEGER _ 0;--remaining valid words in Get buffer Buffer: TYPE = RECORD[SEQUENCE COMPUTED CARDINAL OF WORD]; BufferP: TYPE = LONG POINTER TO Buffer; bRef, bEnd: BufferP _ NIL; bStart: BufferP _ uz.NEW[Buffer[bufferWords]]; bEnd _ bStart+bufferWords; }.--CGBandStreamImpl LOG converted to IOStreams, 10-Dec-81 10:50:15, by Pier changed PutBand, GetBand from Band to BandStreamHandle, 15-Jan-82, Pier reformatted, 19-JAN-82 converted to FileIOStreams, 2/2/82 added large buffer stuff and SkipBand, 2/23/82 added SetBufferPages, 2/28/82 added UNCOUNTED ZONE, 3/3/82 changed Put and Get to use LONG POINTERS instead of REFs, 30-Mar-82 swapped UnsafeStorage for Heap, 5/3/82 convert to Cedar 3.2, June 29, 1982 added option to ignore BandIndex in OpenBand, 7/13/82