void test_copy (void) { char str1[] = "\x01\x01x\x01\x01y\x01\x01xy\x01\x01"; char *str2 = (char *)NULL; char *str3 = (char *)NULL; cbuffer_t *buf1 = (cbuffer_t *)NULL; cbuffer_t *buf2 = (cbuffer_t *)NULL; buf1 = cbuf_new(); buf2 = cbuf_new(); cbuf_import (buf1, str1, strlen (str1)); cbuf_copy (buf2, buf1); printf ("test_copy(): str1 = %s\n", str1); str2 = (char *)xmalloc (buf1->sz + 1); memset (str2, (int)NULL, buf1->sz + 1); memcpy (str2, buf1->data, buf1->sz); str3 = (char *)xmalloc (buf2->sz + 1); memset (str3, (int)NULL, buf2->sz + 1); memcpy (str3, buf2->data, buf2->sz); printf ("test_copy(): str2 = %s\ntest_copy(): str3 = %s\n", str2, str3); xfree (str2); xfree (str3); cbuf_delete (buf1); cbuf_delete (buf2); }
int cbufq_pullup(cbufq_t *cbufq, size_t min_contig) { cbuf_t *cbuf0, *cbuf1; size_t sz, pos0; if (min_contig == 0) { return (0); } top: /* * Case 1: There are no buffers. */ if (cbufq->cbufq_count == 0) { VERIFY(list_is_empty(&cbufq->cbufq_bufs)); errno = EIO; return (-1); } /* * Case 2: There is one buffer. */ if (cbufq->cbufq_count == 1) { VERIFY(!list_is_empty(&cbufq->cbufq_bufs)); VERIFY(list_head(&cbufq->cbufq_bufs) == list_tail(&cbufq->cbufq_bufs)); if (min_contig > cbuf_available(list_head( &cbufq->cbufq_bufs))) { errno = EIO; return (-1); } return (0); } /* * Case 3: There are two or more buffers. */ VERIFY(!list_is_empty(&cbufq->cbufq_bufs)); VERIFY(list_head(&cbufq->cbufq_bufs) != list_tail(&cbufq->cbufq_bufs)); cbuf0 = list_head(&cbufq->cbufq_bufs); if (min_contig <= cbuf_available(cbuf0)) { /* * The first buffer is long enough. */ return (0); } VERIFY0(cbuf_safe_add(&sz, cbuf_available(cbuf0), cbuf_unused(cbuf0))); if (min_contig > sz) { /* * The first buffer does not even have enough backing store to * allow for the requested minimum contiguous length. Extend * the buffer. */ if (cbuf_extend(cbuf0, min_contig - cbuf_position(cbuf0)) != 0) { return (-1); } } /* * Preserve the original position for the first buffer in the queue; it * will be restored after the copying. Resume putting to the buffer at * the current limit. */ pos0 = cbuf_position(cbuf0); cbuf_resume(cbuf0); cbuf1 = list_next(&cbufq->cbufq_bufs, cbuf0); cbuf_copy(cbuf1, cbuf0); if (cbuf_available(cbuf1) == 0) { /* * Consign this buffer to the scrap heap, as it is now empty. */ list_remove(&cbufq->cbufq_bufs, cbuf1); cbufq->cbufq_count--; cbuf_free(cbuf1); } cbuf_flip(cbuf0); VERIFY0(cbuf_position_set(cbuf0, pos0)); goto top; }