int Cbuf_peek_and_drop(cbuf_t buf, void *buffer, int len) { int rv, r_len, dropped = 0; assert(buf); assert(buffer); assert(len > 0); if ((r_len = cbuf_peek(buf, buffer, len)) < 0) ierr_exit("Cbuf_peek: %s", strerror(errno)); /* Nothing there */ if (!r_len) return 0; if ((dropped = cbuf_drop(buf, len)) < 0) ierr_exit("Cbuf_peek: cbuf_drop: %s", strerror(errno)); if (dropped != r_len) ierr_exit("Cbuf_peek: dropped incorrect bytes: %d", dropped); if ((rv = cbuf_drop(buf, -1)) < 0) ierr_exit("Cbuf_peek: cbuf_drop: %s", strerror(errno)); if (rv > 0) ierr_dbg("Cbuf_peek: cbuf_drop dropped data: %d", rv); return r_len; }
/* * Search the buffer for the specified pattern. Update the read/get * pointer to point to the start of the pattern. Return the number of * bytes from the current get pointer to the pattern offset, or -1 * if the pattern was not found. */ int cbuf_find(CircBuf * cbuf, unsigned char * pattern, int len) { unsigned char * tmp; int ofs = 0; tmp = malloc(len); while (1) { if (cbuf_peek(cbuf, ofs, tmp, len) != len) { /* Not found */ free(tmp); return -1; } if (memcmp(tmp, pattern, len) == 0) break; ofs++; } /* Found it */ free(tmp); cbuf->get = cbuf->buf + (((cbuf->get - cbuf->buf) + ofs) % cbuf->size); return ofs; }
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; }