-- Stub file  was translated on  September 13, 1983 4:34 pm by Lupine of  September 13, 1983 4:16 pm
-- Source interface LupineMarshalTest came from file LupineMarshalTest.bcd, which was created on  September 12, 1983 5:15 pm with version stamp 234#313#4263372323 from source of July 7, 1982 11:31 am.

-- The RPC stub modules for LupineMarshalTest are:
--   LupineMarshalTestRpcControl.mesa;
--   LupineMarshalTestRpcClientImpl.mesa;
--   LupineMarshalTestRpcBinderImpl.mesa;
--   LupineMarshalTestRpcServerImpl.mesa.

-- The parameters for this translation are:
--   Target language = Cedar
--   Default parameter passing = VALUE
--   Deallocate server heap arguments = TRUE
--   Inline RpcServerImpl dispatcher stubs = TRUE
--   Declare signals = FALSE
--   Warn about short POINTER ("MDS") allocations = FALSE
--   Maximum number of dynamic heap NEWs = 50, MDS NEWs = 50
--   Acceptable parameter protocols = VersionRange[1..1].


DIRECTORY
  Rope,
  LupineMarshalTest,
  LupineMarshalTestRpcControl USING [InterMdsCallsOnly, LupineProtocolVersion,
      ProcedureIndex, SignalIndex],
  RPC USING [InterfaceName, standardZones, Zones],
  RPCLupine --USING SOME OF [Call, DataLength, Dispatcher, GetStubPkt,
      -- ImportHandle, ImportInterface, maxDataLength, maxPrincipalLength,
      -- maxShortStringLength, pktOverhead, ReceiveExtraPkt, SendPrelimPkt,
      -- StartCall, StartSignal, StubPkt, UnimportInterface]--,
  LupineRuntime --USING SOME OF [BindingError, CheckPktLength, CopyFromPkt,
      -- CopyFromMultiplePkts, CopyToPkt, CopyToMultiplePkts, defaultZones,
      -- DispatchingError, FinishThisPkt, ListHeader, MarshalingError,
      -- MarshalingExprError, NilHeader, ProtocolError, RopeHeader, RpcPktDoubleWord,
      -- RuntimeError, SequenceHeader, SHORT, StartNextPkt, StringHeader,
      -- StubPktDoubleWord, TranslationError, UnmarshalingError, UnmarshalingExprError,
      -- WordsForChars]--,
  Atom --USING SOME OF [GetPName, MakeAtom]--;


LupineMarshalTestRpcClientImpl: MONITOR
  IMPORTS LupineMarshalTest, RpcPrivate: RPCLupine, Lupine: LupineRuntime,
      Atom, Rope
  EXPORTS LupineMarshalTest, LupineMarshalTestRpcControl
  SHARES  LupineMarshalTest, LupineMarshalTestRpcControl, Rope
  = BEGIN OPEN LupineMarshalTest, RpcControl: LupineMarshalTestRpcControl,
      RpcPublic: RPC;


-- Standard remote binding routines.

  bound: BOOLEAN ← FALSE;
  myInterface: RpcPrivate.ImportHandle;
  paramZones: RpcPublic.Zones ← RpcPublic.standardZones;

  ImportInterface: PUBLIC ENTRY SAFE PROCEDURE [
        interfaceName: RpcPublic.InterfaceName,
        parameterStorage: RpcPublic.Zones ] =
    TRUSTED BEGIN ENABLE UNWIND => NULL;
    IsNull: PROCEDURE [string: Rope.ROPE] RETURNS [BOOLEAN] =
      INLINE {RETURN[string.Length[] = 0]};
    IF bound THEN Lupine.BindingError;
    myInterface ← RpcPrivate.ImportInterface [
      interface: [
        type: IF ~IsNull[interfaceName.type]
          THEN interfaceName.type ELSE "LupineMarshalTest~234#313#4263372323",
        instance: interfaceName.instance,
        version: interfaceName.version ],
      localOnly: RpcControl.InterMdsCallsOnly,
      stubProtocol: RpcControl.LupineProtocolVersion ];
    paramZones ← [
      gc: IF parameterStorage.gc # NIL
        THEN parameterStorage.gc ELSE Lupine.defaultZones.gc,
      heap: IF parameterStorage.heap # NIL
        THEN parameterStorage.heap ELSE Lupine.defaultZones.heap,
      mds: IF parameterStorage.mds # NIL
        THEN parameterStorage.mds ELSE Lupine.defaultZones.mds ];
    bound ← TRUE;
    END;

  UnimportInterface: PUBLIC ENTRY SAFE PROCEDURE =
    TRUSTED BEGIN ENABLE UNWIND => NULL;
    IF ~bound THEN Lupine.BindingError;
    myInterface ← RpcPrivate.UnimportInterface[myInterface];
    paramZones ← RpcPublic.standardZones;
    bound ← FALSE;
    END;



