void chunkqueue_get_memory(chunkqueue *cq, char **mem, size_t *len, size_t min_size, size_t alloc_size) { static const size_t REALLOC_MAX_SIZE = 256; chunk *c; buffer *b; char *dummy_mem; size_t dummy_len; force_assert(NULL != cq); if (NULL == mem) mem = &dummy_mem; if (NULL == len) len = &dummy_len; /* default values: */ if (0 == min_size) min_size = 1024; if (0 == alloc_size) alloc_size = 4096; if (alloc_size < min_size) alloc_size = min_size; if (NULL != cq->last && MEM_CHUNK == cq->last->type) { size_t have; b = cq->last->mem; have = buffer_string_space(b); /* unused buffer: allocate space */ if (buffer_string_is_empty(b)) { buffer_string_prepare_copy(b, alloc_size); have = buffer_string_space(b); } /* if buffer is really small just make it bigger */ else if (have < min_size && b->size <= REALLOC_MAX_SIZE) { size_t cur_len = buffer_string_length(b); size_t new_size = cur_len + min_size, append; if (new_size < alloc_size) new_size = alloc_size; append = new_size - cur_len; if (append >= min_size) { buffer_string_prepare_append(b, append); have = buffer_string_space(b); } } /* return pointer into existing buffer if large enough */ if (have >= min_size) { *mem = b->ptr + buffer_string_length(b); *len = have; return; } } /* allocate new chunk */ c = chunkqueue_get_unused_chunk(cq); c->type = MEM_CHUNK; chunkqueue_append_chunk(cq, c); b = c->mem; buffer_string_prepare_append(b, alloc_size); *mem = b->ptr + buffer_string_length(b); *len = buffer_string_space(b); }
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_append_mem(chunkqueue *cq, const char * mem, size_t len) { chunk *c; if (0 == len) return; c = chunkqueue_get_unused_chunk(cq); c->type = MEM_CHUNK; buffer_copy_string_len(c->mem, mem, len); chunkqueue_append_chunk(cq, c); }
void chunkqueue_append_buffer(chunkqueue *cq, buffer *mem) { chunk *c; if (buffer_string_is_empty(mem)) return; c = chunkqueue_get_unused_chunk(cq); c->type = MEM_CHUNK; force_assert(NULL != c->mem); buffer_move(c->mem, mem); chunkqueue_append_chunk(cq, c); }
buffer *chunkqueue_get_append_buffer(chunkqueue *cq) { chunk *c; c = chunkqueue_get_unused_chunk(cq); c->type = MEM_CHUNK; c->offset = 0; buffer_reset(c->mem); chunkqueue_append_chunk(cq, c); return c->mem; }
int chunkqueue_append_buffer_weak(chunkqueue *cq, buffer *mem) { chunk *c; c = chunkqueue_get_unused_chunk(cq); c->type = MEM_CHUNK; c->offset = 0; if (c->mem) buffer_free(c->mem); c->mem = mem; chunkqueue_append_chunk(cq, c); return 0; }
int chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) { chunk *c; if (len == 0) return 0; c = chunkqueue_get_unused_chunk(cq); c->type = MEM_CHUNK; c->offset = 0; buffer_copy_string_len(c->mem, mem, len - 1); chunkqueue_append_chunk(cq, c); return 0; }
int chunkqueue_append_buffer(chunkqueue *cq, buffer *mem) { chunk *c; if (mem->used == 0) return 0; c = chunkqueue_get_unused_chunk(cq); c->type = MEM_CHUNK; c->offset = 0; buffer_copy_string_buffer(c->mem, mem); chunkqueue_append_chunk(cq, c); return 0; }
void chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) { chunk *c; if (0 == len) return; c = chunkqueue_get_unused_chunk(cq); c->type = FILE_CHUNK; buffer_copy_buffer(c->file.name, fn); c->file.start = offset; c->file.length = len; c->offset = 0; chunkqueue_append_chunk(cq, c); }
int chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) { chunk *c; if (len == 0) return 0; c = chunkpool_get_unused_chunk(); c->type = FILE_CHUNK; buffer_copy_string_buffer(c->file.name, fn); c->file.start = offset; c->file.length = len; c->offset = 0; chunkqueue_append_chunk(cq, c); return 0; }
int chunkqueue_steal_tempfile(chunkqueue *cq, chunk *in) { chunk *c; assert(in->type == FILE_CHUNK); assert(in->file.is_temp == 1); c = chunkpool_get_unused_chunk(); c->type = FILE_CHUNK; buffer_copy_string_buffer(c->file.name, in->file.name); c->file.start = in->file.start + in->offset; c->file.length = in->file.length - in->offset; c->offset = 0; c->file.is_temp = 1; in->file.is_temp = 0; chunkqueue_append_chunk(cq, c); return 0; }
int chunkqueue_append_smb_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) { chunk *c; if (len == 0) return 0; c = chunkqueue_get_unused_chunk(cq); c->type = SMB_CHUNK; buffer_copy_string_buffer(c->file.name, fn); c->file.start = offset; c->file.length = len; c->offset = 0; //- JerryLin add c->roffset = 0; c->open_thread = -1; c->listcount = 0; Cdbg(1,"chunkqueue_append_smb_file.....fn=[%s]", fn->ptr); chunkqueue_append_chunk(cq, c); return 0; }