text: /*
  ** buffers.c - Routines dealing with I/O and expansion buffers for LZCopy()
  **             and DOS command-line programs.
  **
  ** Author:  DavidDi
  */
  
  
  // Headers
  ///////////
  
  #ifndef LZA_DLL
  
  #include <dos.h>
  #include <fcntl.h>
  
  #endif
  
  #include "lz_common.h"
  #include "lz_buffers.h"
  
  /*
  ** int ReadInBuf(BYTE ARG_PTR *pbyte, int doshSource);
  **
  ** Read input file into input buffer.
  **
  ** Arguments:  pbyte      - pointer to storage for first byte read from file
  **                          into buffer
  **             doshSource - DOS file handle to open input file
  **
  ** Returns:    int - TRUE or END_OF_INPUT if successful.  LZERROR_BADINHANDLE
  **                   if not.
  **
  ** Globals:    rgbyteInBuf[0] - holds last byte from previous buffer
  **             pbyteInBufEnd  - set to point to first byte beyond end of data
  **                              in input buffer
  **             bLastUsed      - reset to FALSE if currently TRUE
  */
  INT ReadInBuf(BYTE ARG_PTR *pbyte, INT doshSource, PLZINFO pLZI)
  {
     DWORD ucbRead;          // number of bytes actually read
  
     // !!! Assumes pLZI parm is valid.  No sanity check (should be done above in caller).
  
     pLZI->rgbyteInBuf[0] = *(pLZI->pbyteInBufEnd - 1);
  
     if ((ucbRead = FREAD(doshSource, &pLZI->rgbyteInBuf[1], pLZI->ucbInBufLen))
         != pLZI->ucbInBufLen)
     {
  #ifdef LZA_DLL
        if (ucbRead == (DWORD)(-1)) {
  #else
        if (_error != 0U) {
  #endif
           // We were handed a bad input file handle.
           return(LZERROR_BADINHANDLE);
        }
        else if (ucbRead > 0U)
           // Read last ucbRead bytes of input file.  Change input buffer end
           // to account for shorter read.
           pLZI->pbyteInBufEnd = &pLZI->rgbyteInBuf[1] + ucbRead;
        else  { // (ucbRead == 0U) {
           // We couldn't read any bytes from input file (EOF reached).
           return(END_OF_INPUT);
        }
     }
  
     // Reset read pointer to beginning of input buffer.
     pLZI->pbyteInBuf = &pLZI->rgbyteInBuf[1];
  
     // Was an UnreadByte() done at the beginning of the last buffer?
     if (pLZI->bLastUsed)
     {
        // Return the last byte from the previous input buffer
        *pbyte = pLZI->rgbyteInBuf[0];
        pLZI->bLastUsed = FALSE;
     }
     else
        // Return the first byte from the new input buffer.
        *pbyte = *pLZI->pbyteInBuf++;
  
     return(TRUE);
  }
  
  
  /*
  ** int WriteOutBuf(BYTE byteNext, int doshDest);
  **
  ** Dumps output buffer to output file.  Prompts for new floppy disk if the
  ** old one if full.  Continues dumping to output file of same name on new
  ** floppy disk.
  **
  ** Arguments:  byteNext - first byte to be added to empty buffer after buffer
  **                        is written
  **             doshDest - output DOS file handle
  **
  ** Returns:    int - TRUE if successful.  LZERROR_BADOUTHANDLE or
  **                   LZERROR_WRITE if unsuccessful.
  **
  ** Globals:    pbyteOutBuf - reset to point to free byte after byteNext in
  **                           rgbyteOutBuf
  */
  INT WriteOutBuf(BYTE byteNext, INT doshDest, PLZINFO pLZI)
  {
     DWORD ucbToWrite,       // number of bytes to write from buffer
              ucbWritten,       // number of bytes actually written
              ucbTotWritten;    // total number of bytes written to output
  
     // !!! Assumes pLZI parm is valid.  No sanity check (should be done above in caller).
  
     // How much of the buffer should be written to the output file?
     ucbTotWritten = ucbToWrite = (DWORD)(pLZI->pbyteOutBuf - pLZI->rgbyteOutBuf);
     // Reset pointer to beginning of buffer.
     pLZI->pbyteOutBuf = pLZI->rgbyteOutBuf;
  
     // Write to ouput file.
     if (doshDest != NO_DOSH &&
         (ucbWritten = FWRITE(doshDest, pLZI->pbyteOutBuf, ucbToWrite)) != ucbToWrite)
     {
  #ifdef LZA_DLL
        if (ucbWritten == (DWORD)(-1)) {
  #else
        if (_error != 0U) {
  #endif
           // Bad DOS file handle.
           return(LZERROR_BADOUTHANDLE);
        }
        else {
           // Insufficient space on destination drive.
           return(LZERROR_WRITE);
        }
     }
  
     // Add the next byte to the buffer.
     *pLZI->pbyteOutBuf++ = byteNext;
  
     return(TRUE);
  }
  
  