- Main Page
- Data Structures
- Files

- File List

# E:/DevIL/src-IL/src/il_files.c

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Sources
    00004 // Copyright (C) 2000-2009 by Denton Woods
    00005 // Last modified: 01/04/2009
    00006 //
    00007 // Filename: src-IL/src/il_files.c
    00008 //
    00009 // Description: File handling for DevIL
    00010 //
    00011 //-----------------------------------------------------------------------------
    00012
    00013
    00014 #define __FILES_C
    00015 #include "il_internal.h"
    00016 #include <stdarg.h>
    00017
    00018
    00019 // All specific to the next set of functions
    00020 ILboolean       ILAPIENTRY iEofFile(void);
    00021 ILboolean       ILAPIENTRY iEofLump(void);
    00022 ILint           ILAPIENTRY iGetcFile(void);
    00023 ILint           ILAPIENTRY iGetcLump(void);
    00024 ILuint          ILAPIENTRY iReadFile(void *Buffer, ILuint Size, ILuint Number);
    00025 ILuint          ILAPIENTRY iReadLump(void *Buffer, const ILuint Size, const ILuint Number);
    00026 ILint           ILAPIENTRY iSeekRFile(ILint Offset, ILuint Mode);
    00027 ILint           ILAPIENTRY iSeekRLump(ILint Offset, ILuint Mode);
    00028 ILint           ILAPIENTRY iSeekWFile(ILint Offset, ILuint Mode);
    00029 ILint           ILAPIENTRY iSeekWLump(ILint Offset, ILuint Mode);
    00030 ILuint          ILAPIENTRY iTellRFile(void);
    00031 ILuint          ILAPIENTRY iTellRLump(void);
    00032 ILuint          ILAPIENTRY iTellWFile(void);
    00033 ILuint          ILAPIENTRY iTellWLump(void);
    00034 ILint           ILAPIENTRY iPutcFile(ILubyte Char);
    00035 ILint           ILAPIENTRY iPutcLump(ILubyte Char);
    00036 ILint           ILAPIENTRY iWriteFile(const void *Buffer, ILuint Size, ILuint Number);
    00037 ILint           ILAPIENTRY iWriteLump(const void *Buffer, ILuint Size, ILuint Number);
    00038 ILHANDLE        FileRead = NULL, FileWrite = NULL;
    00039 const void *ReadLump = NULL;
    00040 void            *WriteLump = NULL;
    00041 ILuint          ReadLumpPos = 0, ReadLumpSize = 0, ReadFileStart = 0, WriteFileStart = 0;
    00042 ILuint          WriteLumpPos = 0, WriteLumpSize = 0;
    00043
    00044 fGetcProc       GetcProcCopy;
    00045 fReadProc       ReadProcCopy;
    00046 fSeekRProc      SeekProcCopy;
    00047 fTellRProc      TellProcCopy;
    00048 ILHANDLE        (ILAPIENTRY *iopenCopy)(ILconst_string);
    00049 void            (ILAPIENTRY *icloseCopy)(ILHANDLE);
    00050
    00051 fPutcProc       PutcProcCopy;
    00052 fSeekWProc      SeekWProcCopy;
    00053 fTellWProc      TellWProcCopy;
    00054 fWriteProc      WriteProcCopy;
    00055 ILHANDLE        (ILAPIENTRY *iopenwCopy)(ILconst_string);
    00056 void            (ILAPIENTRY *iclosewCopy)(ILHANDLE);
    00057
    00058 ILboolean       UseCache = IL_FALSE;
    00059 ILubyte         *Cache = NULL;
    00060 ILuint          CacheSize, CachePos, CacheStartPos, CacheBytesRead;
    00061
    00062 // "Fake" size functions
    00063 //  Definitions are in il_size.c.
    00064 ILint           ILAPIENTRY iSizeSeek(ILint Offset, ILuint Mode);
    00065 ILuint          ILAPIENTRY iSizeTell(void);
    00066 ILint           ILAPIENTRY iSizePutc(ILubyte Char);
    00067 ILint           ILAPIENTRY iSizeWrite(const void *Buffer, ILuint Size, ILuint Number);
    00068
    00069 /*// Just preserves the current read functions and replaces
    00070 //      the current read functions with the default read funcs.
    00071 void ILAPIENTRY iPreserveReadFuncs()
    00072 {
    00073         // Create backups
    00074         GetcProcCopy = GetcProc;
    00075         ReadProcCopy = ReadProc;
    00076         SeekProcCopy = SeekRProc;
    00077         TellProcCopy = TellRProc;
    00078         iopenCopy = iopenr;
    00079         icloseCopy = icloser;
    00080
    00081         // Set the standard procs to read
    00082         ilResetRead();
    00083
    00084         return;
    00085 }
    00086
    00087
    00088 // Restores the read functions - must be used after iPreserveReadFuncs().
    00089 void ILAPIENTRY iRestoreReadFuncs()
    00090 {
    00091         GetcProc = GetcProcCopy;
    00092         ReadProc = ReadProcCopy;
    00093         SeekRProc = SeekProcCopy;
    00094         TellRProc = TellProcCopy;
    00095         iopenr = iopenCopy;
    00096         icloser = icloseCopy;
    00097
    00098         return;
    00099 }*/
    00100
    00101
    00102 // Just preserves the current read functions and replaces
    00103 //      the current read functions with the default read funcs.
    00104 void ILAPIENTRY iPreserveWriteFuncs()
    00105 {
    00106         // Create backups
    00107         PutcProcCopy = PutcProc;
    00108         SeekWProcCopy = SeekWProc;
    00109         TellWProcCopy = TellWProc;
    00110         WriteProcCopy = WriteProc;
    00111         iopenwCopy = iopenw;
    00112         iclosewCopy = iclosew;
    00113
    00114         // Set the standard procs to write
    00115         ilResetWrite();
    00116
    00117         return;
    00118 }
    00119
    00120
    00121 // Restores the read functions - must be used after iPreserveReadFuncs().
    00122 void ILAPIENTRY iRestoreWriteFuncs()
    00123 {
    00124         PutcProc = PutcProcCopy;
    00125         SeekWProc = SeekWProcCopy;
    00126         TellWProc = TellWProcCopy;
    00127         WriteProc = WriteProcCopy;
    00128         iopenw = iopenwCopy;
    00129         iclosew = iclosewCopy;
    00130
    00131         return;
    00132 }
    00133
    00134
    00135 // Next 7 functions are the default read functions
    00136
    00137 ILHANDLE ILAPIENTRY iDefaultOpenR(ILconst_string FileName)
    00138 {
    00139 #ifndef _UNICODE
    00140         return (ILHANDLE)fopen((char*)FileName, "rb");
    00141 #else
    00142         // Windows has a different function, _wfopen, to open UTF16 files,
    00143         //  whereas Linux just uses fopen for its UTF8 files.
    00144         #ifdef _WIN32
    00145                 return (ILHANDLE)_wfopen(FileName, L"rb");
    00146         #else
    00147                 return (ILHANDLE)fopen((char*)FileName, "rb");
    00148         #endif
    00149 #endif//UNICODE
    00150 }
    00151
    00152
    00153 void ILAPIENTRY iDefaultCloseR(ILHANDLE Handle)
    00154 {
    00155         fclose((FILE*)Handle);
    00156         return;
    00157 }
    00158
    00159
    00160 ILboolean ILAPIENTRY iDefaultEof(ILHANDLE Handle)
    00161 {
    00162         ILuint OrigPos, FileSize;
    00163
    00164         // Find out the filesize for checking for the end of file
    00165         OrigPos = itell();
    00166         iseek(0, IL_SEEK_END);
    00167         FileSize = itell();
    00168         iseek(OrigPos, IL_SEEK_SET);
    00169
    00170         if (itell() >= FileSize)
    00171                 return IL_TRUE;
    00172         return IL_FALSE;
    00173 }
    00174
    00175
    00176 ILint ILAPIENTRY iDefaultGetc(ILHANDLE Handle)
    00177 {
    00178         ILint Val;
    00179
    00180         if (!UseCache) {
    00181                 Val = fgetc((FILE*)Handle);
    00182                 if (Val == IL_EOF)
    00183                         ilSetError(IL_FILE_READ_ERROR);
    00184         }
    00185         else {
    00186                 Val = 0;
    00187                 if (iread(&Val, 1, 1) != 1)
    00188                         return IL_EOF;
    00189         }
    00190         return Val;
    00191 }
    00192
    00193
    00194 ILint ILAPIENTRY iDefaultRead(void *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle)
    00195 {
    00196         return (ILint)fread(Buffer, Size, Number, (FILE*)Handle);
    00197 }
    00198
    00199
    00200 ILint ILAPIENTRY iDefaultRSeek(ILHANDLE Handle, ILint Offset, ILint Mode)
    00201 {
    00202         return fseek((FILE*)Handle, Offset, Mode);
    00203 }
    00204
    00205
    00206 ILint ILAPIENTRY iDefaultWSeek(ILHANDLE Handle, ILint Offset, ILint Mode)
    00207 {
    00208         return fseek((FILE*)Handle, Offset, Mode);
    00209 }
    00210
    00211
    00212 ILint ILAPIENTRY iDefaultRTell(ILHANDLE Handle)
    00213 {
    00214         return ftell((FILE*)Handle);
    00215 }
    00216
    00217
    00218 ILint ILAPIENTRY iDefaultWTell(ILHANDLE Handle)
    00219 {
    00220         return ftell((FILE*)Handle);
    00221 }
    00222
    00223
    00224 ILHANDLE ILAPIENTRY iDefaultOpenW(ILconst_string FileName)
    00225 {
    00226 #ifndef _UNICODE
    00227         return (ILHANDLE)fopen((char*)FileName, "wb");
    00228 #else
    00229         // Windows has a different function, _wfopen, to open UTF16 files,
    00230         //  whereas Linux just uses fopen.
    00231         #ifdef _WIN32
    00232                 return (ILHANDLE)_wfopen(FileName, L"wb");
    00233         #else
    00234                 return (ILHANDLE)fopen((char*)FileName, "wb");
    00235         #endif
    00236 #endif//UNICODE
    00237 }
    00238
    00239
    00240 void ILAPIENTRY iDefaultCloseW(ILHANDLE Handle)
    00241 {
    00242         fclose((FILE*)Handle);
    00243         return;
    00244 }
    00245
    00246
    00247 ILint ILAPIENTRY iDefaultPutc(ILubyte Char, ILHANDLE Handle)
    00248 {
    00249         return fputc(Char, (FILE*)Handle);
    00250 }
    00251
    00252
    00253 ILint ILAPIENTRY iDefaultWrite(const void *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle)
    00254 {
    00255         return (ILint)fwrite(Buffer, Size, Number, (FILE*)Handle);
    00256 }
    00257
    00258
    00259 void ILAPIENTRY ilResetRead()
    00260 {
    00261         ilSetRead(iDefaultOpenR, iDefaultCloseR, iDefaultEof, iDefaultGetc,
    00262                                 iDefaultRead, iDefaultRSeek, iDefaultRTell);
    00263         return;
    00264 }
    00265
    00266
    00267 void ILAPIENTRY ilResetWrite()
    00268 {
    00269         ilSetWrite(iDefaultOpenW, iDefaultCloseW, iDefaultPutc,
    00270                                 iDefaultWSeek, iDefaultWTell, iDefaultWrite);
    00271         return;
    00272 }
    00273
    00274
    00276 void ILAPIENTRY ilSetRead(fOpenRProc Open, fCloseRProc Close, fEofProc Eof, fGetcProc Getc, fReadProc Read, fSeekRProc Seek, fTellRProc Tell)
    00277 {
    00278         iopenr    = Open;
    00279         icloser   = Close;
    00280         EofProc   = Eof;
    00281         GetcProc  = Getc;
    00282         ReadProc  = Read;
    00283         SeekRProc = Seek;
    00284         TellRProc = Tell;
    00285
    00286         return;
    00287 }
    00288
    00289
    00291 void ILAPIENTRY ilSetWrite(fOpenRProc Open, fCloseRProc Close, fPutcProc Putc, fSeekWProc Seek, fTellWProc Tell, fWriteProc Write)
    00292 {
    00293         iopenw    = Open;
    00294         iclosew   = Close;
    00295         PutcProc  = Putc;
    00296         WriteProc = Write;
    00297         SeekWProc = Seek;
    00298         TellWProc = Tell;
    00299
    00300         return;
    00301 }
    00302
    00303
    00304 // Tells DevIL that we're reading from a file, not a lump
    00305 void iSetInputFile(ILHANDLE File)
    00306 {
    00307         ieof  = iEofFile;
    00308         igetc = iGetcFile;
    00309         iread = iReadFile;
    00310         iseek = iSeekRFile;
    00311         itell = iTellRFile;
    00312         FileRead = File;
    00313         ReadFileStart = itell();
    00314 }
    00315
    00316
    00317 // Tells DevIL that we're reading from a lump, not a file
    00318 void iSetInputLump(const void *Lump, ILuint Size)
    00319 {
    00320         ieof  = iEofLump;
    00321         igetc = iGetcLump;
    00322         iread = iReadLump;
    00323         iseek = iSeekRLump;
    00324         itell = iTellRLump;
    00325         ReadLump = Lump;
    00326         ReadLumpPos = 0;
    00327         ReadLumpSize = Size;
    00328 }
    00329
    00330
    00331 // Tells DevIL that we're writing to a file, not a lump
    00332 void iSetOutputFile(ILHANDLE File)
    00333 {
    00334         // Helps with ilGetLumpPos().
    00335         WriteLump = NULL;
    00336         WriteLumpPos = 0;
    00337         WriteLumpSize = 0;
    00338
    00339         iputc  = iPutcFile;
    00340         iseekw = iSeekWFile;
    00341         itellw = iTellWFile;
    00342         iwrite = iWriteFile;
    00343         FileWrite = File;
    00344 }
    00345
    00346
    00347 // This is only called by ilDetermineSize.  Associates iputc, etc. with
    00348 //  "fake" writing functions in il_size.c.
    00349 void iSetOutputFake(void)
    00350 {
    00351         iputc  = iSizePutc;
    00352         iseekw = iSizeSeek;
    00353         itellw = iSizeTell;
    00354         iwrite = iSizeWrite;
    00355         return;
    00356 }
    00357
    00358
    00359 // Tells DevIL that we're writing to a lump, not a file
    00360 void iSetOutputLump(void *Lump, ILuint Size)
    00361 {
    00362         // In this case, ilDetermineSize is currently trying to determine the
    00363         //  output buffer size.  It already has the write functions it needs.
    00364         if (Lump == NULL)
    00365                 return;
    00366
    00367         iputc  = iPutcLump;
    00368         iseekw = iSeekWLump;
    00369         itellw = iTellWLump;
    00370         iwrite = iWriteLump;
    00371         WriteLump = Lump;
    00372         WriteLumpPos = 0;
    00373         WriteLumpSize = Size;
    00374 }
    00375
    00376
    00377 ILuint ILAPIENTRY ilGetLumpPos()
    00378 {
    00379         if (WriteLump)
    00380                 return WriteLumpPos;
    00381         return 0;
    00382 }
    00383
    00384
    00385 ILuint ILAPIENTRY ilprintf(const char *Line, ...)
    00386 {
    00387         char    Buffer[2048];  // Hope this is large enough
    00388         va_list VaLine;
    00389         ILuint  i;
    00390
    00391         va_start(VaLine, Line);
    00392         vsprintf(Buffer, Line, VaLine);
    00393         va_end(VaLine);
    00394
    00395         i = ilCharStrLen(Buffer);
    00396         iwrite(Buffer, 1, i);
    00397
    00398         return i;
    00399 }
    00400
    00401
    00402 // To pad zeros where needed...
    00403 void ipad(ILuint NumZeros)
    00404 {
    00405         ILuint i = 0;
    00406         for (; i < NumZeros; i++)
    00407                 iputc(0);
    00408         return;
    00409 }
    00410
    00411
    00412 //
    00413 // The rest of the functions following in this file are quite
    00414 //      self-explanatory, except where commented.
    00415 //
    00416
    00417 // Next 12 functions are the default write functions
    00418
    00419 ILboolean ILAPIENTRY iEofFile(void)
    00420 {
    00421         return EofProc((FILE*)FileRead);
    00422 }
    00423
    00424
    00425 ILboolean ILAPIENTRY iEofLump(void)
    00426 {
    00427         if (ReadLumpSize)
    00428                 return (ReadLumpPos >= ReadLumpSize);
    00429         return IL_FALSE;
    00430 }
    00431
    00432
    00433 ILint ILAPIENTRY iGetcFile(void)
    00434 {
    00435         if (!UseCache) {
    00436                 return GetcProc(FileRead);
    00437         }
    00438         if (CachePos >= CacheSize) {
    00439                 iPreCache(CacheSize);
    00440         }
    00441
    00442         CacheBytesRead++;
    00443         return Cache[CachePos++];
    00444 }
    00445
    00446
    00447 ILint ILAPIENTRY iGetcLump(void)
    00448 {
    00449         // If ReadLumpSize is 0, don't even check to see if we've gone past the bounds.
    00450         if (ReadLumpSize > 0) {
    00451                 if (ReadLumpPos + 1 > ReadLumpSize) {
    00452                         ReadLumpPos--;
    00453                         ilSetError(IL_FILE_READ_ERROR);
    00454                         return IL_EOF;
    00455                 }
    00456         }
    00457
    00458         return *((ILubyte*)ReadLump + ReadLumpPos++);
    00459 }
    00460
    00461
    00462 ILuint ILAPIENTRY iReadFile(void *Buffer, ILuint Size, ILuint Number)
    00463 {
    00464         ILuint  TotalBytes = 0, BytesCopied;
    00465         ILuint  BuffSize = Size * Number;
    00466         ILuint  NumRead;
    00467
    00468         if (!UseCache) {
    00469                 NumRead = ReadProc(Buffer, Size, Number, FileRead);
    00470                 if (NumRead != Number)
    00471                         ilSetError(IL_FILE_READ_ERROR);
    00472                 return NumRead;
    00473         }
    00474
    00475         /*if (Cache == NULL || CacheSize == 0) {  // Shouldn't happen, but we check anyway.
    00476                 return ReadProc(Buffer, Size, Number, FileRead);
    00477         }*/
    00478
    00479         if (BuffSize < CacheSize - CachePos) {
    00480                 memcpy(Buffer, Cache + CachePos, BuffSize);
    00481                 CachePos += BuffSize;
    00482                 CacheBytesRead += BuffSize;
    00483                 if (Size != 0)
    00484                         BuffSize /= Size;
    00485                 return BuffSize;
    00486         }
    00487         else {
    00488                 while (TotalBytes < BuffSize) {
    00489                         // If loop through more than once, after first, CachePos is 0.
    00490                         if (TotalBytes + CacheSize - CachePos > BuffSize)
    00491                                 BytesCopied = BuffSize - TotalBytes;
    00492                         else
    00493                                 BytesCopied = CacheSize - CachePos;
    00494
    00495                         memcpy((ILubyte*)Buffer + TotalBytes, Cache + CachePos, BytesCopied);
    00496                         TotalBytes += BytesCopied;
    00497                         CachePos += BytesCopied;
    00498                         if (TotalBytes < BuffSize) {
    00499                                 iPreCache(CacheSize);
    00500                         }
    00501                 }
    00502         }
    00503
    00504         // DW: Changed on 12-27-2008.  Was causing the position to go too far if the
    00505         //     cache was smaller than the buffer.
    00506         //CacheBytesRead += TotalBytes;
    00507         CacheBytesRead = CachePos;
    00508         if (Size != 0)
    00509                 TotalBytes /= Size;
    00510         if (TotalBytes != Number)
    00511                 ilSetError(IL_FILE_READ_ERROR);
    00512         return TotalBytes;
    00513 }
    00514
    00515
    00516 ILuint ILAPIENTRY iReadLump(void *Buffer, const ILuint Size, const ILuint Number)
    00517 {
    00518         ILuint i, ByteSize = IL_MIN( Size*Number, ReadLumpSize-ReadLumpPos);
    00519
    00520         for (i = 0; i < ByteSize; i++) {
    00521                 *((ILubyte*)Buffer + i) = *((ILubyte*)ReadLump + ReadLumpPos + i);
    00522                 if (ReadLumpSize > 0) {  // ReadLumpSize is too large to care about apparently
    00523                         if (ReadLumpPos + i > ReadLumpSize) {
    00524                                 ReadLumpPos += i;
    00525                                 if (i != Number)
    00526                                         ilSetError(IL_FILE_READ_ERROR);
    00527                                 return i;
    00528                         }
    00529                 }
    00530         }
    00531
    00532         ReadLumpPos += i;
    00533         if (Size != 0)
    00534                 i /= Size;
    00535         if (i != Number)
    00536                 ilSetError(IL_FILE_READ_ERROR);
    00537         return i;
    00538 }
    00539
    00540
    00541 ILboolean iPreCache(ILuint Size)
    00542 {
    00543         // Reading from a memory lump, so don't cache.
    00544         if (iread == iReadLump) {
    00545                 //iUnCache();  // DW: Removed 06-10-2002.
    00546                 return IL_TRUE;
    00547         }
    00548
    00549         if (Cache) {
    00550                 ifree(Cache);
    00551         }
    00552
    00553         if (Size == 0) {
    00554                 Size = 1;
    00555         }
    00556
    00557         Cache = (ILubyte*)ialloc(Size);
    00558         if (Cache == NULL) {
    00559                 return IL_FALSE;
    00560         }
    00561
    00562         UseCache = IL_FALSE;
    00563         CacheStartPos = itell();
    00564         CacheSize = iread(Cache, 1, Size);
    00565         if (CacheSize != Size)
    00566                 ilGetError();  // Get rid of the IL_FILE_READ_ERROR.
    00567
    00568         //2003-09-09: uncommented the following line to prevent
    00569         //an infinite loop in ilPreCache()
    00570         CacheSize = Size;
    00571         CachePos = 0;
    00572         UseCache = IL_TRUE;
    00573         CacheBytesRead = 0;
    00574
    00575         return IL_TRUE;
    00576 }
    00577
    00578
    00579 void iUnCache()
    00580 {
    00581         //changed 2003-09-01:
    00582         //make iUnCache smart enough to return if
    00583         //no cache is used
    00584         if (!UseCache)
    00585                 return;
    00586
    00587         if (iread == iReadLump)
    00588                 return;
    00589
    00590         CacheSize = 0;
    00591         CachePos = 0;
    00592         if (Cache) {
    00593                 ifree(Cache);
    00594                 Cache = NULL;
    00595         }
    00596         UseCache = IL_FALSE;
    00597
    00598         iseek(CacheStartPos + CacheBytesRead, IL_SEEK_SET);
    00599
    00600         return;
    00601 }
    00602
    00603
    00604 ILint ILAPIENTRY iSeekRFile(ILint Offset, ILuint Mode)
    00605 {
    00606         if (Mode == IL_SEEK_SET)
    00607                 Offset += ReadFileStart;  // This allows us to use IL_SEEK_SET in the middle of a file.
    00608         return SeekRProc(FileRead, Offset, Mode);
    00609 }
    00610
    00611
    00612 // Returns 1 on error, 0 on success
    00613 ILint ILAPIENTRY iSeekRLump(ILint Offset, ILuint Mode)
    00614 {
    00615         switch (Mode)
    00616         {
    00617                 case IL_SEEK_SET:
    00618                         if (Offset > (ILint)ReadLumpSize)
    00619                                 return 1;
    00620                         ReadLumpPos = Offset;
    00621                         break;
    00622
    00623                 case IL_SEEK_CUR:
    00624                         if (ReadLumpPos + Offset > ReadLumpSize)
    00625                                 return 1;
    00626                         ReadLumpPos += Offset;
    00627                         break;
    00628
    00629                 case IL_SEEK_END:
    00630                         if (Offset > 0)
    00631                                 return 1;
    00632                         // Should we use >= instead?
    00633                         if (abs(Offset) > (ILint)ReadLumpSize)  // If ReadLumpSize == 0, too bad
    00634                                 return 1;
    00635                         ReadLumpPos = ReadLumpSize + Offset;
    00636                         break;
    00637
    00638                 default:
    00639                         return 1;
    00640         }
    00641
    00642         return 0;
    00643 }
    00644
    00645
    00646 ILuint ILAPIENTRY iTellRFile(void)
    00647 {
    00648         return TellRProc(FileRead);
    00649 }
    00650
    00651
    00652 ILuint ILAPIENTRY iTellRLump(void)
    00653 {
    00654         return ReadLumpPos;
    00655 }
    00656
    00657
    00658 ILHANDLE ILAPIENTRY iGetFile(void)
    00659 {
    00660         return FileRead;
    00661 }
    00662
    00663
    00664 const ILubyte* ILAPIENTRY iGetLump(void) {
    00665         return (ILubyte*)ReadLump;
    00666 }
    00667
    00668
    00669
    00670 // Next 4 functions are the default write functions
    00671
    00672 ILint ILAPIENTRY iPutcFile(ILubyte Char)
    00673 {
    00674         return PutcProc(Char, FileWrite);
    00675 }
    00676
    00677
    00678 ILint ILAPIENTRY iPutcLump(ILubyte Char)
    00679 {
    00680         if (WriteLumpPos >= WriteLumpSize)
    00681                 return IL_EOF;  // IL_EOF
    00682         *((ILubyte*)(WriteLump) + WriteLumpPos++) = Char;
    00683         return Char;
    00684 }
    00685
    00686
    00687 ILint ILAPIENTRY iWriteFile(const void *Buffer, ILuint Size, ILuint Number)
    00688 {
    00689         ILuint NumWritten;
    00690         NumWritten = WriteProc(Buffer, Size, Number, FileWrite);
    00691         if (NumWritten != Number) {
    00692                 ilSetError(IL_FILE_WRITE_ERROR);
    00693                 return 0;
    00694         }
    00695         return NumWritten;
    00696 }
    00697
    00698
    00699 ILint ILAPIENTRY iWriteLump(const void *Buffer, ILuint Size, ILuint Number)
    00700 {
    00701         ILuint SizeBytes = Size * Number;
    00702         ILuint i = 0;
    00703
    00704         for (; i < SizeBytes; i++) {
    00705                 if (WriteLumpSize > 0) {
    00706                         if (WriteLumpPos + i >= WriteLumpSize) {  // Should we use > instead?
    00707                                 ilSetError(IL_FILE_WRITE_ERROR);
    00708                                 WriteLumpPos += i;
    00709                                 return i;
    00710                         }
    00711                 }
    00712
    00713                 *((ILubyte*)WriteLump + WriteLumpPos + i) = *((ILubyte*)Buffer + i);
    00714         }
    00715
    00716         WriteLumpPos += SizeBytes;
    00717
    00718         return SizeBytes;
    00719 }
    00720
    00721
    00722 ILint ILAPIENTRY iSeekWFile(ILint Offset, ILuint Mode)
    00723 {
    00724         if (Mode == IL_SEEK_SET)
    00725                 Offset += WriteFileStart;  // This allows us to use IL_SEEK_SET in the middle of a file.
    00726         return SeekWProc(FileWrite, Offset, Mode);
    00727 }
    00728
    00729
    00730 // Returns 1 on error, 0 on success
    00731 ILint ILAPIENTRY iSeekWLump(ILint Offset, ILuint Mode)
    00732 {
    00733         switch (Mode)
    00734         {
    00735                 case IL_SEEK_SET:
    00736                         if (Offset > (ILint)WriteLumpSize)
    00737                                 return 1;
    00738                         WriteLumpPos = Offset;
    00739                         break;
    00740
    00741                 case IL_SEEK_CUR:
    00742                         if (WriteLumpPos + Offset > WriteLumpSize)
    00743                                 return 1;
    00744                         WriteLumpPos += Offset;
    00745                         break;
    00746
    00747                 case IL_SEEK_END:
    00748                         if (Offset > 0)
    00749                                 return 1;
    00750                         // Should we use >= instead?
    00751                         if (abs(Offset) > (ILint)WriteLumpSize)  // If WriteLumpSize == 0, too bad
    00752                                 return 1;
    00753                         WriteLumpPos = WriteLumpSize + Offset;
    00754                         break;
    00755
    00756                 default:
    00757                         return 1;
    00758         }
    00759
    00760         return 0;
    00761 }
    00762
    00763
    00764 ILuint ILAPIENTRY iTellWFile(void)
    00765 {
    00766         return TellWProc(FileWrite);
    00767 }
    00768
    00769
    00770 ILuint ILAPIENTRY iTellWLump(void)
    00771 {
    00772         return WriteLumpPos;
    00773 }