Commit 742fa79a authored by conrad's avatar conrad

add delayed callback return values for oggz_write_*(), so that user stopped

callbacks are always reported (on the subsequent call if data was written
during the current call; semantics for the current call are unchanged).
+ generalises delayed return values and callback return -> error mappings


git-svn-id: http://svn.annodex.net/liboggz/trunk@2014 8158c8cd-e7e1-0310-9fa4-c5954c97daef
parent ec3ba8d1
......@@ -123,12 +123,14 @@ enum OggzError {
OGGZ_ERR_NOSEEK = -13,
/** Reading was stopped by an OggzReadCallback returning OGGZ_STOP_OK
* before any input bytes were consumed */
OGGZ_ERR_READ_STOP_OK = -14,
* or writing was stopped by an OggzWriteHungry callback returning
* OGGZ_STOP_OK */
OGGZ_ERR_STOP_OK = -14,
/** Reading was stopped by an OggzReadCallback returning OGGZ_STOP_ERR
* before any input bytes were consumed */
OGGZ_ERR_READ_STOP_ERR = -15,
* or writing was stopped by an OggzWriteHungry callback returning
* OGGZ_STOP_ERR */
OGGZ_ERR_STOP_ERR = -15,
/** no data available from IO, try again */
OGGZ_ERR_IO_AGAIN = -16,
......
......@@ -47,7 +47,18 @@
* code should distinguish between these two too :-) Hence, don't use this
* (unreleased) name in new code.
*/
#define OGGZ_ERR_USER_STOPPED OGGZ_ERR_READ_STOP_OK
#define OGGZ_ERR_USER_STOPPED OGGZ_ERR_STOP_OK
/**
* DEPRECATED CONSTANTS.
* OGGZ_ERR_READ_STOP_OK, OGGZ_ERR_READ_STOP_ERR were introduced to allow
* the user to differentiate between a cancelled oggz_read_*() returning
* due to error or an ok condition.
* From 0.9.4 similar functionality was added for oggz_write_*(), hence these
* constants were renamed appropriately.
*/
#define OGGZ_ERR_READ_STOP_OK OGGZ_ERR_STOP_OK
#define OGGZ_ERR_READ_STOP_ERR OGGZ_ERR_STOP_ERR
/**
* DEPRECATED FUNCTION
......
......@@ -514,3 +514,19 @@ oggz_set_order (OGGZ * oggz, long serialno,
return 0;
}
/* Map callback return values to error return values */
int
oggz_map_return_value_to_error (int cb_ret)
{
switch (cb_ret) {
case OGGZ_CONTINUE:
return OGGZ_ERR_OK;
case OGGZ_STOP_OK:
return OGGZ_ERR_STOP_OK;
case OGGZ_STOP_ERR:
return OGGZ_ERR_STOP_ERR;
default:
return OGGZ_ERR_STOP_ERR;
}
}
......@@ -223,6 +223,8 @@ OGGZ * oggz_write_init (OGGZ * oggz);
int oggz_write_flush (OGGZ * oggz);
OGGZ * oggz_write_close (OGGZ * oggz);
int oggz_map_return_value_to_error (int cb_ret);
int oggz_get_bos (OGGZ * oggz, long serialno);
ogg_int64_t oggz_get_unit (OGGZ * oggz, long serialno, ogg_int64_t granulepos);
......
......@@ -369,23 +369,6 @@ 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)
{
......@@ -402,7 +385,7 @@ oggz_read (OGGZ * oggz, long n)
if ((cb_ret = oggz->cb_next) != OGGZ_CONTINUE) {
oggz->cb_next = 0;
return map_return_value_to_error (cb_ret);
return oggz_map_return_value_to_error (cb_ret);
}
reader = &oggz->x.reader;
......@@ -455,7 +438,11 @@ oggz_read (OGGZ * oggz, long n)
default: break;
}
return map_return_value_to_error (cb_ret);
if (cb_ret == OGGZ_READ_EMPTY) {
return 0;
} else {
return oggz_map_return_value_to_error (cb_ret);
}
} else {
if (cb_ret == OGGZ_READ_EMPTY) cb_ret = OGGZ_CONTINUE;
......@@ -482,7 +469,7 @@ oggz_read_input (OGGZ * oggz, unsigned char * buf, long n)
if ((cb_ret = oggz->cb_next) != OGGZ_CONTINUE) {
oggz->cb_next = 0;
return map_return_value_to_error (cb_ret);
return oggz_map_return_value_to_error (cb_ret);
}
reader = &oggz->x.reader;
......@@ -516,9 +503,9 @@ oggz_read_input (OGGZ * oggz, unsigned char * buf, long n)
if (nread == 0) {
/* Don't return 0 unless it's actually an EOF condition */
if (cb_ret == OGGZ_READ_EMPTY) {
return OGGZ_ERR_READ_STOP_OK;
return OGGZ_ERR_STOP_OK;
} else {
return map_return_value_to_error (cb_ret);
return oggz_map_return_value_to_error (cb_ret);
}
} else {
if (cb_ret == OGGZ_READ_EMPTY) cb_ret = OGGZ_CONTINUE;
......
......@@ -534,35 +534,35 @@ oggz_page_writeout (OGGZ * oggz, long n)
return h + b;
}
static oggz_writer_packet_t *
oggz_dequeue_packet (OGGZ * oggz)
static int
oggz_dequeue_packet (OGGZ * oggz, oggz_writer_packet_t ** next_zpacket)
{
OggzWriter * writer = &oggz->x.writer;
oggz_writer_packet_t * next_zpacket;
int ret = 0;
if (writer->next_zpacket != NULL) {
#ifdef DEBUG
printf ("oggz_dequeue_packet: queue EMPTY\n");
#endif
next_zpacket = writer->next_zpacket;
*next_zpacket = writer->next_zpacket;
writer->next_zpacket = NULL;
} else {
next_zpacket = oggz_vector_pop (writer->packet_queue);
*next_zpacket = oggz_vector_pop (writer->packet_queue);
#ifdef DEBUG
printf ("oggz_dequeue_packet: dequeued packet, queue size %d\n",
oggz_vector_size (writer->packet_queue));
#endif
if (next_zpacket == NULL) {
if (*next_zpacket == NULL) {
if (writer->hungry) {
writer->hungry (oggz, 1, writer->hungry_user_data);
next_zpacket = oggz_vector_pop (writer->packet_queue);
ret = writer->hungry (oggz, 1, writer->hungry_user_data);
*next_zpacket = oggz_vector_pop (writer->packet_queue);
}
}
}
return next_zpacket;
return ret;
}
static long
......@@ -570,7 +570,7 @@ oggz_writer_make_packet (OGGZ * oggz)
{
OggzWriter * writer = &oggz->x.writer;
oggz_writer_packet_t * zpacket, * next_zpacket;
int cb_ret = 0, ret = 0;
int cb_ret = 0;
#ifdef DEBUG
printf ("oggz_writer_make_packet: IN\n");
......@@ -591,12 +591,12 @@ oggz_writer_make_packet (OGGZ * oggz)
if (cb_ret == 0) {
/* dequeue and init the next packet */
if ((next_zpacket = oggz_dequeue_packet (oggz)) == NULL) {
cb_ret = oggz_dequeue_packet (oggz, &next_zpacket);
if (next_zpacket == NULL) {
#ifdef DEBUG
printf ("oggz_writer_make_packet: packet queue empty\n");
#endif
/*writer->eos = 1;*/
ret = 0;
} else {
if ((writer->current_stream != NULL) &&
(next_zpacket->flush & OGGZ_FLUSH_BEFORE)) {
......@@ -610,13 +610,10 @@ oggz_writer_make_packet (OGGZ * oggz)
} else {
oggz_packet_init (oggz, next_zpacket);
}
ret = 1;
}
} else {
ret = 0;
}
return ret;
return cb_ret;
}
long
......@@ -624,7 +621,7 @@ oggz_write_output (OGGZ * oggz, unsigned char * buf, long n)
{
OggzWriter * writer = &oggz->x.writer;
long bytes, bytes_written = 1, remaining = n, nwritten = 0;
int active = 1;
int active = 1, cb_ret = 0;
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
......@@ -635,11 +632,16 @@ oggz_write_output (OGGZ * oggz, unsigned char * buf, long n)
if (writer->writing) return OGGZ_ERR_RECURSIVE_WRITE;
writer->writing = 1;
if ((cb_ret = oggz->cb_next) != OGGZ_CONTINUE) {
oggz->cb_next = 0;
return oggz_map_return_value_to_error (cb_ret);
}
while (active && remaining > 0) {
bytes = MIN (remaining, 1024);
while (writer->state == OGGZ_MAKING_PACKETS) {
if (!oggz_writer_make_packet (oggz)) {
if ((cb_ret = oggz_writer_make_packet (oggz)) != OGGZ_CONTINUE) {
active = 0;
break;
}
......@@ -653,7 +655,7 @@ oggz_write_output (OGGZ * oggz, unsigned char * buf, long n)
if (bytes_written == -1) {
active = 0;
return OGGZ_ERR_SYSTEM; /* XXX: catch next */
cb_ret = OGGZ_ERR_SYSTEM; /* XXX: catch next */
} else if (bytes_written == 0) {
if (!oggz_page_init (oggz)) {
writer->state = OGGZ_MAKING_PACKETS;
......@@ -669,6 +671,12 @@ oggz_write_output (OGGZ * oggz, unsigned char * buf, long n)
writer->writing = 0;
if (nwritten == 0) {
return oggz_map_return_value_to_error (cb_ret);
} else {
oggz->cb_next = cb_ret;
}
return nwritten;
}
......@@ -677,7 +685,7 @@ oggz_write (OGGZ * oggz, long n)
{
OggzWriter * writer = &oggz->x.writer;
long bytes, bytes_written = 1, remaining = n, nwritten = 0;
int active = 1;
int active = 1, cb_ret = 0;
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
......@@ -692,6 +700,11 @@ oggz_write (OGGZ * oggz, long n)
printf ("oggz_write: IN\n");
#endif
if ((cb_ret = oggz->cb_next) != OGGZ_CONTINUE) {
oggz->cb_next = 0;
return oggz_map_return_value_to_error (cb_ret);
}
while (active && remaining > 0) {
bytes = MIN (remaining, 1024);
......@@ -701,7 +714,7 @@ oggz_write (OGGZ * oggz, long n)
#endif
while (writer->state == OGGZ_MAKING_PACKETS) {
if (!oggz_writer_make_packet (oggz)) {
if ((cb_ret = oggz_writer_make_packet (oggz)) != OGGZ_CONTINUE) {
active = 0;
#ifdef DEBUG
printf ("oggz_write: no packets\n");
......@@ -739,6 +752,12 @@ oggz_write (OGGZ * oggz, long n)
writer->writing = 0;
if (nwritten == 0) {
return oggz_map_return_value_to_error (cb_ret);
} else {
oggz->cb_next = cb_ret;
}
return nwritten;
}
......
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