Remove the GStreamer decoder
[alure.git] / src / istream.cpp
blob818abadb62d9848370b880d22fac6fee4c7c47bd
1 /*
2 * ALURE OpenAL utility library
3 * Copyright (C) 2009 by Chris Robinson.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 /* Title: File I/O */
23 #include "config.h"
25 #include "main.h"
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <errno.h>
33 #include <iostream>
35 #ifndef O_BINARY
36 #define O_BINARY 0
37 #endif
39 MemStreamBuf::int_type MemStreamBuf::underflow()
41 if(gptr() == egptr())
43 char_type *data = (char_type*)memInfo.Data;
44 setg(data, data + memInfo.Pos, data + memInfo.Length);
45 memInfo.Pos = memInfo.Length;
47 if(gptr() == egptr())
48 return traits_type::eof();
49 return (*gptr())&0xFF;
52 MemStreamBuf::pos_type MemStreamBuf::seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode)
54 if((mode&std::ios_base::out))
55 return traits_type::eof();
57 pos_type pos;
58 switch(whence)
60 case std::ios_base::beg:
61 pos = pos_type(offset);
62 break;
63 case std::ios_base::cur:
64 pos = pos_type(memInfo.Pos) - pos_type(egptr()-gptr());
65 pos += offset;
66 break;
67 case std::ios_base::end:
68 pos = memInfo.Length + pos_type(offset);
69 break;
70 default:
71 return traits_type::eof();
74 return seekpos(pos, mode);
77 MemStreamBuf::pos_type MemStreamBuf::seekpos(pos_type pos, std::ios_base::openmode mode)
79 if((mode&std::ios_base::out))
80 return traits_type::eof();
82 if(pos < 0 || pos > pos_type(memInfo.Length) || pos != pos_type(size_t(pos)))
83 return traits_type::eof();
84 memInfo.Pos = pos;
86 setg(0, 0, 0);
87 return pos;
91 int FileStreamBuf::underflow()
93 if(usrFile && gptr() == egptr())
95 ALsizei amt = fio.read(usrFile, reinterpret_cast<ALubyte*>(&buffer[0]), sizeof(buffer));
96 if(amt >= 0) setg(buffer, buffer, buffer+amt);
98 if(gptr() == egptr())
99 return traits_type::eof();
100 return (*gptr())&0xFF;
103 FileStreamBuf::pos_type FileStreamBuf::seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode)
105 if(!usrFile || (mode&std::ios_base::out))
106 return traits_type::eof();
108 pos_type pos;
109 switch(whence)
111 case std::ios_base::beg:
112 pos = pos_type(fio.seek(usrFile, offset, SEEK_SET));
113 break;
115 case std::ios_base::cur:
116 offset -= off_type(egptr()-gptr());
117 pos = pos_type(fio.seek(usrFile, offset, SEEK_CUR));
118 break;
120 case std::ios_base::end:
121 pos = pos_type(fio.seek(usrFile, offset, SEEK_END));
122 break;
124 default:
125 pos = traits_type::eof();
127 if(pos >= 0)
128 setg(0, 0, 0);
129 return pos;
132 FileStreamBuf::pos_type FileStreamBuf::seekpos(pos_type pos, std::ios_base::openmode mode)
134 if(pos != pos_type(off_type(pos)))
135 return traits_type::eof();
136 return seekoff(off_type(pos), std::ios_base::beg, mode);
140 static void *open_wrap(const char *filename, ALuint mode)
142 if(mode != 0)
143 return NULL;
145 return fopen(filename, "rb");
148 static void close_wrap(void *user_data)
150 FILE *f = (FILE*)user_data;
151 fclose(f);
154 ALsizei read_wrap(void *user_data, ALubyte *buf, ALuint bytes)
156 FILE *f = (FILE*)user_data;
157 return fread(buf, 1, bytes, f);
160 ALsizei write_wrap(void *user_data, const ALubyte *buf, ALuint bytes)
162 FILE *f = (FILE*)user_data;
163 return fwrite(buf, 1, bytes, f);
166 alureInt64 seek_wrap(void *user_data, alureInt64 offset, int whence)
168 FILE *f = (FILE*)user_data;
169 #ifdef HAVE_FSEEKO
170 if(offset != (off_t)offset || fseeko(f, offset, whence) != 0)
171 return -1;
172 return ftello(f);
173 #else
174 if(offset != (long)offset || fseek(f, offset, whence) != 0)
175 return -1;
176 return ftell(f);
177 #endif
180 UserFuncs Funcs = {
181 open_wrap,
182 close_wrap,
183 read_wrap,
184 write_wrap,
185 seek_wrap
188 extern "C" {
190 /* Function: alureSetIOCallbacks
192 * Provides callbacks for alternative methods to handle file I/O. Passing NULL
193 * for all callbacks is a valid way to revert to normal I/O, otherwise they
194 * must all be specified. Changing the callbacks will not affect open files
195 * (they will continue using the callbacks that were set at the time they were
196 * opened).
198 * Parameters:
199 * open - This callback is called to open the named file. The given mode is the
200 * access rights the open file should have. Currently, this will always
201 * be 0 for read-only (applications should check this to make sure, as
202 * future versions may pass other values for other modes). Upon success,
203 * a non-NULL handle must be returned which will be used as a unique
204 * identifier for the file.
205 * close - This callback is called to close an opened file handle. The handle
206 * will no longer be used after this function.
207 * read - This callback is called when data needs to be read from the given
208 * handle. Up to the given number of bytes should be copied into 'buf'
209 * and the number of bytes actually copied should be returned. Returning
210 * 0 means the end of the file has been reached (so non-blocking I/O
211 * methods should ensure at least 1 byte gets read), and negative
212 * indicates an error.
213 * write - This callback is called when data needs to be written to the given
214 * handle. Up to the given number of bytes should be copied from 'buf'
215 * and the number of bytes actually copied should be returned. A return
216 * value of 0 means no more data can be written (so non-blocking I/O
217 * methods should ensure at least 1 byte gets written), and negative
218 * indicates an error.
219 * seek - This callback is called to reposition the offset of the file handle.
220 * The given offset is interpreted according to 'whence', which may be
221 * SEEK_SET (absolute position from the start of the file), SEEK_CUR
222 * (relative position from the current offset), or SEEK_END (absolute
223 * position from the end of the file), as defined by standard C. The new
224 * offset from the beginning of the file should be returned. If the file
225 * cannot seek, such as when using a FIFO, -1 should be returned.
227 * Returns:
228 * AL_FALSE on error.
230 ALURE_API ALboolean ALURE_APIENTRY alureSetIOCallbacks(
231 void* (*open)(const char *filename, ALuint mode),
232 void (*close)(void *handle),
233 ALsizei (*read)(void *handle, ALubyte *buf, ALuint bytes),
234 ALsizei (*write)(void *handle, const ALubyte *buf, ALuint bytes),
235 alureInt64 (*seek)(void *handle, alureInt64 offset, int whence))
237 if(open && close && read && write && seek)
239 Funcs.open = open;
240 Funcs.close = close;
241 Funcs.read = read;
242 Funcs.write = write;
243 Funcs.seek = seek;
244 return AL_TRUE;
247 if(!open && !close && !read && !write && !seek)
249 Funcs.open = open_wrap;
250 Funcs.close = close_wrap;
251 Funcs.read = read_wrap;
252 Funcs.write = write_wrap;
253 Funcs.seek = seek_wrap;
254 return AL_TRUE;
257 SetError("Missing callback functions");
258 return AL_FALSE;
261 } // extern "C"