diff options
Diffstat (limited to 'util')
| -rw-r--r-- | util/fifo8.c | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/util/fifo8.c b/util/fifo8.c index 4e01b532d9..1ffa19d900 100644 --- a/util/fifo8.c +++ b/util/fifo8.c @@ -16,12 +16,17 @@ #include "migration/vmstate.h" #include "qemu/fifo8.h" +void fifo8_reset(Fifo8 *fifo) +{ + fifo->num = 0; + fifo->head = 0; +} + void fifo8_create(Fifo8 *fifo, uint32_t capacity) { fifo->data = g_new(uint8_t, capacity); fifo->capacity = capacity; - fifo->head = 0; - fifo->num = 0; + fifo8_reset(fifo); } void fifo8_destroy(Fifo8 *fifo) @@ -87,20 +92,49 @@ static const uint8_t *fifo8_peekpop_buf(Fifo8 *fifo, uint32_t max, return ret; } -const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) +const uint8_t *fifo8_peek_bufptr(Fifo8 *fifo, uint32_t max, uint32_t *numptr) { return fifo8_peekpop_buf(fifo, max, numptr, false); } -const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) +const uint8_t *fifo8_pop_bufptr(Fifo8 *fifo, uint32_t max, uint32_t *numptr) { return fifo8_peekpop_buf(fifo, max, numptr, true); } -void fifo8_reset(Fifo8 *fifo) +uint32_t fifo8_pop_buf(Fifo8 *fifo, uint8_t *dest, uint32_t destlen) { - fifo->num = 0; - fifo->head = 0; + const uint8_t *buf; + uint32_t n1, n2 = 0; + uint32_t len; + + if (destlen == 0) { + return 0; + } + + len = destlen; + buf = fifo8_pop_bufptr(fifo, len, &n1); + if (dest) { + memcpy(dest, buf, n1); + } + + /* Add FIFO wraparound if needed */ + len -= n1; + len = MIN(len, fifo8_num_used(fifo)); + if (len) { + buf = fifo8_pop_bufptr(fifo, len, &n2); + if (dest) { + memcpy(&dest[n1], buf, n2); + } + } + + return n1 + n2; +} + +void fifo8_drop(Fifo8 *fifo, uint32_t len) +{ + len -= fifo8_pop_buf(fifo, NULL, len); + assert(len == 0); } bool fifo8_is_empty(Fifo8 *fifo) |