-- Copyright (C) 1985 by Xerox Corporation.  All rights reserved.
-- Stub file  was translated on June 22, 1985 9:34:12 pm PDT by Lupine of May 23, 1985 8:38:08 am PDT
-- Source interface CedarNSPrint came from file CedarNSPrint.bcd, which was created on June 22, 1985 9:34:02 pm PDT with version stamp 14#21#26004275173 from source of June 22, 1985 9:31:11 pm PDT.

-- The RPC stub modules for CedarNSPrint are:
--   CedarNSPrintRpcControl.mesa;
--   CedarNSPrintRpcClientImpl.mesa;
--   CedarNSPrintRpcBinderImpl.mesa;
--   CedarNSPrintRpcServerImpl.mesa.

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


DIRECTORY
  CedarNSPrint,
  CedarNSPrintRpcControl USING [
    InterMdsCallsOnly, LupineProtocolVersion, ProcedureIndex, SignalIndex],
  MesaRPC USING [EncryptionKey, InterfaceName, Principal, standardZones, Zones],
  MesaRPCLupine  --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, MarshalAtom, MarshalRope, NilHeader, ProtocolError,
  -- RopeHeader, RpcPktDoubleWord, RuntimeError, SequenceHeader, SHORT,
  -- StartNextPkt, StringHeader, StubPktDoubleWord, TranslationError,
  -- UnmarshalingError, UnmarshalingExprError, UnmarshalAtom, UnmarshalRope,
  -- WordsForChars]-- ;


