Exemplo n.º 1
0
/*
 * Copy and nul-terminate a ringbuffer to a string.
 */
ssize_t
ringbuf_to_string(char *buf, size_t len, struct ringbuf *rb)
{
	size_t copy_len, n;

	if (buf == NULL || rb == NULL || len == 0)
		return (-1);

	copy_len = MINIMUM(len - 1, ringbuf_used(rb));

	if (copy_len == 0)
		return (copy_len);

	if (rb->start < rb->end)
		memcpy(buf, rb->buf + rb->start, copy_len);
	else {
		/* If the buffer is wrapped, copy each hunk separately */
		n = rb->len - rb->start;
		memcpy(buf, rb->buf + rb->start, MINIMUM(n, copy_len));
		if (copy_len > n)
			memcpy(buf + n, rb->buf,
			    MINIMUM(rb->end, copy_len - n));
	}
	buf[copy_len] = '\0';

	return (ringbuf_used(rb));
}
Exemplo n.º 2
0
/*
 * Append a line to a ring buffer, will delete lines from start
 * of buffer as necessary
 */
int
ringbuf_append_line(struct ringbuf *rb, char *line)
{
	size_t llen, used, copy_len;
	int overflow = 0;

	if (rb == NULL || line == NULL)
		return (-1);

	llen = strlen(line);
	if (llen == 0)
		return (-1);

	if (line[llen - 1] != '\n')
		llen++; /* one extra for appended '\n' */

	if (llen >= rb->len)
		return (-1);

	/*
	 * If necessary, advance start pointer to make room for appended
	 * string. Ensure that start pointer is at the beginning of a line
	 * once we are done (i.e move to after '\n').
	 */
	used = ringbuf_used(rb);
	if (used + llen >= rb->len) {
		rb->start = (rb->start + used + llen - rb->len) % rb->len;

		/* Find next '\n' */
		while (rb->buf[rb->start] != '\n')
			rb->start = (rb->start + 1) % rb->len;
		/* Skip it */
		rb->start = (rb->start + 1) % rb->len;

		overflow = 1;
	}

	/*
	 * Now append string, starting from last pointer and wrapping if
	 * necessary
	 */
	if (rb->end + llen > rb->len) {
		copy_len = rb->len - rb->end;
		memcpy(rb->buf + rb->end, line, copy_len);
		memcpy(rb->buf, line + copy_len, llen - copy_len - 1);
		rb->buf[llen - copy_len - 1] = '\n';
	} else {
		memcpy(rb->buf + rb->end, line, llen - 1);
		rb->buf[rb->end + llen - 1] = '\n';
	}

	rb->end = (rb->end + llen) % rb->len;

	return (overflow);
}
Exemplo n.º 3
0
ssize_t ringbuf_read(ringbuf_t *rb, char *target, size_t len)
{
    size_t used, tail_len;

    if (!rb || !target) {
        return -1;
    }
    used = ringbuf_used(rb);
    len = MIN(len, used);
    tail_len = rb->len - rb->start + 1;
    tail_len = MIN(len, tail_len);
    memcpy(target, rb->buf + rb->start, tail_len);
    if (len - tail_len > 0) {
        memcpy(target + tail_len, rb->buf, len - tail_len);
    }
    rb->start = (rb->start + len) % rb->len;

    return len;
}