/// @test Test util list library - ib_list_push() and ib_list_pop() TEST_F(TestIBUtilList, test_list_push_and_pop) { ib_list_t *list; ib_status_t rc; int v0 = 0; int v1 = 1; int v2 = 2; int v3 = 3; int v4 = 4; int *val; rc = ib_list_create(&list, MemPool()); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(list); ASSERT_EQ(0UL, ib_list_elements(list)); /* Pop invalid. */ rc = ib_list_pop(list,(void *)&val); ASSERT_EQ(IB_ENOENT, rc); ASSERT_FALSE(val); ASSERT_EQ(0UL, ib_list_elements(list)); /* Simple pushes followed by pops. */ rc = ib_list_push(list, &v0); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(1UL, ib_list_elements(list)); rc = ib_list_push(list, &v1); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(2UL, ib_list_elements(list)); rc = ib_list_push(list, &v2); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(3UL, ib_list_elements(list)); rc = ib_list_push(list, &v3); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(4UL, ib_list_elements(list)); rc = ib_list_push(list, &v4); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(5UL, ib_list_elements(list)); ASSERT_EQ(v0, *(int *)(ib_list_node_data(ib_list_first(list)))); ASSERT_EQ(v4, *(int *)(ib_list_node_data(ib_list_last(list)))); rc = ib_list_pop(list, (void *)&val); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(val); ASSERT_EQ(v4, *val); ASSERT_EQ(4UL, ib_list_elements(list)); rc = ib_list_pop(list, (void *)&val); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(val); ASSERT_EQ(v3, *val); ASSERT_EQ(3UL, ib_list_elements(list)); rc = ib_list_pop(list, (void *)&val); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(val); ASSERT_EQ(v2, *val); ASSERT_EQ(2UL, ib_list_elements(list)); rc = ib_list_pop(list, (void *)&val); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(val); ASSERT_EQ(v1, *val); ASSERT_EQ(1UL, ib_list_elements(list)); rc = ib_list_pop(list, (void *)&val); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(val); ASSERT_EQ(v0, *val); ASSERT_EQ(0UL, ib_list_elements(list)); }
/// @test Test ironbee library - data provider TEST(TestIronBee, test_data_dynf) { ib_engine_t *ib; ib_data_config_t *dataconfig; ib_data_t *data; ib_field_t *dynf; ib_field_t *f; ib_field_t *f2; ib_status_t rc; ib_num_t n; ib_list_t* l; ibtest_engine_create(&ib); ASSERT_EQ(IB_OK, ib_data_config_create(ib_engine_pool_main_get(ib), & dataconfig)); ASSERT_EQ(IB_OK, ib_data_create(dataconfig, ib_engine_pool_main_get(ib), &data)); ASSERT_TRUE(data); /* Create a field with no initial value. */ ASSERT_EQ( IB_OK, ib_field_create_dynamic( &dynf, ib_engine_pool_main_get(ib), IB_FIELD_NAME("test_dynf"), IB_FTYPE_LIST, dyn_get, (void *)ib_engine_pool_main_get(ib), NULL, NULL ) ); ASSERT_TRUE(dynf); ASSERT_EQ(9UL, dynf->nlen); ASSERT_MEMEQ("test_dynf", dynf->name, 9); /* Add the field to the data store. */ ASSERT_EQ(IB_OK, ib_data_add(data, dynf)); /* Fetch the field from the data store */ ASSERT_EQ(IB_OK, ib_data_get(data, "test_dynf", &f)); ASSERT_TRUE(f); ASSERT_EQ(dynf, f); /* Fetch a dynamic field from the data store */ ASSERT_EQ(IB_OK, ib_data_get(data, "test_dynf:dyn_subkey", &f)); ASSERT_TRUE(f); ASSERT_EQ(9UL, f->nlen); /* Get the list value from the dynamic field. */ rc = ib_field_mutable_value(f, ib_ftype_list_mutable_out(&l)); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(1UL, ib_list_elements(l)); /* Get the single value from the list. */ f2 = (ib_field_t *)ib_list_node_data(ib_list_first(l)); ASSERT_TRUE(f2); ASSERT_EQ(10UL, f2->nlen); rc = ib_field_value(f2, ib_ftype_num_out(&n)); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(5, n); /* Fetch a another subkey */ ASSERT_EQ(IB_OK, ib_data_get(data, "test_dynf:dyn_subkey2", &f)); ASSERT_TRUE(f); ASSERT_EQ(9UL, f->nlen); /* Get the list value from the dynamic field. */ rc = ib_field_mutable_value(f, ib_ftype_list_mutable_out(&l)); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(1UL, ib_list_elements(l)); /* Get the single value from the list. */ f2 = (ib_field_t *)ib_list_node_data(ib_list_first(l)); ASSERT_TRUE(f2); ASSERT_EQ(11UL, f2->nlen); rc = ib_field_value(f2, ib_ftype_num_out(&n)); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(5, n); ibtest_engine_destroy(ib); }
ib_status_t ib_string_join( const char *join_string, ib_list_t *list, ib_mm_t mm, const char **pout, size_t *pout_len ) { assert(join_string != NULL); assert(list != NULL); assert(pout != NULL); assert(pout_len != NULL); const ib_list_node_t *node; char *end; /* Points to the \0 in out. */ const char *out; size_t out_len = 1; /* Size to hold an empty string, '\0' */ size_t *str_len; /* Array of lengths of char*s in list. */ size_t str_idx; /* Index into str_len. */ size_t join_string_len; join_string_len = strlen(join_string); /* Handle the base-case and avoid asking for size 0 memory segments. */ if (ib_list_elements(list) == 0) { *pout = ""; *pout_len = 0; return IB_OK; } /* First, build a place to cache string lengths. */ str_len = ib_mm_alloc(mm, sizeof(*str_len) * ib_list_elements(list)); if (str_len == NULL) { return IB_EALLOC; } /* Record each string length and sum those lengths into out_len. * Recall that out_len starts equal to 1 for the '\0'. */ str_idx = 0; IB_LIST_LOOP_CONST(list, node) { const size_t len = strlen((const char *)ib_list_node_data_const(node)); out_len += len; str_len[str_idx] = len; ++str_idx; } /* Increase out_len by the join string length * (n-1) elements. */ out_len += (ib_list_elements(list) - 1)* join_string_len; /* Allocate the final string. */ end = ib_mm_alloc(mm, out_len); if (end == NULL) { return IB_EALLOC; } /* Setup vars for joining the strings into out. */ out = end; str_idx = 0; node = ib_list_first(list); /* Copy the first string. We know the list is > 0 elements long. */ strcpy(end, (const char *)ib_list_node_data_const(node)); end += str_len[str_idx]; ++str_idx; /* Having copied the first string, now copy the join string, then the * the next string until the end of the list. */ for ( node = ib_list_node_next_const(node); node != NULL; node = ib_list_node_next_const(node) ) { /* Copy the join string first. */ strcpy(end, join_string); end += join_string_len; /* Copy the lagging string. */ strcpy(end, (const char *)ib_list_node_data_const(node)); end += str_len[str_idx]; ++str_idx; } /* Commit work back to the caller. */ *pout = out; *pout_len = out_len-1; return IB_OK; }