Commit ec3ba8d1 authored by conrad's avatar conrad

oggz_read_*(): when reading is stopped by the user, cache the return value

and return it on the subsequent read call (unless no data has been read, in
which case return it on this call as before). This ensures that when the
user returns OGGZ_STOP_OK or OGGZ_STOP_ERR in a read callback, that condition
is acknowledged in a subsequent call to oggz_read_*().


git-svn-id: http://svn.annodex.net/liboggz/trunk@2012 8158c8cd-e7e1-0310-9fa4-c5954c97daef
parent 9189e459
......@@ -84,6 +84,8 @@ oggz_new (int flags)
oggz->offset = 0;
oggz->offset_data_begin = 0;
oggz->cb_next = 0;
oggz->streams = oggz_vector_new ();
oggz->all_at_eos = 0;
......
......@@ -198,6 +198,8 @@ struct _OGGZ {
off_t offset; /* offset of current page start */
off_t offset_data_begin; /* offset of unit 0 page start */
int cb_next;
OggzVector * streams;
int all_at_eos; /* all streams are at eos */
......
......@@ -285,7 +285,9 @@ oggz_read_sync (OGGZ * oggz)
result = ogg_stream_packetout(os, op);
if(result == -1) {
/* hole in the data. */
#ifdef DEBUG
printf ("oggz_read_sync: hole in the data\n");
#endif
return -7;
}
......@@ -367,6 +369,23 @@ oggz_read_sync (OGGZ * oggz)
return cb_ret;
}
/* Map callback return values to error return values for oggz_read_*() */
static int
map_return_value_to_error (int cb_ret)
{
switch (cb_ret) {
case OGGZ_CONTINUE:
case OGGZ_READ_EMPTY:
return OGGZ_CONTINUE;
case OGGZ_STOP_OK:
return OGGZ_ERR_READ_STOP_OK;
case OGGZ_STOP_ERR:
return OGGZ_ERR_READ_STOP_ERR;
default:
return OGGZ_ERR_READ_STOP_ERR;
}
}
long
oggz_read (OGGZ * oggz, long n)
{
......@@ -381,6 +400,11 @@ oggz_read (OGGZ * oggz, long n)
return OGGZ_ERR_INVALID;
}
if ((cb_ret = oggz->cb_next) != OGGZ_CONTINUE) {
oggz->cb_next = 0;
return map_return_value_to_error (cb_ret);
}
reader = &oggz->x.reader;
cb_ret = oggz_read_sync (oggz);
......@@ -431,15 +455,11 @@ oggz_read (OGGZ * oggz, long n)
default: break;
}
switch (cb_ret) {
case OGGZ_CONTINUE: case OGGZ_READ_EMPTY:
#ifdef DEBUG
printf ("oggz_read: nread==0, cb_ret==%d, returning 0\n", cb_ret);
#endif
return 0; break;
case OGGZ_STOP_ERR: return OGGZ_ERR_READ_STOP_ERR; break;
case OGGZ_STOP_OK: default: return OGGZ_ERR_READ_STOP_OK; break;
}
return map_return_value_to_error (cb_ret);
} else {
if (cb_ret == OGGZ_READ_EMPTY) cb_ret = OGGZ_CONTINUE;
oggz->cb_next = cb_ret;
}
return nread;
......@@ -460,6 +480,11 @@ oggz_read_input (OGGZ * oggz, unsigned char * buf, long n)
return OGGZ_ERR_INVALID;
}
if ((cb_ret = oggz->cb_next) != OGGZ_CONTINUE) {
oggz->cb_next = 0;
return map_return_value_to_error (cb_ret);
}
reader = &oggz->x.reader;
cb_ret = oggz_read_sync (oggz);
......@@ -472,7 +497,8 @@ oggz_read_input (OGGZ * oggz, unsigned char * buf, long n)
}
#endif
while (cb_ret != -1 && cb_ret != 1 && /* !oggz->eos && */ remaining > 0) {
while (cb_ret != OGGZ_STOP_ERR && cb_ret != OGGZ_STOP_OK &&
/* !oggz->eos && */ remaining > 0) {
bytes = MIN (remaining, 4096);
buffer = ogg_sync_buffer (&reader->ogg_sync, bytes);
memcpy (buffer, buf, bytes);
......@@ -487,19 +513,16 @@ oggz_read_input (OGGZ * oggz, unsigned char * buf, long n)
if (cb_ret == OGGZ_STOP_ERR) oggz_purge (oggz);
/* Don't return 0 unless it's actually an EOF condition */
if (nread == 0) {
switch (cb_ret) {
case OGGZ_CONTINUE: return 0; break;
case OGGZ_READ_EMPTY:
#ifdef DEBUG
printf ("oggz_read_input: OUT EMPTY\n");
#endif
/* Don't return 0 unless it's actually an EOF condition */
if (cb_ret == OGGZ_READ_EMPTY) {
return OGGZ_ERR_READ_STOP_OK;
break;
case OGGZ_STOP_ERR: return OGGZ_ERR_READ_STOP_ERR; break;
case OGGZ_STOP_OK: default: return OGGZ_ERR_READ_STOP_OK; break;
} else {
return map_return_value_to_error (cb_ret);
}
} else {
if (cb_ret == OGGZ_READ_EMPTY) cb_ret = OGGZ_CONTINUE;
oggz->cb_next = cb_ret;
}
return nread;
......
......@@ -131,7 +131,7 @@ main (int argc, char * argv[])
{
OGGZ * reader, * writer;
unsigned char buf[READ_SIZE];
long n, remaining;
long n, remaining, err;
INFO ("Testing ability to pause while reading (OGGZ_STOP_OK)");
......@@ -153,10 +153,18 @@ main (int argc, char * argv[])
while ((remaining = oggz_write_output (writer, buf, READ_SIZE)) > 0) {
n = oggz_read_input (reader, buf, remaining);
if (n < remaining)
if (n == OGGZ_ERR_READ_STOP_OK) {
INFO ("+ Interrupted read detected");
remaining -= n;
} else {
remaining -= n;
err = oggz_read_input (reader, buf+n, remaining);
if (err == OGGZ_ERR_READ_STOP_OK) {
INFO ("+ Interrupted read detected");
} else {
FAIL ("Interrupted read not reported");
}
}
n = oggz_read_input (reader, buf+n, remaining);
remaining -= n;
......
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