1 /* MikMod sound library
2 (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of
8 the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 /*==============================================================================
25 Portable file I/O routines
27 ==============================================================================*/
31 The way this module works:
33 - _mm_fopen will call the errorhandler [see mmerror.c] in addition to
34 setting _mm_errno on exit.
35 - _mm_iobase is for internal use. It is used by Player_LoadFP to
36 ensure that it works properly with wad files.
37 - _mm_read_I_* and _mm_read_M_* differ : the first is for reading data
38 written by a little endian (intel) machine, and the second is for reading
39 big endian (Mac, RISC, Alpha) machine data.
40 - _mm_write functions work the same as the _mm_read functions.
41 - _mm_read_string is for reading binary strings. It is basically the same
61 #include "mikmod_internals.h"
64 extern int fclose(FILE *);
65 extern int fgetc(FILE *);
66 extern int fputc(int, FILE *);
67 extern size_t fread(void *, size_t, size_t, FILE *);
68 extern int fseek(FILE *, long, int);
69 extern size_t fwrite(const void *, size_t, size_t, FILE *);
72 #define COPY_BUFSIZE 1024
75 static BOOL _mm_MemReader_Eof(MREADER* reader);
76 static BOOL _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size);
77 static int _mm_MemReader_Get(MREADER* reader);
78 static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence);
79 static long _mm_MemReader_Tell(MREADER* reader);
81 /*static long _mm_iobase = 0, temp_iobase = 0;*/
83 FILE* _mm_fopen(const CHAR* fname, const CHAR* attrib)
87 if(!(fp=fopen(fname,attrib))) {
88 _mm_errno = MMERR_OPENING_FILE;
89 if(_mm_errorhandler) _mm_errorhandler();
94 BOOL _mm_FileExists(const CHAR* fname)
98 if(!(fp=fopen(fname,"r"))) return 0;
104 int _mm_fclose(FILE *fp)
109 /* Sets the current file-position as the new iobase */
110 void _mm_iobase_setcur(MREADER* reader)
112 reader->prev_iobase=reader->iobase; /* store old value in case of revert */
113 reader->iobase=reader->Tell(reader);
116 /* Reverts to the last known iobase value. */
117 void _mm_iobase_revert(MREADER* reader)
119 reader->iobase=reader->prev_iobase;
122 /*========== File Reader */
124 typedef struct MFILEREADER {
129 static BOOL _mm_FileReader_Eof(MREADER* reader)
131 return feof(((MFILEREADER*)reader)->file);
134 static BOOL _mm_FileReader_Read(MREADER* reader,void* ptr,size_t size)
136 return !!fread(ptr,size,1,((MFILEREADER*)reader)->file);
139 static int _mm_FileReader_Get(MREADER* reader)
141 return fgetc(((MFILEREADER*)reader)->file);
144 static int _mm_FileReader_Seek(MREADER* reader,long offset,int whence)
146 return fseek(((MFILEREADER*)reader)->file,
147 (whence==SEEK_SET)?offset+reader->iobase:offset,whence);
150 static long _mm_FileReader_Tell(MREADER* reader)
152 return ftell(((MFILEREADER*)reader)->file)-reader->iobase;
155 MREADER *_mm_new_file_reader(FILE* fp)
157 MFILEREADER* reader=(MFILEREADER*)MikMod_calloc(1,sizeof(MFILEREADER));
159 reader->core.Eof =&_mm_FileReader_Eof;
160 reader->core.Read=&_mm_FileReader_Read;
161 reader->core.Get =&_mm_FileReader_Get;
162 reader->core.Seek=&_mm_FileReader_Seek;
163 reader->core.Tell=&_mm_FileReader_Tell;
166 return (MREADER*)reader;
169 void _mm_delete_file_reader (MREADER* reader)
174 /*========== File Writer */
176 typedef struct MFILEWRITER {
181 static int _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence)
183 return fseek(((MFILEWRITER*)writer)->file,offset,whence);
186 static long _mm_FileWriter_Tell(MWRITER* writer)
188 return ftell(((MFILEWRITER*)writer)->file);
191 static BOOL _mm_FileWriter_Write(MWRITER* writer, const void* ptr, size_t size)
193 return (fwrite(ptr,size,1,((MFILEWRITER*)writer)->file)==size);
196 static int _mm_FileWriter_Put(MWRITER* writer,int value)
198 return fputc(value,((MFILEWRITER*)writer)->file);
201 MWRITER *_mm_new_file_writer(FILE* fp)
203 MFILEWRITER* writer=(MFILEWRITER*)MikMod_calloc(1,sizeof(MFILEWRITER));
205 writer->core.Seek =&_mm_FileWriter_Seek;
206 writer->core.Tell =&_mm_FileWriter_Tell;
207 writer->core.Write=&_mm_FileWriter_Write;
208 writer->core.Put =&_mm_FileWriter_Put;
211 return (MWRITER*) writer;
214 void _mm_delete_file_writer (MWRITER* writer)
216 MikMod_free (writer);
219 /*========== Memory Reader */
221 typedef struct MMEMREADER {
228 void _mm_delete_mem_reader(MREADER* reader)
233 MREADER *_mm_new_mem_reader(const void *buffer, long len)
235 MMEMREADER* reader=(MMEMREADER*)MikMod_calloc(1,sizeof(MMEMREADER));
238 reader->core.Eof =&_mm_MemReader_Eof;
239 reader->core.Read=&_mm_MemReader_Read;
240 reader->core.Get =&_mm_MemReader_Get;
241 reader->core.Seek=&_mm_MemReader_Seek;
242 reader->core.Tell=&_mm_MemReader_Tell;
243 reader->buffer = buffer;
247 return (MREADER*)reader;
250 static BOOL _mm_MemReader_Eof(MREADER* reader)
252 MMEMREADER* mr = (MMEMREADER*) reader;
254 if (mr->pos >= mr->len) return 1;
258 static BOOL _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size)
261 const unsigned char *s;
266 if (!reader || !size || (size > (size_t) LONG_MAX))
269 mr = (MMEMREADER*) reader;
271 if (mr->pos >= mr->len) return 0; /* @ eof */
272 if (mr->pos + siz > mr->len) {
273 siz = mr->len - mr->pos;
274 ret = 0; /* not enough remaining bytes */
280 s = (const unsigned char *) mr->buffer;
283 d = (unsigned char *) ptr;
293 static int _mm_MemReader_Get(MREADER* reader)
298 mr = (MMEMREADER*) reader;
299 if (mr->pos >= mr->len) return EOF;
300 c = ((const unsigned char*) mr->buffer)[mr->pos];
306 static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence)
310 if (!reader) return -1;
311 mr = (MMEMREADER*) reader;
318 mr->pos = reader->iobase + offset;
321 mr->pos = mr->len + offset;
324 if (mr->pos < reader->iobase) {
325 mr->pos = mr->core.iobase;
328 if (mr->pos > mr->len) {
334 static long _mm_MemReader_Tell(MREADER* reader)
337 return ((MMEMREADER*)reader)->pos - reader->iobase;
342 /*========== Write functions */
344 void _mm_write_string(const CHAR* data,MWRITER* writer)
347 _mm_write_UBYTES(data,strlen(data),writer);
350 void _mm_write_M_UWORD(UWORD data,MWRITER* writer)
352 _mm_write_UBYTE(data>>8,writer);
353 _mm_write_UBYTE(data&0xff,writer);
356 void _mm_write_I_UWORD(UWORD data,MWRITER* writer)
358 _mm_write_UBYTE(data&0xff,writer);
359 _mm_write_UBYTE(data>>8,writer);
362 void _mm_write_M_ULONG(ULONG data,MWRITER* writer)
364 _mm_write_M_UWORD(data>>16,writer);
365 _mm_write_M_UWORD(data&0xffff,writer);
368 void _mm_write_I_ULONG(ULONG data,MWRITER* writer)
370 _mm_write_I_UWORD(data&0xffff,writer);
371 _mm_write_I_UWORD(data>>16,writer);
374 void _mm_write_M_SWORD(SWORD data,MWRITER* writer)
376 _mm_write_M_UWORD((UWORD)data,writer);
379 void _mm_write_I_SWORD(SWORD data,MWRITER* writer)
381 _mm_write_I_UWORD((UWORD)data,writer);
384 void _mm_write_M_SLONG(SLONG data,MWRITER* writer)
386 _mm_write_M_ULONG((ULONG)data,writer);
389 void _mm_write_I_SLONG(SLONG data,MWRITER* writer)
391 _mm_write_I_ULONG((ULONG)data,writer);
394 void _mm_write_M_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
396 while(cnt-- > 0) _mm_write_M_SWORD(*(buffer++),writer);
399 void _mm_write_M_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
401 while(cnt-- > 0) _mm_write_M_UWORD(*(buffer++),writer);
404 void _mm_write_I_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
406 while(cnt-- > 0) _mm_write_I_SWORD(*(buffer++),writer);
409 void _mm_write_I_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
411 while(cnt-- > 0) _mm_write_I_UWORD(*(buffer++),writer);
414 void _mm_write_M_SLONGS(SLONG *buffer,int cnt,MWRITER* writer)
416 while(cnt-- > 0) _mm_write_M_SLONG(*(buffer++),writer);
419 void _mm_write_M_ULONGS(ULONG *buffer,int cnt,MWRITER* writer)
421 while(cnt-- > 0) _mm_write_M_ULONG(*(buffer++),writer);
424 void _mm_write_I_SLONGS(SLONG *buffer,int cnt,MWRITER* writer)
426 while(cnt-- > 0) _mm_write_I_SLONG(*(buffer++),writer);
429 void _mm_write_I_ULONGS(ULONG *buffer,int cnt,MWRITER* writer)
431 while(cnt-- > 0) _mm_write_I_ULONG(*(buffer++),writer);
434 /*========== Read functions */
436 BOOL _mm_read_string(CHAR* buffer,int cnt,MREADER* reader)
438 return reader->Read(reader,buffer,cnt);
441 UWORD _mm_read_M_UWORD(MREADER* reader)
443 UWORD result=((UWORD)_mm_read_UBYTE(reader))<<8;
444 result|=_mm_read_UBYTE(reader);
448 UWORD _mm_read_I_UWORD(MREADER* reader)
450 UWORD result=_mm_read_UBYTE(reader);
451 result|=((UWORD)_mm_read_UBYTE(reader))<<8;
455 ULONG _mm_read_M_ULONG(MREADER* reader)
457 ULONG result=((ULONG)_mm_read_M_UWORD(reader))<<16;
458 result|=_mm_read_M_UWORD(reader);
462 ULONG _mm_read_I_ULONG(MREADER* reader)
464 ULONG result=_mm_read_I_UWORD(reader);
465 result|=((ULONG)_mm_read_I_UWORD(reader))<<16;
469 SWORD _mm_read_M_SWORD(MREADER* reader)
471 return((SWORD)_mm_read_M_UWORD(reader));
474 SWORD _mm_read_I_SWORD(MREADER* reader)
476 return((SWORD)_mm_read_I_UWORD(reader));
479 SLONG _mm_read_M_SLONG(MREADER* reader)
481 return((SLONG)_mm_read_M_ULONG(reader));
484 SLONG _mm_read_I_SLONG(MREADER* reader)
486 return((SLONG)_mm_read_I_ULONG(reader));
489 BOOL _mm_read_M_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
491 while(cnt-- > 0) *(buffer++)=_mm_read_M_SWORD(reader);
492 return !reader->Eof(reader);
495 BOOL _mm_read_M_UWORDS(UWORD *buffer,int cnt,MREADER* reader)
497 while(cnt-- > 0) *(buffer++)=_mm_read_M_UWORD(reader);
498 return !reader->Eof(reader);
501 BOOL _mm_read_I_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
503 while(cnt-- > 0) *(buffer++)=_mm_read_I_SWORD(reader);
504 return !reader->Eof(reader);
507 BOOL _mm_read_I_UWORDS(UWORD *buffer,int cnt,MREADER* reader)
509 while(cnt-- > 0) *(buffer++)=_mm_read_I_UWORD(reader);
510 return !reader->Eof(reader);
513 BOOL _mm_read_M_SLONGS(SLONG *buffer,int cnt,MREADER* reader)
515 while(cnt-- > 0) *(buffer++)=_mm_read_M_SLONG(reader);
516 return !reader->Eof(reader);
519 BOOL _mm_read_M_ULONGS(ULONG *buffer,int cnt,MREADER* reader)
521 while(cnt-- > 0) *(buffer++)=_mm_read_M_ULONG(reader);
522 return !reader->Eof(reader);
525 BOOL _mm_read_I_SLONGS(SLONG *buffer,int cnt,MREADER* reader)
527 while(cnt-- > 0) *(buffer++)=_mm_read_I_SLONG(reader);
528 return !reader->Eof(reader);
531 BOOL _mm_read_I_ULONGS(ULONG *buffer,int cnt,MREADER* reader)
533 while(cnt-- > 0) *(buffer++)=_mm_read_I_ULONG(reader);
534 return !reader->Eof(reader);