static char *test_trim(void *context)
{
    qd_iterator_t *iter = qd_iterator_string("testing.trim", ITER_VIEW_ALL);

    qd_iterator_trim_view(iter, 7);
    if (!qd_iterator_equal(iter, (unsigned char*) "testing"))
        return "Trim on ITER_VIEW_ALL failed (1)";

    qd_iterator_reset_view(iter, ITER_VIEW_ALL);
    if (!qd_iterator_equal(iter, (unsigned char*) "testing.trim"))
        return "Trim on ITER_VIEW_ALL failed (2)";

    qd_iterator_advance(iter, 4);
    qd_iterator_trim_view(iter, 5);
    if (!qd_iterator_equal(iter, (unsigned char*) "ing.t"))
        return "Trim on ITER_VIEW_ALL failed (3)";

    qd_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH);
    qd_iterator_trim_view(iter, 9);
    if (!qd_iterator_equal(iter, (unsigned char*) "M0testing"))
        return "Trim on ITER_VIEW_ADDRESS_HASH failed";

    qd_iterator_reset(iter);
    qd_iterator_annotate_space(iter, "my_space.", 9);
    qd_iterator_trim_view(iter, 18);
    if (!qd_iterator_equal(iter, (unsigned char*) "M0my_space.testing"))
        return "Trim on ITER_VIEW_ADDRESS_HASH (with space 1) failed";

    qd_iterator_reset(iter);
    qd_iterator_trim_view(iter, 10);
    if (!qd_iterator_equal(iter, (unsigned char*) "M0my_space"))
        return "Trim on ITER_VIEW_ADDRESS_HASH (in space 1) failed";

    qd_iterator_reset(iter);
    qd_iterator_trim_view(iter, 2);
    if (!qd_iterator_equal(iter, (unsigned char*) "M0"))
        return "Trim on ITER_VIEW_ADDRESS_HASH (in annotation 1) failed";

    qd_iterator_reset(iter);
    qd_iterator_trim_view(iter, 1);
    if (!qd_iterator_equal(iter, (unsigned char*) "M"))
        return "Trim on ITER_VIEW_ADDRESS_HASH (in annotation 2) failed";

    qd_iterator_free(iter);
    return 0;
}
static char *test_sub_iterator(void *context)
{
    qd_iterator_t *iter = qd_iterator_string("test_sub_iterator", ITER_VIEW_ALL);
    qd_iterator_t *sub1 = qd_iterator_sub(iter, qd_iterator_remaining(iter));
    qd_iterator_advance(iter, 5);
    qd_iterator_t *sub2 = qd_iterator_sub(iter, qd_iterator_remaining(iter));
    qd_iterator_t *sub3 = qd_iterator_sub(iter, 3);

    if (!qd_iterator_equal(sub1, (unsigned char*) "test_sub_iterator"))
        return "Sub Iterator failed - 1";
    if (!qd_iterator_equal(sub2, (unsigned char*) "sub_iterator"))
        return "Sub Iterator failed - 2";
    if (!qd_iterator_equal(sub3, (unsigned char*) "sub"))
        return "Sub Iterator failed - 3";

    qd_iterator_free(iter);
    qd_iterator_free(sub1);
    qd_iterator_free(sub2);
    qd_iterator_free(sub3);

    return 0;
}
Beispiel #3
0
static qd_parsed_field_t *qd_parse_internal(qd_iterator_t *iter, qd_parsed_field_t *p)
{
    qd_parsed_field_t *field = new_qd_parsed_field_t();
    if (!field)
        return 0;

    DEQ_ITEM_INIT(field);
    DEQ_INIT(field->children);
    field->parent   = p;
    field->raw_iter = 0;
    field->typed_iter = qd_iterator_dup(iter);

    uint32_t size            = 0;
    uint32_t count           = 0;
    uint32_t length_of_count = 0;
    uint32_t length_of_size  = 0;

    field->parse_error = get_type_info(iter, &field->tag, &size, &count, &length_of_size, &length_of_count);

    if (!field->parse_error) {
        qd_iterator_trim_view(field->typed_iter, size + length_of_size + 1); // + 1 accounts for the tag length

        field->raw_iter = qd_iterator_sub(iter, size - length_of_count);

        qd_iterator_advance(iter, size - length_of_count);

        for (uint32_t idx = 0; idx < count; idx++) {
            qd_parsed_field_t *child = qd_parse_internal(field->raw_iter, field);
            DEQ_INSERT_TAIL(field->children, child);
            if (!qd_parse_ok(child)) {
                field->parse_error = child->parse_error;
                break;
            }
        }
    }

    return field;
}
Beispiel #4
0
const char *qd_parse_turbo(qd_iterator_t          *iter,
                           qd_parsed_turbo_list_t *annos,
                           uint32_t               *user_entries,
                           uint32_t               *user_bytes)
{
    if (!iter || !annos || !user_entries || !user_bytes)
        return  "missing argument";

    DEQ_INIT(*annos);
    *user_entries = 0;
    *user_bytes = 0;

    // The iter is addressing the message-annotations map.
    // Open the field describing the map's items
    uint8_t  tag             = 0;
    uint32_t size            = 0;
    uint32_t count           = 0;
    uint32_t length_of_count = 0;
    uint32_t length_of_size  = 0;
    const char * parse_error = get_type_info(iter, &tag, &size, &count, &length_of_size, &length_of_count);

    if (parse_error)
        return parse_error;

    if (count == 0)
        return 0;

    int n_allocs = 0;

    // Do skeletal parse of each map element
    for (uint32_t idx = 0; idx < count; idx++) {
        qd_parsed_turbo_t *turbo;
        if (n_allocs < QD_MA_FILTER_LEN * 2) {
            turbo = new_qd_parsed_turbo_t();
            n_allocs++;

        } else {
            // Retire an existing element.
            // If there are this many in the list then this one cannot be a
            // router annotation and must be a user annotation.
            turbo = DEQ_HEAD(*annos);
            *user_entries += 1;
            *user_bytes += sizeof(turbo->tag) + turbo->size + turbo->length_of_size;
            DEQ_REMOVE_HEAD(*annos);
        }
        if (!turbo)
            return "failed to allocate qd_parsed_turbo_t";
        ZERO(turbo);

        // Get the buffer pointers for the map element
        qd_iterator_get_view_cursor(iter, &turbo->bufptr);

        // Get description of the map element
        parse_error = get_type_info(iter, &turbo->tag, &turbo->size, &turbo->count,
                                    &turbo->length_of_size, &turbo->length_of_count);
        if (parse_error) {
            return parse_error;
        }

        // Save parsed element
        DEQ_INSERT_TAIL(*annos, turbo);

        // Advance map iterator to next map element
        qd_iterator_advance(iter, turbo->size - turbo->length_of_count);
    }

    // remove leading annos in the queue if their prefix is not a match and
    // return them as part of the user annotations
    for (int idx=0; idx < n_allocs; idx += 2) {
        qd_parsed_turbo_t *turbo = DEQ_HEAD(*annos);
        assert(turbo);
        if (qd_iterator_prefix_ptr(&turbo->bufptr, turbo->length_of_size + 1, QD_MA_PREFIX))
            break;

        // leading anno is a user annotation map key
        // remove the key and value from the list and accumulate them as user items
        *user_bytes += sizeof(turbo->tag) + turbo->size + turbo->length_of_size;
        DEQ_REMOVE_HEAD(*annos);
        free_qd_parsed_turbo_t(turbo);

        turbo = DEQ_HEAD(*annos);
        assert(turbo);
        *user_bytes += sizeof(turbo->tag) + turbo->size + turbo->length_of_size;
        DEQ_REMOVE_HEAD(*annos);
        free_qd_parsed_turbo_t(turbo);

        *user_entries += 2;
    }
    return parse_error;
}