Commit 967088ac authored by conrad's avatar conrad

- added OggzIO interface (<oggz/oggz_io.h>, src/liboggz/oggz_io.c)

 - added test cases for IO overriding
 - added OGGZ_CONTINUE, OGGZ_STOP_OK, OGGZ_STOP_ERR constants
 - added test cases for read callback stopping (OK and ERR)


git-svn-id: http://svn.annodex.net/liboggz/trunk@382 8158c8cd-e7e1-0310-9fa4-c5954c97daef
parent 824868c7
......@@ -2,5 +2,5 @@
# Include files to install
includedir = $(prefix)/include/oggz
include_HEADERS = oggz.h oggz_constants.h oggz_table.h
include_HEADERS = oggz.h oggz_constants.h oggz_io.h oggz_table.h
......@@ -1094,5 +1094,6 @@ long oggz_seek_packets (OGGZ * oggz, long serialno, long packets, int whence);
*/
long oggz_serialno_new (OGGZ * oggz);
#include <oggz/oggz_io.h>
#endif /* __OGGZ_H__ */
......@@ -63,6 +63,17 @@ enum OggzFlags {
OGGZ_AUTO = 0x20
};
enum OggzStopCtl {
/** Continue calling read callbacks */
OGGZ_CONTINUE = 0,
/** Stop calling callbacks, but retain buffered packet data */
OGGZ_STOP_OK = 1,
/** Stop calling callbacks, and purge buffered packet data */
OGGZ_STOP_ERR = -1
};
/**
* Flush options for oggz_write_feed; can be or'ed together
*/
......
......@@ -62,7 +62,7 @@
* \retval 0 to indicate that there is no more data to read (End of file)
* \retval "< 0" An error condition
*/
typedef long (*OggzIORead) (void * user_handle, void * buf, long n);
typedef size_t (*OggzIORead) (void * user_handle, void * buf, size_t n);
/**
* This is the signature of a function which you provide for Oggz
......@@ -75,7 +75,7 @@ typedef long (*OggzIORead) (void * user_handle, void * buf, long n);
* \a n if a write error has occurred)
* \retval "< 0" An error condition
*/
typedef long (*OggzIOWrite) (void * user_handle, void * buf, long n);
typedef size_t (*OggzIOWrite) (void * user_handle, void * buf, size_t n);
/**
* This is the signature of a function which you provide for Oggz
......@@ -86,8 +86,11 @@ typedef long (*OggzIOWrite) (void * user_handle, void * buf, long n);
* \param whence SEEK_SET, SEEK_CUR or SEEK_END (as for stdio.h)
* \retval ">= 0" The offset seeked to
* \retval "< 0" An error condition
*
* \note If you provide an OggzIOSeek function, you MUST also provide
* an OggzIOTell function, or else all your seeks will fail.
*/
typedef off_t (*OggzIOSeek) (void * user_handle, off_t offset, int whence);
typedef int (*OggzIOSeek) (void * user_handle, long offset, int whence);
/**
* This is the signature of a function which you provide for Oggz
......@@ -98,7 +101,7 @@ typedef off_t (*OggzIOSeek) (void * user_handle, off_t offset, int whence);
* \retval ">= 0" The offset
* \retval "< 0" An error condition
*/
typedef off_t (*OggzIOTell) (void * user_handle);
typedef long (*OggzIOTell) (void * user_handle);
/**
* This is the signature of a function which you provide for Oggz
......@@ -165,6 +168,9 @@ void * oggz_io_get_write_user_handle (OGGZ * oggz);
* \retval 0 Success
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
*
* \note If you provide an OggzIOSeek function, you MUST also provide
* an OggzIOTell function, or else all your seeks will fail.
*/
int oggz_io_set_seek (OGGZ * oggz, OggzIOSeek seek, void * user_handle);
......
......@@ -12,6 +12,7 @@ lib_LTLIBRARIES = liboggz.la
liboggz_la_SOURCES = \
oggz.c \
oggz_private.h oggz_byteorder.h oggz_compat.h oggz_macros.h \
oggz_io.c \
oggz_read.c oggz_write.c \
oggz_auto.c oggz_auto.h \
oggz_table.c \
......
......@@ -79,6 +79,7 @@ oggz_new (int flags)
oggz->flags = flags;
oggz->file = NULL;
oggz->io = NULL;
oggz->offset = 0;
oggz->offset_data_begin = 0;
......@@ -141,13 +142,7 @@ oggz_flush (OGGZ * oggz)
{
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
if (oggz->file == NULL) return OGGZ_ERR_INVALID;
if (fflush (oggz->file) == EOF) {
return OGGZ_ERR_SYSTEM;
}
return 0;
return oggz_io_flush (oggz);
}
static int
......
......@@ -42,6 +42,7 @@
#include "oggz_vector.h"
typedef struct _OGGZ OGGZ;
typedef struct _OggzIO OggzIO;
typedef struct _OggzReader OggzReader;
typedef struct _OggzWriter OggzWriter;
......@@ -57,6 +58,13 @@ typedef int (*OggzOrder) (OGGZ * oggz, ogg_packet * op, void * target,
typedef int (*OggzWriteHungry) (OGGZ * oggz, int empty, void * user_data);
/* oggz_io */
typedef size_t (*OggzIORead) (void * user_handle, void * buf, size_t n);
typedef size_t (*OggzIOWrite) (void * user_handle, void * buf, size_t n);
typedef int (*OggzIOSeek) (void * user_handle, long offset, int whence);
typedef long (*OggzIOTell) (void * user_handle);
typedef int (*OggzIOFlush) (void * user_handle);
typedef struct {
ogg_stream_state ogg_stream;
......@@ -139,9 +147,27 @@ struct _OggzWriter {
ogg_stream_state * current_stream;
};
struct _OggzIO {
OggzIORead read;
void * read_user_handle;
OggzIOWrite write;
void * write_user_handle;
OggzIOSeek seek;
void * seek_user_handle;
OggzIOTell tell;
void * tell_user_handle;
OggzIOFlush flush;
void * flush_user_handle;
};
struct _OGGZ {
int flags;
FILE * file;
OggzIO * io;
ogg_packet current_packet;
ogg_page current_page;
......@@ -184,4 +210,11 @@ int oggz_purge (OGGZ * oggz);
int oggz_auto (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data);
/* oggz_io */
size_t oggz_io_read (OGGZ * oggz, void * buf, size_t n);
size_t oggz_io_write (OGGZ * oggz, void * buf, size_t n);
int oggz_io_seek (OGGZ * oggz, long offset, int whence);
long oggz_io_tell (OGGZ * oggz);
int oggz_io_flush (OGGZ * oggz);
#endif /* __OGGZ_PRIVATE_H__ */
......@@ -157,7 +157,7 @@ oggz_get_next_page_7 (OGGZ * oggz, ogg_page * og)
page_offset = 0;
#if _UMMODIFIED_
buffer = ogg_sync_buffer (&reader->ogg_sync, CHUNKSIZE);
if ((bytes = fread (buffer, 1, CHUNKSIZE, oggz->file)) == 0) {
if ((bytes = oggz_io_read (oggz, buffer, CHUNKSIZE)) == 0) {
if (ferror (oggz->file)) {
oggz_set_error (oggz, OGGZ_ERR_SYSTEM);
return -1;
......@@ -188,7 +188,7 @@ oggz_get_next_page_7 (OGGZ * oggz, ogg_page * og)
/* Calculate the byte offset of the page which was found */
if (bytes > 0) {
oggz->offset = ftell (oggz->file) - bytes + page_offset;
oggz->offset = oggz_io_tell (oggz) - bytes + page_offset;
ret = oggz->offset;
} else {
/* didn't need to do any reading -- accumulate the page_offset */
......@@ -275,6 +275,9 @@ oggz_read_sync (OGGZ * oggz)
}
}
/* If we've got a stop already, don't read more data in */
if (cb_ret != 0) return cb_ret;
if(oggz_get_next_page_7 (oggz, &og) < 0)
return -404; /* eof. leave unitialized */
......@@ -348,7 +351,7 @@ oggz_read (OGGZ * oggz, long n)
while (cb_ret != -1 && cb_ret != 1 && bytes_read > 0 && remaining > 0) {
bytes = MIN (remaining, 4096);
buffer = ogg_sync_buffer (&reader->ogg_sync, bytes);
if ((bytes_read = (long)fread (buffer, 1, bytes, oggz->file)) == 0) {
if ((bytes_read = (long) oggz_io_read (oggz, buffer, bytes)) == 0) {
if (ferror (oggz->file)) {
return OGGZ_ERR_SYSTEM;
......@@ -432,7 +435,7 @@ oggz_tell_raw (OGGZ * oggz)
{
oggz_off_t offset_at;
offset_at = ftell (oggz->file);
offset_at = oggz_io_tell (oggz);
return offset_at;
}
......@@ -446,16 +449,11 @@ oggz_seek_raw (OGGZ * oggz, oggz_off_t offset, int whence)
OggzReader * reader = &oggz->x.reader;
oggz_off_t offset_at;
if (fseek (oggz->file, offset, whence) == -1) {
if (errno == ESPIPE) {
/*oggz_set_error (oggz, OGGZ_ERR_NOSEEK);*/
} else {
/*oggz_set_error (oggz, OGGZ_ERR_SYSTEM);*/
}
if (oggz_io_seek (oggz, offset, whence) == -1) {
return -1;
}
offset_at = ftell (oggz->file);
offset_at = oggz_io_tell (oggz);
oggz->offset = offset_at;
......@@ -554,7 +552,7 @@ oggz_get_next_page (OGGZ * oggz, ogg_page * og)
page_offset = 0;
buffer = ogg_sync_buffer (&reader->ogg_sync, CHUNKSIZE);
if ((bytes = (long)fread (buffer, 1, CHUNKSIZE, oggz->file)) == 0) {
if ((bytes = (long) oggz_io_read (oggz, buffer, CHUNKSIZE)) == 0) {
if (ferror (oggz->file)) {
/*oggz_set_error (oggz, OGGZ_ERR_SYSTEM);*/
return -1;
......
......@@ -455,11 +455,14 @@ oggz_page_writeout (OGGZ * oggz, long n)
#ifdef OGGZ_WRITE_DIRECT
nwritten = write (fd, og->header + writer->page_offset, h);
#else
nwritten = (long)fwrite (og->header + writer->page_offset, 1, h, oggz->file);
nwritten = (long)oggz_io_write (oggz, og->header + writer->page_offset, h);
#endif
#ifdef DEBUG
if (nwritten < h) {
printf ("oggz_page_writeout: %ld < %ld\n", nwritten, h);
}
#endif
writer->page_offset += h;
n -= h;
} else {
......@@ -472,12 +475,13 @@ oggz_page_writeout (OGGZ * oggz, long n)
nwritten = write (fd,
og->body + (writer->page_offset - og->header_len), b);
#else
nwritten = (long)fwrite (og->body + (writer->page_offset - og->header_len),
1, b, oggz->file);
nwritten = (long)oggz_io_write (oggz, og->body + (writer->page_offset - og->header_len), b);
#endif
#ifdef DEBUG
if (nwritten < b) {
printf ("oggz_page_writeout: %ld < %ld\n", nwritten, b);
}
#endif
writer->page_offset += b;
n -= b;
} else {
......
......@@ -17,7 +17,14 @@ write_tests = write-bad-guard write-unmarked-guard write-recursive \
write-bad-granulepos write-bad-packetno
endif
TESTS = $(write_tests)
if OGGZ_CONFIG_READ
if OGGZ_CONFIG_WRITE
rw_tests = read-generated read-stop-ok read-stop-err \
io-read io-seek io-write
endif
endif
TESTS = $(write_tests) $(rw_tests)
noinst_PROGRAMS = $(TESTS)
noinst_HEADERS = oggz_tests.h
......@@ -48,3 +55,21 @@ write_bad_granulepos_LDADD = $(OGGZ_LIBS)
write_bad_packetno_SOURCES = write-bad-packetno.c
write_bad_packetno_LDADD = $(OGGZ_LIBS)
read_generated_SOURCES = read-generated.c
read_generated_LDADD = $(OGGZ_LIBS)
read_stop_ok_SOURCES = read-stop-ok.c
read_stop_ok_LDADD = $(OGGZ_LIBS)
read_stop_err_SOURCES = read-stop-err.c
read_stop_err_LDADD = $(OGGZ_LIBS)
io_read_SOURCES = io-read.c
io_read_LDADD = $(OGGZ_LIBS)
io_seek_SOURCES = io-seek.c
io_seek_LDADD = $(OGGZ_LIBS)
io_write_SOURCES = io-write.c
io_write_LDADD = $(OGGZ_LIBS)
......@@ -30,9 +30,25 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#else
# define PRId64 "I64d"
#endif
/* FIXME: on Mac OS X, off_t is 64-bits. Obviously we want a nicer
* way to do it than this, but a quick fix is a good fix */
#ifdef __APPLE__
# define PRI_off_t "q"
#else
# define PRI_off_t "l"
#endif
#define INFO(str) \
{ printf ("---- %s ...\n", (str)); }
......@@ -41,3 +57,6 @@
#define FAIL(str) \
{ printf ("%s:%d: %s\n", __FILE__, __LINE__, (str)); exit(1); }
#undef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment