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
28 #include <sys/types.h>
39 MemStreamBuf::int_type
MemStreamBuf::underflow()
43 char_type
*data
= (char_type
*)memInfo
.Data
;
44 setg(data
, data
+ memInfo
.Pos
, data
+ memInfo
.Length
);
45 memInfo
.Pos
= memInfo
.Length
;
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();
60 case std::ios_base::beg
:
61 pos
= pos_type(offset
);
63 case std::ios_base::cur
:
64 pos
= pos_type(memInfo
.Pos
) - pos_type(egptr()-gptr());
67 case std::ios_base::end
:
68 pos
= memInfo
.Length
+ pos_type(offset
);
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();
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
);
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();
111 case std::ios_base::beg
:
112 pos
= pos_type(fio
.seek(usrFile
, offset
, SEEK_SET
));
115 case std::ios_base::cur
:
116 offset
-= off_type(egptr()-gptr());
117 pos
= pos_type(fio
.seek(usrFile
, offset
, SEEK_CUR
));
120 case std::ios_base::end
:
121 pos
= pos_type(fio
.seek(usrFile
, offset
, SEEK_END
));
125 pos
= traits_type::eof();
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
)
145 return fopen(filename
, "rb");
148 static void close_wrap(void *user_data
)
150 FILE *f
= (FILE*)user_data
;
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
;
170 if(offset
!= (off_t
)offset
|| fseeko(f
, offset
, whence
) != 0)
174 if(offset
!= (long)offset
|| fseek(f
, offset
, whence
) != 0)
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
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.
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
)
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
;
257 SetError("Missing callback functions");