-- Copyright (C) 1982, 1984  by Xerox Corporation. All rights reserved. 
-- LupineRuntime.mesa, HGM, 21-Jan-84 21:47:57
-- Cedar 5, HGM, 21-Jan-84 20:43:43

-- File [Ivy]<Nelson>Lupine>LupineRuntime.mesa.
-- Last edited by BZM on 11-May-82 16:17:07.

-- This interface is used at runtime for marshaling and other common functions.


DIRECTORY
  Environment USING [charsPerWord],
  Inline USING [LongCOPY, HighHalf, LowHalf],
  MesaRPC USING [Zones],
  MesaRPCLupine USING [DataLength, maxDataLength, --PktLength,-- RPCPkt, StubPkt];


LupineRuntime: DEFINITIONS IMPORTS Inline =
  BEGIN OPEN RpcPrivate: MesaRPCLupine;


  -- Lupine's no-nonsense errors.

  TranslationError: ERROR;
  BindingError: ERROR;
  RuntimeError: ERROR;

  -- These procedures map into ERRORs (for now).

  MarshalingError: PROCEDURE;
  MarshalingExprError: PROCEDURE RETURNS [never: UNSPECIFIED];

  -- These procedures map into RpcRuntime ERRORs.

  UnmarshalingError: PROCEDURE;
  UnmarshalingExprError: PROCEDURE RETURNS [never: UNSPECIFIED];
  DispatchingError: PROCEDURE RETURNS [never: UNSPECIFIED];


  defaultZones: MesaRPC.Zones;


  -- Parameter protocol headers.

  NilHeader: TYPE = BOOLEAN ← NULL;
  RopeHeader: TYPE = CARDINAL ← NULL;
  ListHeader, SequenceHeader: TYPE = LONG CARDINAL ← NULL;

  StringHeader: TYPE = MACHINE DEPENDENT RECORD [
    header(0): SELECT OVERLAID * FROM
      Lengths => [maxLength(0), length(1): CARDINAL ← NULL],
      All => [all(0): LONG CARDINAL],
      ENDCASE] ← [Lengths[]];

  -- Parameter marshaling routines.

  StubPktDoubleWord: PROC [pkt: RpcPrivate.StubPkt, index: RpcPrivate.DataLength]
    RETURNS [ --ptrToDoubleWord:-- POINTER TO LONG UNSPECIFIED] = INLINE {
    RETURN[@pkt.data[index]]};

  RpcPktDoubleWord: PROC [pkt: RpcPrivate.RPCPkt, index: RpcPrivate.DataLength]
    RETURNS [ --ptrToDoubleWord:-- LONG POINTER TO LONG UNSPECIFIED] = INLINE {
    RETURN[@pkt.data[index]]};

  SHORT: PROCEDURE [long: LONG CARDINAL] RETURNS [CARDINAL] = INLINE
    BEGIN
    RETURN[
      --IF long IN [0..LAST[CARDINAL]]
      IF Inline.HighHalf[long] = 0 THEN Inline.LowHalf[long]
      ELSE UnmarshalingExprError[]];
    END;


  Words: TYPE = --LONG-- CARDINAL ← NULL;

  WordsForChars: PROCEDURE [chars: CARDINAL] RETURNS [ --words:-- Words] = INLINE
    BEGIN
    RETURN[(chars + Environment.charsPerWord - 1)/Environment.charsPerWord];
    END;


  CheckPktLength: PROCEDURE [
    pkt: RpcPrivate.RPCPkt, lastPkt: BOOLEAN ← TRUE,
    pktLength: RpcPrivate.DataLength] = INLINE
    BEGIN
    -- IF RpcPrivate.PktLength[pkt: pkt] # [lastPkt: lastPkt, pktLength: pktLength]
    --  THEN UnmarshalingError;
    END;

  FinishThisPkt, StartNextPkt: PROCEDURE [
    pkt: RpcPrivate.RPCPkt, pktLength: RpcPrivate.DataLength]
    RETURNS [zeroPktLength: RpcPrivate.DataLength];

  CopyToPkt: PROCEDURE [
    pkt: RpcPrivate.RPCPkt, pktLength: RpcPrivate.DataLength,
    dataAdr: LONG POINTER, dataLength: Words, alwaysOnePkt: BOOLEAN ← FALSE]
    RETURNS [ --newPktLength:-- RpcPrivate.DataLength] = INLINE
    BEGIN
    IF alwaysOnePkt OR pktLength + dataLength <= RpcPrivate.maxDataLength THEN
      BEGIN
      Inline.LongCOPY[
        to: @pkt.data[pktLength], from: dataAdr, nwords: dataLength];
      RETURN[pktLength + dataLength];
      END
    ELSE RETURN[CopyToMultiplePkts[pkt, pktLength, dataAdr, dataLength]];
    END;

  CopyFromPkt: PROCEDURE [
    pkt: RpcPrivate.RPCPkt, pktLength: RpcPrivate.DataLength,
    dataAdr: LONG POINTER, dataLength: Words, alwaysOnePkt: BOOLEAN ← FALSE]
    RETURNS [ --newPktLength:-- RpcPrivate.DataLength] = INLINE
    BEGIN
    IF alwaysOnePkt OR pktLength + dataLength <= RpcPrivate.maxDataLength THEN
      BEGIN
      Inline.LongCOPY[
        to: dataAdr, from: @pkt.data[pktLength], nwords: dataLength];
      RETURN[pktLength + dataLength];
      END
    ELSE RETURN[CopyFromMultiplePkts[pkt, pktLength, dataAdr, dataLength]];
    END;

  CopyToMultiplePkts, CopyFromMultiplePkts: PRIVATE PROCEDURE [
    pkt: RpcPrivate.RPCPkt, pktLength: RpcPrivate.DataLength,
    dataAdr: LONG POINTER, dataLength: Words]
    RETURNS [ --newPktLength:-- RpcPrivate.DataLength];


  END.  -- LupineRuntime.