windows-nt/Source/XPSP1/NT/base/win32/lz32/winlza/buffers.c
2020-09-26 16:20:57 +08:00

140 lines
4 KiB
C

/*
** 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);
}