2 * ALURE OpenAL utility library
3 * Copyright (c) 2009 by Chris Robinson.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
31 #include <sys/types.h>
42 MemStreamBuf::int_type
MemStreamBuf::underflow()
46 char_type
*data
= (char_type
*)memInfo
.Data
;
47 setg(data
, data
+ memInfo
.Pos
, data
+ memInfo
.Length
);
48 memInfo
.Pos
= memInfo
.Length
;
51 return traits_type::eof();
52 return (*gptr())&0xFF;
55 MemStreamBuf::pos_type
MemStreamBuf::seekoff(off_type offset
, std::ios_base::seekdir whence
, std::ios_base::openmode mode
)
57 if((mode
&std::ios_base::out
))
58 return traits_type::eof();
63 case std::ios_base::beg
:
64 pos
= pos_type(offset
);
66 case std::ios_base::cur
:
67 pos
= pos_type(memInfo
.Pos
) - pos_type(egptr()-gptr());
70 case std::ios_base::end
:
71 pos
= memInfo
.Length
+ pos_type(offset
);
74 return traits_type::eof();
77 return seekpos(pos
, mode
);
80 MemStreamBuf::pos_type
MemStreamBuf::seekpos(pos_type pos
, std::ios_base::openmode mode
)
82 if((mode
&std::ios_base::out
))
83 return traits_type::eof();
85 if(pos
< 0 || pos
> pos_type(memInfo
.Length
) || pos
!= pos_type(size_t(pos
)))
86 return traits_type::eof();
94 int FileStreamBuf::underflow()
96 if(usrFile
&& gptr() == egptr())
98 ALsizei amt
= fio
.read(usrFile
, reinterpret_cast<ALubyte
*>(&buffer
[0]), sizeof(buffer
));
99 if(amt
>= 0) setg(buffer
, buffer
, buffer
+amt
);
101 if(gptr() == egptr())
102 return traits_type::eof();
103 return (*gptr())&0xFF;
106 FileStreamBuf::pos_type
FileStreamBuf::seekoff(off_type offset
, std::ios_base::seekdir whence
, std::ios_base::openmode mode
)
108 if(!usrFile
|| (mode
&std::ios_base::out
))
109 return traits_type::eof();
114 case std::ios_base::beg
:
115 pos
= pos_type(fio
.seek(usrFile
, offset
, SEEK_SET
));
118 case std::ios_base::cur
:
119 offset
-= off_type(egptr()-gptr());
120 pos
= pos_type(fio
.seek(usrFile
, offset
, SEEK_CUR
));
123 case std::ios_base::end
:
124 pos
= pos_type(fio
.seek(usrFile
, offset
, SEEK_END
));
128 pos
= traits_type::eof();
135 FileStreamBuf::pos_type
FileStreamBuf::seekpos(pos_type pos
, std::ios_base::openmode mode
)
137 if(pos
!= pos_type(off_type(pos
)))
138 return traits_type::eof();
139 return seekoff(off_type(pos
), std::ios_base::beg
, mode
);
143 static void *open_wrap(const char *filename
, ALuint mode
)
148 return fopen(filename
, "rb");
151 static void close_wrap(void *user_data
)
153 FILE *f
= (FILE*)user_data
;
157 ALsizei
read_wrap(void *user_data
, ALubyte
*buf
, ALuint bytes
)
159 FILE *f
= (FILE*)user_data
;
160 return fread(buf
, 1, bytes
, f
);
163 ALsizei
write_wrap(void *user_data
, const ALubyte
*buf
, ALuint bytes
)
165 FILE *f
= (FILE*)user_data
;
166 return fwrite(buf
, 1, bytes
, f
);
169 alureInt64
seek_wrap(void *user_data
, alureInt64 offset
, int whence
)
171 FILE *f
= (FILE*)user_data
;
173 if(offset
!= (off_t
)offset
|| fseeko(f
, offset
, whence
) != 0)
177 if(offset
!= (long)offset
|| fseek(f
, offset
, whence
) != 0)
193 /* Function: alureSetIOCallbacks
195 * Provides callbacks for alternative methods to handle file I/O. Passing NULL
196 * for all callbacks is a valid way to revert to normal I/O, otherwise they
197 * must all be specified. Changing the callbacks will not affect open files
198 * (they will continue using the callbacks that were set at the time they were
202 * open - This callback is called to open the named file. The given mode is the
203 * access rights the open file should have. Currently, this will always
204 * be 0 for read-only (applications should check this to make sure, as
205 * future versions may pass other values for other modes). Upon success,
206 * a non-NULL handle must be returned which will be used as a unique
207 * identifier for the file.
208 * close - This callback is called to close an opened file handle. The handle
209 * will no longer be used after this function.
210 * read - This callback is called when data needs to be read from the given
211 * handle. Up to the given number of bytes should be copied into 'buf'
212 * and the number of bytes actually copied should be returned. Returning
213 * 0 means the end of the file has been reached (so non-blocking I/O
214 * methods should ensure at least 1 byte gets read), and negative
215 * indicates an error.
216 * write - This callback is called when data needs to be written to the given
217 * handle. Up to the given number of bytes should be copied from 'buf'
218 * and the number of bytes actually copied should be returned. A return
219 * value of 0 means no more data can be written (so non-blocking I/O
220 * methods should ensure at least 1 byte gets written), and negative
221 * indicates an error.
222 * seek - This callback is called to reposition the offset of the file handle.
223 * The given offset is interpreted according to 'whence', which may be
224 * SEEK_SET (absolute position from the start of the file), SEEK_CUR
225 * (relative position from the current offset), or SEEK_END (absolute
226 * position from the end of the file), as defined by standard C. The new
227 * offset from the beginning of the file should be returned. If the file
228 * cannot seek, such as when using a FIFO, -1 should be returned.
233 * *Version Added*: 1.1
235 ALURE_API ALboolean ALURE_APIENTRY
alureSetIOCallbacks(
236 void* (*open
)(const char *filename
, ALuint mode
),
237 void (*close
)(void *handle
),
238 ALsizei (*read
)(void *handle
, ALubyte
*buf
, ALuint bytes
),
239 ALsizei (*write
)(void *handle
, const ALubyte
*buf
, ALuint bytes
),
240 alureInt64 (*seek
)(void *handle
, alureInt64 offset
, int whence
))
242 if(open
&& close
&& read
&& write
&& seek
)
252 if(!open
&& !close
&& !read
&& !write
&& !seek
)
254 Funcs
.open
= open_wrap
;
255 Funcs
.close
= close_wrap
;
256 Funcs
.read
= read_wrap
;
257 Funcs
.write
= write_wrap
;
258 Funcs
.seek
= seek_wrap
;
262 SetError("Missing callback functions");