1 #include "alutInternal.h"
11 #define structStat struct stat
13 #define stat(p,b) _stat((p),(b))
14 #define structStat struct _stat
16 #error No stat-like function on this platform
19 struct InputStream_struct
21 ALboolean isFileStream;
23 size_t remainingLength;
26 FILE *fileDescriptor; /* for file streams */
27 const ALvoid *data; /* for memory streams */
31 /****************************************************************************
32 * The functions below know the internal InputStream representation.
33 ****************************************************************************/
36 _alutInputStreamConstructFromFile (const char *fileName)
43 stream = (InputStream *) _alutMalloc (sizeof (InputStream));
49 if (stat (fileName, &statBuf))
51 _alutSetError (ALUT_ERROR_IO_ERROR);
56 fileDescriptor = fopen (fileName, "rb");
57 if (fileDescriptor == NULL)
59 _alutSetError (ALUT_ERROR_IO_ERROR);
64 fileNameBuffer = (char *) _alutMalloc (strlen (fileName) + 1);
65 if (fileNameBuffer == NULL)
71 stream->isFileStream = AL_TRUE;
72 stream->fileName = strcpy (fileNameBuffer, fileName);
73 stream->remainingLength = statBuf.st_size;
74 stream->u.fileDescriptor = fileDescriptor;
79 _alutInputStreamConstructFromMemory (const ALvoid *data, size_t length)
81 InputStream *stream = (InputStream *) _alutMalloc (sizeof (InputStream));
87 stream->isFileStream = AL_FALSE;
88 stream->fileName = NULL;
89 stream->remainingLength = length;
90 stream->u.data = data;
95 _alutInputStreamDestroy (InputStream *stream)
98 (stream->isFileStream && fclose (stream->u.fileDescriptor)) ?
100 if (stream->fileName)
102 free (stream->fileName);
109 _alutInputStreamGetFileName (const InputStream *stream)
111 return stream->fileName;
115 _alutInputStreamGetRemainingLength (const InputStream *stream)
117 return stream->remainingLength;
121 _alutInputStreamEOF (InputStream *stream)
123 if (stream->isFileStream)
125 int c = fgetc (stream->u.fileDescriptor);
128 ungetc (c, stream->u.fileDescriptor);
130 return (c == EOF) ? AL_TRUE : AL_FALSE;
134 return (stream->remainingLength == 0) ? AL_TRUE : AL_FALSE;
139 streamRead (InputStream *stream, void *ptr, size_t numBytesToRead)
141 if (stream->isFileStream)
143 size_t numBytesRead =
144 fread (ptr, 1, numBytesToRead, stream->u.fileDescriptor);
145 if (numBytesToRead != numBytesRead)
147 _alutSetError (ferror (stream->u.fileDescriptor) ?
148 ALUT_ERROR_IO_ERROR :
149 ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA);
156 if (stream->remainingLength < numBytesToRead)
158 _alutSetError (ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA);
161 memcpy (ptr, stream->u.data, numBytesToRead);
162 stream->u.data = ((const char *) (stream->u.data) + numBytesToRead);
167 /****************************************************************************
168 * The utility functions below do not know the internal InputStream
170 ****************************************************************************/
173 _alutInputStreamRead (InputStream *stream, size_t length)
175 ALvoid *data = _alutMalloc (length);
181 if (!streamRead (stream, data, length))
191 _alutInputStreamSkip (InputStream *stream, size_t numBytesToSkip)
195 if (numBytesToSkip == 0)
199 buf = (char *) _alutMalloc (numBytesToSkip);
204 status = streamRead (stream, buf, numBytesToSkip);
210 _alutInputStreamReadUInt16LE (InputStream *stream, UInt16LittleEndian *value)
212 unsigned char buf[2];
213 if (!streamRead (stream, buf, sizeof (buf)))
217 *value = ((UInt16LittleEndian) buf[1] << 8) | ((UInt16LittleEndian) buf[0]);
222 _alutInputStreamReadInt32BE (InputStream *stream, Int32BigEndian *value)
224 unsigned char buf[4];
225 if (!streamRead (stream, buf, sizeof (buf)))
230 ((Int32BigEndian) buf[0] << 24) |
231 ((Int32BigEndian) buf[1] << 16) |
232 ((Int32BigEndian) buf[2] << 8) | ((Int32BigEndian) buf[3]);
237 _alutInputStreamReadUInt32LE (InputStream *stream, UInt32LittleEndian *value)
239 unsigned char buf[4];
240 if (!streamRead (stream, buf, sizeof (buf)))
245 ((UInt32LittleEndian) buf[3] << 24) |
246 ((UInt32LittleEndian) buf[2] << 16) |
247 ((UInt32LittleEndian) buf[1] << 8) | ((UInt32LittleEndian) buf[0]);