Пример #1
0
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);
}
Пример #2
0
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;
}