140 lines
4.0 KiB
C
140 lines
4.0 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);
|
|
}
|
|
|