<> <> <> <> <<>> DIRECTORY Basics, Heap, IO, Inline, Space, Stream, System, VM, BasicTime, UnsafeStorage, Time, Rope, PupStream, RuntimeError, NameInfoDefs, GVNames; PilotBridgeImpl: MONITOR IMPORTS Basics, BasicTime, IO, UnsafeStorage, VM, PupStream, RuntimeError, GVNames, Rope EXPORTS Heap, Inline, Space, Stream, System, Time, NameInfoDefs ~ BEGIN <> systemZone: PUBLIC UNCOUNTED ZONE ~ UnsafeStorage.GetSystemUZone[]; <> bitsPerWord: NAT ~ Basics.bitsPerWord; DBITSHIFT: PUBLIC PROCEDURE [value: LONG UNSPECIFIED, count: INTEGER] RETURNS [LONG UNSPECIFIED] ~ { a: Inline.LongNumber.num _ LOOPHOLE[value]; IF count >= 0 THEN { WHILE count >= bitsPerWord DO a.highbits _ a.lowbits; a.lowbits _ 0; count _ count - bitsPerWord; ENDLOOP; a.highbits _ Basics.BITSHIFT[a.highbits, count] + Basics.BITSHIFT[a.lowbits, count-bitsPerWord]; a.lowbits _ Basics.BITSHIFT[a.lowbits, count]; } ELSE { WHILE count <= -bitsPerWord DO a.lowbits _ a.highbits; a.highbits _ 0; count _ count + bitsPerWord; ENDLOOP; a.lowbits _ Basics.BITSHIFT[a.highbits, count+bitsPerWord] + Basics.BITSHIFT[a.lowbits, count]; a.highbits _ Basics.BITSHIFT[a.highbits, count]; }; RETURN [LOOPHOLE[a]] }; <> ScratchMap: PUBLIC PROCEDURE [count: VM.PageCount, usage: Space.Usage] RETURNS [pointer: LONG POINTER] ~ { interval: Space.Interval _ Allocate[count]; AddToScratchList[interval]; pointer _ interval.pointer; }; Unmap: PUBLIC PROCEDURE [pointer: LONG POINTER, returnWait: Space.ReturnWait] RETURNS [nil: LONG POINTER _ NIL] ~ { interval: Space.Interval _ RemoveFromScratchList[pointer]; IF interval.pointer = NIL THEN Error[invalidParameters]; Deallocate[interval]; }; scratchList: LIST OF Space.Interval; AddToScratchList: ENTRY PROC [interval: Space.Interval] ~ { scratchList _ CONS[interval, scratchList]; }; RemoveFromScratchList: ENTRY PROC [pointer: LONG POINTER] RETURNS [Space.Interval] ~ { prev: LIST OF Space.Interval _ NIL; FOR p: LIST OF Space.Interval _ scratchList, p.rest UNTIL p=NIL DO IF p.first.pointer = pointer THEN { IF prev = NIL THEN scratchList _ p.rest ELSE prev.rest _ p.rest; p.rest _ NIL; RETURN [p.first]; }; prev _ p; ENDLOOP; RETURN [Space.nullInterval] }; <> Allocate: PUBLIC PROCEDURE [count: VM.PageCount] RETURNS [interval: Space.Interval] ~ { interval _ SpaceIntervalFromVMInterval[VM.Allocate[count]]; }; Deallocate: PUBLIC PROCEDURE [interval: Space.Interval] ~ { VM.Free[VMIntervalFromSpaceInterval[interval]]; }; SpaceIntervalFromVMInterval: PROCEDURE [vmInterval: VM.Interval] RETURNS [interval: Space.Interval] ~ { interval.pointer _ VM.AddressForPageNumber[vmInterval.page]; interval.count _ vmInterval.count; }; VMIntervalFromSpaceInterval: PROCEDURE [interval: Space.Interval] RETURNS [vmInterval: VM.Interval] ~ { vmInterval.page _ VM.PageNumberForAddress[interval.pointer]; vmInterval.count _ interval.count; }; Error: PUBLIC ERROR [type: Space.ErrorType] ~ CODE; <> Attention: PUBLIC SIGNAL [nextIndex: CARDINAL] ~ CODE; EndOfStream: PUBLIC SIGNAL [nextIndex: CARDINAL] ~ CODE; LongBlock: PUBLIC SIGNAL [nextIndex: CARDINAL] ~ CODE; ShortBlock: PUBLIC ERROR ~ CODE; SSTChange: PUBLIC SIGNAL [sst: Stream.SubSequenceType, nextIndex: CARDINAL] ~ CODE; TimeOut: PUBLIC SIGNAL [nextIndex: CARDINAL] ~ CODE; InvalidOperation: PUBLIC ERROR ~ CODE; EndRecord: PUBLIC SIGNAL [nextIndex: CARDINAL] ~ CODE; defaultObject: PUBLIC Stream.Object _ [ options: Stream.defaultInputOptions, getByte: DefaultGetByte, putByte: DefaultPutByte, getWord: DefaultGetWord, putWord: DefaultPutWord, get: NIL, put: NIL, setSST: NIL, sendAttention: NIL, waitAttention: NIL, delete: NIL, getPosition: NIL, setPosition: NIL, sendNow: NIL, clientData: NIL, getSST: NIL, getTimeout: NIL, setTimeout: NIL ]; DefaultGetByte: PROCEDURE [sH: Stream.Handle] RETURNS [Stream.Byte] ~ { bytes: PACKED ARRAY [0..4] OF Stream.Byte; [] _ sH.get[sH, [@bytes, 0, 1], sH.options]; RETURN [bytes[0]]; }; DefaultGetWord: PROCEDURE [sH: Stream.Handle] RETURNS [Stream.Word] ~ { words: PACKED ARRAY [0..2] OF WORD; ptr: LONG POINTER _ @words; [] _ sH.get[sH, [ptr, 0, Basics.bytesPerWord], sH.options]; RETURN [words[0]]; }; DefaultPutByte: PROCEDURE [sH: Stream.Handle, byte: Stream.Byte] ~ { bytes: PACKED ARRAY [0..4] OF Stream.Byte; bytes[0] _ byte; sH.put[sH, [@bytes, 0, 1], FALSE]; }; DefaultPutWord: PROCEDURE [sH: Stream.Handle, word: Stream.Word] ~ { words: PACKED ARRAY [0..2] OF WORD; ptr: LONG POINTER _ @words; words[0] _ word; sH.put[sH, [ptr, 0, Basics.bytesPerWord], FALSE]; }; StreamPair: TYPE ~ REF StreamPairRep; StreamPairRep: TYPE ~ RECORD [in, out: IO.STREAM]; IOGet: PROCEDURE [sH: Stream.Handle, block: Stream.Block, options: Stream.InputOptions] RETURNS [bytesTransferred: CARDINAL, why: Stream.CompletionCode, sst: Stream.SubSequenceType] ~ { streamPair: StreamPair _ NARROW[sH.clientData]; ioStream: IO.STREAM _ streamPair.in; why _ normal; sst _ 0; bytesTransferred _ ioStream.UnsafeGetBlock[[LOOPHOLE[block.blockPointer], block.startIndex, block.stopIndexPlusOne-block.startIndex] ! IO.Error => { }; PupStream.TimeOut => TRUSTED { IF options.signalTimeout THEN SIGNAL TimeOut[nextIndex]; RESUME; }; ]; IF bytesTransferred = 0 THEN { gotMark: BOOL _ FALSE; IF ioStream.GetInfo.class = $Pup THEN { gotMark _ TRUE; sst _ PupStream.ConsumeMark[ioStream ! RuntimeError.UNCAUGHT => {gotMark _ FALSE; CONTINUE}]; }; IF gotMark THEN { IF options.signalSSTChange THEN SIGNAL SSTChange[sst, 0]; bytesTransferred _ 0; why _ sstChange; } ELSE why _ endOfStream; }; }; IOPut: PROCEDURE [sH: Stream.Handle, block: Stream.Block, endRecord: BOOLEAN] ~ { streamPair: StreamPair _ NARROW[sH.clientData]; ioStream: IO.STREAM _ streamPair.out; ioStream.UnsafePutBlock[[LOOPHOLE[block.blockPointer], block.startIndex, block.stopIndexPlusOne-block.startIndex] ! IO.Error => { }; ]; }; IOFlush: PROCEDURE [sH: Stream.Handle, endRecord: BOOLEAN] ~ { streamPair: StreamPair _ NARROW[sH.clientData]; ioStream: IO.STREAM _ streamPair.out; ioStream.Flush; }; IOClose: PROCEDURE [sH: Stream.Handle] ~ { streamPair: StreamPair _ NARROW[sH.clientData]; IF streamPair.in # NIL THEN streamPair.in.Close; IF streamPair.out # NIL AND streamPair.out # streamPair.in THEN streamPair.out.Close; }; FromIOStreams: PUBLIC PROC [in, out: IO.STREAM] RETURNS [stream: Stream.Handle] ~ { stream _ NEW[Stream.Object _ defaultObject]; stream.clientData _ NEW[StreamPairRep _ [in, out]]; stream.get _ IOGet; stream.put _ IOPut; stream.sendNow _ IOFlush; stream.delete _ IOClose; }; <> GetClockPulses: PUBLIC PROC RETURNS [System.Pulses] ~ { RETURN [[BasicTime.GetClockPulses[]]] }; PulsesToMicroseconds: PUBLIC PROC[p: System.Pulses] RETURNS [System.Microseconds] ~ { RETURN [BasicTime.PulsesToMicroseconds[p]] }; MicrosecondsToPulses: PUBLIC PROC[m: System.Microseconds] RETURNS[System.Pulses] ~ { RETURN [[BasicTime.MicrosecondsToPulses[m]]] }; Overflow: PUBLIC ERROR ~ CODE; switches: PUBLIC System.Switches _ System.defaultSwitches; isUtilityPilot: PUBLIC BOOLEAN _ TRUE; <> Current: PUBLIC PROC RETURNS [time: Time.Packed] ~ { RETURN [BasicTime.Now[]] }; Unpack: PUBLIC PROC [time: Time.Packed] RETURNS [unpacked: Time.Unpacked] ~ { RETURN [BasicTime.Unpack[time]] }; Invalid: PUBLIC ERROR ~ CODE; Pack: PUBLIC PROC [unpacked: Time.Unpacked] RETURNS [time: Time.Packed] ~ { RETURN [BasicTime.Pack[unpacked]] }; monthName: ARRAY BasicTime.MonthOfYear OF Rope.ROPE ~ ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???"]; Append: PUBLIC PROC [s: LONG STRING, unpacked: Time.Unpacked, zone: BOOLEAN _ FALSE] ~ { stream: IO.STREAM _ IO.TOS[]; text: REF TEXT _ NIL; zoneChar: CHAR _ ' ; IO.PutF[stream, "%2g-%g-%02g ", IO.int[unpacked.day], IO.rope[monthName[unpacked.month]], IO.int[unpacked.year MOD 100]]; IO.PutF[stream, "%2g:%02g:%02g", IO.int[unpacked.hour], IO.int[unpacked.minute], IO.int[unpacked.second]]; zoneChar _ SELECT unpacked.zone/60 FROM 0 => 'G, 5 => 'E, 6 => 'C, 7 => 'M, 8 => 'P, ENDCASE => ' ; IF zone AND zoneChar # ' THEN { IO.PutChar[stream, ' ]; IO.PutChar[stream, zoneChar]; IO.PutChar[stream, IF unpacked.dst = yes THEN 'D ELSE 'S]; IO.PutChar[stream, 'T]; }; text _ IO.TextFromTOS[stream]; FOR i: NAT IN [0..text.length) DO s[s.length] _ text[i]; s.length _ s.length + 1; ENDLOOP; }; AppendCurrent: PUBLIC PROC [s: LONG STRING, zone: BOOLEAN _ FALSE] ~ { Append[s, Unpack[Current[]], zone] }; <> Authenticate: PUBLIC PROC[name: NameInfoDefs.RName, password: LONG STRING] RETURNS[ NameInfoDefs.AuthenticateInfo ] ~ { RETURN [GVNames.Authenticate[name: Rs[name], password: Rs[password]]] }; Rs: PROC [string: LONG STRING] RETURNS [Rope.ROPE] ~ { i: INTEGER _ -1; fet: SAFE PROC RETURNS [CHAR] ~ TRUSTED {RETURN [string[i_i+1]]}; IF string = NIL THEN RETURN [NIL]; RETURN [Rope.FromProc[string.length, fet]]; }; IsInList: PUBLIC PROC[name: NameInfoDefs.RName, member: NameInfoDefs.RName, level: NameInfoDefs.MembershipLevel, grade: NameInfoDefs.MembershipGrade, acl: NameInfoDefs.ListType] RETURNS[NameInfoDefs.Membership] ~ { RETURN [GVNames.IsInList[name: Rs[name], member: Rs[member], level: level, grade: grade, acl: acl]] }; END.