*DECK FFSUPEF 
USETEXT TEXTFFS                      # FS  SYSTEM DEFINITIONS         # 
      PROC FFSUPEF; 
*CALL COPYRITE
# TITLE FFSUPEF - PROCESS EOF CONDITIONS.                             # 
  
      BEGIN                          # FFSUPEF #
  
# 
**    FFSUPEF - PROCESS EOF CONDITIONS. 
* 
*     CMP   03/88 
* 
*     'FFSUPEF' PROCESSES EOF/EOI ON AN ASCII88 FILE TRANSFER.
*     THE FOLLOWING CONDITIONS HAVE TO BE PROVIDED FOR:-
*     1. BINARY TRANSFER & A CONTROL RECORD EXISTS. 
*     2. BINARY TRANSFER & NO CONTROL RECORD EXISTS.
*     3. CHARACTER TRANSFER 
*         (A) LINE TERMINATOR OCCURS IN THE LAST WORD.
*         (B) NO LINE TERMINATOR. 
* 
*     ENTRY:  
*           (WDCNT) = WORDS OF DATA IN OUTBUF.
*           COMMON BLOCK OUTBUFF CONTAINS THE BLOCK TO BE SENT. 
*           COMMON BLOCK CTRLREC CONTAINS THE FTP/NOS CONTROL RECORD
*           IF ONE EXISTS FOR THIS FILE.
* 
*     METHOD: 
*           FOR CHARACTER MODE TRANSFERS, ANY PAD CHARACTERS (BINARY
*           ZEROS) BETWEEN THE LAST LINE TERMINATOR IN THE FILE AND 
*           EOF OR EOI, ARE DISGARDED. IF NO LINE TERMINATOR IS FOUND,
*           THE ENTIRE LAST WORD IS SENT (MINUS 4 BITS IF THE FILE HAS
*           AN ODD WORD COUNT). 
*           FOR BINARY TRANSFERS, THE LAST 4 BITS OF A FILE WITH AN 
*           ODD WORD COUNT ARE SENT BY APPENDING A 4-BIT PAD. 
* 
*     EXIT :  
*            BLOCK IS SET UP AND SENT VIA FFSUSOB.
# 
  
      XREF
        BEGIN 
        PROC ABORT;                  # NOS ABORT MACRO                # 
        PROC MESSAGE;                # NOS MESSAGE MACRO              # 
        PROC FFSUSOB;                # SEND OUTPUT BLOCK              # 
        END 
  
  
      ARRAY BADCOUNT [00:00] S(4);   # BAD BINARY FILE COUNT          # 
        BEGIN 
        ITEM BADCNT  C(00,00,31) =
          [" FFSUPEF -BAD BINARY FILE COUNT"];
        ITEM BADZB0  U(03,06,54) = [0]; 
        END 
  
      ITEM ADJUST      I;            # BYTE COUNT ADJUSTMENT          # 
      ITEM BCNT        I;            # BYTE COUNT IN BLOCK            # 
      ITEM CHTR        U;            # EXTRACTED BITS                 # 
      ITEM COUNT       I;            # LOOP COUNT                     # 
      ITEM FOUND       B;            # EOL TERMINATOR FOUND FLAG      # 
      ITEM I           I; 
      ITEM K           I; 
      ITEM L           I; 
      ITEM OUBBIT      I;            # BIT POSITION IN CURRENT WORD   # 
  
  
                                                         CONTROL EJECT; 
  
      IF TPTTYPE[0] EQ TYPE$I 
      THEN
        BEGIN                        # BINARY TRANSFER                # 
        BCNT = (WDCNT * 60 + 7) / 8; # BYTE COUNT ROUNDED UP          # 
        IF OUCHDRU NQ 0 
        THEN
          BEGIN                      # CONTROL RECORD EXISTS          # 
          IF OUCBCNT LS BYTESOUT
          THEN
            BEGIN 
            MESSAGE(BADCOUNT, 0); 
            ABORT;
            END 
          BYTESOUT = OUCBCNT; 
          END                        # CONTROL RECORD EXISTS          # 
        ELSE
          BEGIN                      # NO CONTROL RECORD              # 
  
