diff --git a/include/oggz/oggz.h b/include/oggz/oggz.h index ef5b9c60f9b6f13d1e4e97acc34147b699c15f2e..605d44db39d2bbf0f47b85e2afb6a64d45c24f6a 100644 --- a/include/oggz/oggz.h +++ b/include/oggz/oggz.h @@ -578,6 +578,10 @@ int oggz_set_read_callback (OGGZ * oggz, long serialno, * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ * \retval OGGZ_ERR_SYSTEM System error; check errno for details + * \retval OGGZ_ERR_USER_STOPPED Reading was stopped by a user callback + * returning OGGZ_STOP_OK or OGGZ_STOP_ERR before any input bytes were + * consumed. This will occur when a packet is read from a previously + * buffered page of input data, and stopping is immediately requested. */ long oggz_read (OGGZ * oggz, long n); @@ -589,6 +593,10 @@ long oggz_read (OGGZ * oggz, long n); * \retval "> 0" The number of bytes successfully ingested. * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ + * \retval OGGZ_ERR_USER_STOPPED Reading was stopped by a user callback + * returning OGGZ_STOP_OK or OGGZ_STOP_ERR before any input bytes were + * consumed. This will occur when a packet is read from a previously + * buffered page of input data, and stopping is immediately requested. */ long oggz_read_input (OGGZ * oggz, unsigned char * buf, long n); diff --git a/include/oggz/oggz_constants.h b/include/oggz/oggz_constants.h index 2449b762b498ca2da3ac36775fcc69f96636c6a0..dcf2cdf57f4cef7ab3a68f8e010e50b3f8c9a7b4 100644 --- a/include/oggz/oggz_constants.h +++ b/include/oggz/oggz_constants.h @@ -132,6 +132,9 @@ enum OggzError { /** Seeking operation is not possible for this OGGZ */ OGGZ_ERR_NOSEEK = -13, + /** Reading stopped by user before any input bytes were consumed */ + OGGZ_ERR_USER_STOPPED = -14, + /** The requested serialno does not exist in this OGGZ */ OGGZ_ERR_BAD_SERIALNO = -20, diff --git a/src/liboggz/oggz_read.c b/src/liboggz/oggz_read.c index fa6f9548e246e1d69363a75dd865855878b32df5..e599ecf02ab39ecb0b7beea11ae443b446e6ef87 100644 --- a/src/liboggz/oggz_read.c +++ b/src/liboggz/oggz_read.c @@ -66,6 +66,8 @@ #define CHUNKSIZE 65536 +#define OGGZ_READ_EOF (-404) + #define oggz_off_t long OGGZ * @@ -278,10 +280,10 @@ 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 (cb_ret == OGGZ_STOP_OK || cb_ret == OGGZ_STOP_ERR) return cb_ret; if(oggz_get_next_page_7 (oggz, &og) < 0) - return -404; /* eof. leave unitialized */ + return OGGZ_READ_EOF; /* eof. leave unitialized */ serialno = ogg_page_serialno (&og); reader->current_serialno = serialno; /* XXX: maybe not necessary */ @@ -348,7 +350,7 @@ oggz_read (OGGZ * oggz, long n) cb_ret = oggz_read_sync (oggz); /* If there's nothing to read yet, don't flag an error */ - if (reader->current_unit == 0 && cb_ret == -404) cb_ret = 0; + if (reader->current_unit == 0 && cb_ret == OGGZ_READ_EOF) cb_ret = 0; while (cb_ret != -1 && cb_ret != 1 && bytes_read > 0 && remaining > 0) { bytes = MIN (remaining, CHUNKSIZE); @@ -370,6 +372,10 @@ oggz_read (OGGZ * oggz, long n) if (cb_ret == -1) oggz_purge (oggz); + /* Don't return 0 unless it's actually an EOF condition */ + if (nread == 0 && (cb_ret == OGGZ_STOP_OK || cb_ret == OGGZ_STOP_ERR)) + return OGGZ_ERR_USER_STOPPED; + return nread; } @@ -393,7 +399,7 @@ oggz_read_input (OGGZ * oggz, unsigned char * buf, long n) cb_ret = oggz_read_sync (oggz); /* If there's nothing to read yet, don't flag an error */ - if (reader->current_unit == 0 && cb_ret == -404) cb_ret = 0; + if (reader->current_unit == 0 && cb_ret == OGGZ_READ_EOF) cb_ret = 0; while (cb_ret != -1 && cb_ret != 1 && /* !oggz->eos && */ remaining > 0) { bytes = MIN (remaining, 4096); @@ -410,6 +416,10 @@ oggz_read_input (OGGZ * oggz, unsigned char * buf, long n) if (cb_ret == -1) oggz_purge (oggz); + /* Don't return 0 unless it's actually an EOF condition */ + if (nread == 0 && (cb_ret == OGGZ_STOP_OK || cb_ret == OGGZ_STOP_ERR)) + return OGGZ_ERR_USER_STOPPED; + return nread; }