c16ac03ece628908324db86ad1a3b95e59f0b058
[idzebra-moved-to-github.git] / dict / lookup.c
1 /*
2  * Copyright (C) 1994-1998, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: lookup.c,v $
7  * Revision 1.8  1998-03-05 08:17:24  adam
8  * Added a few comments - no code changed.
9  *
10  * Revision 1.7  1996/02/02 13:43:51  adam
11  * The public functions simply use char instead of Dict_char to represent
12  * search strings. Dict_char is used internally only.
13  *
14  * Revision 1.6  1995/12/11  09:04:50  adam
15  * Bug fix: the lookup/scan/lookgrep didn't handle empty dictionary.
16  *
17  * Revision 1.5  1995/09/04  09:09:15  adam
18  * String arg in lookup is const.
19  *
20  * Revision 1.4  1994/10/05  12:16:51  adam
21  * Pagesize is a resource now.
22  *
23  * Revision 1.3  1994/09/26  10:17:25  adam
24  * Minor changes.
25  *
26  * Revision 1.2  1994/09/16  15:39:14  adam
27  * Initial code of lookup - not tested yet.
28  *
29  * Revision 1.1  1994/08/16  16:26:48  adam
30  * Added dict.
31  *
32  */
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include <stdio.h>
37 #include <assert.h>
38
39 #include <dict.h>
40
41 static char *dict_look (Dict dict, const Dict_char *str)
42 {
43     Dict_ptr ptr = 1;
44     int mid, lo, hi;
45     int cmp;
46     void *p;
47     short *indxp;
48     char *info;
49
50     dict_bf_readp (dict->dbf, ptr, &p);
51     mid = lo = 0;
52     hi = DICT_nodir(p)-1;
53     indxp = (short*) ((char*) p+DICT_pagesize(dict)-sizeof(short));    
54     while (lo <= hi)
55     {
56         mid = (lo+hi)/2;
57         if (indxp[-mid] > 0)
58         {
59             /* string (Dict_char *) DICT_EOS terminated */
60             /* unsigned char        length of information */
61             /* char *               information */
62             info = (char*)p + indxp[-mid];
63             cmp = dict_strcmp((Dict_char*) info, str);
64             if (!cmp)
65                 return info+(dict_strlen ((Dict_char*) info)+1)
66                     *sizeof(Dict_char);
67         }
68         else
69         {
70             Dict_char dc;
71             Dict_ptr subptr;
72
73             /* Dict_ptr             subptr */
74             /* Dict_char            sub char */
75             /* unsigned char        length of information */
76             /* char *               information */
77             info = (char*)p - indxp[-mid];
78             memcpy (&dc, info+sizeof(Dict_ptr), sizeof(Dict_char));
79             cmp = dc- *str;
80             if (!cmp)
81             {
82                 memcpy (&subptr, info, sizeof(Dict_ptr));
83                 if (*++str == DICT_EOS)
84                 {
85                     if (info[sizeof(Dict_ptr)+sizeof(Dict_char)])
86                         return info+sizeof(Dict_ptr)+sizeof(Dict_char);
87                     return NULL;
88                 }
89                 else
90                 {
91                     if (subptr == 0)
92                         return NULL;
93                     ptr = subptr;
94                     dict_bf_readp (dict->dbf, ptr, &p);
95                     mid = lo = 0;
96                     hi = DICT_nodir(p)-1;
97                     indxp = (short*) ((char*) p+DICT_pagesize(dict)
98                                       -sizeof(short));
99                     continue;
100                 }
101             }
102         }
103         if (cmp < 0)
104             lo = mid+1;
105         else
106             hi = mid-1;
107     }
108     return NULL;
109 }
110
111 char *dict_lookup (Dict dict, const char *p)
112 {
113     if (dict->head.last <= 1)
114         return NULL;
115     return dict_look (dict, (const Dict_char *) p);
116 }
117
118