TEST(TestIronBee, test_data_name) { ib_engine_t *ib = NULL; ib_data_t *data = NULL; ib_field_t *list_field = NULL; ib_field_t *out_field = NULL; ibtest_engine_create(&ib); ASSERT_EQ(IB_OK, ib_data_create(ib_engine_pool_main_get(ib), &data)); ASSERT_TRUE(data); ASSERT_IB_OK(ib_data_add_list(data, "ARGV", &list_field)); ASSERT_IB_OK(ib_data_get(data, "ARGV", &out_field)); ASSERT_TRUE(out_field); out_field = NULL; ASSERT_IB_OK(ib_data_get_ex(data, "ARGV:/.*(1|3)/", 4, &out_field)); ASSERT_TRUE(out_field); ibtest_engine_destroy(ib); }
ib_status_t ib_tfn_data_get_ex( ib_engine_t *ib, ib_data_t *data, const char *name, size_t nlen, const ib_field_t **pf, const char *tfn ) { assert(data != NULL); char *fullname; size_t fnlen; size_t tlen; ib_status_t rc; /* No tfn just means a normal get. */ if (tfn == NULL) { rc = ib_data_get_ex(data, name, nlen, (void *)pf); return rc; } /* Build the full name with tfn: "name.t(tfn)" */ tlen = strlen(tfn); fnlen = nlen + tlen + 4; /* Additional ".t()" bytes */ fullname = (char *)ib_mpool_alloc(ib_data_pool(data), fnlen); memcpy(fullname, name, nlen); memcpy(fullname + nlen, ".t(", fnlen - nlen); memcpy(fullname + nlen + 3, tfn, fnlen - nlen - 3); fullname[fnlen - 1] = ')'; /* See if there is already a transformed version, otherwise * one needs to be created. */ rc = ib_data_get_ex(data, fullname, fnlen, (void *)pf); if (rc == IB_ENOENT) { const char *tname; size_t i; ib_field_t *new_pf; /* Get the non-tfn field. */ rc = ib_data_get_ex(data, name, nlen, &new_pf); if (rc != IB_OK) { return rc; } /* Currently this only works for string type fields. */ if ( (new_pf->type != IB_FTYPE_NULSTR) && (new_pf->type != IB_FTYPE_BYTESTR)) { return IB_EINVAL; } /* Copy the field, noting the tfn. */ rc = ib_field_copy(&new_pf, ib_data_pool(data), fullname, fnlen, new_pf); if (rc != IB_OK) { return rc; } new_pf->tfn = (char *)ib_mpool_memdup(ib_data_pool(data), tfn, tlen + 1); /* Transform. */ tname = tfn; for (i = 0; i <= tlen; ++i) { ib_tfn_t *t; ib_flags_t flags; if ((tfn[i] == ',') || (i == tlen)) { size_t len = (tfn + i) - tname; rc = ib_tfn_lookup_ex(ib, tname, len, &t); if (rc == IB_OK) { rc = ib_tfn_transform(ib, ib_data_pool(data), t, new_pf, (const ib_field_t**) &new_pf, &flags); if (rc != IB_OK) { /// @todo What to do here? Fail or ignore? } } else { /// @todo What to do here? Fail or ignore? } tname = tfn + i + 1; } } /* Store the transformed field. */ rc = ib_data_set(data, new_pf, name, nlen); if (rc != IB_OK) { return rc; } *pf = new_pf; } return rc; }