Happy new year.
[idzebra-moved-to-github.git] / dict / lookup.c
1 /* This file is part of the Zebra server.
2    Copyright (C) 1994-2011 Index Data
3
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 */
19
20
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include <assert.h>
26
27 #include "dict-p.h"
28
29 static char *dict_look(Dict dict, const Dict_char *str, Dict_ptr ptr)
30 {
31     int mid, lo, hi;
32     int cmp;
33     void *p;
34     short *indxp;
35     char *info;
36
37     dict_bf_readp(dict->dbf, ptr, &p);
38     mid = lo = 0;
39     hi = DICT_nodir(p)-1;
40     indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));    
41     while (lo <= hi)
42     {
43         mid = (lo+hi)/2;
44         if (indxp[-mid] > 0)
45         {
46             /* string (Dict_char *) DICT_EOS terminated */
47             /* unsigned char        length of information */
48             /* char *               information */
49             info = (char*)p + indxp[-mid];
50             cmp = dict_strcmp((Dict_char*) info, str);
51             if (!cmp)
52                 return info+(dict_strlen ((Dict_char*) info)+1)
53                     *sizeof(Dict_char);
54         }
55         else
56         {
57             Dict_char dc;
58             Dict_ptr subptr;
59
60             /* Dict_ptr             subptr */
61             /* Dict_char            sub char */
62             /* unsigned char        length of information */
63             /* char *               information */
64             info = (char*)p - indxp[-mid];
65             memcpy(&dc, info+sizeof(Dict_ptr), sizeof(Dict_char));
66             cmp = dc- *str;
67             if (!cmp)
68             {
69                 memcpy(&subptr, info, sizeof(Dict_ptr));
70                 if (*++str == DICT_EOS)
71                 {
72                     if (info[sizeof(Dict_ptr)+sizeof(Dict_char)])
73                         return info+sizeof(Dict_ptr)+sizeof(Dict_char);
74                     return NULL;
75                 }
76                 else
77                 {
78                     if (subptr == 0)
79                         return NULL;
80                     ptr = subptr;
81                     dict_bf_readp(dict->dbf, ptr, &p);
82                     mid = lo = 0;
83                     hi = DICT_nodir(p)-1;
84                     indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
85                     continue;
86                 }
87             }
88         }
89         if (cmp < 0)
90             lo = mid+1;
91         else
92             hi = mid-1;
93     }
94     return NULL;
95 }
96
97 char *dict_lookup(Dict dict, const char *p)
98 {
99     dict->no_lookup++;
100     if (!dict->head.root)
101         return NULL;
102     return dict_look(dict, (const Dict_char *) p, dict->head.root);
103 }
104 /*
105  * Local variables:
106  * c-basic-offset: 4
107  * c-file-style: "Stroustrup"
108  * indent-tabs-mode: nil
109  * End:
110  * vim: shiftwidth=4 tabstop=8 expandtab
111  */
112