mmio.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:9k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* MikMod sound library
  2. (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for
  3. complete list.
  4. This library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of
  7. the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  17. 02111-1307, USA.
  18. */
  19. /*==============================================================================
  20.   $Id: mmio.c,v 1.2 2004/02/06 19:29:05 raph Exp $
  21.   Portable file I/O routines
  22. ==============================================================================*/
  23. /*
  24. The way this module works:
  25. - _mm_fopen will call the errorhandler [see mmerror.c] in addition to
  26.   setting _mm_errno on exit.
  27. - _mm_iobase is for internal use.  It is used by Player_LoadFP to
  28.   ensure that it works properly with wad files.
  29. - _mm_read_I_* and _mm_read_M_* differ : the first is for reading data
  30.   written by a little endian (intel) machine, and the second is for reading
  31.   big endian (Mac, RISC, Alpha) machine data.
  32. - _mm_write functions work the same as the _mm_read functions.
  33. - _mm_read_string is for reading binary strings.  It is basically the same
  34.   as an fread of bytes.
  35. */
  36. /* FIXME
  37. the _mm_iobase variable ought to be MREADER-specific. It will eventually
  38. become a private field of the MREADER structure, but this will require a
  39. soname version bump.
  40. In the meantime, the drawback is that if you use the xxx_LoadFP functions,
  41. you can't have several MREADER objects with different iobase values.
  42. */
  43. #ifdef HAVE_CONFIG_H
  44. #include "config.h"
  45. #endif
  46. #ifdef HAVE_UNISTD_H
  47. #include <unistd.h>
  48. #endif
  49. #include <stdio.h>
  50. #include <string.h>
  51. #include "mikmod_internals.h"
  52. #ifdef SUNOS
  53. extern int fclose(FILE *);
  54. extern int fgetc(FILE *);
  55. extern int fputc(int, FILE *);
  56. extern size_t fread(void *, size_t, size_t, FILE *);
  57. extern int fseek(FILE *, long, int);
  58. extern size_t fwrite(const void *, size_t, size_t, FILE *);
  59. #endif
  60. #define COPY_BUFSIZE  1024
  61. static long _mm_iobase=0,temp_iobase=0;
  62. FILE* _mm_fopen(CHAR* fname,CHAR* attrib)
  63. {
  64. FILE *fp;
  65. if(!(fp=fopen(fname,attrib))) {
  66. _mm_errno = MMERR_OPENING_FILE;
  67. if(_mm_errorhandler) _mm_errorhandler();
  68. }
  69. return fp;
  70. }
  71. BOOL _mm_FileExists(CHAR* fname)
  72. {
  73. FILE *fp;
  74. if(!(fp=fopen(fname,"r"))) return 0;
  75. fclose(fp);
  76. return 1;
  77. }
  78. int _mm_fclose(FILE *fp)
  79. {
  80. return fclose(fp);
  81. }
  82. /* Sets the current file-position as the new _mm_iobase */
  83. void _mm_iobase_setcur(MREADER* reader)
  84. {
  85. temp_iobase=_mm_iobase;  /* store old value in case of revert */
  86. _mm_iobase=reader->Tell(reader);
  87. }
  88. /* Reverts to the last known _mm_iobase value. */
  89. void _mm_iobase_revert(void)
  90. {
  91. _mm_iobase=temp_iobase;
  92. }
  93. /*========== File Reader */
  94. typedef struct MFILEREADER {
  95. MREADER core;
  96. FILE*   file;
  97. } MFILEREADER;
  98. static BOOL _mm_FileReader_Eof(MREADER* reader)
  99. {
  100. return feof(((MFILEREADER*)reader)->file);
  101. }
  102. static BOOL _mm_FileReader_Read(MREADER* reader,void* ptr,size_t size)
  103. {
  104. return fread(ptr,size,1,((MFILEREADER*)reader)->file);
  105. }
  106. static int _mm_FileReader_Get(MREADER* reader)
  107. {
  108. return fgetc(((MFILEREADER*)reader)->file);
  109. }
  110. static BOOL _mm_FileReader_Seek(MREADER* reader,long offset,int whence)
  111. {
  112. return fseek(((MFILEREADER*)reader)->file,
  113.  (whence==SEEK_SET)?offset+_mm_iobase:offset,whence);
  114. }
  115. static long _mm_FileReader_Tell(MREADER* reader)
  116. {
  117. return ftell(((MFILEREADER*)reader)->file)-_mm_iobase;
  118. }
  119. MREADER *_mm_new_file_reader(FILE* fp)
  120. {
  121. MFILEREADER* reader=(MFILEREADER*)_mm_malloc(sizeof(MFILEREADER));
  122. if (reader) {
  123. reader->core.Eof =&_mm_FileReader_Eof;
  124. reader->core.Read=&_mm_FileReader_Read;
  125. reader->core.Get =&_mm_FileReader_Get;
  126. reader->core.Seek=&_mm_FileReader_Seek;
  127. reader->core.Tell=&_mm_FileReader_Tell;
  128. reader->file=fp;
  129. }
  130. return (MREADER*)reader;
  131. }
  132. void _mm_delete_file_reader (MREADER* reader)
  133. {
  134. if(reader) free(reader);
  135. }
  136. /*========== File Writer */
  137. typedef struct MFILEWRITER {
  138. MWRITER core;
  139. FILE*   file;
  140. } MFILEWRITER;
  141. static BOOL _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence)
  142. {
  143. return fseek(((MFILEWRITER*)writer)->file,offset,whence);
  144. }
  145. static long _mm_FileWriter_Tell(MWRITER* writer)
  146. {
  147. return ftell(((MFILEWRITER*)writer)->file);
  148. }
  149. static BOOL _mm_FileWriter_Write(MWRITER* writer,void* ptr,size_t size)
  150. {
  151. return (fwrite(ptr,size,1,((MFILEWRITER*)writer)->file)==size);
  152. }
  153. static BOOL _mm_FileWriter_Put(MWRITER* writer,int value)
  154. {
  155. return fputc(value,((MFILEWRITER*)writer)->file);
  156. }
  157. MWRITER *_mm_new_file_writer(FILE* fp)
  158. {
  159. MFILEWRITER* writer=(MFILEWRITER*)_mm_malloc(sizeof(MFILEWRITER));
  160. if (writer) {
  161. writer->core.Seek =&_mm_FileWriter_Seek;
  162. writer->core.Tell =&_mm_FileWriter_Tell;
  163. writer->core.Write=&_mm_FileWriter_Write;
  164. writer->core.Put  =&_mm_FileWriter_Put;
  165. writer->file=fp;
  166. }
  167. return (MWRITER*) writer;
  168. }
  169. void _mm_delete_file_writer (MWRITER* writer)
  170. {
  171. if(writer) free (writer);
  172. }
  173. /*========== Write functions */
  174. void _mm_write_string(CHAR* data,MWRITER* writer)
  175. {
  176. if(data)
  177. _mm_write_UBYTES(data,strlen(data),writer);
  178. }
  179. void _mm_write_M_UWORD(UWORD data,MWRITER* writer)
  180. {
  181. _mm_write_UBYTE(data>>8,writer);
  182. _mm_write_UBYTE(data&0xff,writer);
  183. }
  184. void _mm_write_I_UWORD(UWORD data,MWRITER* writer)
  185. {
  186. _mm_write_UBYTE(data&0xff,writer);
  187. _mm_write_UBYTE(data>>8,writer);
  188. }
  189. void _mm_write_M_ULONG(ULONG data,MWRITER* writer)
  190. {
  191. _mm_write_M_UWORD(data>>16,writer);
  192. _mm_write_M_UWORD(data&0xffff,writer);
  193. }
  194. void _mm_write_I_ULONG(ULONG data,MWRITER* writer)
  195. {
  196. _mm_write_I_UWORD(data&0xffff,writer);
  197. _mm_write_I_UWORD(data>>16,writer);
  198. }
  199. void _mm_write_M_SWORD(SWORD data,MWRITER* writer)
  200. {
  201. _mm_write_M_UWORD((UWORD)data,writer);
  202. }
  203. void _mm_write_I_SWORD(SWORD data,MWRITER* writer)
  204. {
  205. _mm_write_I_UWORD((UWORD)data,writer);
  206. }
  207. void _mm_write_M_SLONG(SLONG data,MWRITER* writer)
  208. {
  209. _mm_write_M_ULONG((ULONG)data,writer);
  210. }
  211. void _mm_write_I_SLONG(SLONG data,MWRITER* writer)
  212. {
  213. _mm_write_I_ULONG((ULONG)data,writer);
  214. }
  215. #if defined __STDC__ || defined _MSC_VER || defined MPW_C
  216. #define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type)
  217. void _mm_write_##type_name##S (type *buffer,int number,MWRITER* writer)
  218. {
  219. while(number-->0)
  220. _mm_write_##type_name(*(buffer++),writer);
  221. }
  222. #else
  223. #define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type)
  224. void _mm_write_/**/type_name/**/S (type *buffer,int number,MWRITER* writer)
  225. {
  226. while(number-->0)
  227. _mm_write_/**/type_name(*(buffer++),writer);
  228. }
  229. #endif
  230. DEFINE_MULTIPLE_WRITE_FUNCTION(M_SWORD,SWORD)
  231. DEFINE_MULTIPLE_WRITE_FUNCTION(M_UWORD,UWORD)
  232. DEFINE_MULTIPLE_WRITE_FUNCTION(I_SWORD,SWORD)
  233. DEFINE_MULTIPLE_WRITE_FUNCTION(I_UWORD,UWORD)
  234. DEFINE_MULTIPLE_WRITE_FUNCTION(M_SLONG,SLONG)
  235. DEFINE_MULTIPLE_WRITE_FUNCTION(M_ULONG,ULONG)
  236. DEFINE_MULTIPLE_WRITE_FUNCTION(I_SLONG,SLONG)
  237. DEFINE_MULTIPLE_WRITE_FUNCTION(I_ULONG,ULONG)
  238. /*========== Read functions */
  239. int _mm_read_string(CHAR* buffer,int number,MREADER* reader)
  240. {
  241. return reader->Read(reader,buffer,number);
  242. }
  243. UWORD _mm_read_M_UWORD(MREADER* reader)
  244. {
  245. UWORD result=((UWORD)_mm_read_UBYTE(reader))<<8;
  246. result|=_mm_read_UBYTE(reader);
  247. return result;
  248. }
  249. UWORD _mm_read_I_UWORD(MREADER* reader)
  250. {
  251. UWORD result=_mm_read_UBYTE(reader);
  252. result|=((UWORD)_mm_read_UBYTE(reader))<<8;
  253. return result;
  254. }
  255. ULONG _mm_read_M_ULONG(MREADER* reader)
  256. {
  257. ULONG result=((ULONG)_mm_read_M_UWORD(reader))<<16;
  258. result|=_mm_read_M_UWORD(reader);
  259. return result;
  260. }
  261. ULONG _mm_read_I_ULONG(MREADER* reader)
  262. {
  263. ULONG result=_mm_read_I_UWORD(reader);
  264. result|=((ULONG)_mm_read_I_UWORD(reader))<<16;
  265. return result;
  266. }
  267. SWORD _mm_read_M_SWORD(MREADER* reader)
  268. {
  269. return((SWORD)_mm_read_M_UWORD(reader));
  270. }
  271. SWORD _mm_read_I_SWORD(MREADER* reader)
  272. {
  273. return((SWORD)_mm_read_I_UWORD(reader));
  274. }
  275. SLONG _mm_read_M_SLONG(MREADER* reader)
  276. {
  277. return((SLONG)_mm_read_M_ULONG(reader));
  278. }
  279. SLONG _mm_read_I_SLONG(MREADER* reader)
  280. {
  281. return((SLONG)_mm_read_I_ULONG(reader));
  282. }
  283. #if defined __STDC__ || defined _MSC_VER || defined MPW_C
  284. #define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type)
  285. int _mm_read_##type_name##S (type *buffer,int number,MREADER* reader)
  286. {
  287. while(number-->0)
  288. *(buffer++)=_mm_read_##type_name(reader);
  289. return !reader->Eof(reader);
  290. }
  291. #else
  292. #define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type)
  293. int _mm_read_/**/type_name/**/S (type *buffer,int number,MREADER* reader)
  294. {
  295. while(number-->0)
  296. *(buffer++)=_mm_read_/**/type_name(reader);
  297. return !reader->Eof(reader);
  298. }
  299. #endif
  300. DEFINE_MULTIPLE_READ_FUNCTION(M_SWORD,SWORD)
  301. DEFINE_MULTIPLE_READ_FUNCTION(M_UWORD,UWORD)
  302. DEFINE_MULTIPLE_READ_FUNCTION(I_SWORD,SWORD)
  303. DEFINE_MULTIPLE_READ_FUNCTION(I_UWORD,UWORD)
  304. DEFINE_MULTIPLE_READ_FUNCTION(M_SLONG,SLONG)
  305. DEFINE_MULTIPLE_READ_FUNCTION(M_ULONG,ULONG)
  306. DEFINE_MULTIPLE_READ_FUNCTION(I_SLONG,SLONG)
  307. DEFINE_MULTIPLE_READ_FUNCTION(I_ULONG,ULONG)
  308. /* ex:set ts=4: */