static RNode * _find_node_with_state(RFindNodeState *state, RNode *root, guint8 *key, gint keylen) { RNode *ret; state->require_complete_match = TRUE; state->partial_match_found = FALSE; ret = _find_node_recursively(state, root, key, keylen); if (!ret && state->partial_match_found) { state->require_complete_match = FALSE; ret = _find_node_recursively(state, root, key, keylen); } return ret; }
static RNode * _find_child_by_remaining_key(RFindNodeState *state, RNode *root, guint8 *remaining_key, gint remaining_keylen) { RNode *candidate = r_find_child_by_first_character(root, remaining_key[0]); if (candidate) { return _find_node_recursively(state, candidate, remaining_key, remaining_keylen); } return NULL; }
static RNode * _find_child_by_remaining_key(RFindNodeState *state, RNode *root, gchar *remaining_key, gint remaining_keylen) { RNode *candidate; if (remaining_keylen >= 2 && remaining_key[0] == '\r' && remaining_key[1] == '\n') { remaining_key++; remaining_keylen--; } candidate = r_find_child_by_first_character(root, remaining_key[0]); if (candidate) return _find_node_recursively(state, candidate, remaining_key, remaining_keylen); return NULL; }
static RNode * _try_parse_with_a_given_child(RFindNodeState *state, RNode *root, gint parser_ndx, gint matches_slot_index, gchar *remaining_key, gint remaining_keylen) { RNode *child_node = root->pchildren[parser_ndx]; RParserNode *parser_node = child_node->parser; RParserMatch *match_slot = NULL; gint extracted_match_len; RNode *ret = NULL; match_slot = _clear_match_slot(state, matches_slot_index); if (_pnode_try_parse(parser_node, remaining_key, &extracted_match_len, match_slot)) { /* FIXME: we don't try to find the longest match in case * the radix tree is split on a parser node. The correct * approach would be to try all parsers and select the * best match, however it is quite expensive and difficult * to implement and we don't really expect this to be a * realistic case. A log message is printed if such a * collision occurs, so there's a slight chance we'll * recognize if this happens in real life. */ _add_parser_match_debug_info(state, root, parser_node, remaining_key, extracted_match_len, match_slot); ret = _find_node_recursively(state, root->pchildren[parser_ndx], remaining_key + extracted_match_len, remaining_keylen - extracted_match_len); /* we have to look up "match_slot" again as the GArray may have * moved the data in case r_find_node() expanded it above */ match_slot = _get_match_slot(state, matches_slot_index); if (match_slot) { if (ret) _fixup_match_offsets(state, parser_node, extracted_match_len, remaining_key, match_slot); else _clear_match_content(match_slot); } } return ret; }