Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
250 lines (225 sloc) 5.81 KB
#include "alutInternal.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_STAT
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#define structStat struct stat
#elif HAVE__STAT
#define stat(p,b) _stat((p),(b))
#define structStat struct _stat
#else
#error No stat-like function on this platform
#endif
struct InputStream_struct
{
ALboolean isFileStream;
char *fileName;
size_t remainingLength;
union
{
FILE *fileDescriptor; /* for file streams */
const ALvoid *data; /* for memory streams */
} u;
};
/****************************************************************************
* The functions below know the internal InputStream representation.
****************************************************************************/
InputStream *
_alutInputStreamConstructFromFile (const char *fileName)
{
InputStream *stream;
structStat statBuf;
FILE *fileDescriptor;
char *fileNameBuffer;
stream = (InputStream *) _alutMalloc (sizeof (InputStream));
if (stream == NULL)
{
return NULL;
}
if (stat (fileName, &statBuf))
{
_alutSetError (ALUT_ERROR_IO_ERROR);
free (stream);
return NULL;
}
fileDescriptor = fopen (fileName, "rb");
if (fileDescriptor == NULL)
{
_alutSetError (ALUT_ERROR_IO_ERROR);
free (stream);
return NULL;
}
fileNameBuffer = (char *) _alutMalloc (strlen (fileName) + 1);
if (fileNameBuffer == NULL)
{
free (stream);
return NULL;
}
stream->isFileStream = AL_TRUE;
stream->fileName = strcpy (fileNameBuffer, fileName);
stream->remainingLength = statBuf.st_size;
stream->u.fileDescriptor = fileDescriptor;
return stream;
}
InputStream *
_alutInputStreamConstructFromMemory (const ALvoid *data, size_t length)
{
InputStream *stream = (InputStream *) _alutMalloc (sizeof (InputStream));
if (stream == NULL)
{
return NULL;
}
stream->isFileStream = AL_FALSE;
stream->fileName = NULL;
stream->remainingLength = length;
stream->u.data = data;
return stream;
}
ALboolean
_alutInputStreamDestroy (InputStream *stream)
{
ALboolean status =
(stream->isFileStream && fclose (stream->u.fileDescriptor)) ?
AL_FALSE : AL_TRUE;
if (stream->fileName)
{
free (stream->fileName);
}
free (stream);
return status;
}
const char *
_alutInputStreamGetFileName (const InputStream *stream)
{
return stream->fileName;
}
size_t
_alutInputStreamGetRemainingLength (const InputStream *stream)
{
return stream->remainingLength;
}
ALboolean
_alutInputStreamEOF (InputStream *stream)
{
if (stream->isFileStream)
{
int c = fgetc (stream->u.fileDescriptor);
if (c != EOF)
{
ungetc (c, stream->u.fileDescriptor);
}
return (c == EOF) ? AL_TRUE : AL_FALSE;
}
else
{
return (stream->remainingLength == 0) ? AL_TRUE : AL_FALSE;
}
}
static ALboolean
streamRead (InputStream *stream, void *ptr, size_t numBytesToRead)
{
if (stream->isFileStream)
{
size_t numBytesRead =
fread (ptr, 1, numBytesToRead, stream->u.fileDescriptor);
if (numBytesToRead != numBytesRead)
{
_alutSetError (ferror (stream->u.fileDescriptor) ?
ALUT_ERROR_IO_ERROR :
ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA);
return AL_FALSE;
}
return AL_TRUE;
}
else
{
if (stream->remainingLength < numBytesToRead)
{
_alutSetError (ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA);
return AL_FALSE;
}
memcpy (ptr, stream->u.data, numBytesToRead);
stream->u.data = ((const char *) (stream->u.data) + numBytesToRead);
return AL_TRUE;
}
}
/****************************************************************************
* The utility functions below do not know the internal InputStream
* representation.
****************************************************************************/
ALvoid *
_alutInputStreamRead (InputStream *stream, size_t length)
{
ALvoid *data = _alutMalloc (length);
if (data == NULL)
{
return NULL;
}
if (!streamRead (stream, data, length))
{
free (data);
return NULL;
}
return data;
}
ALboolean
_alutInputStreamSkip (InputStream *stream, size_t numBytesToSkip)
{
ALboolean status;
char *buf;
if (numBytesToSkip == 0)
{
return AL_TRUE;
}
buf = (char *) _alutMalloc (numBytesToSkip);
if (buf == NULL)
{
return AL_FALSE;
}
status = streamRead (stream, buf, numBytesToSkip);
free (buf);
return status;
}
ALboolean
_alutInputStreamReadUInt16LE (InputStream *stream, UInt16LittleEndian *value)
{
unsigned char buf[2];
if (!streamRead (stream, buf, sizeof (buf)))
{
return AL_FALSE;
}
*value = ((UInt16LittleEndian) buf[1] << 8) | ((UInt16LittleEndian) buf[0]);
return AL_TRUE;
}
ALboolean
_alutInputStreamReadInt32BE (InputStream *stream, Int32BigEndian *value)
{
unsigned char buf[4];
if (!streamRead (stream, buf, sizeof (buf)))
{
return AL_FALSE;
}
*value =
((Int32BigEndian) buf[0] << 24) |
((Int32BigEndian) buf[1] << 16) |
((Int32BigEndian) buf[2] << 8) | ((Int32BigEndian) buf[3]);
return AL_TRUE;
}
ALboolean
_alutInputStreamReadUInt32LE (InputStream *stream, UInt32LittleEndian *value)
{
unsigned char buf[4];
if (!streamRead (stream, buf, sizeof (buf)))
{
return AL_FALSE;
}
*value =
((UInt32LittleEndian) buf[3] << 24) |
((UInt32LittleEndian) buf[2] << 16) |
((UInt32LittleEndian) buf[1] << 8) | ((UInt32LittleEndian) buf[0]);
return AL_TRUE;
}
Something went wrong with that request. Please try again.