static void chunkqueue_append_chunk(chunkqueue *cq, chunk *c) { c->next = NULL; if (cq->last) { cq->last->next = c; } cq->last = c; if (NULL == cq->first) { cq->first = c; } cq->bytes_in += chunk_remaining_length(c); }
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; clen = chunk_remaining_length(c); if (0 == clen) { /* drop empty chunk */ src->first = c->next; if (c == src->last) src->last = NULL; chunkqueue_push_unused_chunk(src, c); continue; } use = len >= clen ? clen : len; len -= use; if (use == clen) { /* move complete chunk */ src->first = c->next; if (c == src->last) src->last = NULL; chunkqueue_append_chunk(dest, c); } else { /* 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); } src->bytes_out += use; } }