Chris@1:
Chris@1: Although stdio is convenient and nearly universally implemented as per
Chris@1: ANSI C, it is not suited to all or even most potential uses of Vorbis.
Chris@1: For additional flexibility, embedded applications may provide their
Chris@1: own I/O functions for use with Vorbisfile when stdio is unavailable or not
Chris@1: suitable. One common example is decoding a Vorbis stream from a
Chris@1: memory buffer.
Chris@1:
Chris@1: Use custom I/O functions by populating an ov_callbacks structure and calling ov_open_callbacks() or ov_test_callbacks() rather than the
Chris@1: typical ov_open() or ov_test(). Past the open call, use of
Chris@1: libvorbisfile is identical to using it with stdio.
Chris@1:
Chris@1:
Read function
Chris@1:
Chris@1: The read-like function provided in the read_func field is
Chris@1: used to fetch the requested amount of data. It expects the fetch
Chris@1: operation to function similar to file-access, that is, a multiple read
Chris@1: operations will retrieve contiguous sequential pieces of data,
Chris@1: advancing a position cursor after each read.
Chris@1:
Chris@1: The following behaviors are also expected:
Chris@1:
Chris@1:
a return of '0' indicates end-of-data (if the by-thread errno is unset)
Chris@1:
short reads mean nothing special (short reads are not treated as error conditions)
Chris@1:
a return of zero with the by-thread errno set to nonzero indicates a read error
Chris@1:
Chris@1:
Chris@1:
Chris@1:
Seek function
Chris@1:
Chris@1: The seek-like function provided in the seek_func field is
Chris@1: used to request non-sequential data access by libvorbisfile, moving
Chris@1: the access cursor to the requested position. The seek function is
Chris@1: optional; if callbacks are only to handle non-seeking (streaming) data
Chris@1: or the application wishes to force streaming behavior,
Chris@1: seek_func and tell_func should be set to NULL. If
Chris@1: the seek function is non-NULL, libvorbisfile mandates the following
Chris@1: behavior:
Chris@1:
Chris@1:
Chris@1:
The seek function must always return -1 (failure) if the given
Chris@1: data abstraction is not seekable. It may choose to always return -1
Chris@1: if the application desires libvorbisfile to treat the Vorbis data
Chris@1: strictly as a stream (which makes for a less expensive open
Chris@1: operation).
Chris@1:
Chris@1:
If the seek function initially indicates seekability, it must
Chris@1: always succeed upon being given a valid seek request.
Chris@1:
Chris@1:
The seek function must implement all of SEEK_SET, SEEK_CUR and
Chris@1: SEEK_END. The implementation of SEEK_END should set the access cursor
Chris@1: one past the last byte of accessible data, as would stdio
Chris@1: fseek()
Chris@1:
Chris@1:
Chris@1:
Close function
Chris@1:
Chris@1: The close function should deallocate any access state used by the
Chris@1: passed in instance of the data access abstraction and invalidate the
Chris@1: instance handle. The close function is assumed to succeed; its return
Chris@1: code is not checked.
Chris@1:
Chris@1: The close_func may be set to NULL to indicate that libvorbis
Chris@1: should not attempt to close the file/data handle in ov_clear but allow the application to handle
Chris@1: file/data access cleanup itself. For example, by passing the normal
Chris@1: stdio calls as callback functions, but passing a close_func
Chris@1: that is NULL or does nothing (as in the case of OV_CALLBACKS_NOCLOSE), an
Chris@1: application may call ov_clear() and then
Chris@1: later fclose() the file originally passed to libvorbisfile.
Chris@1:
Chris@1:
Tell function
Chris@1:
Chris@1: The tell function is intended to mimic the
Chris@1: behavior of ftell() and must return the byte position of the
Chris@1: next data byte that would be read. If the data access cursor is at
Chris@1: the end of the 'file' (pointing to one past the last byte of data, as
Chris@1: it would be after calling fseek(file,SEEK_END,0)), the tell
Chris@1: function must return the data position (and thus the total file size),
Chris@1: not an error.
Chris@1:
Chris@1: The tell function need not be provided if the data IO abstraction is
Chris@1: not seekable, or the application wishes to force streaming
Chris@1: behavior. In this case, the tell_func and seek_func
Chris@1: fields should be set to NULL.