Old tools that got removed a long time ago.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1545 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
/*--gio.c-----------------------------------------------------------------
|
||||
* Buffered i/o.
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define local static
|
||||
|
||||
/* --- Segment of optional buffer for speeding-up i/o. */
|
||||
local UWORD ioBufferSeg = NULL;
|
||||
local UWORD ioBufSize = 0, ioBufNext, ioBufLimit;
|
||||
local BOOL ioWriting;
|
||||
|
||||
/* ---------- OpenIOBuffer ---------- */
|
||||
void OpenIOBuffer(BOOL forWriting)
|
||||
{
|
||||
register WORD bufSize;
|
||||
auto WORD tempSeg;
|
||||
|
||||
ioWriting = forWriting;
|
||||
|
||||
/* --- Allocate i/o buffer. */
|
||||
if (ioBufferSeg == NULL) {
|
||||
for (bufSize = 16 * 1024; bufSize >= 512; bufSize >>= 1) {
|
||||
ioBufferSeg = DAlloc(bufSize);
|
||||
if (ioBufferSeg) {
|
||||
/* --- Leave at least 4 KB free for other uses. */
|
||||
tempSeg = DAlloc(4096);
|
||||
if (tempSeg) {
|
||||
tempSeg = SFree(tempSeg);
|
||||
break; /* Success; leave loop. */
|
||||
} else
|
||||
ioBufferSeg = SFree(ioBufferSeg);
|
||||
}
|
||||
}
|
||||
if (ioBufferSeg != NULL)
|
||||
ioBufSize = bufSize;
|
||||
}
|
||||
ioBufNext = ioBufLimit = 0;
|
||||
/* Reading: When next==limit, buffer is empty.
|
||||
* Writing: When next== 0, buffer is empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/* ---------- CloseIOBuffer -----------------
|
||||
* Writing: flush any remaining data to file.
|
||||
* Free the i/o buffer. Do this whenever finish i/o, so RAM not tied up.
|
||||
*/
|
||||
void CloseIOBuffer(WORD file)
|
||||
{
|
||||
if (ioWriting)
|
||||
GFlush(file); /* TBD: ignoring error. */
|
||||
ioBufferSeg = SFree(ioBufferSeg);
|
||||
ioBufSize = 0;
|
||||
}
|
||||
|
||||
/* ---------- GRead ---------------------------------------------
|
||||
* Like DOS "read" function, RETURNS # bytes read, or 0 at EOF,
|
||||
* or -1 at error.
|
||||
*/
|
||||
WORD GRead(WORD file, UBYTE *buffer, UWORD nBytes)
|
||||
{
|
||||
UWORD nRemaining, nAvail, nThisTime;
|
||||
|
||||
if (ioBufferSeg) {
|
||||
nAvail = ioBufLimit - ioBufNext;
|
||||
if (!nAvail && nBytes >= ioBufSize)
|
||||
goto readDirectly; /* More efficient to read buffer directly. */
|
||||
|
||||
/* --- Remaining # bytes that need reading. */
|
||||
for (nRemaining = nBytes; nRemaining; nRemaining -= nThisTime) {
|
||||
if (!nAvail) {
|
||||
ioBufLimit = nAvail =
|
||||
readdos(file, ioBufferSeg, 0, ioBufSize);
|
||||
if (nAvail == 0xffff || nAvail == 0) {
|
||||
ioBufLimit = 0;
|
||||
return (nAvail);
|
||||
}
|
||||
ioBufNext = 0;
|
||||
}
|
||||
nThisTime = MIN(nRemaining, nAvail);
|
||||
far_movmem(ioBufferSeg, ioBufNext,
|
||||
dataseg(), (UWORD)buffer,
|
||||
(UWORD)nThisTime);
|
||||
buffer += nThisTime;
|
||||
ioBufNext += nThisTime;
|
||||
nAvail -= nThisTime;
|
||||
}
|
||||
return (nBytes);
|
||||
} else /* No ioBuf */
|
||||
readDirectly:
|
||||
return (read(file, buffer, nBytes));
|
||||
}
|
||||
|
||||
/* --------------- GReadOne --------------------------------
|
||||
* Like "GRead", but read a single byte, with less overhead.
|
||||
*/
|
||||
WORD GReadOne(WORD file, UBYTE *buffer)
|
||||
{
|
||||
if (!ioBufferSeg || ioBufLimit == ioBufNext)
|
||||
return GRead(file, buffer, 1);
|
||||
|
||||
*buffer = *BYTE_FAR_PTR(ioBufferSeg, ioBufNext);
|
||||
ioBufNext++;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* ---------- GFlush ------------------------------
|
||||
* Write out any bytes remaining in the buffer.
|
||||
* Return what writedos does, or 0 if nothing to do.
|
||||
*/
|
||||
WORD GFlush(WORD file)
|
||||
{
|
||||
auto WORD result = 0;
|
||||
|
||||
if (ioBufferSeg && ioBufNext && ioWriting) {
|
||||
result = writedos(file, ioBufferSeg, 0, ioBufNext);
|
||||
if (result < ioBufNext)
|
||||
result = -1; /* Disk must be full, turn it into an error. */
|
||||
ioBufNext = 0; /* Writing: buffer is empty. */
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* ---------- GSeek ----------------------------------------------------
|
||||
* When reading, ASSUMES seeking forwards.
|
||||
* When writing, flush buffer and use lseek.
|
||||
* RETURNS 0 if succeeded in seeking w/i buffer. DIFFERENT THAN LSEEK.
|
||||
*/
|
||||
LONG GSeek(WORD file, LONG count, WORD seekType)
|
||||
{
|
||||
UWORD nAvail;
|
||||
|
||||
if (ioBufferSeg) {
|
||||
if (ioWriting && ioBufNext) {
|
||||
GFlush(file); /* TBD: Ignoring error code. */
|
||||
goto seekDirectly;
|
||||
}
|
||||
nAvail = ioBufLimit - ioBufNext;
|
||||
|
||||
if (seekType != SEEK_CUR) { /* Check for absolute positioning */
|
||||
goto emptyAndSeekDirectly;
|
||||
}
|
||||
if (count > nAvail) {
|
||||
count -= nAvail; /* Adjust seek for bytes already read ahead. */
|
||||
emptyAndSeekDirectly:
|
||||
ioBufNext = ioBufLimit; /* Reading: buffer is empty. */
|
||||
goto seekDirectly;
|
||||
}
|
||||
ioBufNext += (UWORD)count; /* Seek within the buffer. */
|
||||
return (0); /* DIFFERENT THAN LSEEK */
|
||||
} else
|
||||
seekDirectly:
|
||||
return lseek(file, count, seekType);
|
||||
}
|
||||
|
||||
/* ---------- GWrite ---------------------------------------------
|
||||
* Like DOS "write" function, RETURNS # bytes written, or -1 at error.
|
||||
* DIFFERENCE: if can't write them all, returns -1 instead of # written,
|
||||
* UNLESS "writeDirectly", which just uses write().
|
||||
*/
|
||||
WORD GWrite(WORD file, UBYTE * buffer, UWORD nBytes)
|
||||
{
|
||||
UWORD nRemaining, nUnused, nThisTime, nWritten;
|
||||
|
||||
if (ioBufferSeg) {
|
||||
if (!ioBufNext && nBytes >= ioBufSize)
|
||||
goto writeDirectly; /* More efficient to write buffer directly. */
|
||||
|
||||
nUnused = ioBufSize - ioBufNext; /* # bytes unused in buffer. */
|
||||
|
||||
/* Remaining # bytes that need writing. */
|
||||
for (nRemaining = nBytes; nRemaining; nRemaining -= nThisTime) {
|
||||
if (!nUnused) {
|
||||
nWritten = writedos(file, ioBufferSeg, 0, ioBufNext);
|
||||
if (nWritten != ioBufNext) {
|
||||
ioBufNext = 0; /* Flush the data -- it is lost. */
|
||||
return (-1); /* ERROR */
|
||||
}
|
||||
ioBufNext = 0;
|
||||
nUnused = ioBufSize;
|
||||
}
|
||||
nThisTime = MIN(nRemaining, nUnused);
|
||||
far_movmem(dataseg(),
|
||||
(UWORD)buffer, ioBufferSeg,
|
||||
ioBufNext, (UWORD)nThisTime);
|
||||
buffer += nThisTime;
|
||||
ioBufNext += nThisTime;
|
||||
nUnused -= nThisTime;
|
||||
}
|
||||
return (nBytes); /* OKAY */
|
||||
} else /* No ioBuf */
|
||||
writeDirectly:
|
||||
return (write(file, buffer, nBytes));
|
||||
}
|
||||
Reference in New Issue
Block a user