struct cbuf * cbuf_realloc_tailroom(struct cbuf *b, size_t room, int do_free) { struct cbuf *old = b; if (room < cbuf_tailroom(b)) { b = alloc_cbuf(old->len + room); cbuf_put(b, old->len); memcpy(b->data, old->data, old->len); if (do_free) free(old); } return b; }
struct cbuf * cbuf_realloc_headroom(struct cbuf *b, size_t room, int do_free) { struct cbuf *old = b; if (1 /*room < cbuf_headroom(b)*/) { b = alloc_cbuf(old->len + room); cbuf_put(b, old->len + room); cbuf_pull(b, room); memcpy(b->data, old->data, old->len); //printf(" b %p b->data %p b->tail %p b->end %p\n", b, b->data, b->tail, b->end); if (do_free) free(old); } return b; }
int main(void) { CircBuf *cbuf; unsigned long val, val2; unsigned long vals[32]; unsigned char c, c2; unsigned char s[10]; int i, j; cbuf = cbuf_new(sizeof(val), 32); assert(cbuf != NULL); assert(cbuf->size == (sizeof(val) * 32)); assert(cbuf_unread(cbuf) == 0); assert(cbuf_unwritten(cbuf) == 31); val = 0xaaaaaaaa; cbuf_put(cbuf, &val, 1); /* * Note: unread() + unwritten() should always equal 31 * (one less than the size of the buffer) */ assert(cbuf_unread(cbuf) == 1); assert(cbuf_unwritten(cbuf) == 30); cbuf_peek(cbuf, 0, &val2, 1); assert(val2 == val); assert(cbuf_unread(cbuf) == 1); assert(cbuf_unwritten(cbuf) == 30); val = 0xdeadbeef; cbuf_put(cbuf, &val, 1); assert(cbuf_unread(cbuf) == 2); assert(cbuf_unwritten(cbuf) == 29); val2 = 0; cbuf_get(cbuf, &val2, 1); assert(val2 == 0xaaaaaaaa); assert(cbuf_unread(cbuf) == 1); assert(cbuf_unwritten(cbuf) == 30); val = 0xdeadbabe; cbuf_put(cbuf, &val, 1); val = 0x12345678; cbuf_put(cbuf, &val, 1); /* Write 10 elements */ for (i = 0; i < 10; i++) vals[i] = i; cbuf_put(cbuf, vals, 10); assert(cbuf_unread(cbuf) == 13); assert(cbuf_unwritten(cbuf) == 18); val2 = 0; cbuf_get(cbuf, &val2, 1); assert(val2 == 0xdeadbeef); cbuf_get(cbuf, &val2, 1); assert(val2 == 0xdeadbabe); /* * Now let's try writing across the boundary.. we've written * a total of 14 elements so far. So let's write 18 now * to make sure we're overwriting the first things we wrote. */ for (i = 0; i < 18; i++) vals[i] = 0xFFFF0000 | i; cbuf_put(cbuf, vals, 18); assert(cbuf_unread(cbuf) == 29); assert(cbuf_unwritten(cbuf) == 2); cbuf_get(cbuf, &val2, 1); assert(val2 == 0x12345678); cbuf_get(cbuf, vals, 10); for (i = 0; i < 10; i++) assert(vals[i] == i); assert(cbuf_unread(cbuf) == 18); assert(cbuf_unwritten(cbuf) == 13); /* Now read across boundary */ cbuf_get(cbuf, vals, 18); for (i = 0; i < 18; i++) assert(vals[i] == (0xFFFF0000 | i)); assert(cbuf_unread(cbuf) == 0); assert(cbuf_unwritten(cbuf) == 31); /* One more boundary test, writing 1 element at a time */ for (i = 0; i < 31; i++) { val = (0xaaaa0000 | i); cbuf_put(cbuf, &val, 1); } assert(cbuf_unread(cbuf) == 31); assert(cbuf_unwritten(cbuf) == 0); for (i = 0; i < 31; i++) { cbuf_get(cbuf, &val, 1); assert(val == (0xaaaa0000 | i)); } assert(cbuf_unread(cbuf) == 0); assert(cbuf_unwritten(cbuf) == 31); cbuf_destroy(cbuf); /* Test with character elements instead of longs */ cbuf = cbuf_new(sizeof(c), 10); assert(cbuf != NULL); assert(cbuf->size == (sizeof(c) * 10)); assert(cbuf_unread(cbuf) == 0); assert(cbuf_unwritten(cbuf) == 9); c = '@'; cbuf_put(cbuf, &c, 1); assert(cbuf_unread(cbuf) == 1); assert(cbuf_unwritten(cbuf) == 8); cbuf_peek(cbuf, 0, &c2, 1); assert(c2 == c); assert(cbuf_unread(cbuf) == 1); assert(cbuf_unwritten(cbuf) == 8); c = 'a'; cbuf_put(cbuf, &c, 1); assert(cbuf_unread(cbuf) == 2); assert(cbuf_unwritten(cbuf) == 7); c2 = '\0'; cbuf_get(cbuf, &c2, 1); assert(c2 == '@'); assert(cbuf_unread(cbuf) == 1); assert(cbuf_unwritten(cbuf) == 8); c = 'b'; cbuf_put(cbuf, &c, 1); c = '#'; cbuf_put(cbuf, &c, 1); cbuf_get(cbuf, &c, 1); assert(c == 'a'); cbuf_get(cbuf, &c, 1); assert(c == 'b'); assert(cbuf_unread(cbuf) == 1); assert(cbuf_unwritten(cbuf) == 8); /* Write 8 elements */ for (i = 0; i < 8; i++) s[i] = (unsigned char) i; cbuf_put(cbuf, s, 8); assert(cbuf_unwritten(cbuf) == 0); assert(cbuf_unread(cbuf) == 9); c = '\0'; cbuf_get(cbuf, &c, 1); assert(c == '#'); for (i = 0; i < 8; i++) s[i] = '0'; cbuf_get(cbuf, s, 8); for (i = 0; i < 8; i++) assert(s[i] == (unsigned char) i); assert(cbuf_unread(cbuf) == 0); assert(cbuf_unwritten(cbuf) == 9); cbuf_destroy(cbuf); printf("Unit test PASSED\n"); return 0; }