CedarNSPrintRpcServerImpl: MONITOR
  IMPORTS CedarNSPrint, RpcPrivate: MesaRPCLupine, Lupine: LupineRuntime
  EXPORTS CedarNSPrintRpcControl
  SHARES CedarNSPrint, CedarNSPrintRpcControl =
  BEGIN
  OPEN CedarNSPrint, RpcControl: CedarNSPrintRpcControl, RpcPublic: MesaRPC;


  -- Standard remote binding routines.

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

  ExportInterface: PUBLIC ENTRY PROCEDURE [
    interfaceName: RpcPublic.InterfaceName, user: RpcPublic.Principal,
    password: RpcPublic.EncryptionKey, parameterStorage: RpcPublic.Zones] =
    BEGIN
    ENABLE UNWIND => NULL;
    IsNull: PROCEDURE [string: LONG STRING] RETURNS [BOOLEAN] = INLINE {
      RETURN[string = NIL OR string.length = 0]};
    IF bound THEN Lupine.BindingError;
    myInterface ← RpcPrivate.ExportInterface[
      interface: [
      type:
      IF ~IsNull[interfaceName.type] THEN interfaceName.type
      ELSE "CedarNSPrint~14#21#26004275173", 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 PROCEDURE =
    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

      Error --ERROR [why: ErrorRecord]-- =>
        BEGIN
        ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
          transferIndex(0): RpcControl.SignalIndex ← Error,
          why(1): ErrorRecord];
        argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
        pktLength: RpcPrivate.DataLength ← 3;
        lastPkt: BOOLEAN;
        RpcPrivate.StartSignal[signalPkt: pkt];
        argPkt↑ ← [why: why];
        [returnLength:, lastPkt: lastPkt] ← RpcPrivate.Call[
          pkt: pkt, callLength: pktLength, maxReturnLength: 0];
        Lupine.RuntimeError;  -- Impossible to RESUME an ERROR.
        END;  -- Error.

      END;  -- Catch public signals.


    -- Call public procedures (still in dispatcher).

    SELECT LOOPHOLE[pkt.data[0], RpcControl.ProcedureIndex] FROM
      Print =>
        RETURN[
          PrintStub[
            pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      GetPrinterProperties =>
        RETURN[
          GetPrinterPropertiesStub[
            pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      GetPrinterStatus =>
        RETURN[
          GetPrinterStatusStub[
            pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      GetPrintRequestStatus =>
        RETURN[
          GetPrintRequestStatusStub[
            pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      AddressTranslationStringToNetworkAddress =>
        RETURN[
          AddressTranslationStringToNetworkAddressStub[
            pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      ENDCASE => RETURN[Lupine.DispatchingError[]];

    END;  -- ServerDispatcher


  -- Public procedure dispatcher stubs.

  PrintStub:  --PROCEDURE [master: Source, printAttributes: PrintAttributes,
    -- printOptions: PrintOptions, systemElement: SystemElement]
    -- RETURNS [printRequestID: RequestID]-- RpcPrivate.Dispatcher =
    BEGIN
    master: Source;
    printAttributes: PrintAttributes;
    printOptions: PrintOptions;
    systemElement: SystemElement;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
      transferIndex(0): RpcControl.ProcedureIndex,
      systemElement(1): SystemElement];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
      printRequestID(0): RequestID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay;
    pktLength: RpcPrivate.DataLength ← 7;
    MaxHeapAllocs: CARDINAL = 55;
    heapAllocs: CARDINAL ← 0;
    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;
          paramZones.heap.FREE[@heapAllocVector[ptr]];
          ENDLOOP;
        END;  -- Free storage.
    BEGIN  -- OnePkt.
    onePkt: BOOLEAN = lastPkt;
    IF ~onePkt THEN
      BEGIN  -- Must move statics from pkt now.
      [systemElement: systemElement] ← argPkt↑;
      END;
    BEGIN  -- Unmarshal master: Source 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 master ← NIL
    ELSE
      BEGIN
      stringHeader: Lupine.StringHeader;
      stringHeader.all ← Lupine.RpcPktDoubleWord[pkt, pktLength]↑;
      pktLength ← pktLength + 2;
      master ←
        (heapAllocVector[
          (IF (heapAllocs ← heapAllocs + 1) <= MaxHeapAllocs THEN heapAllocs
           ELSE Lupine.UnmarshalingExprError[])] ← paramZones.heap.NEW[
          StringBody [stringHeader.maxLength]]);
      master.length ← stringHeader.length;
      pktLength ← Lupine.CopyFromPkt[
        pkt: pkt, pktLength: pktLength, dataAdr: BASE[master.text],
        dataLength: Lupine.WordsForChars[stringHeader.length],
        alwaysOnePkt: FALSE];
      END;  -- IF stringIsNIL.
    END;  -- Unmarshal master.
    BEGIN  -- Unmarshal printAttributes: PrintAttributes from pkt.data[pktLength].
    DescriptorType: TYPE = RECORD [
      SEQUENCE COMPUTED CARDINAL OF PrintAttribute];
    descLength: Lupine.SequenceHeader;
    IF pktLength + 2 > RpcPrivate.maxDataLength THEN
      pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength: pktLength];
    descLength ← Lupine.RpcPktDoubleWord[pkt, pktLength]↑;
    pktLength ← pktLength + 2;
    printAttributes ← DESCRIPTOR[
      (heapAllocVector[
        (IF (heapAllocs ← heapAllocs + 1) <= MaxHeapAllocs THEN heapAllocs
         ELSE Lupine.UnmarshalingExprError[])] ← paramZones.heap.NEW[
        DescriptorType [Lupine.SHORT[descLength]]]), Lupine.SHORT[descLength]];
    FOR element1: CARDINAL IN
      [FIRST[CARDINAL]..FIRST[CARDINAL] + LENGTH[printAttributes]) DO
      BEGIN  -- Unmarshal printAttributes[element1]: PrintAttribute
      -- from pkt.data[pktLength].
      pktLength ← Lupine.CopyFromPkt[
        pkt: pkt, pktLength: pktLength, dataAdr: @printAttributes[element1],
        dataLength: SIZE[PrintAttribute], alwaysOnePkt: FALSE];
      BEGIN OPEN record: printAttributes[element1];
      WITH variant: record SELECT FROM
        printObjectName =>
          BEGIN  -- Unmarshal variant: MACHINE DEPENDENT RECORD
          -- [printObjectName: String] from pkt.data[pktLength].
          BEGIN OPEN record: variant;
          BEGIN  -- Unmarshal record.printObjectName: String
          -- from pkt.data[pktLength].
          BEGIN OPEN record: record.printObjectName;
          BEGIN  -- Unmarshal record.bytes: LONG POINTER
          -- TO PACKED ARRAY CARDINAL OF [0..255] from pkt.data[pktLength].
          isNIL: Lupine.NilHeader;
          IF pktLength + 1 > RpcPrivate.maxDataLength THEN
            pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength: pktLength];
          isNIL ← pkt.data[pktLength];
          pktLength ← pktLength + 1;
          IF isNIL THEN record.bytes ← NIL
          ELSE
            BEGIN
            record.bytes ←
              (heapAllocVector[
                (IF (heapAllocs ← heapAllocs + 1) <= MaxHeapAllocs THEN
                 heapAllocs ELSE Lupine.UnmarshalingExprError[])] ←
                paramZones.heap.NEW[PACKED ARRAY CARDINAL OF [0..255]]);
            BEGIN  -- Unmarshal record.bytes↑: PACKED
            -- ARRAY CARDINAL OF [0..255] from pkt.data[pktLength].
            pktLength ← Lupine.CopyFromPkt[
              pkt: pkt, pktLength: pktLength, dataAdr: @record.bytes↑,
              dataLength: SIZE[PACKED ARRAY CARDINAL OF [0..255]],
              alwaysOnePkt: FALSE];
            END;  -- Unmarshal record.bytes↑.
            END;  -- IF isNIL.
          END;  -- Unmarshal record.bytes.
          END;  -- OPEN record: record.printObjectName.
          END;  -- Unmarshal record.printObjectName.
          END;  -- OPEN record: variant.
          END;  -- Unmarshal variant.
        senderName =>
          BEGIN  -- Unmarshal variant: MACHINE DEPENDENT RECORD
          -- [senderName: String] from pkt.data[pktLength].
          BEGIN OPEN record: variant;
          BEGIN  -- Unmarshal record.senderName: String from
          -- pkt.data[pktLength].
          BEGIN OPEN record: record.senderName;
          BEGIN  -- Unmarshal record.bytes: LONG POINTER
          -- TO PACKED ARRAY CARDINAL OF [0..255] from pkt.data[pktLength].
          isNIL: Lupine.NilHeader;
          IF pktLength + 1 > RpcPrivate.maxDataLength THEN
            pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength: pktLength];
          isNIL ← pkt.data[pktLength];
          pktLength ← pktLength + 1;
          IF isNIL THEN record.bytes ← NIL
          ELSE
            BEGIN
            record.bytes ←
              (heapAllocVector[
                (IF (heapAllocs ← heapAllocs + 1) <= MaxHeapAllocs THEN
                 heapAllocs ELSE Lupine.UnmarshalingExprError[])] ←
                paramZones.heap.NEW[PACKED ARRAY CARDINAL OF [0..255]]);
            BEGIN  -- Unmarshal record.bytes↑: PACKED
            -- ARRAY CARDINAL OF [0..255] from pkt.data[pktLength].
            pktLength ← Lupine.CopyFromPkt[
              pkt: pkt, pktLength: pktLength, dataAdr: @record.bytes↑,
              dataLength: SIZE[PACKED ARRAY CARDINAL OF [0..255]],
              alwaysOnePkt: FALSE];
            END;  -- Unmarshal record.bytes↑.
            END;  -- IF isNIL.
          END;  -- Unmarshal record.bytes.
          END;  -- OPEN record: record.senderName.
          END;  -- Unmarshal record.senderName.
          END;  -- OPEN record: variant.
          END;  -- Unmarshal variant.
        ENDCASE => NULL;  -- WITH variant: record.
      END;  -- OPEN record: printAttributes[element1].
      END;  -- Unmarshal printAttributes[element1].
      ENDLOOP;  -- FOR element1.
    END;  -- Unmarshal printAttributes.
    BEGIN  -- Unmarshal printOptions: PrintOptions from pkt.data[pktLength].
    DescriptorType: TYPE = RECORD [SEQUENCE COMPUTED CARDINAL OF PrintOption];
    descLength: Lupine.SequenceHeader;
    IF pktLength + 2 > RpcPrivate.maxDataLength THEN
      pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength: pktLength];
    descLength ← Lupine.RpcPktDoubleWord[pkt, pktLength]↑;
    pktLength ← pktLength + 2;
    printOptions ← DESCRIPTOR[
      (heapAllocVector[
        (IF (heapAllocs ← heapAllocs + 1) <= MaxHeapAllocs THEN heapAllocs
         ELSE Lupine.UnmarshalingExprError[])] ← paramZones.heap.NEW[
        DescriptorType [Lupine.SHORT[descLength]]]), Lupine.SHORT[descLength]];
    FOR element1: CARDINAL IN
      [FIRST[CARDINAL]..FIRST[CARDINAL] + LENGTH[printOptions]) DO
      BEGIN  -- Unmarshal printOptions[element1]: PrintOption from
      -- pkt.data[pktLength].
      pktLength ← Lupine.CopyFromPkt[
        pkt: pkt, pktLength: pktLength, dataAdr: @printOptions[element1],
        dataLength: SIZE[PrintOption], alwaysOnePkt: FALSE];
      BEGIN OPEN record: printOptions[element1];
      WITH variant: record SELECT FROM
        recipientName =>
          BEGIN  -- Unmarshal variant: MACHINE DEPENDENT RECORD
          -- [recipientName: String] from pkt.data[pktLength].
          BEGIN OPEN record: variant;
          BEGIN  -- Unmarshal record.recipientName: String
          -- from pkt.data[pktLength].
          BEGIN OPEN record: record.recipientName;
          BEGIN  -- Unmarshal record.bytes: LONG POINTER
          -- TO PACKED ARRAY CARDINAL OF [0..255] from pkt.data[pktLength].
          isNIL: Lupine.NilHeader;
          IF pktLength + 1 > RpcPrivate.maxDataLength THEN
            pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength: pktLength];
          isNIL ← pkt.data[pktLength];
          pktLength ← pktLength + 1;
          IF isNIL THEN record.bytes ← NIL
          ELSE
            BEGIN
            record.bytes ←
              (heapAllocVector[
                (IF (heapAllocs ← heapAllocs + 1) <= MaxHeapAllocs THEN
                 heapAllocs ELSE Lupine.UnmarshalingExprError[])] ←
                paramZones.heap.NEW[PACKED ARRAY CARDINAL OF [0..255]]);
            BEGIN  -- Unmarshal record.bytes↑: PACKED
            -- ARRAY CARDINAL OF [0..255] from pkt.data[pktLength].
            pktLength ← Lupine.CopyFromPkt[
              pkt: pkt, pktLength: pktLength, dataAdr: @record.bytes↑,
              dataLength: SIZE[PACKED ARRAY CARDINAL OF [0..255]],
              alwaysOnePkt: FALSE];
            END;  -- Unmarshal record.bytes↑.
            END;  -- IF isNIL.
          END;  -- Unmarshal record.bytes.
          END;  -- OPEN record: record.recipientName.
          END;  -- Unmarshal record.recipientName.
          END;  -- OPEN record: variant.
          END;  -- Unmarshal variant.
        message =>
          BEGIN  -- Unmarshal variant: MACHINE DEPENDENT RECORD
          -- [message: String] from pkt.data[pktLength].
          BEGIN OPEN record: variant;
          BEGIN  -- Unmarshal record.message: String from pkt.data[pktLength].
          BEGIN OPEN record: record.message;
          BEGIN  -- Unmarshal record.bytes: LONG POINTER
          -- TO PACKED ARRAY CARDINAL OF [0..255] from pkt.data[pktLength].
          isNIL: Lupine.NilHeader;
          IF pktLength + 1 > RpcPrivate.maxDataLength THEN
            pktLength ← Lupine.FinishThisPkt[pkt: pkt, pktLength: pktLength];
          isNIL ← pkt.data[pktLength];
          pktLength ← pktLength + 1;
          IF isNIL THEN record.bytes ← NIL
          ELSE
            BEGIN
            record.bytes ←
              (heapAllocVector[
                (IF (heapAllocs ← heapAllocs + 1) <= MaxHeapAllocs THEN
                 heapAllocs ELSE Lupine.UnmarshalingExprError[])] ←
                paramZones.heap.NEW[PACKED ARRAY CARDINAL OF [0..255]]);
            BEGIN  -- Unmarshal record.bytes↑: PACKED
            -- ARRAY CARDINAL OF [0..255] from pkt.data[pktLength].
            pktLength ← Lupine.CopyFromPkt[
              pkt: pkt, pktLength: pktLength, dataAdr: @record.bytes↑,
              dataLength: SIZE[PACKED ARRAY CARDINAL OF [0..255]],
              alwaysOnePkt: FALSE];
            END;  -- Unmarshal record.bytes↑.
            END;  -- IF isNIL.
          END;  -- Unmarshal record.bytes.
          END;  -- OPEN record: record.message.
          END;  -- Unmarshal record.message.
          END;  -- OPEN record: variant.
          END;  -- Unmarshal variant.
        ENDCASE => NULL;  -- WITH variant: record.
      END;  -- OPEN record: printOptions[element1].
      END;  -- Unmarshal printOptions[element1].
      ENDLOOP;  -- FOR element1.
    END;  -- Unmarshal printOptions.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    resPkt ← @pkt.data[0];
    IF onePkt THEN
      [resPkt.printRequestID] ← Print[
        master, printAttributes, printOptions, argPkt.systemElement]
    ELSE
      [resPkt.printRequestID] ← Print[
        master, printAttributes, printOptions, systemElement];
    END;  -- OnePkt.
    pktLength ← 5;
    END;  -- ENABLE UNWIND => Free storage.
    FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
      IF heapAllocVector[ptr] = NIL THEN EXIT;
      paramZones.heap.FREE[@heapAllocVector[ptr]];
      ENDLOOP;
    RETURN[returnLength: pktLength];
    END;  -- PrintStub.

  GetPrinterPropertiesStub:  --PROCEDURE [systemElement: SystemElement]
    -- RETURNS [properties: PrinterProperties]-- RpcPrivate.Dispatcher =
    BEGIN
    properties: PrinterProperties;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
      transferIndex(0): RpcControl.ProcedureIndex,
      systemElement(1): SystemElement];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 7];
    [properties] ← GetPrinterProperties[argPkt.systemElement];
    pktLength ← 0;
    BEGIN  -- Marshal properties: PrinterProperties to pkt.data[pktLength].
    IF pktLength + 2 > RpcPrivate.maxDataLength THEN
      pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
    Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ←
      (IF BASE[properties] = NIL THEN 0 ELSE LENGTH[properties]);
    pktLength ← pktLength + 2;
    IF BASE[properties] # NIL THEN
      FOR element1: CARDINAL IN
        [FIRST[CARDINAL]..FIRST[CARDINAL] + LENGTH[properties]) DO
        BEGIN  -- Marshal properties[element1]: PrinterProperty to
        -- pkt.data[pktLength].
        pktLength ← Lupine.CopyToPkt[
          pkt: pkt, pktLength: pktLength, dataAdr: @properties[element1],
          dataLength: SIZE[PrinterProperty], alwaysOnePkt: FALSE];
        BEGIN OPEN record: properties[element1];
        WITH variant: record SELECT FROM
          media =>
            BEGIN  -- Marshal variant: MACHINE DEPENDENT RECORD
            -- [media: Media] to pkt.data[pktLength].
            BEGIN OPEN record: variant;
            BEGIN  -- Marshal record.media: Media to pkt.data[pktLength].
            IF pktLength + 2 > RpcPrivate.maxDataLength THEN
              pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
            Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ←
              (IF BASE[record.media] = NIL THEN 0 ELSE LENGTH[record.media]);
            pktLength ← pktLength + 2;
            IF BASE[record.media] # NIL THEN
              pktLength ← Lupine.CopyToPkt[
                pkt: pkt, pktLength: pktLength, dataAdr: BASE[record.media],
                dataLength: SIZE[Medium] * LENGTH[record.media],
                alwaysOnePkt: FALSE];
            END;  -- Marshal record.media.
            END;  -- OPEN record: variant.
            END;  -- Marshal variant.
          ENDCASE => NULL;  -- WITH variant: record.
        END;  -- OPEN record: properties[element1].
        END;  -- Marshal properties[element1].
        ENDLOOP;  -- FOR element1.
    END;  -- Marshal properties.
    RETURN[returnLength: pktLength];
    END;  -- GetPrinterPropertiesStub.

  GetPrinterStatusStub:  --PROCEDURE [systemElement: SystemElement]
    -- RETURNS [status: PrinterStatus]-- RpcPrivate.Dispatcher =
    BEGIN
    status: PrinterStatus;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
      transferIndex(0): RpcControl.ProcedureIndex,
      systemElement(1): SystemElement];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 7];
    [status] ← GetPrinterStatus[argPkt.systemElement];
    pktLength ← 0;
    BEGIN  -- Marshal status: PrinterStatus to pkt.data[pktLength].
    IF pktLength + 2 > RpcPrivate.maxDataLength THEN
      pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
    Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ←
      (IF BASE[status] = NIL THEN 0 ELSE LENGTH[status]);
    pktLength ← pktLength + 2;
    IF BASE[status] # NIL THEN
      FOR element1: CARDINAL IN
        [FIRST[CARDINAL]..FIRST[CARDINAL] + LENGTH[status]) DO
        BEGIN  -- Marshal status[element1]: PrinterStatusComponent
        -- to pkt.data[pktLength].
        pktLength ← Lupine.CopyToPkt[
          pkt: pkt, pktLength: pktLength, dataAdr: @status[element1],
          dataLength: SIZE[PrinterStatusComponent], alwaysOnePkt: FALSE];
        BEGIN OPEN record: status[element1];
        WITH variant: record SELECT FROM
          media =>
            BEGIN  -- Marshal variant: MACHINE DEPENDENT RECORD
            -- [media: Media] to pkt.data[pktLength].
            BEGIN OPEN record: variant;
            BEGIN  -- Marshal record.media: Media to pkt.data[pktLength].
            IF pktLength + 2 > RpcPrivate.maxDataLength THEN
              pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
            Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ←
              (IF BASE[record.media] = NIL THEN 0 ELSE LENGTH[record.media]);
            pktLength ← pktLength + 2;
            IF BASE[record.media] # NIL THEN
              pktLength ← Lupine.CopyToPkt[
                pkt: pkt, pktLength: pktLength, dataAdr: BASE[record.media],
                dataLength: SIZE[Medium] * LENGTH[record.media],
                alwaysOnePkt: FALSE];
            END;  -- Marshal record.media.
            END;  -- OPEN record: variant.
            END;  -- Marshal variant.
          ENDCASE => NULL;  -- WITH variant: record.
        END;  -- OPEN record: status[element1].
        END;  -- Marshal status[element1].
        ENDLOOP;  -- FOR element1.
    END;  -- Marshal status.
    RETURN[returnLength: pktLength];
    END;  -- GetPrinterStatusStub.

  GetPrintRequestStatusStub:  --PROCEDURE [printRequestID: RequestID,
    -- systemElement: SystemElement] RETURNS [status: RequestStatus]--
    RpcPrivate.Dispatcher =
    BEGIN
    status: RequestStatus;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
      transferIndex(0): RpcControl.ProcedureIndex,
      printRequestID(1): RequestID,
      systemElement(6): SystemElement];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength;
    Lupine.CheckPktLength[pkt: pkt, pktLength: 12];
    [status] ← GetPrintRequestStatus[
      argPkt.printRequestID, argPkt.systemElement];
    pktLength ← 0;
    BEGIN  -- Marshal status: RequestStatus to pkt.data[pktLength].
    IF pktLength + 2 > RpcPrivate.maxDataLength THEN
      pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
    Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ←
      (IF BASE[status] = NIL THEN 0 ELSE LENGTH[status]);
    pktLength ← pktLength + 2;
    IF BASE[status] # NIL THEN
      FOR element1: CARDINAL IN
        [FIRST[CARDINAL]..FIRST[CARDINAL] + LENGTH[status]) DO
        BEGIN  -- Marshal status[element1]: RequestStatusComponent
        -- to pkt.data[pktLength].
        pktLength ← Lupine.CopyToPkt[
          pkt: pkt, pktLength: pktLength, dataAdr: @status[element1],
          dataLength: SIZE[RequestStatusComponent], alwaysOnePkt: FALSE];
        BEGIN OPEN record: status[element1];
        WITH variant: record SELECT FROM
          statusMessage =>
            BEGIN  -- Marshal variant: MACHINE DEPENDENT RECORD
            -- [statusMessage: String] to pkt.data[pktLength].
            BEGIN OPEN record: variant;
            BEGIN  -- Marshal record.statusMessage: String to
            -- pkt.data[pktLength].
            BEGIN OPEN record: record.statusMessage;
            BEGIN  -- Marshal record.bytes: LONG POINTER TO
            -- PACKED ARRAY CARDINAL OF [0..255] to pkt.data[pktLength].
            IF pktLength + 1 > RpcPrivate.maxDataLength THEN
              pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
            pkt.data[pktLength] ← record.bytes = NIL;
            pktLength ← pktLength + 1;
            IF record.bytes # NIL THEN
              BEGIN  -- Marshal record.bytes↑: PACKED ARRAY
              -- CARDINAL OF [0..255] to pkt.data[pktLength].
              pktLength ← Lupine.CopyToPkt[
                pkt: pkt, pktLength: pktLength, dataAdr: @record.bytes↑,
                dataLength: SIZE[PACKED ARRAY CARDINAL OF [0..255]],
                alwaysOnePkt: FALSE];
              END;  -- Marshal record.bytes↑.
            END;  -- Marshal record.bytes.
            END;  -- OPEN record: record.statusMessage.
            END;  -- Marshal record.statusMessage.
            END;  -- OPEN record: variant.
            END;  -- Marshal variant.
          ENDCASE => NULL;  -- WITH variant: record.
        END;  -- OPEN record: status[element1].
        END;  -- Marshal status[element1].
        ENDLOOP;  -- FOR element1.
    END;  -- Marshal status.
    RETURN[returnLength: pktLength];
    END;  -- GetPrintRequestStatusStub.

  AddressTranslationStringToNetworkAddressStub:  --PROCEDURE [name:
    -- LONG STRING] RETURNS [systemElement: SystemElement, chUsed: BOOLEAN]--
    RpcPrivate.Dispatcher =
    BEGIN
    name: LONG STRING;
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
      systemElement(0): SystemElement, chUsed(6): BOOLEAN];
    resPkt: LONG POINTER TO ResultOverlay;
    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;
          paramZones.heap.FREE[@heapAllocVector[ptr]];
          ENDLOOP;
        END;  -- Free storage.
    BEGIN  -- Unmarshal name: 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 name ← NIL
    ELSE
      BEGIN
      stringHeader: Lupine.StringHeader;
      stringHeader.all ← Lupine.RpcPktDoubleWord[pkt, pktLength]↑;
      pktLength ← pktLength + 2;
      name ←
        (heapAllocVector[1] ← paramZones.heap.NEW[
          StringBody [stringHeader.maxLength]]);
      name.length ← stringHeader.length;
      pktLength ← Lupine.CopyFromPkt[
        pkt: pkt, pktLength: pktLength, dataAdr: BASE[name.text],
        dataLength: Lupine.WordsForChars[stringHeader.length],
        alwaysOnePkt: FALSE];
      END;  -- IF stringIsNIL.
    END;  -- Unmarshal name.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    resPkt ← @pkt.data[0];
    [resPkt.systemElement, resPkt.chUsed] ←
      AddressTranslationStringToNetworkAddress[name];
    pktLength ← 7;
    END;  -- ENABLE UNWIND => Free storage.
    FOR ptr: CARDINAL IN [1..LENGTH[heapAllocVector]] DO
      IF heapAllocVector[ptr] = NIL THEN EXIT;
      paramZones.heap.FREE[@heapAllocVector[ptr]];
      ENDLOOP;
    RETURN[returnLength: pktLength];
    END;  -- AddressTranslationStringToNetworkAddressStub.


  -- Marshall/Unmarshal procedures.


  -- No module initialization.

  END.  -- CedarNSPrintRpcServerImpl.