diff --git a/media/liboggz/src/liboggz/oggz_dlist.c b/media/liboggz/src/liboggz/oggz_dlist.c --- a/media/liboggz/src/liboggz/oggz_dlist.c +++ b/media/liboggz/src/liboggz/oggz_dlist.c @@ -133,70 +133,81 @@ oggz_dlist_prepend(OggzDList *dlist, voi new_elem->prev = dlist->head; new_elem->next = dlist->head->next; new_elem->prev->next = new_elem; new_elem->next->prev = new_elem; return 0; } -void +int oggz_dlist_iter(OggzDList *dlist, OggzDListIterFunc func) { OggzDListElem *p; for (p = dlist->head->next; p != dlist->tail; p = p->next) { - if (func(p->data) == DLIST_ITER_CANCEL) { + int r = func(p->data); + if (r == DLIST_ITER_ERROR) { + return -1; + } + + if (r == DLIST_ITER_CANCEL) { break; } } + return 0; } void oggz_dlist_reverse_iter(OggzDList *dlist, OggzDListIterFunc func) { OggzDListElem *p; for (p = dlist->tail->prev; p != dlist->head; p = p->prev) { if (func(p->data) == DLIST_ITER_CANCEL) { break; } } } -void +int oggz_dlist_deliter(OggzDList *dlist, OggzDListIterFunc func) { OggzDListElem *p, *q; + int result = 0; for (p = dlist->head->next; p != dlist->tail; p = q) { - if (func(p->data) == DLIST_ITER_CANCEL) { + int r = func(p->data); + if (r == DLIST_ITER_ERROR) { + result = -1; + } + + if (r == DLIST_ITER_CANCEL) { break; } q = p->next; p->prev->next = p->next; p->next->prev = p->prev; oggz_free(p); } - + return result; } void oggz_dlist_reverse_deliter(OggzDList *dlist, OggzDListIterFunc func) { OggzDListElem *p, *q; for (p = dlist->tail->prev; p != dlist->head; p = q) { if (func(p->data) == DLIST_ITER_CANCEL) { break; } - q = p->prev; p->prev->next = p->next; p->next->prev = p->prev; oggz_free(p); } } diff --git a/media/liboggz/src/liboggz/oggz_dlist.h b/media/liboggz/src/liboggz/oggz_dlist.h --- a/media/liboggz/src/liboggz/oggz_dlist.h +++ b/media/liboggz/src/liboggz/oggz_dlist.h @@ -31,17 +31,17 @@ */ #ifndef __OGGZ_DLIST_H__ #define __OGGZ_DLIST_H__ struct _OggzDList; typedef struct _OggzDList OggzDList; -typedef enum {DLIST_ITER_CANCEL, DLIST_ITER_CONTINUE} OggzDListIterResponse; +typedef enum {DLIST_ITER_ERROR=-1, DLIST_ITER_CANCEL=0, DLIST_ITER_CONTINUE=1} OggzDListIterResponse; typedef OggzDListIterResponse (*OggzDListIterFunc) (void *elem); OggzDList * oggz_dlist_new (void); void oggz_dlist_delete(OggzDList *dlist); @@ -50,21 +50,21 @@ int oggz_dlist_is_empty(OggzDList *dlist); int oggz_dlist_append(OggzDList *dlist, void *elem); int oggz_dlist_prepend(OggzDList *dlist, void *elem); -void +int oggz_dlist_iter(OggzDList *dlist, OggzDListIterFunc func); void oggz_dlist_reverse_iter(OggzDList *dlist, OggzDListIterFunc func); -void +int oggz_dlist_deliter(OggzDList *dlist, OggzDListIterFunc func); void oggz_dlist_reverse_deliter(OggzDList *dlist, OggzDListIterFunc func); #endif diff --git a/media/liboggz/src/liboggz/oggz_read.c b/media/liboggz/src/liboggz/oggz_read.c --- a/media/liboggz/src/liboggz/oggz_read.c +++ b/media/liboggz/src/liboggz/oggz_read.c @@ -292,21 +292,25 @@ oggz_read_deliver_packet(void *elem) { unit_stored = p->reader->current_unit; p->reader->current_granulepos = p->calced_granulepos; p->reader->current_unit = oggz_get_unit (p->oggz, p->serialno, p->calced_granulepos); if (p->stream->read_packet) { - p->stream->read_packet(p->oggz, &(p->packet), p->serialno, - p->stream->read_user_data); + if (p->stream->read_packet(p->oggz, &(p->packet), p->serialno, + p->stream->read_user_data) != 0) { + return DLIST_ITER_ERROR; + } } else if (p->reader->read_packet) { - p->reader->read_packet(p->oggz, &(p->packet), p->serialno, - p->reader->read_user_data); + if (p->reader->read_packet(p->oggz, &(p->packet), p->serialno, + p->reader->read_user_data) != 0) { + return DLIST_ITER_ERROR; + } } p->reader->current_granulepos = gp_stored; p->reader->current_unit = unit_stored; oggz_read_free_pbuffer_entry(p); return DLIST_ITER_CONTINUE; @@ -448,17 +452,19 @@ oggz_read_sync (OGGZ * oggz) * move backward through the list assigning gp values based upon * the granulepos we just recieved. Then move forward through * the list delivering any packets at the beginning with valid * gp values */ ogg_int64_t gp_stored = stream->last_granulepos; stream->last_packet = &packet; oggz_dlist_reverse_iter(oggz->packet_buffer, oggz_read_update_gp); - oggz_dlist_deliter(oggz->packet_buffer, oggz_read_deliver_packet); + if (oggz_dlist_deliter(oggz->packet_buffer, oggz_read_deliver_packet) == -1) { + return OGGZ_ERR_HOLE_IN_DATA; + } /* * fix up the stream granulepos */ stream->last_granulepos = gp_stored; if (!oggz_dlist_is_empty(oggz->packet_buffer)) { OggzBufferedPacket *p = oggz_read_new_pbuffer_entry( @@ -486,17 +492,20 @@ oggz_read_sync (OGGZ * oggz) if (!op->b_o_s) stream->delivered_non_b_o_s = 1; } else break; } } /* If we've got a stop already, don't read more data in */ - if (cb_ret == OGGZ_STOP_OK || cb_ret == OGGZ_STOP_ERR) return cb_ret; + if (cb_ret == OGGZ_STOP_OK || + cb_ret == OGGZ_STOP_ERR || + cb_ret == OGGZ_ERR_HOLE_IN_DATA) + return cb_ret; if(oggz_read_get_next_page (oggz, &og) < 0) return OGGZ_READ_EMPTY; /* eof. leave uninitialized */ serialno = ogg_page_serialno (&og); reader->current_serialno = serialno; /* XXX: maybe not necessary */ stream = oggz_get_stream (oggz, serialno); @@ -588,18 +597,19 @@ oggz_read (OGGZ * oggz, long n) if (bytes_read > 0) { ogg_sync_wrote (&reader->ogg_sync, bytes_read); remaining -= bytes_read; nread += bytes_read; cb_ret = oggz_read_sync (oggz); - if (cb_ret == OGGZ_ERR_OUT_OF_MEMORY) + if (cb_ret == OGGZ_ERR_OUT_OF_MEMORY || cb_ret == OGGZ_ERR_HOLE_IN_DATA) { return cb_ret; + } } } if (cb_ret == OGGZ_STOP_ERR) oggz_purge (oggz); /* Don't return 0 unless it's actually an EOF condition */ if (nread == 0) { switch (bytes_read) {