-- Remote public procedure stubs.

  Null: PUBLIC PROCEDURE =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← Null];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+1] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 1;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt.transferIndex ← Null;
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 0, signalHandler: ClientDispatcher];
    Lupine.CheckPktLength[pkt: pkt, pktLength: 0];
    RETURN[];
    END;  -- Null.

  One: PUBLIC PROCEDURE [one: INTEGER] RETURNS [--a:-- INTEGER] =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← One, one (1): INTEGER];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        a (0): INTEGER];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+2] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 2;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt↑ ← [one: one];
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 1, signalHandler: ClientDispatcher];
    Lupine.CheckPktLength[pkt: pkt, pktLength: 1];
    RETURN[resPkt.a];
    END;  -- One.

  Four: PUBLIC PROCEDURE [one: INTEGER, two: INTEGER, three: INTEGER,
      four: INTEGER]
    RETURNS [--a:-- INTEGER, --b:-- INTEGER, --c:-- INTEGER, --d:--
        INTEGER] =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← Four, one (1): INTEGER,
        two (2): INTEGER, three (3): INTEGER, four (4): INTEGER];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        a (0): INTEGER, b (1): INTEGER, c (2): INTEGER, d (3): INTEGER];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+5] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 5;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt↑ ← [one: one, two: two, three: three, four: four];
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 4, signalHandler: ClientDispatcher];
    Lupine.CheckPktLength[pkt: pkt, pktLength: 4];
    RETURN[resPkt.a, resPkt.b, resPkt.c, resPkt.d];
    END;  -- Four.

  Ten: PUBLIC PROCEDURE [one: INTEGER, two: INTEGER, three: INTEGER,
      four: INTEGER, five: INTEGER, six: INTEGER, seven: INTEGER, eight:
      INTEGER, nine: INTEGER, ten: INTEGER]
    RETURNS [--a:-- INTEGER, --b:-- INTEGER, --c:-- INTEGER, --d:--
        INTEGER, --e:-- INTEGER, --f:-- INTEGER, --g:-- INTEGER, --h:--
        INTEGER, --i:-- INTEGER, --j:-- INTEGER] =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← Ten, one (1): INTEGER,
        two (2): INTEGER, three (3): INTEGER, four (4): INTEGER, five (5):
        INTEGER, six (6): INTEGER, seven (7): INTEGER, eight (8): INTEGER,
        nine (9): INTEGER, ten (10): INTEGER];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        a (0): INTEGER, b (1): INTEGER, c (2): INTEGER, d (3): INTEGER,
        e (4): INTEGER, f (5): INTEGER, g (6): INTEGER, h (7): INTEGER,
        i (8): INTEGER, j (9): INTEGER];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+11] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 11;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt↑ ← [one: one, two: two, three: three, four: four, five:
        five, six: six, seven: seven, eight: eight, nine: nine, ten: ten];
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 10, signalHandler: ClientDispatcher];
    Lupine.CheckPktLength[pkt: pkt, pktLength: 10];
    RETURN[resPkt.a, resPkt.b, resPkt.c, resPkt.d, resPkt.e, resPkt.f,
        resPkt.g, resPkt.h, resPkt.i, resPkt.j];
    END;  -- Ten.

  SignalTest: PUBLIC PROCEDURE [in: INTEGER, action: SignalAction]
      RETURNS [--out:-- INTEGER] =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← SignalTest, in (1):
        INTEGER, action (2): SignalAction];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        out (0): INTEGER];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+3] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 3;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt↑ ← [in: in, action: action];
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 1, signalHandler: ClientDispatcher];
    Lupine.CheckPktLength[pkt: pkt, pktLength: 1];
    RETURN[resPkt.out];
    END;  -- SignalTest.

  TenArray: PUBLIC PROCEDURE [in: Array10] RETURNS [--out:-- Array10]
      =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← TenArray, in (1):
        Array10];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        out (0): Array10];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+11] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 11;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt↑ ← [in: in];
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 10, signalHandler: ClientDispatcher];
    Lupine.CheckPktLength[pkt: pkt, pktLength: 10];
    RETURN[resPkt.out];
    END;  -- TenArray.

  FortyArray: PUBLIC PROCEDURE [in: Array40] RETURNS [--out:-- Array40]
      =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← FortyArray, in (1):
        Array40];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        out (0): Array40];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+41] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 41;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt↑ ← [in: in];
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 40, signalHandler: ClientDispatcher];
    Lupine.CheckPktLength[pkt: pkt, pktLength: 40];
    RETURN[resPkt.out];
    END;  -- FortyArray.

  HundredArray: PUBLIC PROCEDURE [in: Array100] RETURNS [--out:-- Array100]
      =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← HundredArray, in
        (1): Array100];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        out (0): Array100];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+101] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 101;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt↑ ← [in: in];
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 100, signalHandler: ClientDispatcher];
    Lupine.CheckPktLength[pkt: pkt, pktLength: 100];
    RETURN[resPkt.out];
    END;  -- HundredArray.

  SimpleArithmetic: PUBLIC PROCEDURE [pad: VARArithmetic] =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← SimpleArithmetic];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+8] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 1;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt.transferIndex ← SimpleArithmetic;
    BEGIN  -- Marshal pad: VARArithmetic to pkt.data[pktLength].
      pkt.data[pktLength] ← pad=NIL;  pktLength ← pktLength+1;
      IF pad # NIL THEN
        BEGIN  -- Marshal pad↑: ArithmeticRecord to pkt.data[pktLength].
          pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
              dataAdr: pad, dataLength: SIZE[ArithmeticRecord], alwaysOnePkt:
              TRUE];
          END;  -- Marshal pad↑.
      END;  -- Marshal pad.
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 7, signalHandler: ClientDispatcher];
    pktLength ← 0;
    BEGIN  -- Unmarshal pad: VARArithmetic from pkt.data[pktLength].
      isNIL: Lupine.NilHeader;
      isNIL ← pkt.data[pktLength];  pktLength ← pktLength+1;
      IF isNIL # (pad=NIL) THEN Lupine.UnmarshalingError;
      IF ~isNIL THEN
        -- Call by var or result, use existing referent.
        BEGIN  -- Unmarshal pad↑: ArithmeticRecord from pkt.data[pktLength].
          pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
              dataAdr: pad, dataLength: SIZE[ArithmeticRecord], alwaysOnePkt:
              TRUE];
          END;  -- Unmarshal pad↑.
      END;  -- Unmarshal pad.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    RETURN[];
    END;  -- SimpleArithmetic.

  FillArray: PUBLIC PROCEDURE [in: INTEGER, out: RESULTArray] =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← FillArray, in (1):
        INTEGER];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+254] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 2;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt↑ ← [in: in];
    BEGIN  -- Marshal out: RESULTArray to pkt.data[pktLength].
      Lupine.StubPktDoubleWord[pkt, pktLength]↑ ← (IF BASE[out]=NIL
          THEN 0 ELSE LENGTH[out]);
      pktLength ← pktLength + 2;
      IF BASE[out] # NIL THEN
        NULL;  -- Call by result, send length only.
      END;  -- Marshal out.
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 254, signalHandler: ClientDispatcher];
    pktLength ← 0;
    BEGIN  -- Unmarshal out: RESULTArray from pkt.data[pktLength].
      DescriptorType: TYPE = RECORD [SEQUENCE COMPUTED CARDINAL OF
          INTEGER];
      descLength: Lupine.SequenceHeader;
      IF pktLength+2 > RpcPrivate.maxDataLength
        THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
            pktLength];
      descLength ← Lupine.StubPktDoubleWord[pkt, pktLength]↑;
      pktLength ← pktLength + 2;
      IF descLength # (IF BASE[out]=NIL THEN 0 ELSE LENGTH[out])
        THEN Lupine.UnmarshalingError;
      NULL;  -- Call by var or result, use existing descriptor.
      pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: BASE[out], dataLength: SIZE[INTEGER]*LENGTH[out], alwaysOnePkt:
          FALSE];
      END;  -- Unmarshal out.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    RETURN[];
    END;  -- FillArray.

  ReadPages: PUBLIC PROCEDURE [item: Item, buffer: RESULTPages] =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← ReadPages, item
        (1): Item];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+254] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 2;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt↑ ← [item: item];
    BEGIN  -- Marshal buffer: RESULTPages to pkt.data[pktLength].
      Lupine.StubPktDoubleWord[pkt, pktLength]↑ ← (IF BASE[buffer]=NIL
          THEN 0 ELSE LENGTH[buffer]);
      pktLength ← pktLength + 2;
      IF BASE[buffer] # NIL THEN
        NULL;  -- Call by result, send length only.
      END;  -- Marshal buffer.
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 254, signalHandler: ClientDispatcher];
    pktLength ← 0;
    BEGIN  -- Unmarshal buffer: RESULTPages from pkt.data[pktLength].
      DescriptorType: TYPE = RECORD [SEQUENCE COMPUTED CARDINAL OF
          Item];
      descLength: Lupine.SequenceHeader;
      IF pktLength+2 > RpcPrivate.maxDataLength
        THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
            pktLength];
      descLength ← Lupine.StubPktDoubleWord[pkt, pktLength]↑;
      pktLength ← pktLength + 2;
      IF descLength # (IF BASE[buffer]=NIL THEN 0 ELSE LENGTH[buffer])
        THEN Lupine.UnmarshalingError;
      NULL;  -- Call by var or result, use existing descriptor.
      pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: BASE[buffer], dataLength: SIZE[Item]*LENGTH[buffer],
          alwaysOnePkt: FALSE];
      END;  -- Unmarshal buffer.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    RETURN[];
    END;  -- ReadPages.

  CreateList: PUBLIC PROCEDURE [in: LONG INTEGER, length: INTEGER]
      RETURNS [out: IntList] =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← CreateList, in (1):
        LONG INTEGER, length (3): INTEGER];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+254] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 4;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt↑ ← [in: in, length: length];
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 254, signalHandler: ClientDispatcher];
    pktLength ← 0;
    BEGIN  -- Unmarshal out: IntList from pkt.data[pktLength].
      -- Declare readwrite pointer for marshaling readonly pointer.
      writeOk1: LIST OF LONG INTEGER;
      lastNode: LIST OF LONG INTEGER ← (writeOk1 ← NIL);
      listLength: Lupine.ListHeader;
      IF pktLength+2 > RpcPrivate.maxDataLength
        THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
            pktLength];
      listLength ← Lupine.StubPktDoubleWord[pkt, pktLength]↑;
      pktLength ← pktLength + 2;
      WHILE listLength > 0 DO
        thisNode1: LIST OF LONG INTEGER = paramZones.gc.CONS[--DefaultValue--,NIL];
        BEGIN
        IF pktLength+2 > RpcPrivate.maxDataLength
          THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
              pktLength];
        thisNode1.first ← Lupine.StubPktDoubleWord[pkt, pktLength]↑;
        pktLength ← pktLength + 2;
        END;
        IF lastNode # NIL
          THEN lastNode ← (lastNode.rest ← thisNode1)
          ELSE lastNode ← (writeOk1 ← thisNode1);
        listLength ← listLength - 1;
        ENDLOOP;  -- WHILE listLength > 0.
      out ← writeOk1;
      END;  -- Unmarshal out.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    RETURN[out];
    END;  -- CreateList.

  StringCopy: PUBLIC PROCEDURE [in: ReadonlyString, out: VARString]
      =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← StringCopy];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+254] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 1;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt.transferIndex ← StringCopy;
    BEGIN  -- Marshal in: ReadonlyString to pkt.data[pktLength].
      -- Declare readwrite pointer for marshaling readonly pointer.
      writeOk1: LONG POINTER TO StringBody = LOOPHOLE[in];
      BEGIN  -- Marshal writeOk1↑: StringBody to pkt.data[pktLength].
        IF pktLength+3 > RpcPrivate.maxDataLength
          THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength:
              pktLength];
        pkt.data[pktLength] ← writeOk1=NIL;  pktLength ← pktLength+1;
        IF writeOk1 # NIL
          THEN BEGIN
            stringHeader: Lupine.StringHeader = [
              Lengths[length: writeOk1.length, maxLength: writeOk1.maxlength]];
            Lupine.StubPktDoubleWord[pkt, pktLength]↑ ← stringHeader.all;
            pktLength ← pktLength + 2;
            pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
                dataAdr: BASE[writeOk1.text], dataLength: Lupine.WordsForChars[stringHeader.length],
                alwaysOnePkt: FALSE];
            END;  -- IF writeOk1 # NIL.
        END;  -- Marshal writeOk1↑.
      END;  -- Marshal in.
    BEGIN  -- Marshal out: VARString to pkt.data[pktLength].
      IF pktLength+3 > RpcPrivate.maxDataLength
        THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
      pkt.data[pktLength] ← out=NIL;  pktLength ← pktLength+1;
      IF out # NIL
        THEN BEGIN
          stringHeader: Lupine.StringHeader = [
            Lengths[length: out.length, maxLength: out.maxlength]];
          Lupine.StubPktDoubleWord[pkt, pktLength]↑ ← stringHeader.all;
          pktLength ← pktLength + 2;
          pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
              dataAdr: BASE[out.text], dataLength: Lupine.WordsForChars[stringHeader.length],
              alwaysOnePkt: FALSE];
          END;  -- IF out # NIL.
      END;  -- Marshal out.
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 254, signalHandler: ClientDispatcher];
    pktLength ← 0;
    BEGIN  -- Unmarshal out: VARString from pkt.data[pktLength].
      stringIsNIL: Lupine.NilHeader;
      IF pktLength+3 > RpcPrivate.maxDataLength
        THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
            pktLength];
      stringIsNIL ← pkt.data[pktLength];  pktLength ← pktLength+1;
      IF stringIsNIL # (out=NIL) THEN Lupine.UnmarshalingError;
      IF stringIsNIL
        THEN out ← NIL
        ELSE BEGIN
          stringHeader: Lupine.StringHeader;
          stringHeader.all ← Lupine.StubPktDoubleWord[pkt, pktLength]↑;
          pktLength ← pktLength + 2;
          IF stringHeader.maxLength # out.maxlength THEN Lupine.UnmarshalingError;
          NULL;  -- Call by var or result, use existing string.
          out.length ← stringHeader.length;
          pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
              dataAdr: BASE[out.text], dataLength: Lupine.WordsForChars[stringHeader.length],
              alwaysOnePkt: FALSE];
          END;  -- IF stringIsNIL.
      END;  -- Unmarshal out.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    RETURN[];
    END;  -- StringCopy.

  CharToVariantString: PUBLIC PROCEDURE [char: CHARACTER, length: INTEGER,
      type: StringType, makeNil: BOOLEAN]
    RETURNS [anonP1id1980419: StringSelection] =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← CharToVariantString,
        char (1): CHARACTER, length (2): INTEGER, type (3): StringType,
        makeNil (4): BOOLEAN];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+254] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 5;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt↑ ← [char: char, length: length, type: type, makeNil: makeNil];
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 254, signalHandler: ClientDispatcher];
    pktLength ← 0;
    BEGIN  -- Unmarshal anonP1id1980419: StringSelection from pkt.data[pktLength].
      pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: @anonP1id1980419, dataLength: SIZE[StringSelection],
          alwaysOnePkt: FALSE];
      -- Restore garbled REFs to NIL following copy.
      BEGIN OPEN record: anonP1id1980419;
      WITH variant: record SELECT FROM
        rope =>
          BEGIN OPEN record: variant;
          LOOPHOLE[record.rope, LONG POINTER] ← NIL;
          END;  -- OPEN record: variant.
        text =>
          BEGIN OPEN record: variant;
          LOOPHOLE[record.text, LONG POINTER] ← NIL;
          END;  -- OPEN record: variant.
        ENDCASE => NULL;  -- WITH variant: record.
      END;  -- OPEN record: anonP1id1980419.
      BEGIN OPEN record: anonP1id1980419;
      WITH variant: record SELECT FROM
        rope =>
          BEGIN  -- Unmarshal variant: RECORD [seal: INTEGER, rope:
              -- Rope.ROPE] from pkt.data[pktLength].
            BEGIN OPEN record: variant;
            BEGIN  -- Unmarshal record.rope: Rope.ROPE from pkt.data[pktLength].
              ropeIsNIL: Lupine.NilHeader;
              IF pktLength+2 > RpcPrivate.maxDataLength
                THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
                    pktLength];
              ropeIsNIL ← pkt.data[pktLength];  pktLength ← pktLength+1;
              IF ropeIsNIL
                THEN record.rope ← NIL
                ELSE BEGIN
                  ropeLength: Lupine.RopeHeader;
                  textRope: Rope.Text;
                  ropeLength ← pkt.data[pktLength];  pktLength ← pktLength+1;
                  IF ropeLength > LAST[NAT]
                    THEN Lupine.UnmarshalingError;
                  record.rope ← textRope ← Rope.NewText[size: ropeLength];
                  pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength:
                      pktLength, dataAdr: BASE[DESCRIPTOR[textRope.text]],
                      dataLength: Lupine.WordsForChars[ropeLength], alwaysOnePkt:
                      FALSE];
                  END;  -- IF ropeIsNIL.
              END;  -- Unmarshal record.rope.
            END;  -- OPEN record: variant.
            END;  -- Unmarshal variant.
        text =>
          BEGIN  -- Unmarshal variant: RECORD [text: REF READONLY TEXT,
              -- seal: LONG CARDINAL] from pkt.data[pktLength].
            BEGIN OPEN record: variant;
            BEGIN  -- Unmarshal record.text: REF READONLY TEXT from
                -- pkt.data[pktLength].
              -- Declare readwrite pointer for marshaling readonly
                  -- pointer.
              writeOk4: REF TEXT;
              BEGIN  -- Unmarshal writeOk4↑: TEXT from pkt.data[pktLength].
                stringIsNIL: Lupine.NilHeader;
                IF pktLength+3 > RpcPrivate.maxDataLength
                  THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
                      pktLength];
                stringIsNIL ← pkt.data[pktLength];  pktLength ← pktLength+1;
                IF stringIsNIL
                  THEN writeOk4 ← NIL
                  ELSE BEGIN
                    stringHeader: Lupine.StringHeader;
                    stringHeader.all ← Lupine.StubPktDoubleWord[pkt,
                        pktLength]↑;
                    pktLength ← pktLength + 2;
                    writeOk4 ← (paramZones.gc.NEW[TEXT[stringHeader.maxLength]]);
                    writeOk4.length ← stringHeader.length;
                    pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength:
                        pktLength, dataAdr: BASE[DESCRIPTOR[writeOk4.text]],
                        dataLength: Lupine.WordsForChars[stringHeader.length],
                        alwaysOnePkt: FALSE];
                    END;  -- IF stringIsNIL.
                END;  -- Unmarshal writeOk4↑.
              record.text ← writeOk4;
              END;  -- Unmarshal record.text.
            END;  -- OPEN record: variant.
            END;  -- Unmarshal variant.
        ENDCASE => NULL;  -- WITH variant: record.
      END;  -- OPEN record: anonP1id1980419.
      END;  -- Unmarshal anonP1id1980419.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    RETURN[anonP1id1980419];
    END;  -- CharToVariantString.

  BitsToSequence: PUBLIC PROCEDURE [in: BitDescriptor] RETURNS [out:
      REF READONLY BitSequence] =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← BitsToSequence];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+254] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 1;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt.transferIndex ← BitsToSequence;
    BEGIN  -- Marshal in: BitDescriptor to pkt.data[pktLength].
      IF pktLength+2 > RpcPrivate.maxDataLength
        THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
      Lupine.StubPktDoubleWord[pkt, pktLength]↑ ← (IF BASE[in]=NIL
          THEN 0 ELSE LENGTH[in]);
      pktLength ← pktLength + 2;
      IF BASE[in] # NIL THEN
        pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
            dataAdr: BASE[in], dataLength: SIZE[Bits, LENGTH[in]], alwaysOnePkt:
            FALSE];
      END;  -- Marshal in.
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 254, signalHandler: ClientDispatcher];
    pktLength ← 0;
    BEGIN  -- Unmarshal out: REF READONLY BitSequence from pkt.data[pktLength].
      -- Declare readwrite pointer for marshaling readonly pointer.
      writeOk1: REF BitSequence;
      BEGIN  -- Unmarshal writeOk1↑: BitSequence from pkt.data[pktLength].
        recordIsNIL: Lupine.NilHeader;
        IF pktLength+3 > RpcPrivate.maxDataLength
          THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
              pktLength];
        recordIsNIL ← pkt.data[pktLength];  pktLength ← pktLength+1;
        IF recordIsNIL
          THEN writeOk1 ← NIL
          ELSE BEGIN
            seqLength: Lupine.SequenceHeader;
            seqLength ← Lupine.StubPktDoubleWord[pkt, pktLength]↑;
            pktLength ← pktLength + 2;
            writeOk1 ← (paramZones.gc.NEW[BitSequence[Lupine.SHORT[seqLength]]]);
            pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
                dataAdr: LOOPHOLE[writeOk1], dataLength: SIZE[BitSequence[LENGTH[DESCRIPTOR[writeOk1↑]]]],
                alwaysOnePkt: FALSE];
            END;  -- IF recordIsNIL.
        END;  -- Unmarshal writeOk1↑.
      out ← writeOk1;
      END;  -- Unmarshal out.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    RETURN[out];
    END;  -- BitsToSequence.

  StringsToAtoms: PUBLIC PROCEDURE [in: StringList] RETURNS [out: AtomList]
      =
    BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex ← StringsToAtoms];
    pktBuffer: ARRAY [1..RpcPrivate.pktOverhead+254] OF WORD;
    pkt: RpcPrivate.StubPkt = RpcPrivate.GetStubPkt[space: @pktBuffer];
    argPkt: POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 1;
    lastPkt: BOOLEAN;
    RpcPrivate.StartCall[callPkt: pkt, interface: myInterface];
    argPkt.transferIndex ← StringsToAtoms;
    BEGIN  -- Marshal in: StringList to pkt.data[pktLength].
      IF pktLength+2 > RpcPrivate.maxDataLength
        THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
      Lupine.StubPktDoubleWord[pkt, pktLength]↑ ← (IF BASE[in]=NIL
          THEN 0 ELSE LENGTH[in]);
      pktLength ← pktLength + 2;
      IF BASE[in] # NIL THEN
        FOR element1: CARDINAL IN [FIRST[CARDINAL]..FIRST[CARDINAL]+LENGTH[in])
            DO
          BEGIN  -- Marshal in[element1]: LONG STRING to pkt.data[pktLength].
            IF pktLength+3 > RpcPrivate.maxDataLength
              THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength:
                  pktLength];
            pkt.data[pktLength] ← in[element1]=NIL;  pktLength ← pktLength+1;
            IF in[element1] # NIL
              THEN BEGIN
                stringHeader: Lupine.StringHeader = [
                  Lengths[length: in[element1].length, maxLength: in[element1].maxlength]];
                Lupine.StubPktDoubleWord[pkt, pktLength]↑ ← stringHeader.all;
                pktLength ← pktLength + 2;
                pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
                    dataAdr: BASE[in[element1].text], dataLength: Lupine.WordsForChars[stringHeader.length],
                    alwaysOnePkt: FALSE];
                END;  -- IF in[element1] # NIL.
            END;  -- Marshal in[element1].
          ENDLOOP;  -- FOR element1.
      END;  -- Marshal in.
    [returnLength: , lastPkt: lastPkt] ←
      RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
          maxReturnLength: 254, signalHandler: ClientDispatcher];
    pktLength ← 0;
    BEGIN  -- Unmarshal out: AtomList from pkt.data[pktLength].
      lastNode: AtomList ← (out ← NIL);
      listLength: Lupine.ListHeader;
      IF pktLength+2 > RpcPrivate.maxDataLength
        THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
            pktLength];
      listLength ← Lupine.StubPktDoubleWord[pkt, pktLength]↑;
      pktLength ← pktLength + 2;
      WHILE listLength > 0 DO
        thisNode1: AtomList = paramZones.gc.CONS[--DefaultValue--,NIL];
        BEGIN  -- Unmarshal thisNode1.first: ATOM from pkt.data[pktLength].
          pNameOfAtom: Rope.ROPE;
          ropeIsNIL: Lupine.NilHeader;
          IF pktLength+2 > RpcPrivate.maxDataLength
            THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
                pktLength];
          ropeIsNIL ← pkt.data[pktLength];  pktLength ← pktLength+1;
          IF ropeIsNIL
            THEN pNameOfAtom ← NIL
            ELSE BEGIN
              ropeLength: Lupine.RopeHeader;
              textRope: Rope.Text;
              ropeLength ← pkt.data[pktLength];  pktLength ← pktLength+1;
              IF ropeLength > LAST[NAT]
                THEN Lupine.UnmarshalingError;
              pNameOfAtom ← textRope ← Rope.NewText[size: ropeLength];
              pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
                  dataAdr: BASE[DESCRIPTOR[textRope.text]], dataLength:
                  Lupine.WordsForChars[ropeLength], alwaysOnePkt: FALSE];
              END;  -- IF ropeIsNIL.
          thisNode1.first ← Atom.MakeAtom[--pName:-- pNameOfAtom];
          END;  -- Unmarshal thisNode1.first.
        IF lastNode # NIL
          THEN lastNode ← (lastNode.rest ← thisNode1)
          ELSE lastNode ← (out ← thisNode1);
        listLength ← listLength - 1;
        ENDLOOP;  -- WHILE listLength > 0.
      END;  -- Unmarshal out.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    RETURN[out];
    END;  -- StringsToAtoms.


