예제 #1
0
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;
}
예제 #2
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;
  }

  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;
}
예제 #3
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;
}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
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;
}
예제 #7
0
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;
}
예제 #8
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;
}
예제 #9
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);
}
예제 #10
0
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;
}