/*----------------------------------------------------------------------*/ /* GIO.C Generic I/O Speed Up Package 1/23/86 */ /* See GIOCall.C for an example of usage. */ /* Read not speeded-up yet. Only one Write file buffered at a time. */ /* Note: The speed-up provided is ONLY significant for code such as IFF */ /* which does numerous small Writes and Seeks. */ /* */ /* By Jerry Morrison and Steve Shaw, Electronic Arts. */ /* This software is in the public domain. */ /* */ /* This version for the Commodore-Amiga computer. */ /* */ /*----------------------------------------------------------------------*/ #include "iff/gio.h" /* See comments here for explanation.*/ #if GIO_ACTIVE #define local static local BPTR wFile = NULL; local BYTE *wBuffer = NULL; local LONG wNBytes = 0; /* buffer size in bytes.*/ local LONG wIndex = 0; /* index of next available byte.*/ local LONG wWaterline = 0; /* Count of # bytes to be written. * Different than wIndex because of GSeek.*/ /*----------- GOpen ----------------------------------------------------*/ LONG GOpen(filename, openmode) char *filename; LONG openmode; { return( Open(filename, openmode) ); } /*----------- GClose ---------------------------------------------------*/ LONG GClose(file) BPTR file; { LONG signal = 0, signal2; if (file == wFile) signal = GWriteUndeclare(file); signal2 = Close(file); /* Call Close even if trouble with write.*/ if (signal2 < 0) signal = signal2; return( signal ); } /*----------- GRead ----------------------------------------------------*/ LONG GRead(file, buffer, nBytes) BPTR file; BYTE *buffer; LONG nBytes; { LONG signal = 0; /* We don't yet read directly from the buffer, so flush it to disk and * let the DOS fetch it back. */ if (file == wFile) signal = GWriteFlush(file); if (signal >= 0) signal = Read(file, buffer, nBytes); return( signal ); } /* ---------- GWriteFlush ----------------------------------------------*/ LONG GWriteFlush(file) BPTR file; { LONG gWrite = 0; if (wFile != NULL && wBuffer != NULL && wIndex > 0) gWrite = Write(wFile, wBuffer, wWaterline); wWaterline = wIndex = 0; /* No matter what, make sure this happens.*/ return( gWrite ); } /* ---------- GWriteDeclare --------------------------------------------*/ LONG GWriteDeclare(file, buffer, nBytes) BPTR file; BYTE *buffer; LONG nBytes; { LONG gWrite = GWriteFlush(wFile); /* Finish any existing usage.*/ if ( file==NULL || (file==wFile && buffer==NULL) || nBytes<=3) { wFile = NULL; wBuffer = NULL; wNBytes = 0; } else { wFile = file; wBuffer = buffer; wNBytes = nBytes; } return( gWrite ); } /* ---------- GWrite ---------------------------------------------------*/ LONG GWrite(file, buffer, nBytes) BPTR file; BYTE *buffer; LONG nBytes; { LONG gWrite = 0; if (file == wFile && wBuffer != NULL) { if (wNBytes >= wIndex + nBytes) { /* Append to wBuffer.*/ movmem(buffer, wBuffer+wIndex, nBytes); wIndex += nBytes; if (wIndex > wWaterline) wWaterline = wIndex; nBytes = 0; /* Indicate data has been swallowed.*/ } else { wWaterline = wIndex; /* We are about to overwrite any * data above wIndex, up to at least the buffer end.*/ gWrite = GWriteFlush(file); /* Write data out in proper order.*/ } } if (nBytes > 0 && gWrite >= 0) gWrite += Write(file, buffer, nBytes); return( gWrite ); } /* ---------- GSeek ----------------------------------------------------*/ LONG GSeek(file, position, mode) BPTR file; LONG position; LONG mode; { LONG gSeek = -2; LONG newWIndex = wIndex + position; if (file == wFile && wBuffer != NULL) { if (mode == OFFSET_CURRENT && newWIndex >= 0 && newWIndex <= wWaterline) { gSeek = wIndex; /* Okay; return *OLD* position */ wIndex = newWIndex; } else { /* We don't even try to optimize the other cases.*/ gSeek = GWriteFlush(file); if (gSeek >= 0) gSeek = -2; /* OK so far */ } } if (gSeek == -2) gSeek = Seek(file, position, mode); return( gSeek ); } #else /* not GIO_ACTIVE */ void GIODummy() { } /* to keep the compiler happy */ #endif GIO_ACTIVE