--Remote public signals and errors are imported from the interface.


-- Public signal and error dispatcher.

  ClientDispatcher: --PROCEDURE [pkt: RPCPkt, callLength: DataLength,
      -- lastPkt: BOOLEAN, localConversation: Conversation] RETURNS [returnLength:
      -- DataLength]-- RpcPrivate.Dispatcher =
    BEGIN

    SELECT LOOPHOLE[pkt.data[0], RpcControl.SignalIndex] FROM
      Signal => RETURN[
        SignalStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      PuntStringsToAtoms => RETURN[
        PuntStringsToAtomsStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      ENDCASE => RETURN[Lupine.DispatchingError[]];

    END;  -- ClientDispatcher


-- Public signal and error dispatcher stubs.

  SignalStub: --SIGNAL [in: INTEGER] RETURNS [out: INTEGER]-- RpcPrivate.Dispatcher
      =
    INLINE BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.SignalIndex, in (1): INTEGER];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        out (0): INTEGER];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 2];
    [resPkt.out] ← SIGNAL Signal[argPkt.in];
    pktLength ← 1;
    RETURN[returnLength: pktLength];
    END;  -- SignalStub.

  PuntStringsToAtomsStub: --SIGNAL-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 1];
    SIGNAL PuntStringsToAtoms[];
    pktLength ← 0;
    RETURN[returnLength: pktLength];
    END;  -- PuntStringsToAtomsStub.


-- No module initialization.

END.  -- LupineMarshalTestRpcClientImpl.