void nghttp2_bufs_reset(nghttp2_bufs *bufs) { nghttp2_buf_chain *chain, *ci; size_t k; k = bufs->chunk_keep; for(ci = bufs->head; ci; ci = ci->next) { nghttp2_buf_reset(&ci->buf); nghttp2_buf_shift_right(&ci->buf, bufs->offset); if(--k == 0) { break; } } if(ci) { chain = ci->next; ci->next = NULL; for(ci = chain; ci;) { chain = ci->next; buf_chain_del(ci); ci = chain; } bufs->chunk_used = bufs->chunk_keep; } bufs->cur = bufs->head; }
static int bufs_alloc_chain(nghttp2_bufs *bufs) { int rv; nghttp2_buf_chain *chain; if(bufs->cur->next) { bufs->cur = bufs->cur->next; return 0; } if(bufs->max_chunk == bufs->chunk_used) { return NGHTTP2_ERR_BUFFER_ERROR; } rv = buf_chain_new(&chain, bufs->chunk_length); if(rv != 0) { return rv; } DEBUGF(fprintf(stderr, "new buffer %zu bytes allocated for bufs %p, used %zu\n", bufs->chunk_length, bufs, bufs->chunk_used)); ++bufs->chunk_used; bufs->cur->next = chain; bufs->cur = chain; nghttp2_buf_shift_right(&bufs->cur->buf, bufs->offset); return 0; }
int nghttp2_bufs_realloc(nghttp2_bufs *bufs, size_t chunk_length) { int rv; nghttp2_buf_chain *chain; if (chunk_length < bufs->offset) { return NGHTTP2_ERR_INVALID_ARGUMENT; } rv = buf_chain_new(&chain, chunk_length, bufs->mem); if (rv != 0) { return rv; } nghttp2_bufs_free(bufs); bufs->head = chain; bufs->cur = bufs->head; nghttp2_buf_shift_right(&bufs->cur->buf, bufs->offset); bufs->chunk_length = chunk_length; bufs->chunk_used = 1; // h1994st: if (bufs->random_enabled) { // Resize the first chunk hx_nghttp2_buf_resize(&bufs->cur->buf, hx_get_buf_chunk_length(bufs->buf_chunk_length_gen)); } return 0; }
int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length, size_t max_chunk, size_t chunk_keep, size_t offset) { int rv; nghttp2_buf_chain *chain; if(chunk_keep == 0 || max_chunk < chunk_keep || chunk_length < offset) { return NGHTTP2_ERR_INVALID_ARGUMENT; } rv = buf_chain_new(&chain, chunk_length); if(rv != 0) { return rv; } bufs->offset = offset; bufs->head = chain; bufs->cur = bufs->head; nghttp2_buf_shift_right(&bufs->cur->buf, offset); bufs->chunk_length = chunk_length; bufs->chunk_used = 1; bufs->max_chunk = max_chunk; bufs->chunk_keep = chunk_keep; return 0; }
int nghttp2_bufs_realloc(nghttp2_bufs *bufs, size_t chunk_length) { int rv; nghttp2_buf_chain *chain; if (chunk_length < bufs->offset) { return NGHTTP2_ERR_INVALID_ARGUMENT; } rv = buf_chain_new(&chain, chunk_length, bufs->mem); if (rv != 0) { return rv; } nghttp2_bufs_free(bufs); bufs->head = chain; bufs->cur = bufs->head; nghttp2_buf_shift_right(&bufs->cur->buf, bufs->offset); bufs->chunk_length = chunk_length; bufs->chunk_used = 1; return 0; }
ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) { size_t len; nghttp2_buf_chain *chain; nghttp2_buf *buf; uint8_t *res; nghttp2_buf resbuf; len = 0; for(chain = bufs->head; chain; chain = chain->next) { len += nghttp2_buf_len(&chain->buf); } if(!len) { res = NULL; } else { res = (uint8_t *)malloc(len); if(res == NULL) { return NGHTTP2_ERR_NOMEM; } } nghttp2_buf_wrap_init(&resbuf, res, len); for(chain = bufs->head; chain; chain = chain->next) { buf = &chain->buf; if(resbuf.last) { resbuf.last = nghttp2_cpymem(resbuf.last, buf->pos, nghttp2_buf_len(buf)); } nghttp2_buf_reset(buf); nghttp2_buf_shift_right(&chain->buf, bufs->offset); } bufs->cur = bufs->head; *out = res; return (ssize_t)len; }
int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length, size_t max_chunk, size_t chunk_keep, size_t offset, nghttp2_mem *mem) { int rv; nghttp2_buf_chain *chain; if (bufs->random_enabled) { // 0. init random module hx_random_init(); // 1. init buffer chunk length generator hx_nghttp2_bufs_init_buf_chunk_length_generator(bufs, mem); } if (chunk_keep == 0 || max_chunk < chunk_keep || chunk_length < offset) { return NGHTTP2_ERR_INVALID_ARGUMENT; } rv = buf_chain_new(&chain, chunk_length, mem); if (rv != 0) { return rv; } bufs->mem = mem; bufs->offset = offset; bufs->head = chain; bufs->cur = bufs->head; nghttp2_buf_shift_right(&bufs->cur->buf, offset); bufs->chunk_length = chunk_length; bufs->chunk_used = 1; bufs->max_chunk = max_chunk; bufs->chunk_keep = chunk_keep; // h1994st: if (bufs->random_enabled) { // Resize the first chunk hx_nghttp2_buf_resize(&bufs->cur->buf, hx_get_buf_chunk_length(bufs->buf_chunk_length_gen)); } return 0; }
static int bufs_alloc_chain(nghttp2_bufs *bufs) { int rv; nghttp2_buf_chain *chain; if (bufs->cur->next) { bufs->cur = bufs->cur->next; return 0; } // h1994st: if (!bufs->random_enabled && bufs->max_chunk == bufs->chunk_used) { return NGHTTP2_ERR_BUFFER_ERROR; } rv = buf_chain_new(&chain, bufs->chunk_length, bufs->mem); if (rv != 0) { return rv; } DEBUGF(fprintf(stderr, "new buffer %zu bytes allocated for bufs %p, used %zu\n", bufs->chunk_length, bufs, bufs->chunk_used)); ++bufs->chunk_used; bufs->cur->next = chain; bufs->cur = chain; nghttp2_buf_shift_right(&bufs->cur->buf, bufs->offset); // h1994st: if (bufs->random_enabled) { // Resize current chunk hx_nghttp2_buf_resize(&bufs->cur->buf, hx_get_buf_chunk_length(bufs->buf_chunk_length_gen)); } return 0; }
void test_nghttp2_bufs_remove(void) { int rv; nghttp2_bufs bufs; nghttp2_buf_chain *chain; int i; uint8_t *out; ssize_t outlen; rv = nghttp2_bufs_init(&bufs, 1000, 3); CU_ASSERT(0 == rv); nghttp2_buf_shift_right(&bufs.cur->buf, 10); rv = nghttp2_bufs_add(&bufs, "hello ", 6); CU_ASSERT(0 == rv); for(i = 0; i < 2; ++i) { chain = bufs.cur; rv = nghttp2_bufs_advance(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(chain->next == bufs.cur); } rv = nghttp2_bufs_add(&bufs, "world", 5); CU_ASSERT(0 == rv); outlen = nghttp2_bufs_remove(&bufs, &out); CU_ASSERT(11 == outlen); CU_ASSERT(0 == memcmp("hello world", out, outlen)); CU_ASSERT(0 == nghttp2_bufs_len(&bufs)); CU_ASSERT(bufs.cur->buf.pos == bufs.cur->buf.begin); free(out); nghttp2_bufs_free(&bufs); }
void nghttp2_bufs_reset(nghttp2_bufs *bufs) { nghttp2_buf_chain *chain, *ci; size_t k; k = bufs->chunk_keep; for (ci = bufs->head; ci; ci = ci->next) { nghttp2_buf_reset(&ci->buf); nghttp2_buf_shift_right(&ci->buf, bufs->offset); // h1994st: if (bufs->random_enabled) { // Resize each kept chunk hx_nghttp2_buf_resize(&ci->buf, hx_get_buf_chunk_length(bufs->buf_chunk_length_gen)); } if (--k == 0) { break; } } if (ci) { chain = ci->next; ci->next = NULL; for (ci = chain; ci;) { chain = ci->next; buf_chain_del(ci, bufs->mem); ci = chain; } bufs->chunk_used = bufs->chunk_keep; } bufs->cur = bufs->head; }