about summary refs log tree commit homepage
path: root/ext/http11/tst_search.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/http11/tst_search.c')
-rw-r--r--ext/http11/tst_search.c115
1 files changed, 60 insertions, 55 deletions
diff --git a/ext/http11/tst_search.c b/ext/http11/tst_search.c
index 44aee7a..176f953 100644
--- a/ext/http11/tst_search.c
+++ b/ext/http11/tst_search.c
@@ -4,65 +4,70 @@
 #include <stdlib.h>
 #include <assert.h>
 
-void *tst_search(unsigned char *key, struct tst *tst, int *prefix_len)
+
+void *tst_search(const unsigned char *key, struct tst *tst, int option,
+                 unsigned int *match_len)
 {
-  struct node *current_node;
-  void *longest_match = NULL;
-  int key_index;
-  
-  assert(key != NULL && "key can't be NULL");
-  assert(tst != NULL && "tst can't be NULL");
-  
-  if(key[0] == 0)
-    return NULL;
-  
-  if(tst->head[(int)key[0]] == NULL)
-    return NULL;
+    struct node *current_node;
+    struct node *longest_match = NULL;
+    unsigned int longest_match_len = 0;
+    int key_index;
+
+    assert(key != NULL && "key can't be NULL");
+    assert(tst != NULL && "tst can't be NULL");
+
+    if (key[0] == 0)
+        return NULL;
+
+    if (tst->head[(int) key[0]] == NULL)
+        return NULL;
+
+    if (match_len)
+        *match_len = 0;
+
+    current_node = tst->head[(int) key[0]];
+    key_index = 1;
 
-  
-  if(prefix_len) *prefix_len = 0;
-  current_node = tst->head[(int)key[0]];
-  key_index = 1;
-  
-  while (current_node != NULL)
-    {
-      if(key[key_index] == current_node->value)
-        {
-          if(current_node->value == 0) {
-            if(prefix_len) *prefix_len = key_index;
-            return current_node->middle;
-          } else {
-            current_node = current_node->middle;
-            if(current_node && current_node->value == 0) {
-              if(prefix_len) *prefix_len = key_index+1;
-              longest_match = current_node->middle;
+    while (current_node != NULL) {
+        if (key[key_index] == current_node->value) {
+            if (current_node->value == 0) {
+                if (match_len)
+                    *match_len = key_index;
+                return current_node->middle;
+            } else {
+                current_node = current_node->middle;
+                key_index++;
+                continue;
             }
+        } else {
+            if (current_node->value == 0) {
+                if (option & TST_LONGEST_MATCH) {
+                    longest_match = current_node->middle;
+                    longest_match_len = key_index;
+                }
 
-            key_index++;
-            continue;
-          }
-        }
-      else if( ((current_node->value == 0) && (key[key_index] < 64)) ||
-               ((current_node->value != 0) && (key[key_index] <
-                                               current_node->value)) )
-        {
-          if(current_node->value == 0) {
-            if(prefix_len) *prefix_len = key_index;
-            longest_match = current_node->middle;
-          }
-          current_node = current_node->left;
-          continue;
-        }
-      else
-        {
-          if(current_node->value == 0) {
-            if(prefix_len) *prefix_len = key_index;
-            longest_match = current_node->middle;
-          }
-          current_node = current_node->right;
-          continue;
+                if (key[key_index] < 64) {
+                    current_node = current_node->left;
+                    continue;
+                } else {
+                    current_node = current_node->right;
+                    continue;
+                }
+            } else {
+                if (key[key_index] < current_node->value) {
+                    current_node = current_node->left;
+                    continue;
+                } else {
+                    current_node = current_node->right;
+                    continue;
+                }
+            }
         }
     }
-  
-  return longest_match;
+
+    if (match_len)
+        *match_len = longest_match_len;
+
+    return longest_match;
+
 }