ib_status_t ib_tfn_lookup( ib_engine_t *ib, const char *name, const ib_tfn_t **ptfn ) { return ib_tfn_lookup_ex(ib, name, strlen(name), ptfn); }
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; }