/** * Execute the @c ee operator in a streaming fashion. * * See ee_operator_execute(). * * @param[in] tx Current transaction. * @param[in] field The field to operate on. * @param[in] capture If non-NULL, the collection to capture to. * @param[out] result The result of the operator 1=true 0=false. * @param[in] instance_data Instance data needed for execution. * @param[in] cbdata Pointer to the module instance (ib_module_t *) */ static ib_status_t ee_operator_execute_stream( ib_tx_t *tx, const ib_field_t *field, ib_field_t *capture, ib_num_t *result, void *instance_data, void *cbdata ) { ib_status_t rc; ia_eudoxus_result_t ia_rc; ee_operator_data_t *operator_data = instance_data; ia_eudoxus_t* eudoxus = operator_data->eudoxus; ee_tx_data_t* data = NULL; ee_callback_data_t *ee_cbdata; const ib_module_t *m = (const ib_module_t *)cbdata; assert(m != NULL); assert(tx != NULL); assert(instance_data != NULL); *result = 0; /* Persist data. */ rc = get_ee_tx_data(m, tx, operator_data, &data); if (rc == IB_ENOENT) { /* Data not found create it */ data = ib_mm_alloc(tx->mm, sizeof(*data)); ee_cbdata = ib_mm_alloc(tx->mm, sizeof(*ee_cbdata)); if (ee_cbdata == NULL) { return IB_EALLOC; } ee_cbdata->tx = tx; ee_cbdata->capture = capture; data->ee_cbdata = ee_cbdata; ia_rc = ia_eudoxus_create_state(&data->eudoxus_state, eudoxus, ee_first_match_callback, (void *)ee_cbdata); if (ia_rc != IA_EUDOXUS_OK) { if (data->eudoxus_state != NULL) { ia_eudoxus_destroy_state(data->eudoxus_state); data->eudoxus_state = NULL; } return IB_EINVAL; } data->end_of_automata = false; set_ee_tx_data(m, tx, operator_data, data); } else if (rc != IB_OK) { /* Error getting the state -- abort */ return rc; } return ee_operator_execute_common( tx, operator_data, data, field, false, result ); }
/** * Destroy the eudoxus state when the transaction is complete. * * After the transaction is complete iterate over all of the states create * during the transaction and destroy them. * * @param[in] ib IronBee engine. * @param[in] tx Current transaction. * @param[in] state State (should always be @ref tx_finished_state) * @param[in] cbdata Callback data -- pointer to this module (@ref ib_module_t). * * @returns IB_OK on success. */ static ib_status_t ee_tx_finished_handler(ib_engine_t *ib, ib_tx_t *tx, ib_state_t state, void *cbdata) { ib_status_t rc; ib_hash_t *hash; ib_mpool_lite_t* mpl; ib_mm_t mm; const ib_module_t *m = (const ib_module_t *)cbdata; ee_tx_data_t *data; ib_hash_iterator_t *iterator; rc = ib_tx_get_module_data(tx, m, &hash); if (rc == IB_ENOENT) { /* Nothing to do. */ return IB_OK; } if (rc != IB_OK || hash == NULL) { return rc; } rc = ib_mpool_lite_create(&mpl); if (rc != IB_OK) { return rc; } mm = ib_mm_mpool_lite(mpl); iterator = ib_hash_iterator_create(mm); if (iterator == NULL) { ib_mpool_lite_destroy(mpl); return IB_EALLOC; } for ( ib_hash_iterator_first(iterator, hash); ! ib_hash_iterator_at_end(iterator); ib_hash_iterator_next(iterator) ) { ib_hash_iterator_fetch(NULL, NULL, &data, iterator); if (data->eudoxus_state != NULL) { ia_eudoxus_destroy_state(data->eudoxus_state); data->eudoxus_state = NULL; } } ib_mpool_lite_destroy(mpl); return IB_OK; }
/** * Destroy the eudoxus state when the transaction is complete. * * After the transaction is complete iterate over all of the states create * during the transaction and destroy them. * * @param[in] ib IronBee engine. * @param[in] tx Current transaction. * @param[in] event Event type (should always be @ref tx_finished_event) * @param[in] cbdata Callback data -- pointer to this module (@ref ib_module_t). * * @returns IB_OK on success. */ static ib_status_t ee_tx_finished_handler(ib_engine_t *ib, ib_tx_t *tx, ib_state_event_type_t event, void *cbdata) { ib_status_t rc; ib_hash_t *hash; ib_mpool_t *pool; const ib_module_t *m = (const ib_module_t *)cbdata; ia_eudoxus_state_t *state; ib_hash_iterator_t *iterator; rc = ib_tx_get_module_data(tx, m, &hash); if (rc != IB_OK || hash == NULL) { return rc; } rc = ib_mpool_create(&pool, "temp", NULL); if (rc != IB_OK) { return rc; } iterator = ib_hash_iterator_create(pool); if (iterator == NULL) { ib_mpool_destroy(pool); return IB_EALLOC; } for ( ib_hash_iterator_first(iterator, hash); ! ib_hash_iterator_at_end(iterator); ib_hash_iterator_next(iterator) ) { ib_hash_iterator_fetch(NULL, NULL, &state, iterator); if (state != NULL) { ia_eudoxus_destroy_state(state); state = NULL; } } ib_mpool_destroy(pool); return IB_OK; }
/** * Common code for @c ee and @c ee_match operators. * * At first match the operator will stop searching. If @c full_match is * true, the entire input must be matched for success. * * The capture option is supported; the matched pattern will be placed in the * capture variable if a match occurs. * * @param[in] tx Current transaction. * @param[in] instance_data Instance data needed for execution. * @param[in] field The field to operate on. * @param[in] capture If non-NULL, the collection to capture to. * @param[in] full_match If true, the full input text must be matched. * @param[out] result The result of the operator 1=true 0=false. * @param[in] cbdata Pointer to the module instance (ib_module_t *) */ static ib_status_t ee_match_operator_execute_nonstream( ib_tx_t *tx, void *instance_data, const ib_field_t *field, ib_field_t *capture, bool full_match, ib_num_t *result, void *cbdata ) { ia_eudoxus_result_t ia_rc; ee_operator_data_t *operator_data = instance_data; ia_eudoxus_t* eudoxus = operator_data->eudoxus; assert(tx != NULL); assert(instance_data != NULL); *result = 0; /* Not streaming, so create data for this use only */ ee_callback_data_t local_cbdata = { tx, capture, 0 }; ee_tx_data_t local_data; local_data.ee_cbdata = &local_cbdata; ia_rc = ia_eudoxus_create_state(&local_data.eudoxus_state, eudoxus, ee_first_match_callback, (void *)&local_cbdata); if (ia_rc != IA_EUDOXUS_OK) { if (local_data.eudoxus_state != NULL) { ia_eudoxus_destroy_state(local_data.eudoxus_state); } return IB_EINVAL; } local_data.end_of_automata = false; return ee_operator_execute_common( tx, operator_data, &local_data, field, full_match, result ); }
/** * Execute the @c ee_match_any operator. * * At first match the operator will stop searching and return true. * * The capture option is supported; the matched pattern will be placed in the * capture variable if a match occurs. * * @param[in] tx Current transaction. * @param[in] instance_data Instance data needed for execution. * @param[in] field The field to operate on. * @param[in] capture If non-NULL, the collection to capture to. * @param[out] result The result of the operator 1=true 0=false. * @param[in] cbdata Callback data. */ static ib_status_t ee_match_any_operator_execute( ib_tx_t *tx, void *instance_data, const ib_field_t *field, ib_field_t *capture, ib_num_t *result, void *cbdata ) { ib_status_t rc; ia_eudoxus_result_t ia_rc; ee_operator_data_t *operator_data = instance_data; ia_eudoxus_t* eudoxus = operator_data->eudoxus; ia_eudoxus_state_t* state = NULL; const char *input; size_t input_len; ee_callback_data_t *ee_cbdata; const ib_module_t *m = (const ib_module_t *)cbdata; assert(m != NULL); assert(tx != NULL); assert(instance_data != NULL); *result = 0; if (field->type == IB_FTYPE_NULSTR) { rc = ib_field_value(field, ib_ftype_nulstr_out(&input)); if (rc != IB_OK) { return rc; } input_len = strlen(input); } else if (field->type == IB_FTYPE_BYTESTR) { const ib_bytestr_t *bs; rc = ib_field_value(field, ib_ftype_bytestr_out(&bs)); if (rc != IB_OK) { return rc; } input = (const char *)ib_bytestr_const_ptr(bs); input_len = ib_bytestr_length(bs); } else if (field->type == IB_FTYPE_LIST) { return IB_ENOTIMPL; } else { return IB_EINVAL; } rc = get_ee_tx_data(m, tx, operator_data, &state); if (rc == IB_ENOENT) { /* State not found create it */ ee_cbdata = ib_mpool_alloc(tx->mp, sizeof(*ee_cbdata)); if (ee_cbdata == NULL) { return IB_EALLOC; } ee_cbdata->tx = tx; ee_cbdata->capture = capture; ia_rc = ia_eudoxus_create_state(&state, eudoxus, ee_first_match_callback, (void *)ee_cbdata); if (ia_rc != IA_EUDOXUS_OK) { if (state != NULL) { ia_eudoxus_destroy_state(state); state = NULL; } return IB_EINVAL; } set_ee_tx_data(m, tx, operator_data, state); } else if (rc != IB_OK) { /* Error getting the state -- abort */ return rc; } rc = IB_OK; ia_rc = ia_eudoxus_execute(state, (const uint8_t *)input, input_len); if (ia_rc == IA_EUDOXUS_STOP) { *result = 1; rc = IB_OK; } else if (ia_rc == IA_EUDOXUS_ERROR) { rc = IB_EUNKNOWN; } return rc; }