예제 #1
0
static int cr_sendfandreceive(NDPI_REDIS rhnd, char recvtype, const char *format, ...)
{
  int rc;
  va_list ap;
  cr_buffer *buf = &(rhnd->buf);

  va_start(ap, format);
  rc = vsnprintf(buf->data, buf->size, format, ap);
  va_end(ap);

  if (rc < 0)
    return -1;

  if (rc >= buf->size) {
    DEBUG_PRINT("truncated, get more memory and try again");
    if (cr_moremem(buf, rc - buf->size + 1))
      return NDPI_CREDIS_ERR_NOMEM;

    va_start(ap, format);
    rc = vsnprintf(buf->data, buf->size, format, ap);
    va_end(ap);
  }

  buf->len = rc;

  return cr_sendandreceive(rhnd, recvtype);
}
예제 #2
0
/* Appends a zero-terminated string `str' to the end of buffer `buf'. If 
 * available memory in buffer is not enough to hold `str' more memory is 
 * allocated to the buffer. If `space' is not 0 `str' is padded with a space.
 * Returns:
 *   0  on success
 *  <0  on error, i.e. more memory not available */
static int cr_appendstr(cr_buffer *buf, const char *str, int space)
{
  int avail, len, reqd;

  len = strlen(str);
  avail = buf->size - buf->len;

  /* required memory: len, terminating zero and possibly a space */
  reqd = len + 1;
  if (space)
    reqd++;

  if (reqd > avail)
    if (cr_moremem(buf, reqd - avail + 1))
      return NDPI_CREDIS_ERR_NOMEM;

  if (space)
    buf->data[buf->len++] = ' ';

  memcpy(buf->data + buf->len, str, len);
  buf->len += len;

  buf->data[buf->len] = '\0';

  return 0;
}
예제 #3
0
/* Appends a printf style formatted to the end of buffer `buf'. If available
 * memory in buffer is not enough to hold `str' more memory is allocated to 
 * the buffer. 
 * Returns:
 *   0  on success
 *  <0  on error, i.e. more memory not available */
static int cr_appendstrf(cr_buffer *buf, const char *format, ...)
{
  int rc, avail;
  va_list ap;

  avail = buf->size - buf->len;

  va_start(ap, format);
  rc = vsnprintf(buf->data + buf->len, avail, format, ap);
  va_end(ap);

  if (rc < 0)
    return -1;

  if (rc >= avail) {
    if (cr_moremem(buf, rc - avail + 1))
      return NDPI_CREDIS_ERR_NOMEM;

    va_start(ap, format);
    rc = vsnprintf(buf->data + buf->len, buf->size - buf->len, format, ap);
    va_end(ap);
  }
  buf->len += rc;

  return 0;
}
예제 #4
0
/* Buffered read line, returns pointer to zero-terminated string 
 * and length of that string. `start' specifies from which byte
 * to start looking for "\r\n".
 * Returns:
 *  >0  length of string to which pointer `line' refers. `idx' is
 *      an optional pointer for returning start index of line with
 *      respect to buffer.
 *   0  connection to Redis server was closed
 *  -1  on error, i.e. a string is not available */
static int cr_readln(NDPI_REDIS rhnd, int start, char **line, int *idx)
{
  cr_buffer *buf = &(rhnd->buf);
  char *nl;
  int rc, len, avail, more;

  /* do we need more data before we expect to find "\r\n"? */
  if ((more = buf->idx + start + 2 - buf->len) < 0)
    more = 0;
  
  while (more > 0 || 
         (nl = cr_findnl(buf->data + buf->idx + start, buf->len - (buf->idx + start))) == NULL) {
    avail = buf->size - buf->len;
    if (avail < CR_BUFFER_WATERMARK || avail < more) {
      DEBUG_PRINT("available buffer memory is low, get more memory");
      if (cr_moremem(buf, more>0?more:1))
        return NDPI_CREDIS_ERR_NOMEM;

      avail = buf->size - buf->len;
    }

    rc = cr_receivedata(rhnd->fd, rhnd->timeout, buf->data + buf->len, avail);
    if (rc > 0) {
      DEBUG_PRINT("received %d bytes: %s", rc, buf->data + buf->len);
      buf->len += rc;
    }
    else if (rc == 0)
      return 0; /* EOF reached, connection terminated */
    else 
      return -1; /* error */

    /* do we need more data before we expect to find "\r\n"? */
    if ((more = buf->idx + start + 2 - buf->len) < 0)
      more = 0;
  }

  *nl = '\0'; /* zero terminate */

  *line = buf->data + buf->idx;
  if (idx)
    *idx = buf->idx;
  len = nl - *line;
  buf->idx = (nl - buf->data) + 2; /* skip "\r\n" */

  DEBUG_PRINT("size=%d, len=%d, idx=%d, start=%d, line=%s", 
        buf->size, buf->len, buf->idx, start, *line);

  return len;
}
예제 #5
0
/* Appends a string `str' to the end of buffer `buf'. If available memory
 * in buffer is not enough to hold `str' more memory is allocated to the
 * buffer. If `space' is not 0 `str' is padded with a space.
 * Returns:
 *   0  on success
 *  <0  on error, i.e. more memory not available */
static int cr_appendstr(cr_buffer *buf, const char *str, int space)
{
  int rc, avail;
  char *format = (space==0?"%s":" %s");

  /* TODO instead of using formatted print use memcpy() and don't
     blindly add a space before `str' */

  avail = buf->size - buf->len;
  rc = snprintf(buf->data + buf->len, avail, format, str);
  if (rc >= avail) {
    DEBUG("truncated, get more memory and try again");
    if (cr_moremem(buf, rc - avail + 1))
      return CREDIS_ERR_NOMEM;
    
    avail = buf->size - buf->len;
    rc = snprintf(buf->data + buf->len, avail, format, str);
  }
  buf->len += rc;

  return 0;
}
예제 #6
0
파일: credis.cpp 프로젝트: w30afthc/pstat
//__attribute__ ((format(printf,3,4)))
static int cr_sendfandreceive(REDIS rhnd, char recvtype, const char *format, ...)
{
  int rc;
  va_list ap;
  cr_buffer *buf = &(rhnd->buf);

#ifdef WIN32
  ap = NULL;
#endif

  va_start(ap, format);

#ifdef WIN32 
  memset(buf->data, 0, buf->size);
  rc = _vsnprintf(buf->data, buf->size, format, ap);
#else

  rc = vsnprintf(buf->data, buf->size, format, ap);
#endif
  va_end(ap);

  if (rc < 0)
    return -1;

  if (rc >= buf->size) {
    DEBUG("truncated, get more memory and try again");
    if (cr_moremem(buf, rc - buf->size + 1))
      return CREDIS_ERR_NOMEM;

    va_start(ap, format);
    rc = vsnprintf(buf->data, buf->size, format, ap);
    va_end(ap);
  }

  buf->len = rc;

  return cr_sendandreceive(rhnd, recvtype);
}