ia_eudoxus_result_t ia_eudoxus_create_state( ia_eudoxus_state_t **out_state, ia_eudoxus_t *eudoxus, ia_eudoxus_callback_t callback, void *callback_data ) { if (out_state == NULL || eudoxus == NULL) { return IA_EUDOXUS_EINVAL; } if (eudoxus->automata == NULL) { ia_eudoxus_set_error_cstr(eudoxus, "Invalid Automata."); return IA_EUDOXUS_EINVAL; } ia_eudoxus_state_t *state = (ia_eudoxus_state_t *)malloc(sizeof(*state)); if (state == NULL) { ia_eudoxus_set_error(eudoxus, NULL); return IA_EUDOXUS_EINVAL; } state->eudoxus = eudoxus; state->callback = callback; state->callback_data = callback_data; state->input_location = NULL; state->node = (ia_eudoxus_node_t *)( (char *)eudoxus->automata + eudoxus->automata->start_index ); *out_state = state; /* Process outputs for start node. */ return ia_eudoxus_execute(state, NULL, 0); }
/** * Feed data to the automata. * * @param[in] ib IronBee engine; used for logging. * @param[in] eudoxus Eudoxus engine; used for ia_eudoxus_error(). * @param[in] state Current Eudoxus execution state; updated. * @param[in] data Data to send to automata. * @param[in] data_length Length of @a data. * @return * - IB_OK on success. * - IB_EINVAL on IronAutomata failure; will emit log message. */ static ib_status_t fast_feed( const ib_engine_t *ib, const ia_eudoxus_t *eudoxus, ia_eudoxus_state_t *state, const uint8_t *data, size_t data_length ) { assert(ib != NULL); assert(eudoxus != NULL); assert(state != NULL); assert(data != NULL); ia_eudoxus_result_t irc; irc = ia_eudoxus_execute(state, data, data_length); if (irc != IA_EUDOXUS_OK) { ib_log_error( ib, "fast: Eudoxus Execution Failure: %s", fast_eudoxus_error(eudoxus) ); return IB_EINVAL; } return IB_OK; }
/** * Helper function for stream and non-stream execution. * * * * @param[in] tx Transaction * @param[in] operator_data Operator data. * @param[in] data Per-transaction data for this operator instance. * @param[in] field Input field. * @param[in] full_match If true, the full input text must be matched. * @param[out] result Result of execution. */ static ib_status_t ee_operator_execute_common( ib_tx_t *tx, ee_operator_data_t *operator_data, ee_tx_data_t *data, const ib_field_t *field, bool full_match, ib_num_t *result ) { ib_status_t rc; ia_eudoxus_result_t ia_rc; ia_eudoxus_state_t* state = NULL; const char *input; size_t input_len; assert(tx != NULL); assert(operator_data != NULL); assert(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; } if (data->end_of_automata) { /* Nothing to do. */ return IB_OK; } /* Run eudoxus */ state = data->eudoxus_state; rc = IB_OK; ia_rc = ia_eudoxus_execute(state, (const uint8_t *)input, input_len); if (ia_rc == IA_EUDOXUS_STOP) { if (full_match) { if (data->ee_cbdata->match_len == input_len) { *result = 1; } } else { *result = 1; } rc = IB_OK; } else if (ia_rc == IA_EUDOXUS_END) { data->end_of_automata = true; rc = IB_OK; } else if (ia_rc != IA_EUDOXUS_OK) { rc = IB_EUNKNOWN; } return rc; }
/** * 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; }