*DECK XDRINT
USETEXT TEXTXDR 
      PROC XDRINT (BUFFER, BUFPOS, INTARR, INTLEN, OPERATION);
*CALL COPYRITE          CDCNET - COPYRIGHT CONTROL DATA. 1992.
# TITLE XDRINT  CONVERT BETWEEN INTEGERS AND EXT DATA REPRESENTATION   #
  
      BEGIN                            # XDRINT                        #
# 
****  XDRINT - CONVERT BETWEEN INTEGERS AND EXT DATA REPRESENTATION 
* 
*     THIS PROCEDURE WILL READ DATA OUT OF *BUFFER*, OR WRITE DATA INTO 
*     *BUFFER* DEPENDING ON THE *OPERATION* PARAMETER.  THE DATA IN 
*     *BUFFER* IS IN XDR (EXTERNAL DATA REPRESENTATION) FORMAT, 8 BIT 
*     BYTES PACKED 7.5/CYBER WORD.  THE DATA IN *INTARR* IS 32 BIT
*     INTEGERS. 
* 
*     PROC XDRINT (BUFFER, BUFPOS, INTARR, INTLEN, OPERATION) 
* 
*     ENTRY    BUFFER    = INTEGER ARR PACKED 7.5 BYTES WORD. 
*              BUFPOS    = INDEX OF NEXT BYTE TO BE READ OR WRITTEN.
*              INTARR    = 32 BIT INTEGER ARRAY.
*              INTLEN    = NUMBER OF INTEGER VALUES TO BE READ OR 
*                          WRITTEN TO INTARRAY. 
*              OPERATION = EITHER *READ* FROM OR *WRITE* TO *BUFFER*. 
* 
*     EXIT     BUFFER    = DATA READ OUT OR WRITTEN TO. 
*              BUFPOS    = BYTE POSITION IN *BUFFER* AFTER OPERATION. 
*              INTARR    = DATA READ OUT OR WRITTEN TO. 
* 
*     METHOD   IF OPERATION IS *READ*, *INTLEN* INTEGERS ARE READ OUT OF
*              *BUFFER* AND STORED IN *INTARR*. 
*              IF THE OPERATION IS *WRITE*, *INTLEN* BYTES ARE READ 
*              FROM *INTARR* AND ARE STORED IN *BUFFER*.
*              *BUFPOS* IS UPDATED TO THE NEXT READ/WRITE BYTE POSITION.
*              THE ARITHMETIC MODULO BASE 60 FUNCTION IS PERFORMED ON 
*              *BUFPOS* MULTIPLIED BY EIGHT TO DETERMINE THE BIT
*              POSITION WITHIN BUFFER.  IF THE POSITION IS 56, THE
*              BYTE IS SPLIT ACROSS TWO WORDS.
*              THE CALLER IS RESPONSIBLE FOR MAKING SURE THAT THE 
*              DESTINATION ARRAY IS LARGE ENOUGH TO HOLD THE NUMBER 
*              OF VALUES SPECIFIED. 
* 
# 
  
# 
**
# 
  
      ARRAY BUFFER [0:0] S(1);         # ARRAY OF DATA, 7.5 BYTES/WORD #
        ITEM BUF$WRD  U(00,00,60);     # WORD REFERENCE                #
      ITEM BUFPOS            I;        # CUR BYTE POSITION IN BUFFER   #
      ARRAY INTARR [0:0] S(1);         # ARRAY OF INTEGERS             #
        ITEM INT$WRD   U(00,00,60);    # WORD REFERENCE                #
      ITEM INTLEN            I;        # NUMBER OF BYTES TO BE PROCESSD#
      ITEM OPERATION S:XDROPER;        # OPERATION TO PERFORM ON BUFFER#
  
      ITEM BITPOS            I;        # BIT POSITION IN BUFFER        #
      ITEM INDEX             I;        # LOOP INDEX                    #
      ITEM REMBUFF           I;        # BITS REMAINING IN CURRENT WORD#
      ITEM REMINT            I;        # BITS WRAPPED TO SECOND WORD   #
      ITEM WORDPOS           I;        # WORD POSITION IN BUFFER       #
      CONTROL EJECT;
