+
+static size_t cb_read(void *buf, size_t size, size_t nmemb, void *datasource)
+{
+ FILE *f = datasource;
+ return fread(buf, size, nmemb, f);
+}
+
+static int cb_seek(__a_unused void *datasource, ogg_int64_t offset,
+ int whence)
+{
+ FILE *f = datasource;
+ return fseek(f, offset, whence);
+}
+
+/* don't do anything as vss still needs the open filehandle */
+static int cb_close(__a_unused void *datasource)
+{
+ return 0;
+}
+
+long cb_tell(void *datasource)
+{
+ FILE *f = datasource;
+ return ftell(f);
+}
+
+int ogg_open_callbacks(void *datasource, OggVorbis_File *vf, ov_callbacks c)
+{
+ int ret = ov_open_callbacks(datasource, vf,
+ NULL, /* no initial buffer */
+ 0, /* no initial bytes */
+ c); /* the ov_open_callbacks */
+
+ /* FIXME: provide better error codes */
+ if (ret == OV_EREAD)
+ return -E_OGG_READ;
+ if (ret == OV_ENOTVORBIS)
+ return -E_OGG_READ;
+ if (ret == OV_EVERSION)
+ return -E_OGG_READ;
+ if (ret == OV_EBADHEADER)
+ return -E_OGG_READ;
+ if (ret < 0)
+ return -E_OGG_READ;
+ return 1;
+
+}