/// @test Test util field library - ib_field_from_string() TEST_F(TestIBUtilField, test_field_from_string) { ib_field_t *f; ib_status_t rc; ib_num_t fnum; ib_float_t ffloat; const char *fnulstr; rc = ib_field_from_string(MM(), IB_S2SL("test_num"), "11", &f); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(f); ASSERT_EQ(IB_FTYPE_NUM, f->type); ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_num_out(&fnum))); ASSERT_EQ(11, fnum); rc = ib_field_from_string(MM(), IB_S2SL("test_num"), "-11", &f); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(f); ASSERT_EQ(IB_FTYPE_NUM, f->type); ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_num_out(&fnum))); ASSERT_EQ(-11, fnum); rc = ib_field_from_string(MM(), IB_S2SL("test_float"), "1.0", &f); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(f); ASSERT_EQ(IB_FTYPE_FLOAT, f->type); ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_float_out(&ffloat))); ASSERT_EQ(1.0, ffloat); rc = ib_field_from_string(MM(), IB_S2SL("test_num"), "-1.0", &f); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(f); ASSERT_EQ(IB_FTYPE_FLOAT, f->type); ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_float_out(&ffloat))); ASSERT_EQ(-1.0, ffloat); rc = ib_field_from_string(MM(), IB_S2SL("test_str"), "x", &f); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(f); ASSERT_EQ(IB_FTYPE_NULSTR, f->type); ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_nulstr_out(&fnulstr))); ASSERT_STREQ("x", fnulstr); rc = ib_field_from_string(MM(), IB_S2SL("test_str"), "-1.1x", &f); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(f); ASSERT_EQ(IB_FTYPE_NULSTR, f->type); ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_nulstr_out(&fnulstr))); ASSERT_STREQ("-1.1x", fnulstr); }
/** * Handle managed collection registration for vars "name=value" parameters * * @param[in] ib Engine * @param[in] module Collection manager's module object (unused) * @param[in] manager The collection manager object to register with (unused) * @param[in] mp Memory pool to use for allocations * @param[in] collection_name Name of the collection * @param[in] uri Full collection URI (unused) * @param[in] uri_scheme URI scheme (unused) * @param[in] uri_data Hierarchical/data part of the URI * @param[in] params List of parameter strings * @param[in] register_data Register callback data (unused) * @param[out] pmanager_inst_data Pointer to manager specific collection data * * @returns Status code: * - IB_OK All OK * - IB_Exxx Other error */ static ib_status_t core_managed_collection_vars_register_fn( const ib_engine_t *ib, const ib_module_t *module, const ib_collection_manager_t *manager, ib_mpool_t *mp, const char *collection_name, const char *uri, const char *uri_scheme, const char *uri_data, const ib_list_t *params, void *register_data, void **pmanager_inst_data) { assert(ib != NULL); assert(module != NULL); assert(mp != NULL); assert(collection_name != NULL); assert(params != NULL); assert(pmanager_inst_data != NULL); const ib_list_node_t *node; ib_list_t *vars_list; ib_list_t *field_list; ib_mpool_t *tmp = ib_engine_pool_temp_get(ib); ib_status_t rc; if (strlen(uri_data) != 0) { return IB_DECLINED; } if (ib_list_elements(params) < 1) { return IB_EINVAL; } /* Create a temporary list */ rc = ib_list_create(&vars_list, tmp); if (rc != IB_OK) { return rc; } /* First pass; walk through all params, look for "a=b" type syntax */ IB_LIST_LOOP_CONST(params, node) { static const int ovecsize = 9; int ovector[ovecsize]; const char *param = (const char *)node->data; core_vars_t *vars; int pcre_rc; pcre_rc = pcre_exec(core_vars_manager.pattern, NULL, param, strlen(param), 0, 0, ovector, ovecsize); if (pcre_rc < 0) { return IB_DECLINED; } vars = ib_mpool_alloc(tmp, sizeof(*vars)); if (vars == NULL) { return IB_EALLOC; } vars->name = ib_mpool_memdup_to_str(tmp, param + ovector[2], ovector[3] - ovector[2]); vars->value = ib_mpool_memdup_to_str(tmp, param + ovector[4], ovector[5] - ovector[4]); if ( (vars->name == NULL) || (vars->value == NULL) ) { return IB_EALLOC; } rc = ib_list_push(vars_list, vars); if (rc != IB_OK) { return rc; } } /* Build the list of fields */ rc = ib_list_create(&field_list, mp); if (rc != IB_OK) { return rc; } /* Now walk though the list, creating a field for each one */ IB_LIST_LOOP_CONST(vars_list, node) { const core_vars_t *vars = (const core_vars_t *)node->data; ib_field_t *field; ib_field_val_union_t fval; rc = ib_field_from_string(mp, IB_FIELD_NAME(vars->name), vars->value, &field, &fval); if (rc != IB_OK) { ib_log_error(ib, "Error creating field (\"%s\", \"%s\"): %s", vars->name, vars->value, ib_status_to_string(rc)); return rc; } rc = ib_list_push(field_list, field); if (rc != IB_OK) { return rc; } if (field->type == IB_FTYPE_NUM) { ib_log_trace(ib, "Created numeric field \"%s\" %"PRId64" in \"%s\"", vars->name, fval.num, collection_name); } else if (field->type == IB_FTYPE_FLOAT) { ib_log_trace(ib, "Created float field \"%s\" %f in \"%s\"", vars->name, (double)fval.fnum, collection_name); } else { ib_log_trace(ib, "Created string field \"%s\" \"%s\" in \"%s\"", vars->name, fval.nulstr, collection_name); } } /* Finally, store the list as the manager specific collection data */ *pmanager_inst_data = field_list; return IB_OK; }