예제 #1
0
svn_error_t *
svn_spillbuf__read(const char **data,
                   apr_size_t *len,
                   svn_spillbuf_t *buf,
                   apr_pool_t *scratch_pool)
{
  struct memblock_t *mem;

  /* Possibly seek... */
  SVN_ERR(maybe_seek(NULL, buf, scratch_pool));

  SVN_ERR(read_data(&mem, buf, scratch_pool));
  if (mem == NULL)
    {
      *data = NULL;
      *len = 0;
    }
  else
    {
      *data = mem->data;
      *len = mem->size;

      /* If a block was out for reading, then return it.  */
      if (buf->out_for_reading != NULL)
        return_buffer(buf, buf->out_for_reading);

      /* Remember that we've passed this block out for reading.  */
      buf->out_for_reading = mem;
    }

  return SVN_NO_ERROR;
}
예제 #2
0
svn_error_t *
svn_spillbuf__process(svn_boolean_t *exhausted,
                      svn_spillbuf_t *buf,
                      svn_spillbuf_read_t read_func,
                      void *read_baton,
                      apr_pool_t *scratch_pool)
{
  svn_boolean_t has_seeked = FALSE;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);

  *exhausted = FALSE;

  while (TRUE)
    {
      struct memblock_t *mem;
      svn_error_t *err;
      svn_boolean_t stop;

      svn_pool_clear(iterpool);

      /* If this call to read_data() will read from the spill file, and we
         have not seek'd the file... then do it now.  */
      if (!has_seeked)
        SVN_ERR(maybe_seek(&has_seeked, buf, iterpool));

      /* Get some content to pass to the read callback.  */
      SVN_ERR(read_data(&mem, buf, iterpool));
      if (mem == NULL)
        {
          *exhausted = TRUE;
          break;
        }

      err = read_func(&stop, read_baton, mem->data, mem->size, iterpool);

      return_buffer(buf, mem);

      if (err)
        return svn_error_trace(err);

      /* If the callbacks told us to stop, then we're done for now.  */
      if (stop)
        break;
    }

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}
예제 #3
0
파일: s4pp.c 프로젝트: DiUS/s4pp-client
static bool prepare_begin_seq (s4pp_ctx_t *ctx)
{
  clear_dict (ctx);
  ctx->seq.last_time = 0;
  ctx->seq.n_sent = 0;

  // SEQ:<num>,0,1,0\n  - time:0 timediv:1 datafmt:0
  unsigned max_buf_len = 4 + 10 + 6;
  char *outbuf = get_line_buffer (ctx, max_buf_len);
  if (!outbuf)
    return false;
  unsigned overreach =
    max_buf_len - sprintf (outbuf, "SEQ:%u,0,1,0\n", ctx->seq.seq_no++);
  return_buffer (ctx, overreach);
  ctx->state = S4PP_BUFFERING;

  init_hmac (ctx);
  update_hmac (ctx, ctx->authtok, strlen (ctx->authtok));
  update_hmac (ctx, outbuf, max_buf_len - overreach);
  return true;
}
예제 #4
0
파일: s4pp.c 프로젝트: DiUS/s4pp-client
static void prepare_sample_entry (s4pp_ctx_t *ctx, const s4pp_sample_t *sample, unsigned dict_idx)
{
  unsigned val_len =
    sample->type == S4PP_FORMATTED ?
      strlen (sample->val.formatted) :
      (unsigned)snprintf (NULL, 0, "%f", sample->val.numeric);
  unsigned max_buf_len = 10 + 1 + 11 + val_len + 1 + 1;
  char *outbuf = get_line_buffer (ctx, max_buf_len);
  if (!outbuf)
    return;
  int32_t delta = sample->timestamp - ctx->seq.last_time;
  unsigned n;
  if (sample->type == S4PP_FORMATTED)
    n = sprintf (outbuf, "%u,%d,%s\n", dict_idx, delta, sample->val.formatted);
  else
    n = sprintf (outbuf, "%u,%d,%f\n", dict_idx, delta, sample->val.numeric);
  return_buffer (ctx, max_buf_len - n);

  ctx->seq.last_time = sample->timestamp;
  ++ctx->seq.n_sent;
  update_hmac (ctx, outbuf, n);
}
예제 #5
0
파일: s4pp.c 프로젝트: DiUS/s4pp-client
static bool prepare_dict_entry (s4pp_ctx_t *ctx, const char *name, unsigned *idx)
{
  for (dict_entry_t *d = ctx->seq.dict; d; d = d->next)
  {
    if (strcmp (name, d->name) == 0)
    {
      *idx = d->idx;
      return true;
    }
  }
  unsigned len = strlen (name);
  dict_entry_t *d = malloc (sizeof (dict_entry_t) + len + 1);
  if (!d)
  {
    ctx->state = S4PP_ERRORED;
    ctx->err = S4PP_NO_MEMORY;
    return false;
  }
  strcpy (d->name, name);
  d->next = ctx->seq.dict;
  d->idx = d->next ? d->next->idx + 1 : 0;
  ctx->seq.dict = d;

  // DICT:<idx>,,1,<name>\n
  unsigned max_buf_len = 5 + 10 + 4 + len + 1;
  char *outbuf = get_line_buffer (ctx, max_buf_len);
  if (!outbuf)
    return false;
  unsigned overreach =
    max_buf_len - sprintf (outbuf, "DICT:%u,,1,%s\n", d->idx, name);
  return_buffer (ctx, overreach);

  update_hmac (ctx, outbuf, max_buf_len - overreach);
  *idx = d->idx;
  return true;
}
예제 #6
0
/* Return a memblock of content, if any is available. *mem will be NULL if
   no further content is available. The memblock should eventually be
   passed to return_buffer() (or stored into buf->out_for_reading which
   will grab that block at the next get_buffer() call). */
