• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/audio/src/util/alutInputStream.cpp

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;       /* for file streams */
00075     const ALvoid *data;         /* for memory streams */
00076   } u;
00077 };
00078 
00079 /****************************************************************************
00080  * The functions below know the internal InputStream representation.
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  * The utility functions below do not know the internal InputStream
00217  * representation.
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 }

Generated on Fri Jun 18 2010 17:48:39 for Cannonball by  doxygen 1.7.0