Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/freealut-1.1.0/src/alutInputStream.c @ 14

Last change on this file since 14 was 14, checked in by landauf, 16 years ago

added freealut

File size: 5.6 KB
Line 
1#include "alutInternal.h"
2#include <stdio.h>
3#include <string.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6
7#if HAVE_STAT
8#if HAVE_UNISTD_H
9#include <unistd.h>
10#endif
11#define structStat struct stat
12#elif HAVE__STAT
13#define stat(p,b) _stat((p),(b))
14#define structStat struct _stat
15#else
16#error No stat-like function on this platform
17#endif
18
19struct InputStream_struct
20{
21  ALboolean isFileStream;
22  char *fileName;
23  size_t remainingLength;
24  union
25  {
26    FILE *fileDescriptor;       /* for file streams */
27    const ALvoid *data;         /* for memory streams */
28  } u;
29};
30
31/****************************************************************************
32 * The functions below know the internal InputStream representation.
33 ****************************************************************************/
34
35InputStream *
36_alutInputStreamConstructFromFile (const char *fileName)
37{
38  InputStream *stream;
39  structStat statBuf;
40  FILE *fileDescriptor;
41  char *fileNameBuffer;
42
43  stream = (InputStream *) _alutMalloc (sizeof (InputStream));
44  if (stream == NULL)
45    {
46      return NULL;
47    }
48
49  if (stat (fileName, &statBuf))
50    {
51      _alutSetError (ALUT_ERROR_IO_ERROR);
52      free (stream);
53      return NULL;
54    }
55
56  fileDescriptor = fopen (fileName, "rb");
57  if (fileDescriptor == NULL)
58    {
59      _alutSetError (ALUT_ERROR_IO_ERROR);
60      free (stream);
61      return NULL;
62    }
63
64  fileNameBuffer = (char *) _alutMalloc (strlen (fileName) + 1);
65  if (fileNameBuffer == NULL)
66    {
67      free (stream);
68      return NULL;
69    }
70
71  stream->isFileStream = AL_TRUE;
72  stream->fileName = strcpy (fileNameBuffer, fileName);
73  stream->remainingLength = statBuf.st_size;
74  stream->u.fileDescriptor = fileDescriptor;
75  return stream;
76}
77
78InputStream *
79_alutInputStreamConstructFromMemory (const ALvoid *data, size_t length)
80{
81  InputStream *stream = (InputStream *) _alutMalloc (sizeof (InputStream));
82  if (stream == NULL)
83    {
84      return NULL;
85    }
86
87  stream->isFileStream = AL_FALSE;
88  stream->fileName = NULL;
89  stream->remainingLength = length;
90  stream->u.data = data;
91  return stream;
92}
93
94ALboolean
95_alutInputStreamDestroy (InputStream *stream)
96{
97  ALboolean status =
98    (stream->isFileStream && fclose (stream->u.fileDescriptor)) ?
99    AL_FALSE : AL_TRUE;
100  if (stream->fileName)
101    {
102      free (stream->fileName);
103    }
104  free (stream);
105  return status;
106}
107
108const char *
109_alutInputStreamGetFileName (const InputStream *stream)
110{
111  return stream->fileName;
112}
113
114size_t
115_alutInputStreamGetRemainingLength (const InputStream *stream)
116{
117  return stream->remainingLength;
118}
119
120ALboolean
121_alutInputStreamEOF (InputStream *stream)
122{
123  if (stream->isFileStream)
124    {
125      int c = fgetc (stream->u.fileDescriptor);
126      if (c != EOF)
127        {
128          ungetc (c, stream->u.fileDescriptor);
129        }
130      return (c == EOF) ? AL_TRUE : AL_FALSE;
131    }
132  else
133    {
134      return (stream->remainingLength == 0) ? AL_TRUE : AL_FALSE;
135    }
136}
137
138static ALboolean
139streamRead (InputStream *stream, void *ptr, size_t numBytesToRead)
140{
141  if (stream->isFileStream)
142    {
143      size_t numBytesRead =
144        fread (ptr, 1, numBytesToRead, stream->u.fileDescriptor);
145      if (numBytesToRead != numBytesRead)
146        {
147          _alutSetError (ferror (stream->u.fileDescriptor) ?
148                         ALUT_ERROR_IO_ERROR :
149                         ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA);
150          return AL_FALSE;
151        }
152      return AL_TRUE;
153    }
154  else
155    {
156      if (stream->remainingLength < numBytesToRead)
157        {
158          _alutSetError (ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA);
159          return AL_FALSE;
160        }
161      memcpy (ptr, stream->u.data, numBytesToRead);
162      stream->u.data = ((const char *) (stream->u.data) + numBytesToRead);
163      return AL_TRUE;
164    }
165}
166
167/****************************************************************************
168 * The utility functions below do not know the internal InputStream
169 * representation.
170 ****************************************************************************/
171
172ALvoid *
173_alutInputStreamRead (InputStream *stream, size_t length)
174{
175  ALvoid *data = _alutMalloc (length);
176  if (data == NULL)
177    {
178      return NULL;
179    }
180
181  if (!streamRead (stream, data, length))
182    {
183      free (data);
184      return NULL;
185    }
186
187  return data;
188}
189
190ALboolean
191_alutInputStreamSkip (InputStream *stream, size_t numBytesToSkip)
192{
193  ALboolean status;
194  char *buf;
195  if (numBytesToSkip == 0)
196    {
197      return AL_TRUE;
198    }
199  buf = (char *) _alutMalloc (numBytesToSkip);
200  if (buf == NULL)
201    {
202      return AL_FALSE;
203    }
204  status = streamRead (stream, buf, numBytesToSkip);
205  free (buf);
206  return status;
207}
208
209ALboolean
210_alutInputStreamReadUInt16LE (InputStream *stream, UInt16LittleEndian *value)
211{
212  unsigned char buf[2];
213  if (!streamRead (stream, buf, sizeof (buf)))
214    {
215      return AL_FALSE;
216    }
217  *value = ((UInt16LittleEndian) buf[1] << 8) | ((UInt16LittleEndian) buf[0]);
218  return AL_TRUE;
219}
220
221ALboolean
222_alutInputStreamReadInt32BE (InputStream *stream, Int32BigEndian *value)
223{
224  unsigned char buf[4];
225  if (!streamRead (stream, buf, sizeof (buf)))
226    {
227      return AL_FALSE;
228    }
229  *value =
230    ((Int32BigEndian) buf[0] << 24) |
231    ((Int32BigEndian) buf[1] << 16) |
232    ((Int32BigEndian) buf[2] << 8) | ((Int32BigEndian) buf[3]);
233  return AL_TRUE;
234}
235
236ALboolean
237_alutInputStreamReadUInt32LE (InputStream *stream, UInt32LittleEndian *value)
238{
239  unsigned char buf[4];
240  if (!streamRead (stream, buf, sizeof (buf)))
241    {
242      return AL_FALSE;
243    }
244  *value =
245    ((UInt32LittleEndian) buf[3] << 24) |
246    ((UInt32LittleEndian) buf[2] << 16) |
247    ((UInt32LittleEndian) buf[1] << 8) | ((UInt32LittleEndian) buf[0]);
248  return AL_TRUE;
249}
Note: See TracBrowser for help on using the repository browser.