-- 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 [EncryptionKey, InterfaceName, Principal, standardZones,
      Zones],
  RPCLupine --USING SOME OF [Call, DataLength, Dispatcher, ExportHandle,
      -- ExportInterface, GetStubPkt, maxDataLength, maxPrincipalLength,
      -- maxShortStringLength, pktOverhead, ReceiveExtraPkt, SendPrelimPkt,
      -- StartCall, StartSignal, StubPkt, UnexportInterface]--,
  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]--;


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


-- Standard remote binding routines.

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

  ExportInterface: PUBLIC ENTRY SAFE PROCEDURE [
        interfaceName: RpcPublic.InterfaceName,
        user: RpcPublic.Principal,
        password: RpcPublic.EncryptionKey,
        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.ExportInterface [
      interface: [
        type: IF ~IsNull[interfaceName.type]
          THEN interfaceName.type ELSE "LupineMarshalTest~234#313#4263372323",
        instance: interfaceName.instance,
        version: interfaceName.version ],
      user: user,  password: password,
      dispatcher: ServerDispatcher,
      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;

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


-- Public procedure dispatcher and public signal and error catcher.

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

    -- Catch public signals.

      ENABLE BEGIN

      Signal --SIGNAL [in: INTEGER] RETURNS [out: INTEGER]-- =>
        BEGIN
        ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
            transferIndex (0): RpcControl.SignalIndex ← Signal, 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 ← 2;
        lastPkt: BOOLEAN;
        RpcPrivate.StartSignal[signalPkt: pkt];
        argPkt↑ ← [in: in];
        [returnLength: , lastPkt: lastPkt] ←
          RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
              maxReturnLength: 1];
        Lupine.CheckPktLength[pkt: pkt, pktLength: 1];
        RESUME[resPkt.out];
        END;  -- Signal.

      PuntStringsToAtoms --SIGNAL-- =>
        BEGIN
        ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
            transferIndex (0): RpcControl.SignalIndex ← PuntStringsToAtoms];
        argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
        pktLength: RpcPrivate.DataLength ← 1;
        lastPkt: BOOLEAN;
        RpcPrivate.StartSignal[signalPkt: pkt];
        argPkt.transferIndex ← PuntStringsToAtoms;
        [returnLength: , lastPkt: lastPkt] ←
          RpcPrivate.Call[ pkt: pkt, callLength: pktLength,
              maxReturnLength: 0];
        Lupine.CheckPktLength[pkt: pkt, pktLength: 0];
        RESUME[];
        END;  -- PuntStringsToAtoms.

      END;  -- Catch public signals.


    -- Call public procedures (still in dispatcher).

    SELECT LOOPHOLE[pkt.data[0], RpcControl.ProcedureIndex] FROM
      Null => RETURN[
        NullStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      One => RETURN[
        OneStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      Four => RETURN[
        FourStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      Ten => RETURN[
        TenStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      SignalTest => RETURN[
        SignalTestStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      TenArray => RETURN[
        TenArrayStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      FortyArray => RETURN[
        FortyArrayStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      HundredArray => RETURN[
        HundredArrayStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      SimpleArithmetic => RETURN[
        SimpleArithmeticStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      FillArray => RETURN[
        FillArrayStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      ReadPages => RETURN[
        ReadPagesStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      CreateList => RETURN[
        CreateListStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      StringCopy => RETURN[
        StringCopyStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      CharToVariantString => RETURN[
        CharToVariantStringStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      BitsToSequence => RETURN[
        BitsToSequenceStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      StringsToAtoms => RETURN[
        StringsToAtomsStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      ENDCASE => RETURN[Lupine.DispatchingError[]];

    END;  -- ServerDispatcher


-- Public procedure dispatcher stubs.

  NullStub: --PROCEDURE-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 1];
    Null[];
    pktLength ← 0;
    RETURN[returnLength: pktLength];
    END;  -- NullStub.

  OneStub: --PROCEDURE [one: INTEGER] RETURNS [a: INTEGER]-- RpcPrivate.Dispatcher
      =
    INLINE BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, one (1): INTEGER];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        a (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.a] ← One[argPkt.one];
    pktLength ← 1;
    RETURN[returnLength: pktLength];
    END;  -- OneStub.

  FourStub: --PROCEDURE [one: INTEGER, two: INTEGER, three: INTEGER,
      -- four: INTEGER]
    -- RETURNS [a: INTEGER, b: INTEGER, c: INTEGER, d: INTEGER]-- RpcPrivate.Dispatcher
        =
    INLINE BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, 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];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 5];
    [resPkt.a, resPkt.b, resPkt.c, resPkt.d] ←
      Four[argPkt.one, argPkt.two, argPkt.three, argPkt.four];
    pktLength ← 4;
    RETURN[returnLength: pktLength];
    END;  -- FourStub.

  TenStub: --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]-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, 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];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 11];
    [resPkt.a, resPkt.b, resPkt.c, resPkt.d, resPkt.e, resPkt.f, resPkt.g,
        resPkt.h, resPkt.i, resPkt.j] ←
      Ten[argPkt.one, argPkt.two, argPkt.three, argPkt.four, argPkt.five,
          argPkt.six, argPkt.seven, argPkt.eight, argPkt.nine, argPkt.ten];
    pktLength ← 10;
    RETURN[returnLength: pktLength];
    END;  -- TenStub.

  SignalTestStub: --PROCEDURE [in: INTEGER, action: SignalAction] RETURNS
      -- [out: INTEGER]-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, in (1): INTEGER,
        action (2): SignalAction];
    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: 3];
    [resPkt.out] ← SignalTest[argPkt.in, argPkt.action];
    pktLength ← 1;
    RETURN[returnLength: pktLength];
    END;  -- SignalTestStub.

  TenArrayStub: --PROCEDURE [in: Array10] RETURNS [out: Array10]--
      RpcPrivate.Dispatcher =
    INLINE BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, in (1): Array10];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        out (0): Array10];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 11];
    [resPkt.out] ← TenArray[argPkt.in];
    pktLength ← 10;
    RETURN[returnLength: pktLength];
    END;  -- TenArrayStub.

  FortyArrayStub: --PROCEDURE [in: Array40] RETURNS [out: Array40]--
      RpcPrivate.Dispatcher =
    INLINE BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, in (1): Array40];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        out (0): Array40];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 41];
    [resPkt.out] ← FortyArray[argPkt.in];
    pktLength ← 40;
    RETURN[returnLength: pktLength];
    END;  -- FortyArrayStub.

  HundredArrayStub: --PROCEDURE [in: Array100] RETURNS [out: Array100]--
      RpcPrivate.Dispatcher =
    INLINE BEGIN
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, in (1): Array100];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        out (0): Array100];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 101];
    [resPkt.out] ← HundredArray[argPkt.in];
    pktLength ← 100;
    RETURN[returnLength: pktLength];
    END;  -- HundredArrayStub.

  SimpleArithmeticStub: --PROCEDURE [pad: VARArithmetic]-- RpcPrivate.Dispatcher
      =
    INLINE BEGIN
    pad: VARArithmetic;
    pktLength: RpcPrivate.DataLength ← 1;
    MaxHeapAllocs: CARDINAL = 1;
    heapAllocVector: ARRAY [1..MaxHeapAllocs] OF LONG POINTER←ALL[NIL];
    BEGIN ENABLE UNWIND => BEGIN  -- Free storage.
        FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
          IF heapAllocVector[ptr] = NIL
            THEN EXIT
            ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
          ENDLOOP;
        END;  -- Free storage.
      BEGIN  -- Unmarshal pad: VARArithmetic from pkt.data[pktLength].
        isNIL: Lupine.NilHeader;
        isNIL ← pkt.data[pktLength];  pktLength ← pktLength+1;
        IF isNIL
          THEN pad ← NIL
          ELSE BEGIN
            pad ← (heapAllocVector[1] ← paramZones.heap.NEW[ArithmeticRecord]);
            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;  -- IF isNIL.
        END;  -- Unmarshal pad.
      Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
      SimpleArithmetic[pad];
      pktLength ← 0;
      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.
      END;  -- ENABLE UNWIND => Free storage.
    FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
      IF heapAllocVector[ptr] = NIL
        THEN EXIT
        ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
      ENDLOOP;
    RETURN[returnLength: pktLength];
    END;  -- SimpleArithmeticStub.

  FillArrayStub: --PROCEDURE [in: INTEGER, out: RESULTArray]-- RpcPrivate.Dispatcher
      =
    INLINE BEGIN
    out: RESULTArray;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, in (1): INTEGER];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 2;
    MaxHeapAllocs: CARDINAL = 1;
    heapAllocVector: ARRAY [1..MaxHeapAllocs] OF LONG POINTER←ALL[NIL];
    BEGIN ENABLE UNWIND => BEGIN  -- Free storage.
        FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
          IF heapAllocVector[ptr] = NIL
            THEN EXIT
            ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
          ENDLOOP;
        END;  -- Free storage.
      BEGIN  -- Unmarshal out: RESULTArray from pkt.data[pktLength].
        DescriptorType: TYPE = RECORD [SEQUENCE COMPUTED CARDINAL OF
            INTEGER];
        descLength: Lupine.SequenceHeader;
        descLength ← Lupine.RpcPktDoubleWord[pkt, pktLength]↑;
        pktLength ← pktLength + 2;
        out ← DESCRIPTOR[
          (heapAllocVector[1] ← paramZones.heap.NEW[DescriptorType[Lupine.SHORT[descLength]]]),
          Lupine.SHORT[descLength]];
        NULL;  -- Call by result, use uninitialized descriptor.
        END;  -- Unmarshal out.
      Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
      FillArray[argPkt.in, out];
      pktLength ← 0;
      BEGIN  -- Marshal out: RESULTArray to pkt.data[pktLength].
        IF pktLength+2 > RpcPrivate.maxDataLength
          THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength:
              pktLength];
        Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ← (IF BASE[out]=NIL
            THEN 0 ELSE LENGTH[out]);
        pktLength ← pktLength + 2;
        IF BASE[out] # NIL THEN
          pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
              dataAdr: BASE[out], dataLength: SIZE[INTEGER]*LENGTH[out],
              alwaysOnePkt: FALSE];
        END;  -- Marshal out.
      END;  -- ENABLE UNWIND => Free storage.
    FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
      IF heapAllocVector[ptr] = NIL
        THEN EXIT
        ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
      ENDLOOP;
    RETURN[returnLength: pktLength];
    END;  -- FillArrayStub.

  ReadPagesStub: --PROCEDURE [item: Item, buffer: RESULTPages]-- RpcPrivate.Dispatcher
      =
    INLINE BEGIN
    buffer: RESULTPages;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, item (1): Item];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 2;
    MaxHeapAllocs: CARDINAL = 1;
    heapAllocVector: ARRAY [1..MaxHeapAllocs] OF LONG POINTER←ALL[NIL];
    BEGIN ENABLE UNWIND => BEGIN  -- Free storage.
        FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
          IF heapAllocVector[ptr] = NIL
            THEN EXIT
            ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
          ENDLOOP;
        END;  -- Free storage.
      BEGIN  -- Unmarshal buffer: RESULTPages from pkt.data[pktLength].
        DescriptorType: TYPE = RECORD [SEQUENCE COMPUTED CARDINAL OF
            Item];
        descLength: Lupine.SequenceHeader;
        descLength ← Lupine.RpcPktDoubleWord[pkt, pktLength]↑;
        pktLength ← pktLength + 2;
        buffer ← DESCRIPTOR[
          (heapAllocVector[1] ← paramZones.heap.NEW[DescriptorType[Lupine.SHORT[descLength]]]),
          Lupine.SHORT[descLength]];
        NULL;  -- Call by result, use uninitialized descriptor.
        END;  -- Unmarshal buffer.
      Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
      ReadPages[argPkt.item, buffer];
      pktLength ← 0;
      BEGIN  -- Marshal buffer: RESULTPages to pkt.data[pktLength].
        IF pktLength+2 > RpcPrivate.maxDataLength
          THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength:
              pktLength];
        Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ← (IF BASE[buffer]=NIL
            THEN 0 ELSE LENGTH[buffer]);
        pktLength ← pktLength + 2;
        IF BASE[buffer] # NIL THEN
          pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
              dataAdr: BASE[buffer], dataLength: SIZE[Item]*LENGTH[buffer],
              alwaysOnePkt: FALSE];
        END;  -- Marshal buffer.
      END;  -- ENABLE UNWIND => Free storage.
    FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
      IF heapAllocVector[ptr] = NIL
        THEN EXIT
        ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
      ENDLOOP;
    RETURN[returnLength: pktLength];
    END;  -- ReadPagesStub.

  CreateListStub: --PROCEDURE [in: LONG INTEGER, length: INTEGER] RETURNS
      -- [out: IntList]-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    out: IntList;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, in (1): LONG INTEGER,
        length (3): INTEGER];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 4];
    [out] ← CreateList[argPkt.in, argPkt.length];
    pktLength ← 0;
    BEGIN  -- Marshal out: IntList to pkt.data[pktLength].
      -- Declare readwrite pointer for marshaling readonly pointer.
      writeOk1: LIST OF LONG INTEGER = LOOPHOLE[out];
      thisNode1: LIST OF LONG INTEGER;
      listLength: Lupine.ListHeader ← 0;
      FOR thisNode1 ← writeOk1, thisNode1.rest UNTIL thisNode1 = NIL
          DO
        listLength ← listLength + 1;  ENDLOOP;
      IF pktLength+2 > RpcPrivate.maxDataLength
        THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
      Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ← listLength;
      pktLength ← pktLength + 2;
      FOR thisNode1 ← writeOk1, thisNode1.rest UNTIL thisNode1 = NIL
          DO
        BEGIN
        IF pktLength+2 > RpcPrivate.maxDataLength
          THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength:
              pktLength];
        Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ← thisNode1.first;
        pktLength ← pktLength + 2;
        END;
        ENDLOOP;  -- FOR thisNode1.
      END;  -- Marshal out.
    RETURN[returnLength: pktLength];
    END;  -- CreateListStub.

  StringCopyStub: --PROCEDURE [in: ReadonlyString, out: VARString]--
      RpcPrivate.Dispatcher =
    INLINE BEGIN
    in: ReadonlyString;
    out: VARString;
    pktLength: RpcPrivate.DataLength ← 1;
    MaxHeapAllocs: CARDINAL = 1;
    heapAllocVector: ARRAY [1..MaxHeapAllocs] OF LONG POINTER←ALL[NIL];
    MaxMdsAllocs: CARDINAL = 1;
    mdsAllocVector: ARRAY [1..MaxMdsAllocs] OF POINTER←ALL[NIL];
    BEGIN ENABLE UNWIND => BEGIN  -- Free storage.
        FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
          IF heapAllocVector[ptr] = NIL
            THEN EXIT
            ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
          ENDLOOP;
        FOR ptr: CARDINAL IN [1..LENGTH[mdsAllocVector]] DO
          IF mdsAllocVector[ptr] = NIL
            THEN EXIT
            ELSE paramZones.mds.FREE[@mdsAllocVector[ptr]];
          ENDLOOP;
        END;  -- Free storage.
      BEGIN  -- Unmarshal in: ReadonlyString from pkt.data[pktLength].
        -- Declare readwrite pointer for marshaling readonly pointer.
        writeOk1: LONG POINTER TO StringBody;
        BEGIN  -- Unmarshal writeOk1↑: StringBody 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 writeOk1 ← NIL
            ELSE BEGIN
              stringHeader: Lupine.StringHeader;
              stringHeader.all ← Lupine.RpcPktDoubleWord[pkt, pktLength]↑;
              pktLength ← pktLength + 2;
              writeOk1 ← (heapAllocVector[1] ← paramZones.heap.NEW[StringBody[stringHeader.maxLength]]);
              writeOk1.length ← stringHeader.length;
              pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
                  dataAdr: BASE[writeOk1.text], dataLength: Lupine.WordsForChars[stringHeader.length],
                  alwaysOnePkt: FALSE];
              END;  -- IF stringIsNIL.
          END;  -- Unmarshal writeOk1↑.
        in ← writeOk1;
        END;  -- Unmarshal in.
      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
          THEN out ← NIL
          ELSE BEGIN
            stringHeader: Lupine.StringHeader;
            stringHeader.all ← Lupine.RpcPktDoubleWord[pkt, pktLength]↑;
            pktLength ← pktLength + 2;
            out ← (mdsAllocVector[1] ← paramZones.mds.NEW[StringBody[stringHeader.maxLength]]);
            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];
      StringCopy[in, out];
      pktLength ← 0;
      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.RpcPktDoubleWord[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.
      END;  -- ENABLE UNWIND => Free storage.
    FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
      IF heapAllocVector[ptr] = NIL
        THEN EXIT
        ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
      ENDLOOP;
    FOR ptr: CARDINAL IN [1..LENGTH[mdsAllocVector]] DO
      IF mdsAllocVector[ptr] = NIL
        THEN EXIT
        ELSE paramZones.mds.FREE[@mdsAllocVector[ptr]];
      ENDLOOP;
    RETURN[returnLength: pktLength];
    END;  -- StringCopyStub.

  CharToVariantStringStub: --PROCEDURE [char: CHARACTER, length: INTEGER,
      -- type: StringType, makeNil: BOOLEAN]
    -- RETURNS [anonP1id1980419: StringSelection]-- RpcPrivate.Dispatcher
        =
    INLINE BEGIN
    anonP1id1980419: StringSelection;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, char (1): CHARACTER,
        length (2): INTEGER, type (3): StringType, makeNil (4): BOOLEAN];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 5];
    [anonP1id1980419] ← CharToVariantString[argPkt.char, argPkt.length,
        argPkt.type, argPkt.makeNil];
    pktLength ← 0;
    BEGIN  -- Marshal anonP1id1980419: StringSelection to pkt.data[pktLength].
      pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: @anonP1id1980419, dataLength: SIZE[StringSelection],
          alwaysOnePkt: FALSE];
      BEGIN OPEN record: anonP1id1980419;
      WITH variant: record SELECT FROM
        rope =>
          BEGIN  -- Marshal variant: RECORD [seal: INTEGER, rope: Rope.ROPE]
              -- to pkt.data[pktLength].
            BEGIN OPEN record: variant;
            BEGIN  -- Marshal record.rope: Rope.ROPE to pkt.data[pktLength].
              IF pktLength+2 > RpcPrivate.maxDataLength
                THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength:
                    pktLength];
              pkt.data[pktLength] ← record.rope=NIL;  pktLength ← pktLength+1;
              IF record.rope # NIL
                THEN BEGIN
                  textRope: Rope.Text = Rope.InlineFlatten[r: record.rope];
                  pkt.data[pktLength] ← textRope.length;  pktLength
                      ← pktLength+1;
                  pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength:
                      pktLength, dataAdr: BASE[DESCRIPTOR[textRope.text]],
                      dataLength: Lupine.WordsForChars[textRope.length],
                      alwaysOnePkt: FALSE];
                  END;  -- IF record.rope # NIL.
              END;  -- Marshal record.rope.
            END;  -- OPEN record: variant.
            END;  -- Marshal variant.
        text =>
          BEGIN  -- Marshal variant: RECORD [text: REF READONLY TEXT,
              -- seal: LONG CARDINAL] to pkt.data[pktLength].
            BEGIN OPEN record: variant;
            BEGIN  -- Marshal record.text: REF READONLY TEXT to pkt.data[pktLength].
              -- Declare readwrite pointer for marshaling readonly
                  -- pointer.
              writeOk4: REF TEXT = LOOPHOLE[record.text];
              BEGIN  -- Marshal writeOk4↑: TEXT to pkt.data[pktLength].
                IF pktLength+3 > RpcPrivate.maxDataLength
                  THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength:
                      pktLength];
                pkt.data[pktLength] ← writeOk4=NIL;  pktLength ← pktLength+1;
                IF writeOk4 # NIL
                  THEN BEGIN
                    stringHeader: Lupine.StringHeader = [
                      Lengths[length: writeOk4.length, maxLength: writeOk4.maxLength]];
                    Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ← stringHeader.all;
                    pktLength ← pktLength + 2;
                    pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength:
                        pktLength, dataAdr: BASE[DESCRIPTOR[writeOk4.text]],
                        dataLength: Lupine.WordsForChars[stringHeader.length],
                        alwaysOnePkt: FALSE];
                    END;  -- IF writeOk4 # NIL.
                END;  -- Marshal writeOk4↑.
              END;  -- Marshal record.text.
            END;  -- OPEN record: variant.
            END;  -- Marshal variant.
        ENDCASE => NULL;  -- WITH variant: record.
      END;  -- OPEN record: anonP1id1980419.
      END;  -- Marshal anonP1id1980419.
    RETURN[returnLength: pktLength];
    END;  -- CharToVariantStringStub.

  BitsToSequenceStub: --PROCEDURE [in: BitDescriptor] RETURNS [out:
      -- REF READONLY BitSequence]-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    in: BitDescriptor;
    out: REF READONLY BitSequence;
    pktLength: RpcPrivate.DataLength ← 1;
    MaxHeapAllocs: CARDINAL = 1;
    heapAllocVector: ARRAY [1..MaxHeapAllocs] OF LONG POINTER←ALL[NIL];
    BEGIN ENABLE UNWIND => BEGIN  -- Free storage.
        FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
          IF heapAllocVector[ptr] = NIL
            THEN EXIT
            ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
          ENDLOOP;
        END;  -- Free storage.
      BEGIN  -- Unmarshal in: BitDescriptor from pkt.data[pktLength].
        DescriptorType: TYPE = RECORD [PACKED SEQUENCE COMPUTED CARDINAL
            OF Bits];
        descLength: Lupine.SequenceHeader;
        IF pktLength+2 > RpcPrivate.maxDataLength
          THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
              pktLength];
        descLength ← Lupine.RpcPktDoubleWord[pkt, pktLength]↑;
        pktLength ← pktLength + 2;
        in ← DESCRIPTOR[
          (heapAllocVector[1] ← paramZones.heap.NEW[DescriptorType[Lupine.SHORT[descLength]]]),
          Lupine.SHORT[descLength]];
        pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
            dataAdr: BASE[in], dataLength: SIZE[Bits, LENGTH[in]], alwaysOnePkt:
            FALSE];
        END;  -- Unmarshal in.
      Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
      [out] ← BitsToSequence[in];
      pktLength ← 0;
      BEGIN  -- Marshal out: REF READONLY BitSequence to pkt.data[pktLength].
        -- Declare readwrite pointer for marshaling readonly pointer.
        writeOk1: REF BitSequence = LOOPHOLE[out];
        BEGIN  -- Marshal writeOk1↑: BitSequence 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
            -- Record has a sequence, put its length up front.
            Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ← LENGTH[DESCRIPTOR[writeOk1↑]];
            pktLength ← pktLength + 2;
            pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
                dataAdr: LOOPHOLE[writeOk1], dataLength: SIZE[BitSequence[LENGTH[DESCRIPTOR[writeOk1↑]]]],
                alwaysOnePkt: FALSE];
            END;  -- IF writeOk1 # NIL.
          END;  -- Marshal writeOk1↑.
        END;  -- Marshal out.
      END;  -- ENABLE UNWIND => Free storage.
    FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
      IF heapAllocVector[ptr] = NIL
        THEN EXIT
        ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
      ENDLOOP;
    RETURN[returnLength: pktLength];
    END;  -- BitsToSequenceStub.

  StringsToAtomsStub: --PROCEDURE [in: StringList] RETURNS [out: AtomList]--
      RpcPrivate.Dispatcher =
    INLINE BEGIN
    in: StringList;
    out: AtomList;
    pktLength: RpcPrivate.DataLength ← 1;
    MaxHeapAllocs: CARDINAL = 51;
    heapAllocs: CARDINAL ← 0;
    heapAllocVector: ARRAY [1..MaxHeapAllocs] OF LONG POINTER←ALL[NIL];
    MaxMdsAllocs: CARDINAL = 1;
    mdsAllocVector: ARRAY [1..MaxMdsAllocs] OF POINTER←ALL[NIL];
    BEGIN ENABLE UNWIND => BEGIN  -- Free storage.
        FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
          IF heapAllocVector[ptr] = NIL
            THEN EXIT
            ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
          ENDLOOP;
        FOR ptr: CARDINAL IN [1..LENGTH[mdsAllocVector]] DO
          IF mdsAllocVector[ptr] = NIL
            THEN EXIT
            ELSE paramZones.mds.FREE[@mdsAllocVector[ptr]];
          ENDLOOP;
        END;  -- Free storage.
      BEGIN  -- Unmarshal in: StringList from pkt.data[pktLength].
        DescriptorType: TYPE = RECORD [SEQUENCE COMPUTED CARDINAL OF
            LONG STRING];
        descLength: Lupine.SequenceHeader;
        IF pktLength+2 > RpcPrivate.maxDataLength
          THEN pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength:
              pktLength];
        descLength ← Lupine.RpcPktDoubleWord[pkt, pktLength]↑;
        pktLength ← pktLength + 2;
        in ← DESCRIPTOR[
          (mdsAllocVector[1] ← paramZones.mds.NEW[DescriptorType[Lupine.SHORT[descLength]]]),
          Lupine.SHORT[descLength]];
        FOR element1: CARDINAL IN [FIRST[CARDINAL]..FIRST[CARDINAL]+LENGTH[in])
            DO
          BEGIN  -- Unmarshal in[element1]: LONG STRING 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 in[element1] ← NIL
              ELSE BEGIN
                stringHeader: Lupine.StringHeader;
                stringHeader.all ← Lupine.RpcPktDoubleWord[pkt, pktLength]↑;
                pktLength ← pktLength + 2;
                in[element1] ← (heapAllocVector[(IF (heapAllocs ← heapAllocs+1)
                    <= MaxHeapAllocs THEN heapAllocs ELSE Lupine.UnmarshalingExprError[])]
                    ← paramZones.heap.NEW[StringBody[stringHeader.maxLength]]);
                in[element1].length ← stringHeader.length;
                pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength:
                    pktLength, dataAdr: BASE[in[element1].text], dataLength:
                    Lupine.WordsForChars[stringHeader.length], alwaysOnePkt:
                    FALSE];
                END;  -- IF stringIsNIL.
            END;  -- Unmarshal in[element1].
          ENDLOOP;  -- FOR element1.
        END;  -- Unmarshal in.
      Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
      [out] ← StringsToAtoms[in];
      pktLength ← 0;
      BEGIN  -- Marshal out: AtomList to pkt.data[pktLength].
        thisNode1: AtomList;
        listLength: Lupine.ListHeader ← 0;
        FOR thisNode1 ← out, thisNode1.rest UNTIL thisNode1 = NIL DO
          listLength ← listLength + 1;  ENDLOOP;
        IF pktLength+2 > RpcPrivate.maxDataLength
          THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength:
              pktLength];
        Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ← listLength;
        pktLength ← pktLength + 2;
        FOR thisNode1 ← out, thisNode1.rest UNTIL thisNode1 = NIL DO
          BEGIN  -- Marshal thisNode1.first: ATOM to pkt.data[pktLength].
            pNameOfAtom: Rope.Text = Atom.GetPName[atom: thisNode1.first];
            IF pktLength+2 > RpcPrivate.maxDataLength
              THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength:
                  pktLength];
            pkt.data[pktLength] ← pNameOfAtom=NIL;  pktLength ← pktLength+1;
            IF pNameOfAtom # NIL
              THEN BEGIN
                textRope: Rope.Text = Rope.InlineFlatten[r: pNameOfAtom];
                pkt.data[pktLength] ← textRope.length;  pktLength ←
                    pktLength+1;
                pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
                    dataAdr: BASE[DESCRIPTOR[textRope.text]], dataLength:
                    Lupine.WordsForChars[textRope.length], alwaysOnePkt:
                    FALSE];
                END;  -- IF pNameOfAtom # NIL.
            END;  -- Marshal thisNode1.first.
          ENDLOOP;  -- FOR thisNode1.
        END;  -- Marshal out.
      END;  -- ENABLE UNWIND => Free storage.
    FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
      IF heapAllocVector[ptr] = NIL
        THEN EXIT
        ELSE paramZones.heap.FREE[@heapAllocVector[ptr]];
      ENDLOOP;
    FOR ptr: CARDINAL IN [1..LENGTH[mdsAllocVector]] DO
      IF mdsAllocVector[ptr] = NIL
        THEN EXIT
        ELSE paramZones.mds.FREE[@mdsAllocVector[ptr]];
      ENDLOOP;
    RETURN[returnLength: pktLength];
    END;  -- StringsToAtomsStub.


-- No module initialization.

END.  -- LupineMarshalTestRpcServerImpl.