# 
*         IF ODD WORD COUNT IN BUFFER, NEED TO SEND 4 PAD BITS TO 
*         COMPLETE LAST 4 BITS ON FILE. ZERO NEXT WORD IN CASE. 
*         BYTE COUNT IS ALREADY ROUNDED UP. 
# 
  
          DTBUF$WRD[WDCNT] = 0; 
          BYTESOUT = BYTESOUT + BCNT; 
          END                        # NO CONTROL RECORD              # 
        END                          # BINARY TRANSFER                # 
  
      ELSE
  
        BEGIN                        # CHARACTER TRANSFERS            # 
        BCNT = WDCNT * 60 / 8;       # BYTE COUNT - NO ROUND UP       # 
        COUNT = 8;                   # NUMBER OF TIMES TO TRY         # 
        K = (WDCNT / 2) * 2;         # CHECK IF ODD OR EVEN WORD      # 
        OUBBIT = 60;
        IF K NQ WDCNT 
        THEN
          BEGIN                      # ODD WORD BOUNDARY              # 
          OUBBIT = 56;
          COUNT = 7;
          END 
        I = WDCNT - 1;               # TURN WDCNT INTO AN OFFSET      # 
        CHTR = 0; 
        ADJUST = 0;                  # BYTE COUNT ADJUSTMENT COUNTER  # 
        FOUND = FALSE;               # LINE TERMINATOR FOUND FLAG     # 
        IF I EQ 0 
        THEN
          BEGIN                      # NO BOUNDARY SPLIT IF ONLY 1 WD # 
          COUNT = COUNT - 1;
          END 
        CONTROL FASTLOOP; 
        FOR COUNT = COUNT STEP -1 
            WHILE COUNT GR 0 AND NOT FOUND
        DO
          BEGIN                      # WHILE COUNT GR 0...            # 
          K = OUBBIT - (BITSIBYTE * 2); # K IS NEXT STARTING BIT      # 
          L = 60 - BITSIBYTE * 2; 
          IF K LS 0 
          THEN
            BEGIN                    # SOME BITS ARE IN PREVIOUS WORD # 
            K = - K;
            B<L, K>CHTR = B<60 - K, K>DTBUF$WRD[I - 1]; 
            L = L + K;
            B<L, 60 - L>CHTR = B<0, 60 - L>DTBUF$WRD[I];
            END 
          ELSE
            BEGIN                    # ALL BITS ARE IN THIS WORD      # 
            B<L, BITSIBYTE * 2>CHTR = B<K, BITSIBYTE * 2>DTBUF$WRD[I];
            END 
  
          IF CHTR EQ X"0D 0A" 
          THEN
            BEGIN 
            FOUND = TRUE; 
            END 
          ELSE
            BEGIN                    # CHTR NQ <CR><LF>               # 
            CHTR = B<52, 8>CHTR;
            IF CHTR NQ 0
            THEN
              BEGIN                  # BOTTOM BYTE IS NOT PAD         # 
              COUNT = 0;
              ADJUST = 0; 
              END 
            ELSE
              BEGIN                  # BOTTOM BYTE IS PAD             # 
              ADJUST = ADJUST + 1;   # DONT SEND THIS BYTE            # 
              OUBBIT = OUBBIT - BITSIBYTE;
              END 
            END                      # CHTR NQ <CR><LF>               # 
          END                        # WHILE COUNT GR 0...            # 
  
        IF FOUND
        THEN
          BEGIN 
          BCNT = BCNT - ADJUST; 
          END 
        BYTESOUT = BYTESOUT + BCNT; 
        END                          # CHARACTER TRNASFERS            # 
  
      FFSUSOB(TRUE);                 # SEND THE BLOCK                 # 
  
      RETURN; 
  
      END                            # FFSUPEF #
  
      TERM
  
