/* ** buffers.c - Routines dealing with I/O and expansion buffers for LZCopy() ** and DOS command-line programs. ** ** Author: DavidDi */ // Headers /////////// #ifndef LZA_DLL #include #include #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); }