Esempio n. 1
0
/// @test Test util field library - ib_field_create() ib_field_create()
TEST_F(TestIBUtilField, test_field_create)
{
    ib_field_t *f;
    ib_status_t rc;
    const char *nulstrval = "TestValue";
    ib_num_t numval = 5;
    ib_bytestr_t *bytestrval;
    const char *nulout;
    const char *nulcopy;

    nulcopy = ib_mm_strdup(MM(), nulstrval);
    ASSERT_STRNE(NULL, nulcopy);
    rc = ib_field_create(&f, MM(), IB_S2SL("test_nulstr"),
                         IB_FTYPE_NULSTR, ib_ftype_nulstr_in(nulcopy));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(11UL, f->nlen);
    ASSERT_EQ(0, memcmp("test_nulstr", f->name, 11));

    rc = ib_field_value(f, ib_ftype_nulstr_out(&nulout));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_STREQ(nulstrval, nulout);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_num"),
                         IB_FTYPE_NUM, ib_ftype_num_in(&numval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(8UL, f->nlen);
    ASSERT_EQ(0, memcmp("test_num", f->name, 8));

    rc = ib_bytestr_dup_mem(&bytestrval, MM(),
                            (uint8_t *)nulstrval, strlen(nulstrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_bytestr"),
                         IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bytestrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(12UL, f->nlen);
    ASSERT_EQ(0, memcmp("test_bytestr", f->name, 12));

    rc = ib_field_create(&f, MM(), IB_S2SL("test_nulstr_ex"),
                         IB_FTYPE_NULSTR, ib_ftype_nulstr_in(nulstrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_num_ex"),
                         IB_FTYPE_NUM, ib_ftype_num_in(&numval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_bytestr_ex"),
                         IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bytestrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
}
Esempio n. 2
0
File: pcre.c Progetto: niubl/ironbee
/**
 * Set the matches from a multi-match dfa as a list in the CAPTURE
 * collection (all with "0" key).
 *
 * @param[in] tx Current transaction.
 * @param[in] capture Collection to capture to.
 * @param[in] ovector The vector of integer pairs of matches from PCRE.
 * @param[in] matches The number of matches.
 * @param[in] subject The matched-against string data.
 *
 * @returns IB_OK or IB_EALLOC.
 */
static
ib_status_t pcre_dfa_set_match(
    ib_tx_t    *tx,
    ib_field_t *capture,
    int        *ovector,
    int         matches,
    const char *subject
)
{
    assert(tx != NULL);
    assert(tx->ib != NULL);
    assert(capture != NULL);
    assert(ovector != NULL);

    int i;

    /* We have a match! Now populate TX:0-9 in tx->data. */
    ib_log_debug2_tx(tx, "DFA populating %d matches", matches);
    for (i = 0; i < matches; ++i)
    {
        size_t match_len;
        const char *match_start;
        const char *name;
        ib_bytestr_t *bs;
        ib_field_t *field;
        ib_status_t rc;

        /* Readability. Mark the start and length of the string. */
        match_start = subject+ovector[i * 2];
        match_len = ovector[i * 2 + 1] - ovector[i * 2];

        /* Create a byte-string representation */
        rc = ib_bytestr_dup_mem(&bs,
                                tx->mp,
                                (const uint8_t*)match_start,
                                match_len);
        if (rc != IB_OK) {
            return rc;
        }

        /* Create a field to hold the byte-string */
        name = ib_capture_name(0);
        rc = ib_field_create(&field, tx->mp, name, strlen(name),
                             IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
        if (rc != IB_OK) {
            return rc;
        }

        /* Add it to the capture collection */
        rc = ib_capture_add_item(capture, field);
        if (rc != IB_OK) {
            return rc;
        }
    }

    return IB_OK;
}
Esempio n. 3
0
/**
 * Eudoxus first match callback function.  Called when a match occurs.
 *
 * Always returns IA_EUDOXUS_CMD_STOP to stop matching (unless an
 * error occurs). If capture is enabled the matched text will be stored in the
 * capture variable.
 *
 * @param[in] engine Eudoxus engine.
 * @param[in] output Output defined by automata.
 * @param[in] output_length Length of output.
 * @param[in] input Current location in the input (first character
 *                  after the match).
 * @param[in,out] cbdata Pointer to the ee_callback_data_t instance we are
 *                       handling. This is needed for handling capture
 *                       of the match.
 * @return IA_EUDOXUS_CMD_ERROR on error, IA_EUDOXUS_CMD_STOP otherwise.
 */
static
ia_eudoxus_command_t ee_first_match_callback(ia_eudoxus_t* engine,
                                             const char *output,
                                             size_t output_length,
                                             const uint8_t *input,
                                             void *cbdata)
{
    assert(cbdata != NULL);
    assert(output != NULL);

    ib_status_t rc;
    uint32_t match_len;
    const ee_callback_data_t *ee_cbdata = cbdata;
    ib_tx_t *tx = ee_cbdata->tx;
    ib_field_t *capture = ee_cbdata->capture;
    ib_bytestr_t *bs;
    ib_field_t *field;
    const char *name;

    assert(tx != NULL);

    if (capture != NULL) {
        if (output_length != sizeof(uint32_t)) {
            return IA_EUDOXUS_CMD_ERROR;
        }
        match_len = *(uint32_t *)(output);
        rc = ib_capture_clear(capture);
        if (rc != IB_OK) {
            ib_log_error_tx(tx, "Error clearing captures: %s",
                            ib_status_to_string(rc));
            return IA_EUDOXUS_CMD_ERROR;
        }
        /* Create a byte-string representation */
        rc = ib_bytestr_dup_mem(&bs,
                                tx->mp,
                                (input - match_len),
                                match_len);
        if (rc != IB_OK) {
            return IA_EUDOXUS_CMD_ERROR;
        }
        name = ib_capture_name(0);
        rc = ib_field_create(&field, tx->mp, name, strlen(name),
                             IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
        if (rc != IB_OK) {
            return IA_EUDOXUS_CMD_ERROR;
        }
        rc = ib_capture_set_item(capture, 0, tx->mp, field);
        if (rc != IB_OK) {
            return IA_EUDOXUS_CMD_ERROR;
        }
    }

    return IA_EUDOXUS_CMD_STOP;
}
Esempio n. 4
0
void Field::set_byte_string(
    ConstByteString value,
    const char* arg,
    size_t arg_length
) const
{
    Internal::check_type(BYTE_STRING, type());
    Internal::set_value(
        ib(), ib_ftype_bytestr_in(value.ib()),
        arg, arg_length
    );
}
Esempio n. 5
0
/// @test Test ironbee library - transformation registration
TEST(TestIronBee, test_tfn)
{
    ib_engine_t *ib;
    ib_status_t rc;
    ib_tfn_t *tfn = (ib_tfn_t *)-1;
    ib_flags_t flags;
    uint8_t data_in[128];
    ib_field_t *fin;
    const ib_field_t *fout;
    ib_bytestr_t *bs;

    ibtest_engine_create(&ib);

    ASSERT_EQ(IB_OK, ib_tfn_register(ib, "foo2bar", foo2bar,
                                     IB_TFN_FLAG_NONE, NULL));
    ASSERT_EQ(IB_OK, ib_tfn_lookup(ib, "foo2bar", &tfn));
    ASSERT_NE((ib_tfn_t *)-1, tfn);
    ASSERT_TRUE(tfn);

    ib_bytestr_dup_nulstr(&bs, ib->mp, "foo");
    fin = NULL;
    ib_field_create(
        &fin, ib->mp, IB_FIELD_NAME("ByteStr"),
        IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs)
    );
    fout = NULL;
    flags = 0;
    rc = ib_tfn_transform(ib, ib->mp, tfn, fin, &fout, &flags);
    ASSERT_EQ(rc, IB_OK);
    ASSERT_NE((ib_tfn_t *)-1, tfn);
    ASSERT_TRUE(IB_TFN_CHECK_FMODIFIED(flags));
    ASSERT_NE(fin, fout);

    strcpy((char *)data_in, "foo");
    fin = NULL;
    ib_field_create(
        &fin, ib->mp, IB_FIELD_NAME("NulStr"),
        IB_FTYPE_NULSTR,
        ib_ftype_nulstr_in((char *)data_in)
    );
    fout = NULL;
    flags = 0;
    rc = ib_tfn_transform(ib, ib->mp, tfn, fin, &fout, &flags);
    ASSERT_EQ(rc, IB_OK);
    ASSERT_NE((ib_tfn_t *)-1, tfn);
    ASSERT_TRUE(IB_TFN_CHECK_FMODIFIED(flags));
    ASSERT_NE(fin, fout);

    ibtest_engine_destroy(ib);
}
Esempio n. 6
0
Field Field::create_byte_string(
    MemoryPool       pool,
    const char*      name,
    size_t           name_length,
    ConstByteString  value
)
{
    return Internal::create_field(
        pool,
        name, name_length,
        Field::BYTE_STRING,
        ib_ftype_bytestr_in(value.ib())
    );
}
Esempio n. 7
0
/**
 * Set the matches into the given field name as .0, .1, .2 ... .9.
 *
 * @param[in] ib The IronBee engine to log to.
 * @param[in] tx The transaction to store the values into (tx->dpi).
 * @param[in] field_name The field to populate with Regex matches.
 * @param[in] ovector The vector of integer pairs of matches from PCRE.
 * @param[in] matches The number of matches.
 * @param[in] subject The matched-against string data.
 *
 * @returns IB_OK or IB_EALLOC.
 */
static ib_status_t pcre_set_matches(ib_engine_t *ib,
                                    ib_tx_t *tx,
                                    int *ovector,
                                    int matches,
                                    const char *subject)
{
    IB_FTRACE_INIT();

    /* IronBee status. */
    ib_status_t rc;

    /* Iterator. */
    int i;

    rc = ib_data_capture_clear(tx);
    if (rc != IB_OK) {
        ib_log_error_tx(tx, "Error clearing captures: %s",
                        ib_status_to_string(rc));
    }

    /* We have a match! Now populate TX:0-9 in tx->dpi. */
    ib_log_debug2_tx(tx, "REGEX populating %d matches", matches);
    for (i=0; i<matches; i++)
    {
        /* The length of the match. */
        size_t match_len;

        /* The first character in the match. */
        const char *match_start;

        /* Field name */
        const char *name;

        /* Holder for a copy of the field value when creating a new field. */
        ib_bytestr_t *bs;

        /* Field holder. */
        ib_field_t *field;

        /* Readability. Mark the start and length of the string. */
        match_start = subject+ovector[i*2];
        match_len = ovector[i*2+1] - ovector[i*2];

        /* If debugging this, copy the string value out and print it to the
         * log. This could be dangerous as there could be non-character
         * values in the match. */
        ib_log_debug2_tx(tx, "REGEX Setting #%d=%.*s",
                         i, (int)match_len, match_start);

        /* Create a byte-string representation */
        rc = ib_bytestr_dup_mem(&bs,
                                tx->mp,
                                (const uint8_t*)match_start,
                                match_len);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }

        /* Create a field to hold the byte-string */
        name = ib_data_capture_name(i);
        rc = ib_field_create(&field, tx->mp, name, strlen(name),
                             IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }

        /* Add it to the capture collection */
        rc = ib_data_capture_set_item(tx, i, field);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
Esempio n. 8
0
/**
 * Attempt to convert a single field.
 *
 * If the desired type matches the in_field type, out_field is set to NULL
 * and IB_OK is returned.
 *
 * @param[in,out] mp Memory pool to use.
 * @param[in] desired_type The type to try to convert this to.
 * @param[in] in_field The input field.
 * @param[out] out_field The output field to write to.
 *
 * @returns
 *   - IB_OK On success.
 *   - IB_EINVAL If a string cannot be converted to a number type
 *               or some other invalid type conversion is requested.
 *   - IB_EALLOC Memory allocation error.
 */
ib_status_t ib_field_convert(
    ib_mpool_t *mp,
    const ib_ftype_t desired_type,
    const ib_field_t *in_field,
    ib_field_t **out_field)
{
    assert(mp);
    assert(in_field);

    ib_status_t rc;

    /* Holder values for in_field values before being set in out_field. */
    size_t sz;
    const char *str;
    const ib_bytestr_t *bstr;
    ib_num_t num;
    ib_float_t flt;
    void *new_field_value;


    if (in_field->type == desired_type) {
        *out_field = NULL;
        return IB_OK;
    }

    switch (in_field->type) {
        case IB_FTYPE_NULSTR:

            /* Extract string. */
            rc = ib_field_value(in_field, ib_ftype_nulstr_out(&str));
            if (rc!=IB_OK){
                return rc;
            }

            switch(desired_type) {
                case IB_FTYPE_BYTESTR:
                    rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
                    if (rc!=IB_OK){
                        return rc;
                    }
                    new_field_value = ib_ftype_bytestr_in(bstr);
                    break;
                case IB_FTYPE_NUM:
                    rc = ib_string_to_num(str, 0, &num);
                    new_field_value = ib_ftype_num_in(&num);
                    break;
                case IB_FTYPE_FLOAT:
                    rc = ib_string_to_float(str, &flt);
                    new_field_value = ib_ftype_float_in(&flt);
                    break;
                default:
                    return IB_EINVAL;
            }
            break;
        case IB_FTYPE_BYTESTR:

            /* Extract bytestr. */
            rc = ib_field_value(in_field, ib_ftype_bytestr_out(&bstr));
            if (rc!=IB_OK){
                return rc;
            }
            sz = ib_bytestr_length(bstr);

            /* Convert byte str. */
            switch(desired_type) {
                case IB_FTYPE_NULSTR:
                    str = ib_mpool_memdup_to_str(mp, bstr, sz);
                    if (!str) {
                        return rc;
                    }
                    new_field_value = ib_ftype_nulstr_in(str);
                    break;
                case IB_FTYPE_NUM:
                    rc = ib_string_to_num_ex((char *)bstr, sz, 0, &num);
                    new_field_value = ib_ftype_num_in(&num);
                    break;
                case IB_FTYPE_FLOAT:
                    rc = ib_string_to_float_ex((char *)bstr, sz, &flt);
                    new_field_value = ib_ftype_float_in(&flt);
                    break;
                default:
                    return IB_EINVAL;
            }
            break;
        case IB_FTYPE_NUM:

            /* Extract unum. */
            rc = ib_field_value(in_field, ib_ftype_num_out(&num));
            if (rc!=IB_OK){
                return rc;
            }

            switch(desired_type) {
                case IB_FTYPE_NULSTR:
                    str = ib_num_to_string(mp, num);
                    if (!str) {
                        return IB_EINVAL;
                    }
                    new_field_value = ib_ftype_nulstr_in(str);
                    break;
                case IB_FTYPE_BYTESTR:
                    str = ib_num_to_string(mp, num);
                    if (!str) {
                        return IB_EINVAL;
                    }
                    rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
                    if (rc!=IB_OK){
                        return rc;
                    }
                    new_field_value = ib_ftype_bytestr_in(bstr);
                    break;
                case IB_FTYPE_FLOAT:
                    flt = (ib_float_t)num;
                    new_field_value = ib_ftype_float_in(&flt);
                    break;
                default:
                    return IB_EINVAL;
            }
            break;
        case IB_FTYPE_FLOAT:

            /* Extract unum. */
            rc = ib_field_value(in_field, ib_ftype_float_out(&flt));
            if (rc!=IB_OK){
                return rc;
            }

            switch(desired_type) {
                case IB_FTYPE_NULSTR:
                    str = ib_float_to_string(mp, flt);
                    if (!str) {
                        return IB_EINVAL;
                    }
                    new_field_value = ib_ftype_nulstr_in(str);
                    break;
                case IB_FTYPE_BYTESTR:
                    str = ib_float_to_string(mp, flt);
                    if (!str) {
                        return IB_EINVAL;
                    }
                    rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
                    if (rc!=IB_OK){
                        return rc;
                    }
                    new_field_value = ib_ftype_bytestr_in(bstr);
                    break;
                case IB_FTYPE_NUM:
                    num = (ib_float_t)flt;
                    new_field_value = ib_ftype_num_in(&num);
                    break;
                default:
                    return IB_EINVAL;
            }
            break;
        default:
            return IB_EINVAL;
    }

    rc = ib_field_create(
        out_field,
        mp,
        in_field->name,
        in_field->nlen,
        desired_type,
        new_field_value);
    return rc;
}
Esempio n. 9
0
File: pcre.c Progetto: niubl/ironbee
/**
 * Set the matches into the given field name as .0, .1, .2 ... .9.
 *
 * @param[in] tx Current transaction.
 * @param[in] capture Collection to capture to.
 * @param[in] ovector The vector of integer pairs of matches from PCRE.
 * @param[in] matches The number of matches.
 * @param[in] subject The matched-against string data.
 *
 * @returns IB_OK or IB_EALLOC.
 */
static
ib_status_t pcre_set_matches(
    const ib_tx_t *tx,
    ib_field_t    *capture,
    int           *ovector,
    int            matches,
    const char    *subject
)
{
    assert(tx != NULL);
    assert(tx->ib != NULL);
    assert(capture != NULL);
    assert(ovector != NULL);

    ib_status_t rc;
    int i;

    rc = ib_capture_clear(capture);
    if (rc != IB_OK) {
        ib_log_error_tx(tx, "Error clearing captures: %s",
                        ib_status_to_string(rc));
    }

    /* We have a match! Now populate TX:0-9 in tx->data. */
    ib_log_debug2_tx(tx, "REGEX populating %d matches", matches);
    for (i = 0; i < matches; ++i)
    {
        /* The length of the match. */
        size_t match_len;

        /* The first character in the match. */
        const char *match_start;

        /* Field name */
        const char *name;

        /* Holder for a copy of the field value when creating a new field. */
        ib_bytestr_t *bs;

        /* Field holder. */
        ib_field_t *field;

        /* Readability. Mark the start and length of the string. */
        match_start = subject+ovector[i*2];
        match_len = ovector[i*2+1] - ovector[i*2];

        /* Create a byte-string representation */
        rc = ib_bytestr_dup_mem(&bs,
                                tx->mp,
                                (const uint8_t*)match_start,
                                match_len);
        if (rc != IB_OK) {
            return rc;
        }

        /* Create a field to hold the byte-string */
        name = ib_capture_name(i);
        rc = ib_field_create(&field, tx->mp, name, strlen(name),
                             IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
        if (rc != IB_OK) {
            return rc;
        }

        /* Add it to the capture collection */
        rc = ib_capture_set_item(capture, i, tx->mp, field);
        if (rc != IB_OK) {
            return rc;
        }
    }

    return IB_OK;
}
Esempio n. 10
0
void Field::set_byte_string(ConstByteString value) const
{
    Internal::check_type(BYTE_STRING, type());
    Internal::set_value(ib(), ib_ftype_bytestr_in(value.ib()));
}
Esempio n. 11
0
/// @test Test util field library - ib_field_format() with bytestr
TEST_F(TestIBUtilField, test_field_format_bytestr)
{
    ib_field_t *f;
    ib_status_t rc;
    char fmtbuf[32];
    const uint8_t in1[] = "a\0b";
    const uint8_t in2[] = "\fabcd\0efghijk\t";
    size_t size;
    ib_bytestr_t *bs;
    const char *tname;
    const char *buf;

    size = sizeof(in1) - 1;
    rc = ib_bytestr_dup_mem(&bs, MemPool(), in1, size);
    ASSERT_EQ(IB_OK, rc);

    rc = ib_field_create(&f, MemPool(), IB_FIELD_NAME("test_bytestr"),
                         IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f != NULL);

    buf = ib_field_format(f, false, false, &tname, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ((const char *)in1, fmtbuf);
    ASSERT_STREQ("BYTESTR", tname);
    ASSERT_EQ(buf, fmtbuf);

    buf = ib_field_format(f, false, true, &tname, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ("a\\u0000b", fmtbuf);
    ASSERT_STREQ("BYTESTR", tname);
    ASSERT_EQ(buf, fmtbuf);

    buf = ib_field_format(f, true, true, &tname, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ("\"a\\u0000b\"", fmtbuf);
    ASSERT_STREQ("BYTESTR", tname);
    ASSERT_EQ(buf, fmtbuf);


    size = sizeof(in2) - 1;
    rc = ib_bytestr_dup_mem(&bs, MemPool(), in2, size);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f != NULL);

    rc = ib_field_create(&f, MemPool(), IB_FIELD_NAME("test_bytestr"),
                         IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);

    buf = ib_field_format(f, false, false, NULL, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ((const char *)in2, fmtbuf);
    ASSERT_EQ(buf, fmtbuf);

    buf = ib_field_format(f, true, false, NULL, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ("\"\fabcd\"", fmtbuf);
    ASSERT_EQ(buf, fmtbuf);

    buf = ib_field_format(f, false, true, NULL, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ("\\fabcd\\u0000efghijk\\t", fmtbuf);
    ASSERT_EQ(buf, fmtbuf);

    buf = ib_field_format(f, true, true, NULL, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ("\"\\fabcd\\u0000efghijk\\t\"", fmtbuf);
    ASSERT_EQ(buf, fmtbuf);
}
Esempio n. 12
0
static ib_status_t field_from_string_internal(
    ib_mpool_t *mp,
    const char *name,
    size_t nlen,
    const char *vstr,
    size_t vlen,
    bool vstr_is_nulstr,
    ib_field_t **pfield)
{
    assert(mp != NULL);
    assert(name != NULL);
    assert(vstr != NULL);
    assert(pfield != NULL);

    ib_status_t conv;
    ib_status_t rc = IB_OK;
    ib_field_t *field;

    *pfield = NULL;

    /* Try to convert to an integer */
    if (*pfield == NULL) {
        ib_num_t num_val;
        if (vstr_is_nulstr) {
            conv = ib_string_to_num(vstr, 0, &num_val);
        }
        else {
            conv = ib_string_to_num_ex(vstr, vlen, 0, &num_val);
        }
        if (conv == IB_OK) {
            rc = ib_field_create(&field, mp,
                                 name, nlen,
                                 IB_FTYPE_NUM,
                                 ib_ftype_num_in(&num_val));
            *pfield = field;
        }
    }

    /* Try to convert to a float */
    if (*pfield == NULL) {
        ib_float_t float_val;
        if (vstr_is_nulstr) {
            conv = ib_string_to_float(vstr, &float_val);
        }
        else {
            conv = ib_string_to_float_ex(vstr, vlen, &float_val);
        }
        if (conv == IB_OK) {
            rc = ib_field_create(&field, mp,
                                 name, nlen,
                                 IB_FTYPE_FLOAT,
                                 ib_ftype_float_in(&float_val));
            *pfield = field;
        }
    }

    /* Finally, assume that it's a string */
    if (*pfield == NULL) {
        if (vstr_is_nulstr) {
            rc = ib_field_create(&field, mp,
                                 name, nlen,
                                 IB_FTYPE_NULSTR,
                                 ib_ftype_nulstr_in(vstr));
        }
        else {
            ib_bytestr_t *bs;
            rc = ib_bytestr_dup_mem(&bs, mp, (const uint8_t *)vstr, vlen);
            if (rc != IB_OK) {
                return rc;
            }
            rc = ib_field_create(&field, mp,
                                 name, nlen,
                                 IB_FTYPE_BYTESTR,
                                 ib_ftype_bytestr_in(bs));
        }
        *pfield = field;
    }

    return rc;
}
Esempio n. 13
0
ib_status_t ib_field_convert(
    ib_mpool_t        *mp,
    const ib_ftype_t   desired_type,
    const ib_field_t  *in_field,
    ib_field_t       **out_field
)
{
    assert(mp);
    assert(in_field);

    ib_status_t rc;

    /* Holder values for in_field values before being set in out_field. */
    size_t sz;
    const char *str;
    const ib_bytestr_t *bstr;
    ib_num_t num;
    ib_time_t tme;
    ib_float_t flt;
    void *new_field_value;

    if (in_field->type == desired_type) {
        *out_field = NULL;
        return IB_OK;
    }

    switch (in_field->type) {
    case IB_FTYPE_NULSTR:

        /* Extract string.  Note that a zero-length nulstr field can
         * have a NULL value in the union. */
        if ( (in_field->val->u.nulstr == NULL) &&
             (in_field->val->pval == NULL) )
        {
            str = "";
        }
        else {
            rc = ib_field_value(in_field, ib_ftype_nulstr_out(&str));
            if (rc != IB_OK){
                return rc;
            }
        }

        switch (desired_type) {
        case IB_FTYPE_BYTESTR:
            rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_bytestr_in(bstr);
            break;
        case IB_FTYPE_TIME:
            rc = ib_string_to_time(str, &tme);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_time_in(&tme);
            break;
        case IB_FTYPE_NUM:
            rc = ib_string_to_num(str, 0, &num);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_num_in(&num);
            break;
        case IB_FTYPE_FLOAT:
            rc = ib_string_to_float(str, &flt);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_float_in(&flt);
            break;
        default:
            return IB_EINVAL;
        }
        break;

    case IB_FTYPE_BYTESTR:

        /* Extract bytestr. */
        rc = ib_field_value(in_field, ib_ftype_bytestr_out(&bstr));
        if (rc != IB_OK){
            return rc;
        }
        str = (const char *)ib_bytestr_const_ptr(bstr);
        sz = ib_bytestr_length(bstr);

        /* Convert byte str. */
        switch(desired_type) {
        case IB_FTYPE_NULSTR:
            str = ib_mpool_memdup_to_str(mp, str, sz);
            if (!str) {
                return rc;
            }
            new_field_value = ib_ftype_nulstr_in(str);
            break;
        case IB_FTYPE_TIME:
            rc = ib_string_to_time_ex(str, sz, &tme);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_time_in(&tme);
            break;
        case IB_FTYPE_NUM:
            rc = ib_string_to_num_ex(str, sz, 0, &num);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_num_in(&num);
            break;
        case IB_FTYPE_FLOAT:
            rc = ib_string_to_float_ex(str, sz, &flt);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_float_in(&flt);
            break;
        default:
            return IB_EINVAL;
        }
        break;

    case IB_FTYPE_TIME:

        /* Extract time. */
        rc = ib_field_value(in_field, ib_ftype_time_out(&tme));
        if (rc != IB_OK){
            return rc;
        }

        switch (desired_type) {
        case IB_FTYPE_NULSTR:
            str = ib_time_to_string(mp, tme);
            if (! str) {
                return IB_EINVAL;
            }
            new_field_value = ib_ftype_nulstr_in(str);
            break;
        case IB_FTYPE_BYTESTR:
            str = ib_time_to_string(mp, tme);
            if (! str) {
                return IB_EINVAL;
            }
            rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
            if (rc != IB_OK){
                return rc;
            }
            new_field_value = ib_ftype_bytestr_in(bstr);
            break;
        case IB_FTYPE_FLOAT:
            flt = (ib_float_t)tme;
            /* Check that our assignment is within error=1, or fail. */
            if (llabs(tme - flt) > 1) {
                return IB_EINVAL;
            }
            new_field_value = ib_ftype_float_in(&flt);
            break;
        default:
            return IB_EINVAL;
        }
        break;

    case IB_FTYPE_NUM:

        /* Extract unum. */
        rc = ib_field_value(in_field, ib_ftype_num_out(&num));
        if (rc != IB_OK){
            return rc;
        }

        switch (desired_type) {
        case IB_FTYPE_NULSTR:
            str = ib_num_to_string(mp, num);
            if (! str) {
                return IB_EINVAL;
            }
            new_field_value = ib_ftype_nulstr_in(str);
            break;
        case IB_FTYPE_BYTESTR:
            str = ib_num_to_string(mp, num);
            if (! str) {
                return IB_EINVAL;
            }
            rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
            if (rc != IB_OK){
                return rc;
            }
            new_field_value = ib_ftype_bytestr_in(bstr);
            break;
        case IB_FTYPE_TIME:
            if (num < 0) {
                return IB_EINVAL;
            }
            tme = (ib_time_t)num;
            new_field_value = ib_ftype_time_in(&tme);
            break;
        case IB_FTYPE_FLOAT:
            flt = (ib_float_t)num;
            if (llabs(flt - num) > 1) {
                return IB_EINVAL;
            }
            new_field_value = ib_ftype_float_in(&flt);
            break;
        default:
            return IB_EINVAL;
        }
        break;

    case IB_FTYPE_FLOAT:

        /* Extract unum. */
        rc = ib_field_value(in_field, ib_ftype_float_out(&flt));
        if (rc != IB_OK){
            return rc;
        }

        switch (desired_type) {
        case IB_FTYPE_NULSTR:
            str = ib_float_to_string(mp, flt);
            if (!str) {
                return IB_EINVAL;
            }
            new_field_value = ib_ftype_nulstr_in(str);
            break;
        case IB_FTYPE_BYTESTR:
            str = ib_float_to_string(mp, flt);
            if (!str) {
                return IB_EINVAL;
            }
            rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
            if (rc != IB_OK){
                return rc;
            }
            new_field_value = ib_ftype_bytestr_in(bstr);
            break;
        case IB_FTYPE_TIME:
            if (flt < 0) {
                return IB_EINVAL;
            }
            tme = (ib_float_t)flt;
            new_field_value = ib_ftype_time_in(&tme);
            break;
        case IB_FTYPE_NUM:
            num = (ib_float_t)flt;
            new_field_value = ib_ftype_num_in(&num);
            break;
        default:
            return IB_EINVAL;
        }
        break;

    default:
        return IB_EINVAL;
    }

    rc = ib_field_create(
        out_field,
        mp,
        in_field->name,
        in_field->nlen,
        desired_type,
        new_field_value
    );
    return rc;
}
Esempio n. 14
0
/**
 * Create an alias list collection.
 *
 * @param ib Engine.
 * @param tx Transaction.
 * @param name Collection name
 * @param header Header list to alias
 *
 * @returns Status code
 */
static ib_status_t create_header_alias_list(
    ib_engine_t *ib,
    ib_tx_t *tx,
    const char *name,
    ib_parsed_header_wrapper_t *header)
{
    ib_field_t *f;
    ib_list_t *header_list;
    ib_status_t rc;
    ib_parsed_name_value_pair_list_t *nvpair;

    assert(ib != NULL);
    assert(tx != NULL);
    assert(name != NULL);
    assert(header != NULL);

    /* Create the list */
    rc = ib_data_get(tx->data, name, &f);
    if (rc == IB_ENOENT) {
        rc = ib_data_add_list(tx->data, name, &f);
        if (rc != IB_OK) {
            return rc;
        }
    }
    else if (rc != IB_OK) {
        return rc;
    }
    rc = ib_field_mutable_value(f, ib_ftype_list_mutable_out(&header_list));
    if (rc != IB_OK) {
        return rc;
    }

    /* Loop through the list & alias everything */
    for(nvpair = header->head;  nvpair != NULL;  nvpair = nvpair->next) {
        assert(nvpair);
        assert(nvpair->value);
        ib_bytestr_t *bs = NULL;
        if (ib_bytestr_ptr(nvpair->value) != NULL) {
            rc = ib_bytestr_alias_mem(
                &bs,
                tx->mp,
                ib_bytestr_ptr(nvpair->value),
                ib_bytestr_length(nvpair->value)
            );
        }
        else {
            rc = ib_bytestr_dup_mem(&bs, tx->mp, (const uint8_t *)"", 0);
        }
        if (rc != IB_OK) {
            ib_log_error_tx(
                tx,
                "Error creating bytestring of '%.*s' for %s: %s",
                (int)ib_bytestr_length(nvpair->name),
                (const char *)ib_bytestr_ptr(nvpair->name),
                name,
                ib_status_to_string(rc)
            );
            return rc;
        }

        /* Create a byte string field */
        rc = ib_field_create(
            &f,
            tx->mp,
            (const char *)ib_bytestr_const_ptr(nvpair->name),
            ib_bytestr_length(nvpair->name),
            IB_FTYPE_BYTESTR,
            ib_ftype_bytestr_in(bs)
        );
        if (rc != IB_OK) {
            ib_log_error_tx(tx,
                            "Error creating field of '%.*s' for %s: %s",
                            (int)ib_bytestr_length(nvpair->name),
                            (const char *)ib_bytestr_ptr(nvpair->name),
                            name,
                            ib_status_to_string(rc));
            return rc;
        }

        /* Add the field to the list */
        rc = ib_list_push(header_list, f);
        if (rc != IB_OK) {
            ib_log_error_tx(tx, "Error adding alias of '%.*s' to %s list: %s",
                            (int)ib_bytestr_length(nvpair->name),
                            (const char *)ib_bytestr_ptr(nvpair->name),
                            name,
                            ib_status_to_string(rc));
            return rc;
        }
    }

    return IB_OK;
}