#include #include #include #include using namespace std; static bool ret; #define POOL_SIZE 4U #define POOL_CHUNK_SIZE 16U DI_BUFFER_DECL(buf, 256); DI_BUFFER_LIST_DECL(pool, POOL_SIZE, POOL_CHUNK_SIZE); static void test_expect_init(void) { EXPECT_EQ(0U, buf.used); EXPECT_EQ(buf_data, buf.cur); EXPECT_EQ(buf_data, buf.data); EXPECT_EQ(sizeof(buf_data), buf.size); } static void test_expect_destroy(void) { EXPECT_EQ(NULL, buf.cur); EXPECT_EQ(NULL, buf.data); EXPECT_EQ(0U, buf.size); } static void test_expect_element(size_t n) { EXPECT_EQ(n, buf.used); EXPECT_EQ(&buf_data[n], buf.cur); EXPECT_EQ(buf_data, buf.data); EXPECT_EQ(sizeof(buf_data), buf.size); } TEST(buffer, init) { di_buffer_init(&buf, buf_data, sizeof(buf_data)); test_expect_init(); } TEST(buffer, destroy) { di_buffer_destroy(&buf); test_expect_destroy(); } TEST(buffer, write_u8) { di_buffer_init(&buf, buf_data, sizeof(buf_data)); di_buffer_write_u8(&buf, 'a'); di_buffer_write_u8(&buf, 'b'); di_buffer_write_u8(&buf, 'c'); di_buffer_write_u8(&buf, 'd'); di_buffer_write_u8(&buf, 0); ASSERT_STREQ("abcd", (const char *)buf.data); } TEST(buffer, write_data) { di_buffer_init(&buf, buf_data, sizeof(buf_data)); /* Write string with null termination */ di_buffer_write_data(&buf, "1234", 5); ASSERT_STREQ("1234", (const char *)buf.data); ASSERT_EQ(5U, buf.used); /* Set buffer to fake size of 3 bytes */ di_buffer_init(&buf, buf_data, 3); /* Write more data then size of buffer */ di_buffer_write_data(&buf, "1234", 5); /* Null terminate so we can check with STREQ */ *buf.cur = 0; ASSERT_STREQ("12", (const char *)buf.data); } TEST(buffer, next_reset) { di_buffer_init(&buf, buf_data, sizeof(buf_data)); ret = di_buffer_next(&buf); EXPECT_TRUE(ret); test_expect_element(1); di_buffer_reset(&buf); test_expect_init(); } TEST(buffer, next_until_end) { di_buffer_init(&buf, buf_data, sizeof(buf_data)); for (size_t n = 0; n < sizeof(buf_data) - 1; n++) ret = di_buffer_next(&buf); EXPECT_TRUE(ret); test_expect_element(255); } TEST(buffer, next_overflow_check) { di_buffer_init(&buf, buf_data, sizeof(buf_data)); for (size_t n = 0; n < sizeof(buf_data) * 2; n++) ret = di_buffer_next(&buf); EXPECT_FALSE(ret); test_expect_element(255); } TEST(buffer, next_pos_overflow_check) { di_buffer_init(&buf, buf_data, sizeof(buf_data)); EXPECT_EQ(0U, buf.used); EXPECT_EQ(buf_data, buf.cur); buf.used = SIZE_MAX; ret = di_buffer_next(&buf); EXPECT_FALSE(ret); EXPECT_EQ(buf.used, SIZE_MAX); EXPECT_EQ(buf_data, buf.cur); } TEST(buffer, size_inuse_free) { const size_t in_use = 8U; di_buffer_init(&buf, buf_data, sizeof(buf_data)); for (size_t n = 0; n < in_use; n++) ret = di_buffer_next(&buf); EXPECT_TRUE(ret); EXPECT_EQ(sizeof(buf_data), di_buffer_size_free(&buf) + di_buffer_size_inuse(&buf)); EXPECT_EQ(in_use, di_buffer_size_inuse(&buf)); EXPECT_EQ(sizeof(buf_data) - in_use, di_buffer_size_free(&buf)); } TEST(buffer, memcpy) { uint8_t data[16]; uint8_t _expect[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; struct di_buffer b; size_t offset = 8; di_buffer_init(&b, data, sizeof(data)); di_buffer_flush(&b); /* Write first 8 byte chunk with testdata */ offset = 0; ASSERT_EQ(sizeof(_expect), di_buffer_memcpy(&b, offset, _expect, sizeof(_expect))); ASSERT_EQ(0, memcmp((uint8_t *)b.data + offset, _expect, sizeof(_expect))); //test_printf_buf(&b); di_buffer_flush(&b); /* Write first 8 byte chunk with testdata at offset 1 */ offset = 1; ASSERT_EQ(sizeof(_expect), di_buffer_memcpy(&b, offset, _expect, sizeof(_expect))); ASSERT_EQ(0, memcmp((uint8_t *)b.data + offset, _expect, sizeof(_expect))); //test_printf_buf(&b); di_buffer_flush(&b); /* Write second 8 byte chunk with testdata at offset 7 (one byte before end of di_buffer) */ offset = 7; ASSERT_EQ(sizeof(_expect), di_buffer_memcpy(&b, offset, _expect, sizeof(_expect))); ASSERT_EQ(0, memcmp((uint8_t *)b.data + offset, _expect, sizeof(_expect))); //test_printf_buf(&b); di_buffer_flush(&b); /* Wright second 8 byte chunk with testdata */ offset = 8; ASSERT_EQ(sizeof(_expect), di_buffer_memcpy(&b, offset, _expect, sizeof(_expect))); ASSERT_EQ(0, memcmp((uint8_t *)b.data + offset, _expect, sizeof(_expect))); //test_printf_buf(&b); di_buffer_flush(&b); /* Try to memcpy one byte to much */ offset = 9; ASSERT_EQ(0U, di_buffer_memcpy(&b, offset, _expect, sizeof(_expect))); } TEST(buffer, memmem) { void *ptr = NULL; const uint8_t buffer[] = "\x11\x12\x13\x14"; const uint8_t search[] = "\x13"; /* Match */ ptr = di_buffer_memmem(reinterpret_cast(buffer), sizeof(buffer) - 1, reinterpret_cast(search), sizeof(search) - 1); EXPECT_EQ(&buffer[2], ptr); /* 0-length for l_len */ ptr = di_buffer_memmem(reinterpret_cast(buffer), 0, reinterpret_cast(search), sizeof(search) - 1); EXPECT_EQ(NULL, ptr); /* 0-length for s_len */ ptr = di_buffer_memmem(reinterpret_cast(buffer), sizeof(buffer) - 1, reinterpret_cast(search), 0); EXPECT_EQ(NULL, ptr); /* Check length boundary isn't exceeded */ const uint8_t bufabc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const uint8_t searchbuf[] = "U"; ptr = di_buffer_memmem(reinterpret_cast(bufabc), 10, reinterpret_cast(searchbuf), 1); EXPECT_EQ(NULL, ptr); } TEST(buffer, list_init) { DI_BUFFER_LIST_INIT(pool, POOL_SIZE, POOL_CHUNK_SIZE); // Test if the pool buffer pointer is correctly set EXPECT_EQ(pool.buffer, pool_buffer); for (size_t n = 0; n < POOL_SIZE; n++) { EXPECT_FALSE(pool.buffer[n].in_use); EXPECT_EQ(0U, pool.buffer[n].used); EXPECT_EQ(POOL_CHUNK_SIZE, pool.buffer[n].size); EXPECT_EQ(pool_data[n], pool.buffer[n].data); EXPECT_EQ(pool_data[n], pool.buffer[n].cur); } } TEST(buffer, list_get_return) { for (size_t n = 0; n < POOL_SIZE; n++) { EXPECT_FALSE(pool.buffer[n].in_use); EXPECT_EQ(&pool.buffer[n], di_buffer_list_get(&pool)); EXPECT_TRUE(pool.buffer[n].in_use); } for (size_t n = 0; n < POOL_SIZE; n++) { struct di_buffer *b = &pool.buffer[n]; di_buffer_list_return(&pool, &b); EXPECT_FALSE(pool.buffer[n].in_use); } } TEST(buffer, list_get_null) { for (size_t n = 0; n < POOL_SIZE; n++) { EXPECT_FALSE(pool.buffer[n].in_use); EXPECT_EQ(&pool.buffer[n], di_buffer_list_get(&pool)); EXPECT_TRUE(pool.buffer[n].in_use); } EXPECT_EQ(NULL, di_buffer_list_get(&pool)); } TEST(buffer, list_return_invalid) { di_buffer_list_return(NULL, static_cast(NULL)); di_buffer_list_return(&pool, static_cast(NULL)); } /** Check if buf->data is not flushed on reset */ TEST(buffer, reset) { const char *text = "Hello World!"; const size_t size = strlen(text) + 1; di_buffer_init(&buf, buf_data, sizeof(buf_data)); ASSERT_EQ(size, di_buffer_memcpy(&buf, 0, text, size)); ASSERT_STREQ(text, (const char *)buf.data); di_buffer_reset(&buf); ASSERT_STREQ(text, (const char *)buf.data); test_expect_init(); } /** Check if reset sets the pos, used and cur members */ TEST(buffer, reset_members) { di_buffer_init(&buf, buf_data, sizeof(buf_data)); buf.used = 1234; buf.cur = (uint8_t *)&buf_data + 10; di_buffer_reset(&buf); ASSERT_EQ(0U, buf.used); ASSERT_EQ(buf_data, buf.cur); }