void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len) { while (len > 0) { chunk *c = src->first; off_t clen = 0, use; if (NULL == c) break; switch (c->type) { case MEM_CHUNK: clen = buffer_string_length(c->mem); break; case FILE_CHUNK: clen = c->file.length; break; } force_assert(clen >= c->offset); clen -= c->offset; use = len >= clen ? clen : len; src->bytes_out += use; dest->bytes_in += use; len -= use; if (0 == clen) { /* drop empty chunk */ src->first = c->next; if (c == src->last) src->last = NULL; chunkqueue_push_unused_chunk(src, c); continue; } if (use == clen) { /* move complete chunk */ src->first = c->next; if (c == src->last) src->last = NULL; chunkqueue_append_chunk(dest, c); continue; } /* partial chunk with length "use" */ switch (c->type) { case MEM_CHUNK: chunkqueue_append_mem(dest, c->mem->ptr + c->offset, use); break; case FILE_CHUNK: /* tempfile flag is in "last" chunk after the split */ chunkqueue_append_file(dest, c->file.name, c->file.start + c->offset, use); break; } c->offset += use; force_assert(0 == len); } }
void chunkqueue_reset(chunkqueue *cq) { chunk *cur = cq->first; cq->first = cq->last = NULL; while (NULL != cur) { chunk *next = cur->next; chunkqueue_push_unused_chunk(cq, cur); cur = next; } cq->bytes_in = 0; cq->bytes_out = 0; }