Files
Konrad Beckmann 20d7fefaf9 Import mikmod
2021-08-02 02:19:41 +02:00

138 lines
2.8 KiB
C

/* mmloader.c
* Example on how to implement a MREADER that reads from memory
* for libmikmod.
* (C) 2004, Raphael Assenat (raph@raphnet.net)
*
* This example is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRENTY; without event the implied warrenty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <limits.h>
#include <stdlib.h>
#include <mikmod.h>
#include "myloader.h"
static BOOL My_MemReader_Eof(MREADER* reader);
static BOOL My_MemReader_Read(MREADER* reader,void* ptr,size_t size);
static int My_MemReader_Get(MREADER* reader);
static int My_MemReader_Seek(MREADER* reader,long offset,int whence);
static long My_MemReader_Tell(MREADER* reader);
void my_delete_mem_reader(MREADER* reader)
{
if (reader) free(reader);
}
MREADER *my_new_mem_reader(const void *buffer, long len)
{
MY_MEMREADER* reader = (MY_MEMREADER*) calloc(1, sizeof(MY_MEMREADER));
if (reader)
{
reader->core.Eof = &My_MemReader_Eof;
reader->core.Read= &My_MemReader_Read;
reader->core.Get = &My_MemReader_Get;
reader->core.Seek= &My_MemReader_Seek;
reader->core.Tell= &My_MemReader_Tell;
reader->buffer = buffer;
reader->len = len;
reader->pos = 0;
}
return (MREADER*)reader;
}
static BOOL My_MemReader_Eof(MREADER* reader)
{
MY_MEMREADER* mr = (MY_MEMREADER*) reader;
if (!mr) return 1;
if (mr->pos >= mr->len) return 1;
return 0;
}
static BOOL My_MemReader_Read(MREADER* reader,void* ptr,size_t size)
{
unsigned char *d;
const unsigned char *s;
MY_MEMREADER* mr;
long siz;
BOOL ret;
if (!reader || !size || (size > (size_t) LONG_MAX))
return 0;
mr = (MY_MEMREADER*) reader;
siz = (long) size;
if (mr->pos >= mr->len) return 0; /* @ eof */
if (mr->pos + siz > mr->len) {
siz = mr->len - mr->pos;
ret = 0; /* not enough remaining bytes */
}
else {
ret = 1;
}
s = (const unsigned char *) mr->buffer;
s += mr->pos;
mr->pos += siz;
d = (unsigned char *) ptr;
while (siz) {
*d++ = *s++;
siz--;
}
return ret;
}
static int My_MemReader_Get(MREADER* reader)
{
MY_MEMREADER* mr;
int c;
mr = (MY_MEMREADER*) reader;
if (mr->pos >= mr->len) return EOF;
c = ((const unsigned char*) mr->buffer)[mr->pos];
mr->pos++;
return c;
}
static int My_MemReader_Seek(MREADER* reader,long offset,int whence)
{
MY_MEMREADER* mr;
if (!reader) return -1;
mr = (MY_MEMREADER*) reader;
switch(whence)
{
case SEEK_CUR:
mr->pos += offset;
break;
case SEEK_SET:
mr->pos = reader->iobase + offset;
break;
case SEEK_END:
mr->pos = mr->len + offset;
break;
default: /* invalid */
return -1;
}
if (mr->pos < reader->iobase) {
mr->pos = mr->core.iobase;
return -1;
}
if (mr->pos > mr->len) {
mr->pos = mr->len;
}
return 0;
}
static long My_MemReader_Tell(MREADER* reader)
{
if (reader) {
return ((MY_MEMREADER*)reader)->pos - reader->iobase;
}
return 0;
}