static svn_error_t *
read_data(struct memblock_t **mem,
          svn_spillbuf_t *buf,
          apr_pool_t *scratch_pool)
{
  svn_error_t *err;

  /* If we have some in-memory blocks, then return one.  */
  if (buf->head != NULL)
    {
      *mem = buf->head;
      if (buf->tail == *mem)
        buf->head = buf->tail = NULL;
      else
        buf->head = (*mem)->next;

      /* We're using less memory now. If we haven't hit the spill file,
         then we may be able to keep using memory.  */
      buf->memory_size -= (*mem)->size;

      return SVN_NO_ERROR;
    }

  /* No file? Done.  */
  if (buf->spill == NULL)
    {
      *mem = NULL;
      return SVN_NO_ERROR;
    }

  /* Assume that the caller has seeked the spill file to the correct pos.  */

  /* Get a buffer that we can read content into.  */
  *mem = get_buffer(buf);
  /* NOTE: mem's size/next are uninitialized.  */

  if ((apr_uint64_t)buf->spill_size < (apr_uint64_t)buf->blocksize)
    (*mem)->size = (apr_size_t)buf->spill_size;
  else
    (*mem)->size = buf->blocksize;  /* The size of (*mem)->data  */
  (*mem)->next = NULL;

  /* Read some data from the spill file into the memblock.  */
  err = svn_io_file_read(buf->spill, (*mem)->data, &(*mem)->size,
                         scratch_pool);
  if (err)
    {
      return_buffer(buf, *mem);
      return svn_error_trace(err);
    }

  /* Mark the data that we consumed from the spill file.  */
  buf->spill_start += (*mem)->size;

  /* Did we consume all the data from the spill file?  */
  if ((buf->spill_size -= (*mem)->size) == 0)
    {
      /* Close and reset our spill file information.  */
      SVN_ERR(svn_io_file_close(buf->spill, scratch_pool));
      buf->spill = NULL;
      buf->spill_start = 0;
    }

  /* *mem has been initialized. Done.  */
  return SVN_NO_ERROR;
}