# 
****  START MAIN PROCEDURE
# 
  
      BITPOS = XDRMODU (BUFPOS * 8, 60);# INITIAL BIT POSITION IN BUF  #
      WORDPOS = (BUFPOS * 2) / 15;     # INITIAL WORD INDEX WITHIN BUF #
      BUFPOS = BUFPOS + (INTLEN * 4);  # ENDING BUFFER LOCATION        #
  
      SWITCH OPER$:XDROPER  OPER$READ:READ, 
                           OPER$WRITE:WRITE;
  
      GOTO OPER$ [OPERATION]; 
        BEGIN                          # OPERATION TYPE                #
  
    OPER$READ:  
  
        FOR INDEX = 0 STEP 1 UNTIL (INTLEN - 1) DO
          BEGIN                        # LOOP THROUGH REQUESTED INTEGER#
          IF BITPOS LQ 28 THEN
            BEGIN                      # INTEGER DOES NOT WRAP         #
            INT$WRD [INDEX] = B<BITPOS, 32>BUF$WRD [WORDPOS]; 
            BITPOS = BITPOS + 32; 
            IF BITPOS GQ 60 
            THEN
              BEGIN 
              BITPOS = 0; 
              WORDPOS = WORDPOS + 1;
              END 
            END 
          ELSE
            BEGIN                      # INTEGER WRAPS BETWEEN 2 WORDS #
            REMBUFF = 60 - BITPOS;     # BITS REMAINING IN CURRENT WORD#
            REMINT = 32 - REMBUFF;     # NUMBER OF BITS IN SECOND WORD #
            INT$WRD [INDEX] = B<BITPOS, REMBUFF>BUF$WRD [WORDPOS] * 
                              (2 ** REMINT) + 
                              B<0, REMINT>BUF$WRD [WORDPOS + 1];
            WORDPOS = WORDPOS + 1;
            BITPOS = REMINT;
            END 
  
          END                          # LOOP THROUGH REQUESTED INTEGER#
  
        GOTO OPER$END;
  
    OPER$WRITE: 
  
        FOR INDEX = 0 STEP 1 UNTIL (INTLEN - 1) DO
          BEGIN                        # LOOP THROUGH REQUESTED INTEGER#
          IF BITPOS LQ 28 THEN
            BEGIN                      # INTEGER DOES NOT WRAP         #
            B<BITPOS, 32>BUF$WRD [WORDPOS] = INT$WRD [INDEX]; 
            BITPOS = BITPOS + 32; 
            IF BITPOS GQ 60 
            THEN
              BEGIN 
              BITPOS = 0; 
              WORDPOS = WORDPOS + 1;
              END 
            END 
          ELSE
            BEGIN                      # INTEGER WRAPS BETWEEN 2 WORDS #
            REMBUFF = 60 - BITPOS;     # BITS REMAINING IN CURRENT WORD#
            REMINT = 32 - REMBUFF;     # NUMBER OF BITS IN SECOND WORD #
            B<BITPOS, REMBUFF>BUF$WRD [WORDPOS] = 
                B<28, REMBUFF>INT$WRD [INDEX];
            B<0, REMINT>BUF$WRD [WORDPOS + 1] = 
                B<28 + REMBUFF, REMINT>INT$WRD [INDEX]; 
            WORDPOS = WORDPOS + 1;
            BITPOS = REMINT;
            END 
  
          END                          # LOOP THROUGH REQUESTED INTEGER#
  
        GOTO OPER$END;
  
        END                            # OPERATION TYPE                #
  
  OPER$END: 
  
      RETURN;                          # RETURN TO CALLER              #
  
      END                              # XDRINT                        #
  
      TERM
