Go to the documentation of this file.00001 #include "alutInternal.h"
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include <sys/types.h>
00005 #include <sys/stat.h>
00006
00007 #if HAVE_STAT
00008 #if HAVE_UNISTD_H
00009 #include <unistd.h>
00010 #endif
00011 #define structStat struct stat
00012 #elif HAVE__STAT || WIN32
00013 #define stat(p,b) _wstat((p),(b))
00014 #define structStat struct _stat
00015 #else
00016 #error No stat-like function on this platform
00017 #endif
00018
00019 size_t _strlen(const wchar_t* str)
00020 {
00021 size_t i = 0;
00022 while(str[i] != 0) i++;
00023 return i;
00024 };
00025
00026 wchar_t* _strcpy(wchar_t* a, const wchar_t* b)
00027 {
00028 int i = 0;
00029 do{
00030 a[i] = b[i];
00031 }while(b[i++] != 0);
00032 return a;
00033 };
00034
00035 size_t _strlen(const char* str)
00036 {
00037 size_t i = 0;
00038 while(str[i] != 0) i++;
00039 return i;
00040 };
00041
00042 char* _strcpy(char* a, const char* b)
00043 {
00044 int i = 0;
00045 do{
00046 a[i] = b[i];
00047 }while(b[i++] != 0);
00048 return a;
00049 };
00050
00051 FILE* fileopen(wchar_t* file, const wchar_t* param)
00052 {
00053 return _wfopen(file, param);
00054 }
00055
00056 FILE* fileopen(char* file, const char* param)
00057 {
00058 return fopen(file, param);
00059 }
00060
00061 #ifdef UNICODE
00062 # define FOPEN(__file, __param) fileopen((wchar_t*)__file, (const wchar_t*)__param)
00063 #else
00064 # define FOPEN(__file, __param) fileopen((char*)__file, (const char*)__param)
00065 #endif
00066
00067 struct InputStream_struct
00068 {
00069 ALboolean isFileStream;
00070 rchar *fileName;
00071 size_t remainingLength;
00072 union
00073 {
00074 FILE *fileDescriptor;
00075 const ALvoid *data;
00076 } u;
00077 };
00078
00079
00080
00081
00082
00083 InputStream *
00084 _alutInputStreamConstructFromFile (const rchar *fileName)
00085 {
00086 InputStream *stream;
00087 structStat statBuf;
00088 FILE *fileDescriptor;
00089 rchar *fileNameBuffer;
00090
00091 stream = (InputStream *) _alutMalloc (sizeof (InputStream));
00092 if (stream == NULL)
00093 {
00094 return NULL;
00095 }
00096
00097 if (stat (fileName, &statBuf))
00098 {
00099 _alutSetError (ALUT_ERROR_IO_ERROR);
00100 free (stream);
00101 return NULL;
00102 }
00103
00104 fileDescriptor = FOPEN(fileName, _T("rb"));
00105 if (fileDescriptor == NULL)
00106 {
00107 _alutSetError (ALUT_ERROR_IO_ERROR);
00108 free (stream);
00109 return NULL;
00110 }
00111
00112 fileNameBuffer = (rchar*) _alutMalloc(sizeof(rchar)*(_strlen(fileName) + 1));
00113 if (fileNameBuffer == NULL)
00114 {
00115 free (stream);
00116 return NULL;
00117 }
00118
00119 stream->isFileStream = AL_TRUE;
00120 stream->fileName = _strcpy(fileNameBuffer, fileName);
00121 stream->remainingLength = statBuf.st_size;
00122 stream->u.fileDescriptor = fileDescriptor;
00123 return stream;
00124 }
00125
00126 InputStream *
00127 _alutInputStreamConstructFromMemory (const ALvoid *data, size_t length)
00128 {
00129 InputStream *stream = (InputStream *) _alutMalloc (sizeof (InputStream));
00130 if (stream == NULL)
00131 {
00132 return NULL;
00133 }
00134
00135 stream->isFileStream = AL_FALSE;
00136 stream->fileName = NULL;
00137 stream->remainingLength = length;
00138 stream->u.data = data;
00139 return stream;
00140 }
00141
00142 ALboolean
00143 _alutInputStreamDestroy (InputStream *stream)
00144 {
00145 ALboolean status =
00146 (stream->isFileStream && fclose (stream->u.fileDescriptor)) ?
00147 AL_FALSE : AL_TRUE;
00148 if (stream->fileName)
00149 {
00150 free (stream->fileName);
00151 }
00152 free (stream);
00153 return status;
00154 }
00155
00156 const rchar *
00157 _alutInputStreamGetFileName (const InputStream *stream)
00158 {
00159 return stream->fileName;
00160 }
00161
00162 size_t
00163 _alutInputStreamGetRemainingLength (const InputStream *stream)
00164 {
00165 return stream->remainingLength;
00166 }
00167
00168 ALboolean
00169 _alutInputStreamEOF (InputStream *stream)
00170 {
00171 if (stream->isFileStream)
00172 {
00173 int c = fgetc (stream->u.fileDescriptor);
00174 if (c != EOF)
00175 {
00176 ungetc (c, stream->u.fileDescriptor);
00177 }
00178 return (c == EOF) ? AL_TRUE : AL_FALSE;
00179 }
00180 else
00181 {
00182 return (stream->remainingLength == 0) ? AL_TRUE : AL_FALSE;
00183 }
00184 }
00185
00186 static ALboolean
00187 streamRead (InputStream *stream, void *ptr, size_t numBytesToRead)
00188 {
00189 if (stream->isFileStream)
00190 {
00191 size_t numBytesRead =
00192 fread (ptr, 1, numBytesToRead, stream->u.fileDescriptor);
00193 if (numBytesToRead != numBytesRead)
00194 {
00195 _alutSetError (ferror (stream->u.fileDescriptor) ?
00196 ALUT_ERROR_IO_ERROR :
00197 ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA);
00198 return AL_FALSE;
00199 }
00200 return AL_TRUE;
00201 }
00202 else
00203 {
00204 if (stream->remainingLength < numBytesToRead)
00205 {
00206 _alutSetError (ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA);
00207 return AL_FALSE;
00208 }
00209 memcpy (ptr, stream->u.data, numBytesToRead);
00210 stream->u.data = ((const char *) (stream->u.data) + numBytesToRead);
00211 return AL_TRUE;
00212 }
00213 }
00214
00215
00216
00217
00218
00219
00220 ALvoid *
00221 _alutInputStreamRead (InputStream *stream, size_t length)
00222 {
00223 ALvoid *data = _alutMalloc (length);
00224 if (data == NULL)
00225 {
00226 return NULL;
00227 }
00228
00229 if (!streamRead (stream, data, length))
00230 {
00231 free (data);
00232 return NULL;
00233 }
00234
00235 return data;
00236 }
00237
00238 ALboolean
00239 _alutInputStreamSkip (InputStream *stream, size_t numBytesToSkip)
00240 {
00241 ALboolean status;
00242 char *buf;
00243 if (numBytesToSkip == 0)
00244 {
00245 return AL_TRUE;
00246 }
00247 buf = (char *) _alutMalloc (numBytesToSkip);
00248 if (buf == NULL)
00249 {
00250 return AL_FALSE;
00251 }
00252 status = streamRead (stream, buf, numBytesToSkip);
00253 free (buf);
00254 return status;
00255 }
00256
00257 ALboolean
00258 _alutInputStreamReadUInt16LE (InputStream *stream, UInt16LittleEndian *value)
00259 {
00260 unsigned char buf[2];
00261 if (!streamRead (stream, buf, sizeof (buf)))
00262 {
00263 return AL_FALSE;
00264 }
00265 *value = ((UInt16LittleEndian) buf[1] << 8) | ((UInt16LittleEndian) buf[0]);
00266 return AL_TRUE;
00267 }
00268
00269 ALboolean
00270 _alutInputStreamReadInt32BE (InputStream *stream, Int32BigEndian *value)
00271 {
00272 unsigned char buf[4];
00273 if (!streamRead (stream, buf, sizeof (buf)))
00274 {
00275 return AL_FALSE;
00276 }
00277 *value =
00278 ((Int32BigEndian) buf[0] << 24) |
00279 ((Int32BigEndian) buf[1] << 16) |
00280 ((Int32BigEndian) buf[2] << 8) | ((Int32BigEndian) buf[3]);
00281 return AL_TRUE;
00282 }
00283
00284 ALboolean
00285 _alutInputStreamReadUInt32LE (InputStream *stream, UInt32LittleEndian *value)
00286 {
00287 unsigned char buf[4];
00288 if (!streamRead (stream, buf, sizeof (buf)))
00289 {
00290 return AL_FALSE;
00291 }
00292 *value =
00293 ((UInt32LittleEndian) buf[3] << 24) |
00294 ((UInt32LittleEndian) buf[2] << 16) |
00295 ((UInt32LittleEndian) buf[1] << 8) | ((UInt32LittleEndian) buf[0]);
00296 return AL_TRUE;
00297 }