1/*
2 * Copyright (C) 2008-2012  OMRON SOFTWARE Co., Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "nj_lib.h"
18#include "nj_err.h"
19#include "nj_ext.h"
20#include "nj_dic.h"
21#include "njd.h"
22
23
24#define NODE_TERM(x) ((NJ_UINT8)(0x80 & (*(x))))
25#define NODE_LEFT_EXIST(x) ((NJ_UINT8)(0x40 & (*(x))))
26#define NODE_DATA_EXIST(x) ((NJ_UINT8)(0x20 & (*(x))))
27#define NODE_IDX_EXIST(x) ((NJ_UINT8)(0x10 & (*(x))))
28#define NODE_IDX_CNT(x) ((NJ_UINT8)((0x0f & (*(x))) + 2))
29
30#define STEM_TERMINETER(x) ((NJ_UINT8)(0x80 & (*(x))))
31
32#define STEM_NO_CONV_FLG(x) ((NJ_UINT8)(0x40 & (*(x))))
33
34#define TERM_BIT (1)
35#define INDEX_BIT (8)
36
37#define APPEND_YOMI_FLG(h) ((NJ_UINT8)(0x80 & (*((h) + 0x1C))))
38#define HINSI_NO_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x1D)))
39#define FHINSI_NO_CNT(h) ((NJ_INT16)(NJ_INT16_READ((h) + 0x21)))
40#define BHINSI_NO_CNT(h) ((NJ_INT16)(NJ_INT16_READ((h) + 0x23)))
41#define HINSI_NO_BYTE(h) ((NJ_UINT8)(*((h) + 0x25)))
42#define HINDO_NO_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x26)))
43#define HINDO_NO_CNT(h) ((NJ_UINT8)(*((h) + 0x2A)))
44#define STEM_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x2B)))
45#define BIT_CANDIDATE_LEN(h) ((NJ_UINT8)(*((h) + 0x2F)))
46#define BIT_FHINSI(h) ((NJ_UINT8)(*((h) + 0x30)))
47#define BIT_BHINSI(h) ((NJ_UINT8)(*((h) + 0x31)))
48#define BIT_HINDO_LEN(h) ((NJ_UINT8)(*((h) + 0x32)))
49#define BIT_MUHENKAN_LEN(h) ((NJ_UINT8)(*((h) + 0x33)))
50#define BIT_YOMI_LEN(h) ((NJ_UINT8)(*((h) + 0x35)))
51#define YOMI_INDX_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x42)))
52#define YOMI_INDX_CNT(h) ((NJ_INT16)(*((h) + 0x46)))
53#define YOMI_INDX_SIZE(h) ((NJ_INT8)(*((h) + 0x47)))
54#define NODE_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x48)))
55#define BIT_NODE_AREA_DATA_LEN(h) ((NJ_UINT8)(*((h) + 0x4C)))
56#define BIT_NODE_AREA_LEFT_LEN(h) ((NJ_UINT8)(*((h) + 0x4D)))
57#define NODE_AREA_MID_ADDR(h) ((NJ_UINT32)(NJ_INT32_READ((h) + 0x4E)))
58#define CAND_IDX_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x52)))
59#define CAND_IDX_AREA_CNT(h) ((NJ_UINT32)(((NJ_INT32_READ((h) + 0x56)) >> 8) & 0x00FFFFFF))
60#define CAND_IDX_AREA_SIZE(h) ((NJ_UINT8)(*((h) + 0x59)))
61
62#define WORD_LEN(x) ((NJ_UINT16)(0x007F & (x)))
63
64#define CURRENT_INFO_SET ((NJ_UINT8)(0x10))
65
66#define COMP_DIC_FREQ_DIV 63
67
68#define LOC_CURRENT_NO_ENTRY  0xffffffffU
69
70typedef struct {
71    NJ_UINT16 stem_size;
72    NJ_UINT16 term;
73    NJ_UINT16 no_conv_flg;
74    NJ_HINDO hindo;
75    NJ_UINT16 hindo_jitu;
76    NJ_UINT16 candidate_size;
77    NJ_UINT16 yomi_size;
78    NJ_UINT16 fhinsi;
79    NJ_UINT16 bhinsi;
80    NJ_UINT16 fhinsi_jitu;
81    NJ_UINT16 bhinsi_jitu;
82} STEM_DATA_SET;
83
84static NJ_INT16 get_stem_next(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data);
85static void get_stem_word(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set, NJ_UINT8 check);
86static void get_stem_cand_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set);
87static NJ_UINT16 get_stem_yomi_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data,STEM_DATA_SET *stem_set);
88static NJ_UINT16 get_stem_yomi_size(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, NJ_UINT16 yomi_size);
89static NJ_UINT16 get_stem_yomi_string(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, NJ_CHAR *yomi, NJ_UINT16 yomi_pos, NJ_UINT16 yomi_size, NJ_UINT16 size);
90static NJ_INT16 search_node(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset);
91static NJ_INT16 bdic_search_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset);
92static NJ_INT16 bdic_search_fore_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset);
93
94static NJ_HINDO get_stem_hindo(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data);
95
96static NJ_INT16 search_node2(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset,
97                             NJ_UINT16 hidx);
98static NJ_INT16 bdic_search_fore_data2(NJ_SEARCH_CONDITION *condition,
99                                       NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 hidx);
100static NJ_INT16 search_yomi_node(NJ_UINT8 operation, NJ_UINT8 *node,
101                                 NJ_UINT8 *now, NJ_UINT16 idx_no,
102                                 NJ_CHAR  *yomi, NJ_UINT16 yomilen,
103                                 NJ_UINT8 *root, NJ_UINT8 *node_mid,
104                                 NJ_UINT16 bit_left, NJ_UINT16 bit_data,
105                                 NJ_UINT8 *data_top,
106                                 NJ_INT16 ytbl_cnt, NJ_UINT16 y,
107                                 NJ_UINT8 *ytbl_top, NJ_CACHE_INFO *storebuf,
108                                 NJ_UINT8 **con_node, NJ_UINT32 *data_offset);
109static NJ_INT16 get_node_bottom(NJ_CHAR *yomi, NJ_UINT8 *now, NJ_UINT8 *node_mid,
110                                NJ_UINT8 *data_top, NJ_UINT16 bit_left,
111                                NJ_UINT16 bit_data, NJ_UINT32 top,
112                                NJ_DIC_HANDLE handle, NJ_UINT32 *ret_bottom);
113static NJ_INT16 bdic_get_next_data(NJ_UINT8 *data_top, NJ_UINT8 *data_end,
114                                   NJ_SEARCH_LOCATION_SET *loctset,
115                                   NJ_SEARCH_CACHE *psrhCache, NJ_UINT16 abIdx);
116static NJ_INT16 bdic_get_word_freq(NJ_UINT8 *data_top, NJ_SEARCH_LOCATION_SET *loctset,
117                                   NJ_SEARCH_CACHE *psrhCache, NJ_UINT16 abIdx);
118
119static NJ_HINDO get_stem_hindo(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data)
120{
121    NJ_UINT8 flg_bit;
122    NJ_UINT16 data;
123    NJ_UINT16 pos, j, bit_all;
124
125
126
127    flg_bit = BIT_MUHENKAN_LEN(hdl);
128    if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) {
129        flg_bit++;
130    }
131
132    if (BIT_HINDO_LEN(hdl)) {
133
134        bit_all = (NJ_UINT16)(TERM_BIT + flg_bit);
135        pos = (NJ_UINT16)(bit_all >> 3);
136        data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
137
138
139        j = (NJ_UINT16)(bit_all & 0x0007);
140
141        return GET_BITFIELD_16(data, j, BIT_HINDO_LEN(hdl));
142    } else {
143
144        return 0;
145    }
146}
147
148static NJ_INT16 get_stem_next(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data)
149{
150    NJ_UINT8 flg_bit;
151    NJ_UINT16 data;
152    NJ_UINT16 pos, j, bit_all;
153    NJ_UINT16 stem_size, cand_bit, yomi_bit;
154    NJ_UINT16 candidate_size, yomi_size;
155
156
157
158    flg_bit = BIT_MUHENKAN_LEN(hdl);
159    if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) {
160        flg_bit++;
161    }
162
163
164
165    bit_all = (NJ_UINT16)(TERM_BIT + flg_bit +
166                          BIT_HINDO_LEN(hdl) +
167                          BIT_FHINSI(hdl) +
168                          BIT_BHINSI(hdl));
169    pos = (NJ_UINT16)(bit_all >> 3);
170    data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
171
172
173    j = (NJ_UINT16)(bit_all & 0x0007);
174    cand_bit = BIT_CANDIDATE_LEN(hdl);
175
176    candidate_size = GET_BITFIELD_16(data, j, cand_bit);
177    bit_all += cand_bit;
178
179
180    if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) {
181
182
183        pos = (NJ_UINT16)(bit_all >> 3);
184        data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
185
186
187        j = (NJ_UINT16)(bit_all & 0x0007);
188        yomi_bit = BIT_YOMI_LEN(hdl);
189
190        yomi_size = GET_BITFIELD_16(data, j, yomi_bit);
191        bit_all += yomi_bit;
192    } else {
193        yomi_size = 0;
194    }
195
196
197    stem_size = GET_BIT_TO_BYTE(bit_all);
198
199
200    stem_size += candidate_size;
201
202
203    stem_size += yomi_size;
204
205
206    return stem_size;
207}
208
209static void get_stem_word(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set, NJ_UINT8 check)
210{
211    NJ_UINT8 flg_bit;
212    NJ_UINT16 data;
213    NJ_UINT16 pos, j, bit_all = 0;
214    NJ_UINT16 bit;
215    NJ_UINT16 dpos = 0;
216    NJ_INT16 next;
217    NJ_UINT8 b;
218    NJ_UINT8 *wkc;
219
220
221
222    flg_bit = BIT_MUHENKAN_LEN(hdl);
223    if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) {
224        flg_bit++;
225    }
226
227    if (BIT_HINDO_LEN(hdl)) {
228
229        bit_all = (NJ_UINT16)(TERM_BIT + flg_bit);
230        pos = (NJ_UINT16)(bit_all >> 3);
231        data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
232
233
234        j = (NJ_UINT16)(bit_all & 0x0007);
235
236        stem_set->hindo = GET_BITFIELD_16(data, j, BIT_HINDO_LEN(hdl));
237    } else {
238
239        stem_set->hindo = 0;
240    }
241
242    stem_set->hindo_jitu = (NJ_UINT16)(*(HINDO_NO_TOP_ADDR(hdl) + stem_set->hindo));
243
244    if (BIT_FHINSI(hdl)) {
245
246
247        bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl));
248        pos = (NJ_UINT16)(bit_all >> 3);
249        data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
250
251
252        j = (NJ_UINT16)(bit_all & 0x0007);
253
254        stem_set->fhinsi = GET_BITFIELD_16(data, j, BIT_FHINSI(hdl));
255    } else {
256        stem_set->fhinsi = 0;
257    }
258
259
260    b = HINSI_NO_BYTE(hdl);
261    wkc = (NJ_UINT8*)(HINSI_NO_TOP_ADDR(hdl) + (b * (NJ_UINT16)(stem_set->fhinsi)));
262
263
264    if (b == 2) {
265        stem_set->fhinsi_jitu = (NJ_UINT16)(NJ_INT16_READ(wkc));
266    } else {
267        stem_set->fhinsi_jitu = (NJ_UINT16)*wkc;
268    }
269
270    if (BIT_BHINSI(hdl)) {
271
272
273        bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl) + BIT_FHINSI(hdl));
274        pos = (NJ_UINT16)(bit_all >> 3);
275        data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
276
277
278        j = (NJ_UINT16)(bit_all & 0x0007);
279
280        stem_set->bhinsi = GET_BITFIELD_16(data, j, BIT_BHINSI(hdl));
281    } else {
282        stem_set->bhinsi = 0;
283    }
284
285    wkc = (NJ_UINT8*)(HINSI_NO_TOP_ADDR(hdl)
286                      + (b * (FHINSI_NO_CNT(hdl) + (NJ_UINT16)(stem_set->bhinsi))));
287
288    if (b == 2) {
289        stem_set->bhinsi_jitu = (NJ_UINT16)(NJ_INT16_READ(wkc));
290    } else {
291        stem_set->bhinsi_jitu = (NJ_UINT16)*wkc;
292    }
293
294
295    if (check != 1) {
296
297
298        bit_all = (NJ_UINT16)(TERM_BIT + flg_bit +
299                              BIT_HINDO_LEN(hdl) +
300                              BIT_FHINSI(hdl) +
301                              BIT_BHINSI(hdl));
302        pos = (NJ_UINT16)(bit_all >> 3);
303        data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
304
305
306        j = (NJ_UINT16)(bit_all & 0x0007);
307        bit = BIT_CANDIDATE_LEN(hdl);
308
309        stem_set->candidate_size = GET_BITFIELD_16(data, j, bit);
310        bit_all += bit;
311    }
312
313    if (check == 0) {
314        stem_set->yomi_size = 0;
315
316
317        if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) {
318            pos = (NJ_UINT16)(bit_all >> 3);
319            data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
320
321
322            j = (NJ_UINT16)(bit_all & 0x0007);
323            bit = BIT_YOMI_LEN(hdl);
324
325            stem_set->yomi_size = GET_BITFIELD_16(data, j, bit);
326            bit_all += bit;
327
328
329
330            dpos = GET_BIT_TO_BYTE(bit_all);
331            dpos += stem_set->candidate_size;
332
333        } else if (APPEND_YOMI_FLG(hdl)) {
334            while (!(STEM_TERMINETER(stem_data))) {
335                next = get_stem_next(hdl, stem_data);
336                stem_data += next;
337            }
338
339            dpos = get_stem_yomi_data(hdl, stem_data, stem_set);
340        }
341
342        if (stem_set->yomi_size) {
343
344            stem_set->yomi_size = get_stem_yomi_size(hdl, stem_data + dpos, stem_set->yomi_size);
345        }
346    }
347}
348
349static void get_stem_cand_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set)
350{
351    NJ_UINT8 flg_bit;
352    NJ_UINT16 data;
353    NJ_UINT16 pos, j, bit_all;
354    NJ_UINT16 cand_bit, yomi_bit;
355
356
357
358    flg_bit = BIT_MUHENKAN_LEN(hdl);
359    if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) {
360        flg_bit++;
361    }
362
363
364
365    bit_all = (NJ_UINT16)(TERM_BIT + flg_bit +
366                          BIT_HINDO_LEN(hdl) +
367                          BIT_FHINSI(hdl) +
368                          BIT_BHINSI(hdl));
369    pos = (NJ_UINT16)(bit_all >> 3);
370    data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
371
372
373    cand_bit = BIT_CANDIDATE_LEN(hdl);
374    j = (NJ_UINT16)(bit_all & 0x0007);
375
376    stem_set->candidate_size = GET_BITFIELD_16(data, j, cand_bit);
377    bit_all += cand_bit;
378
379
380    if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) {
381
382        yomi_bit = BIT_YOMI_LEN(hdl);
383        bit_all += yomi_bit;
384    }
385
386
387    stem_set->stem_size = GET_BIT_TO_BYTE(bit_all);
388}
389
390static NJ_UINT16 get_stem_yomi_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data,STEM_DATA_SET *stem_set)
391{
392    NJ_UINT16 flg_bit;
393    NJ_UINT16 data;
394    NJ_UINT16 cand_bit, yomi_bit;
395    NJ_UINT16 pos, j, bit_all;
396    NJ_UINT16 yomi_pos;
397    NJ_UINT16 candidate_size;
398
399
400
401    flg_bit = BIT_MUHENKAN_LEN(hdl);
402    if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) {
403        flg_bit++;
404    }
405
406
407
408    bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl) +
409                          BIT_FHINSI(hdl) + BIT_BHINSI(hdl));
410    pos = (NJ_UINT16)(bit_all >> 3);
411    data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
412
413
414    j = (NJ_UINT16)(bit_all & 0x0007);
415
416    cand_bit = BIT_CANDIDATE_LEN(hdl);
417    candidate_size = GET_BITFIELD_16(data, j, cand_bit);
418
419
420    bit_all += cand_bit;
421
422
423    if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) {
424
425
426        pos = (NJ_UINT16)(bit_all >> 3);
427        data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
428
429
430        j = (NJ_UINT16)(bit_all & 0x0007);
431        yomi_bit = BIT_YOMI_LEN(hdl);
432
433        stem_set->yomi_size = GET_BITFIELD_16(data, j, yomi_bit);
434        bit_all += yomi_bit;
435    } else {
436        stem_set->yomi_size = 0;
437    }
438
439
440
441    yomi_pos = GET_BIT_TO_BYTE(bit_all);
442    yomi_pos += candidate_size;
443
444    return yomi_pos;
445}
446
447static NJ_UINT16 get_stem_yomi_size(NJ_DIC_HANDLE hdl, NJ_UINT8 *ydata, NJ_UINT16 yomi_size)
448{
449    NJ_INT16 ytbl_cnt;
450    NJ_INT8 ysize;
451    NJ_UINT8 *ytbl_top;
452    NJ_UINT8 *ytbl;
453    NJ_UINT8 yidx;
454    NJ_UINT16 i;
455    NJ_UINT16 len;
456
457
458
459    ytbl_cnt = YOMI_INDX_CNT(hdl);
460
461    if (ytbl_cnt) {
462    ysize = YOMI_INDX_SIZE(hdl);
463    ytbl_top = YOMI_INDX_TOP_ADDR(hdl);
464
465        len = 0;
466        for (i = 0; i < yomi_size; i++) {
467            if (ysize == 2) {
468
469                yidx = *(ydata+i);
470                ytbl = ytbl_top + ((yidx-1) * ysize);
471                len += UTL_CHAR(ytbl);
472
473            } else {
474
475                len++;
476            }
477        }
478
479        return len * sizeof(NJ_CHAR);
480    } else {
481
482        return yomi_size;
483    }
484}
485
486static NJ_UINT16 get_stem_yomi_string(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, NJ_CHAR *yomi, NJ_UINT16 yomi_pos, NJ_UINT16 yomi_size, NJ_UINT16 size)
487{
488    NJ_INT16 ytbl_cnt;
489    NJ_INT8 ysize;
490    NJ_UINT8 *ytbl_top, *ytbl;
491    NJ_UINT8 *ydata;
492    NJ_UINT8 yidx;
493    NJ_UINT16 i;
494    NJ_UINT16 copy_len;
495    NJ_UINT16 char_len;
496
497
498
499    ytbl_cnt = YOMI_INDX_CNT(hdl);
500    ysize    = YOMI_INDX_SIZE(hdl);
501    ytbl_top = YOMI_INDX_TOP_ADDR(hdl);
502
503
504    ydata = stem_data + yomi_pos;
505
506    if (ytbl_cnt) {
507        copy_len = 0;
508        for (i = 0; i < yomi_size; i++) {
509
510            yidx = *(ydata + i);
511            ytbl = ytbl_top + ((yidx - 1) * ysize);
512            if (ysize == 2) {
513
514                char_len = UTL_CHAR(ytbl);
515                if (((copy_len + char_len + NJ_TERM_LEN) * sizeof(NJ_CHAR)) > size) {
516                    return size;
517                }
518                while (char_len > 0) {
519                    NJ_CHAR_COPY(yomi + copy_len, ytbl);
520                    copy_len++;
521                    char_len--;
522                    ytbl += sizeof(NJ_CHAR);
523                }
524            } else {
525
526                if (((copy_len + 1 + NJ_TERM_LEN) * sizeof(NJ_CHAR)) > size) {
527                    return size;
528                }
529
530                *(yomi + copy_len) = (NJ_CHAR)(*ytbl);
531                copy_len++;
532            }
533        }
534    } else {
535        if ((yomi_size + (NJ_TERM_LEN * sizeof(NJ_CHAR))) > size) {
536            return size;
537        }
538
539        nj_memcpy((NJ_UINT8*)yomi, ydata, yomi_size);
540        copy_len = yomi_size / sizeof(NJ_CHAR);
541    }
542
543
544    *(yomi + copy_len) = NJ_CHAR_NUL;
545
546
547    return copy_len;
548}
549
550static NJ_INT16 search_node(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset)
551{
552    NJ_UINT8 *root, *now, *node, *node_mid;
553    NJ_UINT8 index;
554    NJ_UINT8 *byomi;
555    NJ_UINT8 *wkc;
556    NJ_UINT8 idx_no;
557    NJ_INT16 idx;
558    NJ_INT16 char_size;
559    NJ_INT16 left, right, mid;
560    NJ_INT16 ytbl_cnt;
561    NJ_UINT16 c, d;
562    NJ_UINT8  c1 = 0, c2 = 0;
563    NJ_UINT16 y;
564    NJ_UINT16 ysize = (condition->ylen * sizeof(NJ_CHAR));
565    NJ_UINT8 *ytbl_top;
566    NJ_UINT16 idx_cnt;
567    NJ_UINT16 nd_index;
568    NJ_UINT16 bit_left, bit_data;
569    NJ_UINT32 data_offset;
570    NJ_UINT16 data;
571    NJ_UINT16 pos, j, bit_all, bit_tmp, bit_idx;
572    NJ_UINT32 data_l;
573    NJ_UINT8 restart_flg = 0;
574    NJ_UINT8 bottom_flg = 0;
575    NJ_UINT8 *data_top, *stem_data;
576    NJ_UINT16 hindo, hindo_max;
577    NJ_UINT32 current,hindo_max_data, bottom, next;
578
579
580    node = NULL;
581
582    byomi = (NJ_UINT8*)(condition->yomi);
583
584
585    root = NODE_AREA_TOP_ADDR(loctset->loct.handle);
586
587
588    node_mid = root + NODE_AREA_MID_ADDR(loctset->loct.handle);
589    now = node_mid;
590
591
592    idx_no = 0;
593    idx_cnt = 1;
594
595    bit_left = BIT_NODE_AREA_LEFT_LEN(loctset->loct.handle);
596    bit_data = BIT_NODE_AREA_DATA_LEN(loctset->loct.handle);
597
598    ytbl_cnt = YOMI_INDX_CNT(loctset->loct.handle);
599    y = YOMI_INDX_SIZE(loctset->loct.handle);
600    ytbl_top = YOMI_INDX_TOP_ADDR(loctset->loct.handle);
601
602    data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle);
603
604
605    if ((condition->operation == NJ_CUR_OP_FORE) &&
606        NJ_CHAR_STRLEN_IS_0(condition->yomi)) {
607
608        ysize = 0;
609
610
611        node = root;
612    }
613
614
615    while (ysize > 0) {
616        if (ytbl_cnt != 0) {
617            char_size = UTL_CHAR(byomi) * sizeof(NJ_CHAR);
618            if (char_size > 2) {
619                loctset->loct.status = NJ_ST_SEARCH_END_EXT;
620                return 0;
621            }
622
623            if (char_size == 2) {
624                if (y == 1) {
625                    return 0;
626                }
627                c1 = *byomi;
628                c2 = *(byomi + 1);
629                c = (NJ_UINT16)((c1 << 8) | c2);
630            } else {
631
632                c1 = *byomi;
633                c2 = 0x00;
634                c = (NJ_UINT16)(*byomi);
635            }
636
637            idx = -1;
638            left = 0;
639            right = ytbl_cnt;
640
641            if (y == 2) {
642                while (left <= right) {
643                    mid = (left + right) >> 1;
644                    wkc = ytbl_top + (mid << 1);
645
646                    if (c1 == *wkc) {
647                        if (c2 == *(wkc + 1)) {
648                            idx = (NJ_UINT16)(mid + 1);
649                            break;
650                        }
651                        if (c2 < *(wkc + 1)) {
652                            right = mid - 1;
653                        } else {
654                            left = mid + 1;
655                        }
656                    } else if (c1 < *wkc) {
657                        right = mid - 1;
658                    } else {
659                        left = mid + 1;
660                    }
661                }
662            } else {
663                while (left <= right) {
664                    mid = (left + right) >> 1;
665                    wkc = ytbl_top + (mid * y);
666                    d = (NJ_UINT16)(*wkc);
667                    if (c == d) {
668                        idx = (NJ_UINT16)(mid + 1);
669                        break;
670                    }
671                    if (c < d) {
672                        right = mid - 1;
673                    } else {
674                        left = mid + 1;
675                    }
676                }
677            }
678
679            if (idx < 0) {
680                loctset->loct.status = NJ_ST_SEARCH_END_EXT;
681                return 0;
682            }
683            index = (NJ_UINT8)idx;
684        } else {
685            index = *byomi;
686            char_size = 1;
687        }
688
689        byomi += char_size;
690        ysize -= char_size;
691
692        while (now < data_top) {
693            if (NODE_IDX_EXIST(now)) {
694                bit_idx = 8;
695                idx_cnt = NODE_IDX_CNT(now);
696            } else {
697                bit_idx = 4;
698                idx_cnt = 1;
699            }
700            bit_all = bit_idx;
701
702
703            if (NODE_LEFT_EXIST(now)) {
704                bit_all += bit_left;
705            }
706
707
708            if (NODE_DATA_EXIST(now)) {
709                bit_all += bit_data;
710            }
711
712            bit_tmp = bit_all;
713
714
715            bit_all += (NJ_UINT16)(idx_no << 3);
716
717
718            pos = (NJ_UINT16)(bit_all >> 3);
719
720            data = (NJ_UINT16)(NJ_INT16_READ(now + pos));
721
722
723            j = (NJ_UINT16)(bit_all & 0x0007);
724
725            nd_index = GET_BITFIELD_16(data, j, INDEX_BIT);
726            if (index == (NJ_UINT8)nd_index) {
727
728                break;
729            } else {
730                if ((!NODE_TERM(now)) && (index > (NJ_UINT8)nd_index) && (idx_no == 0)) {
731
732                    now += GET_BIT_TO_BYTE(bit_tmp + (idx_cnt * 8));
733                    if (now == node_mid) {
734                        loctset->loct.status = NJ_ST_SEARCH_END_EXT;
735                        return 0;
736                    }
737                    continue;
738                } else {
739                    if ((now == node_mid) && (restart_flg == 0) &&
740                        (index < (NJ_UINT8)nd_index) && (idx_no == 0) &&
741                        (root != node_mid)) {
742                        now = root;
743                        idx_no = 0;
744                        restart_flg = 1;
745                        continue;
746                    }
747                    loctset->loct.status = NJ_ST_SEARCH_END_EXT;
748                    return 0;
749                }
750            }
751        }
752
753        if ( (idx_cnt > (NJ_UINT16)(idx_no + 1))) {
754            if (ysize == 0) {
755                if (condition->operation == NJ_CUR_OP_FORE) {
756
757                    node = now;
758                    break;
759                }
760                loctset->loct.status = NJ_ST_SEARCH_END;
761                return 0;
762            }
763            idx_no++;
764            continue;
765        }
766        node = now;
767        idx_no = 0;
768
769        if (ysize == 0) {
770            break;
771        } else {
772            if (!(NODE_LEFT_EXIST(now))) {
773                loctset->loct.status = NJ_ST_SEARCH_END_EXT;
774                return 0;
775            }
776        }
777
778        if (NODE_IDX_EXIST(now)) {
779            bit_idx = 8;
780        } else {
781            bit_idx = 4;
782        }
783        pos = (NJ_UINT16)(bit_idx >> 3);
784        data_l = (NJ_UINT32)(NJ_INT32_READ(now + pos));
785
786
787        j = (NJ_UINT16)(bit_idx & 0x0007);
788
789        now += GET_BITFIELD_32(data_l, j, bit_left);
790    }
791
792
793    now = node;
794
795
796    if ((node == NULL) || !(NODE_DATA_EXIST(node))) {
797
798        if ((condition->operation == NJ_CUR_OP_FORE) &&
799            (node != NULL)) {
800            while (!NODE_DATA_EXIST(node)) {
801                if (!(NODE_LEFT_EXIST(node))) {
802                    loctset->loct.status = NJ_ST_SEARCH_END;
803                    return 0;
804                }
805
806                if (NODE_IDX_EXIST(node)) {
807                    bit_idx = 8;
808                } else {
809                    bit_idx = 4;
810                }
811                pos = (NJ_UINT16)(bit_idx >> 3);
812                data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos));
813
814
815                j = (NJ_UINT16)(bit_idx & 0x0007);
816                node += GET_BITFIELD_32(data_l, j, bit_left);
817            }
818        } else {
819            loctset->loct.status = NJ_ST_SEARCH_END;
820            return 0;
821        }
822    }
823
824    if (NODE_IDX_EXIST(node)) {
825        bit_idx = 8;
826    } else {
827        bit_idx = 4;
828    }
829
830
831    if (NODE_LEFT_EXIST(node)) {
832        bit_all = bit_idx + bit_left;
833    } else {
834        bit_all = bit_idx;
835    }
836
837    pos = (NJ_UINT16)(bit_all >> 3);
838    data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos));
839
840
841    j = (NJ_UINT16)(bit_all & 0x0007);
842    data_offset = GET_BITFIELD_32(data_l, j, bit_data);
843
844    loctset->loct.top = data_offset;
845    loctset->loct.current = 0;
846
847    if (condition->operation == NJ_CUR_OP_FORE) {
848
849        bottom = loctset->loct.top;
850
851        if (NJ_CHAR_STRLEN_IS_0(condition->yomi)) {
852            node = node_mid;
853
854        } else {
855
856            node = now;
857            if (NODE_LEFT_EXIST(node)) {
858                if (NODE_IDX_EXIST(node)) {
859                    bit_all = 8;
860                } else {
861                    bit_all = 4;
862                }
863
864                pos = (NJ_UINT16)(bit_all >> 3);
865                data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos));
866
867
868                j = (NJ_UINT16)(bit_all & 0x0007);
869                node += GET_BITFIELD_32(data_l, j, bit_left);
870
871            } else {
872                bottom_flg = 1;
873            }
874        }
875
876        if (!bottom_flg) {
877            while (node < data_top) {
878
879                if (!NODE_TERM(node)) {
880
881                    if (NODE_IDX_EXIST(node)) {
882                        bit_all = 8;
883                        idx_cnt = NODE_IDX_CNT(node);
884                    } else {
885                        bit_all = 4;
886                        idx_cnt = 1;
887                    }
888
889
890                    if (NODE_LEFT_EXIST(node)) {
891                        bit_all += bit_left;
892                    }
893
894
895                    if (NODE_DATA_EXIST(node)) {
896                        bit_all += bit_data;
897                    }
898
899
900                    node += GET_BIT_TO_BYTE(bit_all + (idx_cnt * 8));
901                } else {
902
903                    if (!NODE_LEFT_EXIST(node)) {
904
905                        if (NODE_DATA_EXIST(node)) {
906
907                            if (NODE_IDX_EXIST(node)) {
908                                bit_all = 8;
909                            } else {
910                                bit_all = 4;
911                            }
912
913                            pos = (NJ_UINT16)(bit_all >> 3);
914                            data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos));
915
916
917                            j = (NJ_UINT16)(bit_all & 0x0007);
918                            data_offset = GET_BITFIELD_32(data_l, j, bit_data);
919
920                            bottom = data_offset;
921                            break;
922                        } else {
923                            return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_DIC_BROKEN);
924                        }
925
926                    } else {
927
928                        if (NODE_IDX_EXIST(node)) {
929                            bit_all = 8;
930                        } else {
931                            bit_all = 4;
932                        }
933
934                        pos = (NJ_UINT16)(bit_all >> 3);
935                        data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos));
936
937
938                        j = (NJ_UINT16)(bit_all & 0x0007);
939
940
941                        node += GET_BITFIELD_32(data_l, j, bit_left);
942                    }
943                }
944            }
945        }
946
947        stem_data = data_top + bottom;
948
949        while (!(STEM_TERMINETER(stem_data))) {
950            next = get_stem_next(loctset->loct.handle, stem_data);
951            stem_data += next;
952        }
953        loctset->loct.bottom = (NJ_UINT32)(stem_data - data_top);
954
955
956        stem_data = data_top + loctset->loct.top;
957
958        hindo = (NJ_UINT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
959                                          + get_stem_hindo(loctset->loct.handle, stem_data)));
960
961        hindo_max = hindo;
962        hindo_max_data = 0;
963
964        if (condition->mode == NJ_CUR_MODE_FREQ) {
965
966
967            j = get_stem_next(loctset->loct.handle, stem_data);
968            current = j;
969            stem_data += j;
970
971            while (stem_data <= (data_top + loctset->loct.bottom)) {
972
973
974                hindo = (NJ_UINT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
975                                                  + get_stem_hindo(loctset->loct.handle, stem_data)));
976
977
978                if (hindo > hindo_max) {
979                    hindo_max = hindo;
980                    hindo_max_data = current;
981                }
982
983
984                j = get_stem_next(loctset->loct.handle, stem_data);
985                current += j;
986                stem_data += j;
987            }
988        }
989        loctset->cache_freq = CALCULATE_HINDO(hindo_max, loctset->dic_freq.base,
990                                              loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
991        loctset->loct.current = hindo_max_data;
992
993    }
994
995    return 1;
996}
997
998static NJ_INT16 bdic_search_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset)
999{
1000    NJ_UINT8 *data, *data_end;
1001    NJ_INT16 i, current = 0;
1002    NJ_UINT16 hindo;
1003
1004
1005    data = STEM_AREA_TOP_ADDR(loctset->loct.handle);
1006    data += loctset->loct.top + loctset->loct.current;
1007
1008    if (GET_LOCATION_STATUS(loctset->loct.status) != NJ_ST_SEARCH_NO_INIT) {
1009
1010        if (STEM_TERMINETER(data)) {
1011
1012            loctset->loct.status = NJ_ST_SEARCH_END;
1013            return 0;
1014        }
1015
1016
1017        i = get_stem_next(loctset->loct.handle, data);
1018
1019        data += i;
1020        current += i;
1021    }
1022
1023    if (NJ_GET_DIC_FMT(loctset->loct.handle) == NJ_DIC_FMT_KANAKAN) {
1024        data_end = loctset->loct.handle
1025            + NJ_DIC_COMMON_HEADER_SIZE
1026            + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_DATA_SIZE)
1027            + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_EXT_SIZE)
1028            - NJ_DIC_ID_LEN;
1029    } else {
1030        data_end = CAND_IDX_AREA_TOP_ADDR(loctset->loct.handle);
1031    }
1032
1033    if (data < data_end) {
1034
1035        loctset->loct.status = NJ_ST_SEARCH_READY;
1036        loctset->loct.current += current;
1037        hindo = (NJ_UINT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle) +
1038                                          get_stem_hindo(loctset->loct.handle, data)));
1039        loctset->cache_freq = CALCULATE_HINDO(hindo, loctset->dic_freq.base,
1040                                              loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
1041        return 1;
1042    }
1043
1044    loctset->loct.status = NJ_ST_SEARCH_END;
1045    return 0;
1046}
1047
1048static NJ_INT16 bdic_search_fore_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset)
1049{
1050    NJ_UINT8 *data, *data_top, *bottom, *data_end;
1051    NJ_INT16 i = 0;
1052    NJ_INT16 hindo = 0;
1053    NJ_INT16 hindo_max = -1;
1054    NJ_UINT8 no_hit = 0;
1055    NJ_UINT32 current = loctset->loct.current;
1056    NJ_UINT8 *current_org;
1057    NJ_UINT32 hindo_data = 0;
1058
1059
1060
1061    if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) {
1062        loctset->loct.status = NJ_ST_SEARCH_READY;
1063        loctset->loct.current_info = CURRENT_INFO_SET;
1064        return 1;
1065    }
1066
1067
1068    data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle);
1069
1070
1071    data = data_top + loctset->loct.top + loctset->loct.current;
1072
1073
1074    current_org = data;
1075
1076
1077    bottom = data_top + loctset->loct.bottom;
1078
1079    if (NJ_GET_DIC_FMT(loctset->loct.handle) == NJ_DIC_FMT_KANAKAN) {
1080        data_end = loctset->loct.handle
1081            + NJ_DIC_COMMON_HEADER_SIZE
1082            + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_DATA_SIZE)
1083            + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_EXT_SIZE)
1084            - NJ_DIC_ID_LEN;
1085    } else {
1086        data_end = CAND_IDX_AREA_TOP_ADDR(loctset->loct.handle);
1087    }
1088
1089    if (condition->mode == NJ_CUR_MODE_FREQ) {
1090
1091
1092
1093        while (data < data_end) {
1094
1095            i = get_stem_next(loctset->loct.handle, data);
1096            data += i;
1097            current += i;
1098
1099
1100            if (data > bottom) {
1101                if (loctset->cache_freq == 0) {
1102
1103                    loctset->loct.status = NJ_ST_SEARCH_END;
1104                    return 0;
1105                } else if (no_hit == 1) {
1106
1107                    loctset->loct.status = NJ_ST_SEARCH_END;
1108                    return 0;
1109                }
1110
1111                loctset->cache_freq -= 1;
1112
1113
1114                data = data_top + loctset->loct.top;
1115                current = 0;
1116
1117                no_hit = 1;
1118            }
1119
1120
1121            if ((hindo_max != -1) && (data == current_org)) {
1122                loctset->loct.status = NJ_ST_SEARCH_READY;
1123                loctset->loct.current_info = CURRENT_INFO_SET;
1124                loctset->loct.current = hindo_data;
1125                loctset->cache_freq = hindo_max;
1126                return 1;
1127            }
1128
1129
1130            hindo = (NJ_INT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data)));
1131
1132            hindo = CALCULATE_HINDO(hindo, loctset->dic_freq.base,
1133                                    loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
1134
1135
1136            if (hindo == loctset->cache_freq) {
1137                loctset->loct.status = NJ_ST_SEARCH_READY;
1138                loctset->loct.current_info = CURRENT_INFO_SET;
1139                loctset->loct.current = current;
1140                return 1;
1141            }
1142
1143            if (hindo < loctset->cache_freq) {
1144                if (((hindo == hindo_max) && (current < hindo_data)) ||
1145                    (hindo > hindo_max)) {
1146                    hindo_max = hindo;
1147                    hindo_data = current;
1148                }
1149            }
1150        }
1151    } else {
1152
1153
1154
1155        i = get_stem_next(loctset->loct.handle, data);
1156        data += i;
1157        current += i;
1158
1159
1160        if (data > bottom) {
1161
1162            loctset->loct.status = NJ_ST_SEARCH_END;
1163            return 0;
1164        }
1165
1166
1167        hindo = (NJ_INT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
1168                                         + get_stem_hindo(loctset->loct.handle, data)));
1169        loctset->cache_freq = CALCULATE_HINDO(hindo, loctset->dic_freq.base,
1170                                              loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
1171        loctset->loct.status = NJ_ST_SEARCH_READY;
1172        loctset->loct.current_info = CURRENT_INFO_SET;
1173        loctset->loct.current = current;
1174        return 1;
1175    }
1176
1177    loctset->loct.status = NJ_ST_SEARCH_END;
1178    return 0;
1179}
1180
1181NJ_INT16 njd_b_search_word(NJ_SEARCH_CONDITION *con, NJ_SEARCH_LOCATION_SET *loctset)
1182{
1183    NJ_INT16 ret;
1184    NJ_DIC_INFO *pdicinfo;
1185    NJ_UINT16 hIdx;
1186
1187
1188
1189
1190    switch (con->operation) {
1191    case NJ_CUR_OP_COMP:
1192
1193        if (con->mode != NJ_CUR_MODE_FREQ) {
1194
1195            loctset->loct.status = NJ_ST_SEARCH_END_EXT;
1196            return 0;
1197        }
1198        break;
1199    case NJ_CUR_OP_FORE:
1200
1201        if (APPEND_YOMI_FLG(loctset->loct.handle) == 0) {
1202            loctset->loct.status = NJ_ST_SEARCH_END_EXT;
1203            return 0;
1204        }
1205
1206        if ((NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle) != NJ_DIC_TYPE_CUSTOM_COMPRESS)
1207            && NJ_CHAR_STRLEN_IS_0(con->yomi)) {
1208            loctset->loct.status = NJ_ST_SEARCH_END_EXT;
1209            return 0;
1210        }
1211        break;
1212    default:
1213
1214        loctset->loct.status = NJ_ST_SEARCH_END_EXT;
1215        return 0;
1216    }
1217
1218    if (con->ylen > NJ_GET_MAX_YLEN(loctset->loct.handle)) {
1219        loctset->loct.status = NJ_ST_SEARCH_END_EXT;
1220        return 0;
1221    }
1222
1223    if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) {
1224
1225
1226        switch (con->operation) {
1227        case NJ_CUR_OP_COMP:
1228            ret = search_node(con, loctset);
1229            if (ret < 1) {
1230                return ret;
1231            }
1232            ret = bdic_search_data(con, loctset);
1233            if (ret < 1) {
1234
1235                loctset->loct.status = NJ_ST_SEARCH_END;
1236            }
1237            break;
1238        case NJ_CUR_OP_FORE:
1239            pdicinfo = con->ds->dic;
1240            for (hIdx = 0; (hIdx < NJ_MAX_DIC) && (pdicinfo->handle != loctset->loct.handle); hIdx++) {
1241                pdicinfo++;
1242            }
1243
1244            if (hIdx == NJ_MAX_DIC) {
1245
1246                loctset->loct.status = NJ_ST_SEARCH_END;
1247                return 0;
1248            }
1249
1250            if ((con->ds->dic[hIdx].srhCache == NULL) || (con->ylen == 0) ||
1251                !(con->ds->mode & 0x0001)) {
1252                ret = search_node(con, loctset);
1253                if (ret < 1) {
1254                    return ret;
1255                }
1256                ret = bdic_search_fore_data(con, loctset);
1257            } else {
1258                ret = search_node2(con, loctset, hIdx);
1259                if (ret == NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH)) {
1260
1261                    NJ_SET_CACHEOVER_TO_SCACHE(con->ds->dic[hIdx].srhCache);
1262                    ret = search_node2(con, loctset, hIdx);
1263                }
1264                if (ret < 1) {
1265                    return ret;
1266                }
1267                ret = bdic_search_fore_data2(con, loctset, hIdx);
1268            }
1269            if (ret < 1) {
1270
1271                loctset->loct.status = NJ_ST_SEARCH_END;
1272            }
1273            break;
1274        default:
1275            loctset->loct.status = NJ_ST_SEARCH_END_EXT;
1276            return 0;
1277        }
1278    } else if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY) {
1279
1280        switch (con->operation) {
1281        case NJ_CUR_OP_COMP:
1282            ret = bdic_search_data(con, loctset);
1283            if (ret < 1) {
1284
1285                loctset->loct.status = NJ_ST_SEARCH_END;
1286            }
1287            break;
1288        case NJ_CUR_OP_FORE:
1289            pdicinfo = con->ds->dic;
1290            for (hIdx = 0; (hIdx < NJ_MAX_DIC) && (pdicinfo->handle != loctset->loct.handle); hIdx++) {
1291                pdicinfo++;
1292            }
1293
1294            if (hIdx == NJ_MAX_DIC) {
1295
1296                loctset->loct.status = NJ_ST_SEARCH_END;
1297                return 0;
1298            }
1299
1300            if ((con->ds->dic[hIdx].srhCache == NULL) || (con->ylen == 0) ||
1301                !(con->ds->mode & 0x0001)) {
1302                ret = bdic_search_fore_data(con, loctset);
1303            } else {
1304                ret = bdic_search_fore_data2(con, loctset, hIdx);
1305            }
1306            if (ret < 1) {
1307
1308                loctset->loct.status = NJ_ST_SEARCH_END;
1309            }
1310            break;
1311        default:
1312            loctset->loct.status = NJ_ST_SEARCH_END;
1313            return 0;
1314        }
1315    } else {
1316        loctset->loct.status = NJ_ST_SEARCH_END;
1317        return 0;
1318    }
1319    return ret;
1320}
1321
1322NJ_INT16 njd_b_get_word(NJ_SEARCH_LOCATION_SET *loctset, NJ_WORD *word)
1323{
1324    NJ_UINT8 *data;
1325    STEM_DATA_SET stem_set;
1326    NJ_UINT8 check;
1327
1328
1329
1330
1331    if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END) {
1332        return 0;
1333    }
1334
1335	if (GET_LOCATION_OPERATION(loctset->loct.status) == NJ_CUR_OP_FORE) {
1336        data = STEM_AREA_TOP_ADDR(loctset->loct.handle);
1337        data += loctset->loct.top + loctset->loct.current;
1338
1339
1340        check = 0;
1341    } else {
1342
1343
1344
1345        data = STEM_AREA_TOP_ADDR(loctset->loct.handle);
1346        data += loctset->loct.top + loctset->loct.current;
1347
1348
1349        check = 2;
1350    }
1351
1352
1353    get_stem_word(loctset->loct.handle, data, &stem_set, check);
1354
1355    if (GET_LOCATION_OPERATION(loctset->loct.status) == NJ_CUR_OP_FORE) {
1356        word->stem.info1 = (NJ_UINT16)(stem_set.yomi_size / sizeof(NJ_CHAR));
1357    }
1358    word->stem.info1 = WORD_LEN(word->stem.info1);
1359    word->stem.info1 |= (NJ_UINT16)(stem_set.fhinsi_jitu << 7);
1360
1361    if (check != 1) {
1362        if (stem_set.candidate_size == 0) {
1363
1364            if (GET_LOCATION_OPERATION(loctset->loct.status) == NJ_CUR_OP_FORE) {
1365                word->stem.info2 = (NJ_UINT16)(stem_set.yomi_size / sizeof(NJ_CHAR));
1366            } else {
1367
1368                word->stem.info2 = (NJ_UINT16)NJ_GET_YLEN_FROM_STEM(word);
1369            }
1370        } else {
1371
1372            word->stem.info2 = (NJ_UINT16)(stem_set.candidate_size / sizeof(NJ_CHAR));
1373        }
1374    } else {
1375
1376        word->stem.info2 = (NJ_UINT16)NJ_GET_YLEN_FROM_STEM(word);
1377    }
1378
1379    word->stem.info2 = WORD_LEN(word->stem.info2);
1380    word->stem.info2 |= (NJ_UINT16)(stem_set.bhinsi_jitu << 7);
1381    word->stem.hindo = CALCULATE_HINDO(stem_set.hindo_jitu, loctset->dic_freq.base,
1382                                       loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
1383    word->stem.loc = loctset->loct;
1384
1385    return 1;
1386}
1387
1388NJ_INT16 njd_b_get_candidate(NJ_WORD *word, NJ_CHAR *candidate, NJ_UINT16 size)
1389{
1390    NJ_SEARCH_LOCATION *loc;
1391    NJ_CHAR  *wkc, *cand;
1392    NJ_UINT8  *wkd;
1393    NJ_UINT8 *data;
1394    NJ_UINT8 *data_org;
1395    NJ_UINT16 len, j;
1396    STEM_DATA_SET stem_set;
1397    NJ_INT16  next;
1398    NJ_UINT16 yomi_pos;
1399    NJ_CHAR   ybuf[NJ_MAX_LEN + NJ_TERM_LEN];
1400
1401
1402
1403
1404    if ((GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_COMP) ||
1405        (GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_FORE)) {
1406
1407
1408        loc = &word->stem.loc;
1409        data = STEM_AREA_TOP_ADDR(loc->handle);
1410        data += loc->top + loc->current;
1411
1412
1413        get_stem_cand_data(loc->handle, data, &stem_set);
1414        len = stem_set.candidate_size / sizeof(NJ_CHAR);
1415
1416    } else {
1417
1418        return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_INVALID_RESULT);
1419    }
1420
1421    if (len == 0) {
1422        data_org = data;
1423
1424        if (GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_COMP) {
1425
1426            len = WORD_LEN(word->stem.info1);
1427            if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) {
1428                return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH);
1429            }
1430            wkc = word->yomi;
1431        } else {
1432
1433
1434
1435            while (!(STEM_TERMINETER(data))) {
1436                next = get_stem_next(loc->handle, data);
1437                data += next;
1438            }
1439
1440
1441            yomi_pos = get_stem_yomi_data(loc->handle, data, &stem_set);
1442
1443
1444            wkc = ybuf;
1445            len = get_stem_yomi_string(loc->handle, data, wkc,
1446                                       yomi_pos, stem_set.yomi_size,
1447                                       size);
1448
1449
1450            if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) {
1451                return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH);
1452            }
1453        }
1454
1455        if (STEM_NO_CONV_FLG(data_org) == 0) {
1456            cand = candidate;
1457            for (j = 0; j < len; j++) {
1458                *cand++ = *wkc++;
1459            }
1460            *cand = NJ_CHAR_NUL;
1461        } else {
1462            nje_convert_hira_to_kata(wkc, candidate, len);
1463        }
1464
1465    } else {
1466
1467        if (size < (stem_set.candidate_size + (NJ_TERM_LEN*sizeof(NJ_CHAR)))) {
1468            return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH);
1469        }
1470        wkc = candidate;
1471        wkd = data + stem_set.stem_size;
1472        for (j = 0; j < len; j++) {
1473            NJ_CHAR_COPY(wkc, wkd);
1474            wkd += sizeof(NJ_CHAR);
1475            wkc++;
1476        }
1477        *wkc = NJ_CHAR_NUL;
1478    }
1479
1480    return len;
1481}
1482
1483NJ_INT16 njd_b_get_stroke(NJ_WORD *word, NJ_CHAR *stroke, NJ_UINT16 size)
1484{
1485    NJ_SEARCH_LOCATION *loc;
1486    NJ_UINT8 *data;
1487    NJ_INT16 len;
1488    NJ_INT16 next;
1489    NJ_UINT16 yomi_pos;
1490    STEM_DATA_SET stem_set;
1491
1492
1493
1494
1495    if (GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_FORE) {
1496        if (NJ_GET_YLEN_FROM_STEM(word) == 0) {
1497
1498            return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_INVALID_RESULT);
1499        }
1500
1501
1502        loc = &word->stem.loc;
1503
1504        data = STEM_AREA_TOP_ADDR(loc->handle);
1505        data += loc->top + loc->current;
1506
1507    } else {
1508
1509        return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_INVALID_RESULT);
1510    }
1511
1512
1513    while (!(STEM_TERMINETER(data))) {
1514        next = get_stem_next(loc->handle, data);
1515        data += next;
1516    }
1517
1518
1519    yomi_pos = get_stem_yomi_data(loc->handle, data, &stem_set);
1520    if (stem_set.yomi_size == 0) {
1521
1522        return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_INVALID_RESULT);
1523    }
1524
1525
1526    len = get_stem_yomi_string(loc->handle, data, stroke,
1527                               yomi_pos, stem_set.yomi_size,
1528                               size);
1529
1530
1531    if (size < (NJ_UINT16)((len+NJ_TERM_LEN)*sizeof(NJ_CHAR))) {
1532        return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_BUFFER_NOT_ENOUGH);
1533    }
1534
1535    *(stroke + len) = NJ_CHAR_NUL;
1536    return len;
1537}
1538
1539static NJ_INT16 search_node2(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 hidx)
1540{
1541    NJ_UINT8 *root, *now, *node, *node_mid;
1542    NJ_CHAR  *yomi;
1543
1544    NJ_INT16 ytbl_cnt;
1545    NJ_UINT16 y;
1546    NJ_UINT8 *ytbl_top;
1547
1548    NJ_UINT16 bit_left, bit_data;
1549    NJ_UINT32 data_offset;
1550    NJ_UINT16 j;
1551    NJ_UINT8 *data_top, *stem_data;
1552    NJ_UINT16 hindo, hindo_max, hindo_tmp;
1553    NJ_UINT32 current, hindo_max_data, hindo_tmp_data;
1554
1555
1556    NJ_SEARCH_CACHE *psrhCache = condition->ds->dic[hidx].srhCache;
1557    NJ_CHAR  *key;
1558    NJ_UINT8 cmpflg;
1559    NJ_UINT8 endflg;
1560    NJ_UINT16 abPtrIdx;
1561    NJ_UINT16 key_len;
1562    NJ_UINT16 i, l, m;
1563    NJ_UINT16 abIdx;
1564    NJ_UINT16 abIdx_current;
1565    NJ_UINT16 abIdx_old;
1566    NJ_UINT16 addcnt = 0;
1567    NJ_CHAR   char_tmp[NJ_MAX_LEN + NJ_TERM_LEN];
1568    NJ_UINT16 tmp_len;
1569    NJ_UINT16 endIdx;
1570    NJ_INT16 ret;
1571    NJ_UINT8 *con_node;
1572    NJ_UINT16 yomi_clen;
1573    NJ_UINT8 aimai_flg = 0x01;
1574    NJ_CHAR  key_tmp[NJ_MAX_CHAR_LEN + NJ_TERM_LEN];
1575    NJ_CACHE_INFO tmpbuff;
1576
1577
1578    if (NJ_GET_CACHEOVER_FROM_SCACHE(psrhCache)) {
1579        aimai_flg = 0x00;
1580    }
1581
1582    node = NULL;
1583
1584    yomi = condition->yomi;
1585
1586
1587    root = NODE_AREA_TOP_ADDR(loctset->loct.handle);
1588
1589
1590    node_mid = root + NODE_AREA_MID_ADDR(loctset->loct.handle);
1591    now = node_mid;
1592
1593    bit_left = BIT_NODE_AREA_LEFT_LEN(loctset->loct.handle);
1594    bit_data = BIT_NODE_AREA_DATA_LEN(loctset->loct.handle);
1595
1596    ytbl_cnt = YOMI_INDX_CNT(loctset->loct.handle);
1597    y = YOMI_INDX_SIZE(loctset->loct.handle);
1598    ytbl_top = YOMI_INDX_TOP_ADDR(loctset->loct.handle);
1599
1600    data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle);
1601
1602
1603    endflg = 0x00;
1604    cmpflg = 0x00;
1605    abPtrIdx = 0;
1606    key = condition->ds->keyword;
1607
1608
1609    yomi_clen = condition->yclen;
1610    for (i = 0; i < yomi_clen; i++) {
1611
1612        abPtrIdx = i;
1613
1614
1615        if (!cmpflg) {
1616
1617            if (((abPtrIdx != 0) && (psrhCache->keyPtr[abPtrIdx] == 0))
1618                || (psrhCache->keyPtr[abPtrIdx + 1] == 0)) {
1619
1620                cmpflg = 0x01;
1621            } else {
1622
1623            }
1624        }
1625
1626        addcnt = 0;
1627        if (cmpflg) {
1628
1629            if (abPtrIdx == 0) {
1630
1631                abIdx = 0;
1632
1633                nj_charncpy(key_tmp, yomi, 1);
1634                key_len = nj_strlen(key_tmp);
1635
1636                node = NULL;
1637                now = node_mid;
1638                psrhCache->keyPtr[0] = 0;
1639
1640
1641                ret = search_yomi_node(condition->operation,
1642                                       node, now, 0, key_tmp, key_len,
1643                                       root, node_mid, bit_left, bit_data,
1644                                       data_top, ytbl_cnt, y, ytbl_top,
1645                                       &tmpbuff,
1646                                       &con_node, &data_offset);
1647
1648                if (ret < 0) {
1649
1650                } else {
1651
1652
1653
1654                    psrhCache->storebuff[abIdx] = tmpbuff;
1655
1656
1657                    now = con_node;
1658
1659                    psrhCache->storebuff[abIdx].top = data_offset;
1660
1661                    if (condition->operation == NJ_CUR_OP_FORE) {
1662                        ret = get_node_bottom(key_tmp, now, node_mid, data_top,
1663                                              bit_left, bit_data,
1664                                              psrhCache->storebuff[abIdx].top,
1665                                              loctset->loct.handle,
1666                                              &(psrhCache->storebuff[abIdx].bottom));
1667                        if (ret < 0) {
1668
1669                            return ret;
1670                        }
1671                    }
1672                    addcnt++;
1673                    abIdx++;
1674                }
1675
1676                if ((condition->charset != NULL) && aimai_flg) {
1677
1678                    for (l = 0; l < condition->charset->charset_count; l++) {
1679
1680                        if (nj_charncmp(key, condition->charset->from[l], 1) == 0) {
1681
1682                            nj_strcpy(char_tmp, condition->charset->to[l]);
1683                            tmp_len = nj_strlen(char_tmp);
1684
1685                            node = NULL;
1686                            now = node_mid;
1687
1688
1689                            ret = search_yomi_node(condition->operation,
1690                                                   node, now, 0, char_tmp, tmp_len,
1691                                                   root, node_mid, bit_left, bit_data,
1692                                                   data_top, ytbl_cnt, y, ytbl_top,
1693                                                   &tmpbuff,
1694                                                   &con_node, &data_offset);
1695
1696                            if (ret < 0) {
1697
1698                            } else {
1699
1700
1701
1702                                if (abIdx >= NJ_SEARCH_CACHE_SIZE) {
1703                                    psrhCache->keyPtr[abPtrIdx+1] = 0;
1704                                    return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH);
1705                                }
1706
1707
1708                                psrhCache->storebuff[abIdx] = tmpbuff;
1709
1710
1711                                now = con_node;
1712
1713                                psrhCache->storebuff[abIdx].top = data_offset;
1714
1715                                if (condition->operation == NJ_CUR_OP_FORE) {
1716                                    ret = get_node_bottom(key_tmp, now,
1717                                                          node_mid, data_top,
1718                                                          bit_left, bit_data,
1719                                                          psrhCache->storebuff[abIdx].top,
1720                                                          loctset->loct.handle,
1721                                                          &(psrhCache->storebuff[abIdx].bottom));
1722                                    if (ret < 0) {
1723
1724                                        return ret;
1725                                    }
1726                                }
1727                                addcnt++;
1728                                abIdx++;
1729                            }
1730                        }
1731                    }
1732                }
1733                psrhCache->keyPtr[abPtrIdx + 1] = abIdx;
1734            } else {
1735                nj_charncpy(key_tmp, yomi, 1);
1736                key_len = nj_strlen(key_tmp);
1737
1738                if (psrhCache->keyPtr[abPtrIdx] == psrhCache->keyPtr[abPtrIdx - 1]) {
1739
1740                    psrhCache->keyPtr[abPtrIdx+1] = psrhCache->keyPtr[abPtrIdx-1];
1741                    endflg = 0x01;
1742                } else {
1743                    endIdx = psrhCache->keyPtr[abPtrIdx];
1744                    abIdx_old = psrhCache->keyPtr[abPtrIdx - 1];
1745
1746                    if (NJ_GET_CACHEOVER_FROM_SCACHE(psrhCache)) {
1747                        abIdx = psrhCache->keyPtr[abPtrIdx - 1];
1748                        psrhCache->keyPtr[abPtrIdx] = abIdx;
1749                    } else {
1750                        abIdx = psrhCache->keyPtr[abPtrIdx];
1751                    }
1752
1753                    if ((abIdx > NJ_SEARCH_CACHE_SIZE) || (abIdx_old >= NJ_SEARCH_CACHE_SIZE)
1754                        || (endIdx > NJ_SEARCH_CACHE_SIZE)) {
1755
1756                        return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN);
1757                    }
1758
1759                    for (m = abIdx_old; m < endIdx; m++) {
1760                        node = psrhCache->storebuff[m].node;
1761                        now = psrhCache->storebuff[m].now;
1762
1763                        if ((node == now) && (psrhCache->storebuff[m].idx_no == 0)) {
1764                            continue;
1765                        }
1766
1767
1768                        ret = search_yomi_node(condition->operation,
1769                                               node, now, psrhCache->storebuff[m].idx_no,
1770                                               key_tmp, key_len, root,
1771                                               node_mid, bit_left, bit_data,
1772                                               data_top, ytbl_cnt, y, ytbl_top,
1773                                               &tmpbuff,
1774                                               &con_node, &data_offset);
1775
1776                        if (ret < 0) {
1777
1778                        } else {
1779
1780
1781
1782                            if (abIdx >= NJ_SEARCH_CACHE_SIZE) {
1783                                psrhCache->keyPtr[abPtrIdx+1] = 0;
1784                                return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH);
1785                            }
1786
1787
1788                            psrhCache->storebuff[abIdx] = tmpbuff;
1789
1790
1791                            now = con_node;
1792
1793                            psrhCache->storebuff[abIdx].top = data_offset;
1794
1795                            if (condition->operation == NJ_CUR_OP_FORE) {
1796                                ret = get_node_bottom(key_tmp, now, node_mid, data_top,
1797                                                      bit_left, bit_data,
1798                                                      psrhCache->storebuff[abIdx].top,
1799                                                      loctset->loct.handle,
1800                                                      &(psrhCache->storebuff[abIdx].bottom));
1801
1802                                if (ret < 0) {
1803
1804                                    return ret;
1805                                }
1806                            }
1807                            addcnt++;
1808                            abIdx++;
1809                        }
1810
1811                        if ((condition->charset != NULL) && aimai_flg) {
1812
1813                            for (l = 0; l < condition->charset->charset_count; l++) {
1814
1815                                if (nj_charncmp(key, condition->charset->from[l], 1) == 0) {
1816
1817                                    nj_strcpy(char_tmp, condition->charset->to[l]);
1818
1819                                    tmp_len = nj_strlen(char_tmp);
1820
1821                                    node = psrhCache->storebuff[m].node;
1822                                    now = psrhCache->storebuff[m].now;
1823
1824
1825                                    ret = search_yomi_node(condition->operation,
1826                                                           node, now,
1827                                                           psrhCache->storebuff[m].idx_no,
1828                                                           char_tmp, tmp_len,
1829                                                           root, node_mid,
1830                                                           bit_left, bit_data, data_top,
1831                                                           ytbl_cnt, y, ytbl_top,
1832                                                           &tmpbuff,
1833                                                           &con_node, &data_offset);
1834
1835                                    if (ret < 0) {
1836
1837                                    } else {
1838
1839
1840
1841                                        if (abIdx >= NJ_SEARCH_CACHE_SIZE) {
1842                                            psrhCache->keyPtr[abPtrIdx+1] = 0;
1843                                            return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH);
1844                                        }
1845
1846
1847                                        psrhCache->storebuff[abIdx] = tmpbuff;
1848
1849
1850                                        now = con_node;
1851
1852                                        psrhCache->storebuff[abIdx].top = data_offset;
1853
1854                                        if (condition->operation == NJ_CUR_OP_FORE) {
1855                                            ret = get_node_bottom(key_tmp, now, node_mid,
1856                                                                  data_top, bit_left, bit_data,
1857                                                                  psrhCache->storebuff[abIdx].top,
1858                                                                  loctset->loct.handle,
1859                                                                  &(psrhCache->storebuff[abIdx].bottom));
1860                                            if (ret < 0) {
1861
1862                                                return ret;
1863                                            }
1864                                        }
1865                                        addcnt++;
1866                                        abIdx++;
1867                                    }
1868                                }
1869                            }
1870                        }
1871                    }
1872                    psrhCache->keyPtr[abPtrIdx + 1] = abIdx;
1873                }
1874            }
1875        }
1876        yomi += UTL_CHAR(yomi);
1877        key  += UTL_CHAR(key);
1878    }
1879
1880    if ((addcnt == 0) && (psrhCache->keyPtr[yomi_clen - 1] == psrhCache->keyPtr[yomi_clen])) {
1881        endflg = 0x01;
1882    }
1883
1884    if (endflg) {
1885        loctset->loct.status = NJ_ST_SEARCH_END;
1886        return 0;
1887    }
1888
1889    loctset->loct.current = 0;
1890
1891
1892
1893    abPtrIdx = condition->yclen;
1894
1895
1896    abIdx = psrhCache->keyPtr[abPtrIdx];
1897    abIdx_old = psrhCache->keyPtr[abPtrIdx - 1];
1898    if ((abIdx > NJ_SEARCH_CACHE_SIZE) || (abIdx_old >= NJ_SEARCH_CACHE_SIZE)) {
1899
1900        return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN);
1901    }
1902
1903    if (condition->mode == NJ_CUR_MODE_FREQ) {
1904        hindo_max = 0;
1905        hindo_max_data = 0;
1906        abIdx_current = abIdx_old;
1907
1908
1909        stem_data = data_top + psrhCache->storebuff[abIdx_current].top;
1910
1911        hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) +
1912                                           get_stem_hindo(loctset->loct.handle, stem_data)));
1913
1914        hindo_tmp = 0;
1915        hindo_tmp_data = 0;
1916        current = 0;
1917
1918
1919        while (stem_data <= (data_top + psrhCache->storebuff[abIdx_current].bottom)) {
1920
1921            if (hindo > hindo_tmp) {
1922                hindo_tmp = hindo;
1923                hindo_tmp_data = current;
1924            }
1925
1926
1927            j = get_stem_next(loctset->loct.handle, stem_data);
1928            current += j;
1929            stem_data += j;
1930
1931
1932            hindo = (NJ_UINT16) *((NJ_UINT8 *) (HINDO_NO_TOP_ADDR(loctset->loct.handle) +
1933                                                get_stem_hindo(loctset->loct.handle, stem_data)));
1934
1935        }
1936
1937
1938        psrhCache->storebuff[abIdx_current].current = hindo_tmp_data;
1939
1940
1941        if (hindo_tmp > hindo_max) {
1942            hindo_max = hindo_tmp;
1943            hindo_max_data = hindo_tmp_data;
1944        }
1945    } else {
1946
1947        abIdx_current = abIdx_old;
1948
1949
1950        stem_data = data_top + psrhCache->storebuff[abIdx_current].top;
1951
1952        hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
1953                                           + get_stem_hindo(loctset->loct.handle, stem_data)));
1954
1955        hindo_max = hindo;
1956        hindo_max_data = 0;
1957    }
1958
1959
1960    loctset->loct.top = psrhCache->storebuff[abIdx_current].top;
1961    loctset->loct.bottom = psrhCache->storebuff[abIdx_current].bottom;
1962
1963    loctset->cache_freq = CALCULATE_HINDO(hindo_max, loctset->dic_freq.base,
1964                                          loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
1965    loctset->loct.current = hindo_max_data;
1966    loctset->loct.current_cache = (NJ_UINT8)abIdx_current;
1967
1968
1969    psrhCache->viewCnt = 1;
1970    NJ_SET_AIMAI_TO_SCACHE(psrhCache);
1971
1972    return 1;
1973}
1974
1975static NJ_INT16 search_yomi_node(NJ_UINT8 operation, NJ_UINT8 *node, NJ_UINT8 *now,
1976                                 NJ_UINT16 idx_no, NJ_CHAR  *yomi, NJ_UINT16 yomilen,
1977                                 NJ_UINT8 * root, NJ_UINT8 * node_mid,
1978                                 NJ_UINT16 bit_left, NJ_UINT16 bit_data,
1979                                 NJ_UINT8 * data_top,
1980                                 NJ_INT16 ytbl_cnt, NJ_UINT16 y, NJ_UINT8 * ytbl_top,
1981                                 NJ_CACHE_INFO * storebuf,
1982                                 NJ_UINT8 ** con_node,
1983                                 NJ_UINT32 * data_offset)
1984{
1985
1986    NJ_UINT8 index;
1987    NJ_UINT8 *wkc;
1988    NJ_UINT8 *byomi;
1989    NJ_INT16 idx;
1990    NJ_INT16 char_size;
1991    NJ_INT16 left, right, mid;
1992    NJ_UINT16 c, d;
1993    NJ_UINT8 c1 = 0, c2 = 0;
1994    NJ_UINT16 ysize = yomilen * sizeof(NJ_CHAR);
1995    NJ_UINT16 idx_cnt;
1996    NJ_UINT16 nd_index;
1997    NJ_UINT16 data;
1998    NJ_UINT16 pos, j, bit_all, bit_tmp, bit_idx;
1999    NJ_UINT32 data_l;
2000    NJ_UINT8 restart_flg = 0;
2001
2002
2003    *con_node = NULL;
2004
2005
2006    idx_cnt = 1;
2007    storebuf->idx_no = 0;
2008
2009    byomi = (NJ_UINT8*)yomi;
2010
2011
2012    while (ysize > 0) {
2013        if (ytbl_cnt != 0) {
2014            char_size = UTL_CHAR(byomi) * sizeof(NJ_CHAR);
2015            if (char_size > 2) {
2016                return -1;
2017            }
2018
2019
2020
2021            if (char_size == 2) {
2022                if (y == 1) {
2023                    return -1;
2024                }
2025                c1 = *byomi;
2026                c2 = *(byomi + 1);
2027                c = (NJ_UINT16)((c1 << 8) | c2);
2028            } else {
2029
2030                c1 = *byomi;
2031                c2 = 0x00;
2032                c = (NJ_UINT16)(*byomi);
2033            }
2034
2035            idx = -1;
2036            left = 0;
2037            right = ytbl_cnt;
2038
2039            if (y == 2) {
2040                while (left <= right) {
2041                    mid = (left + right) >> 1;
2042                    wkc = ytbl_top + (mid << 1);
2043
2044                    if (c1 == *wkc) {
2045                        if (c2 == *(wkc + 1)) {
2046                            idx = (NJ_UINT16) (mid + 1);
2047                            break;
2048                        }
2049                        if (c2 < *(wkc + 1)) {
2050                            right = mid - 1;
2051                        } else {
2052                            left = mid + 1;
2053                        }
2054                    } else if (c1 < *wkc) {
2055                        right = mid - 1;
2056                    } else {
2057                        left = mid + 1;
2058                    }
2059                }
2060            } else {
2061                while (left <= right) {
2062                    mid = (left + right) >> 1;
2063                    wkc = ytbl_top + (mid * y);
2064                    d = (NJ_UINT16) (*wkc);
2065                    if (c == d) {
2066                        idx = (NJ_UINT16) (mid + 1);
2067                        break;
2068                    }
2069                    if (c < d) {
2070                        right = mid - 1;
2071                    } else {
2072                        left = mid + 1;
2073                    }
2074                }
2075            }
2076
2077            if (idx < 0) {
2078                return -1;
2079            }
2080            index = (NJ_UINT8) idx;
2081        } else {
2082            index = *byomi;
2083            char_size = 1;
2084        }
2085
2086        byomi += char_size;
2087        ysize -= char_size;
2088
2089        while (now < data_top) {
2090            if (NODE_IDX_EXIST(now)) {
2091                bit_idx = 8;
2092                idx_cnt = NODE_IDX_CNT(now);
2093            } else {
2094                bit_idx = 4;
2095                idx_cnt = 1;
2096            }
2097            bit_all = bit_idx;
2098
2099
2100            if (NODE_LEFT_EXIST(now)) {
2101                bit_all += bit_left;
2102            }
2103
2104
2105            if (NODE_DATA_EXIST(now)) {
2106                bit_all += bit_data;
2107            }
2108
2109            bit_tmp = bit_all;
2110
2111
2112            bit_all += (NJ_UINT16) (idx_no << 3);
2113
2114            pos = (NJ_UINT16) (bit_all >> 3);
2115
2116            data = (NJ_UINT16) (NJ_INT16_READ(now + pos));
2117
2118            j = (NJ_UINT16) (bit_all & 0x0007);
2119
2120            nd_index = GET_BITFIELD_16(data, j, INDEX_BIT);
2121            if (index == (NJ_UINT8) nd_index) {
2122
2123                break;
2124            } else {
2125                if ((!NODE_TERM(now)) && (index > (NJ_UINT8) nd_index) && (idx_no == 0)) {
2126
2127                    now += GET_BIT_TO_BYTE(bit_tmp + (idx_cnt * 8));
2128                    if (now == node_mid) {
2129
2130                        return -1;
2131                    }
2132                    continue;
2133                } else {
2134                    if ((now == node_mid) && (restart_flg == 0)
2135                        && (index < (NJ_UINT8) nd_index) && (idx_no == 0)
2136                        && (root != node_mid)) {
2137                        now = root;
2138                        idx_no = 0;
2139                        restart_flg = 1;
2140                        continue;
2141                    }
2142                    return -1;
2143                }
2144            }
2145        }
2146
2147        if ( (idx_cnt > (NJ_UINT16) (idx_no + 1))) {
2148            if (ysize == 0) {
2149                if (operation == NJ_CUR_OP_FORE) {
2150
2151                    storebuf->node = now;
2152                    storebuf->now = now;
2153                    storebuf->idx_no = idx_no + 1;
2154                    node = now;
2155                    break;
2156                }
2157                return -2;
2158            }
2159            idx_no++;
2160            continue;
2161        }
2162
2163        node = now;
2164        storebuf->node = now;
2165        idx_no = 0;
2166
2167        if (ysize == 0) {
2168            *con_node = now;
2169        } else {
2170            if (!(NODE_LEFT_EXIST(now))) {
2171                return -1;
2172            }
2173        }
2174
2175        if (NODE_LEFT_EXIST(now)) {
2176            if (NODE_IDX_EXIST(now)) {
2177                bit_idx = 8;
2178            } else {
2179                bit_idx = 4;
2180            }
2181            pos = (NJ_UINT16) (bit_idx >> 3);
2182            data_l = (NJ_UINT32) (NJ_INT32_READ(now + pos));
2183
2184
2185            j = (NJ_UINT16) (bit_idx & 0x0007);
2186
2187            now += GET_BITFIELD_32(data_l, j, bit_left);
2188            storebuf->now = now;
2189        } else {
2190            storebuf->now = now;
2191        }
2192    }
2193
2194
2195
2196    if (*con_node == NULL) {
2197        *con_node = now;
2198    }
2199
2200
2201    if ((node == NULL) || !(NODE_DATA_EXIST(node))) {
2202
2203        if ((operation == NJ_CUR_OP_FORE) && (node != NULL)) {
2204            while (!NODE_DATA_EXIST(node)) {
2205                if (!(NODE_LEFT_EXIST(node))) {
2206
2207                    return -2;
2208                }
2209
2210                if (NODE_IDX_EXIST(node)) {
2211                    bit_idx = 8;
2212                } else {
2213                    bit_idx = 4;
2214                }
2215                pos = (NJ_UINT16) (bit_idx >> 3);
2216                data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos));
2217
2218
2219                j = (NJ_UINT16) (bit_idx & 0x0007);
2220                node += GET_BITFIELD_32(data_l, j, bit_left);
2221            }
2222        } else {
2223            return -2;
2224        }
2225    }
2226
2227    if (NODE_IDX_EXIST(node)) {
2228        bit_idx = 8;
2229    } else {
2230        bit_idx = 4;
2231    }
2232
2233
2234    if (NODE_LEFT_EXIST(node)) {
2235        bit_all = bit_idx + bit_left;
2236    } else {
2237        bit_all = bit_idx;
2238    }
2239
2240    pos = (NJ_UINT16) (bit_all >> 3);
2241    data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos));
2242
2243
2244    j = (NJ_UINT16) (bit_all & 0x0007);
2245    *data_offset = GET_BITFIELD_32(data_l, j, bit_data);
2246
2247    return 1;
2248}
2249
2250static NJ_INT16 get_node_bottom(NJ_CHAR * yomi, NJ_UINT8 * now, NJ_UINT8 * node_mid,
2251                                NJ_UINT8 * data_top, NJ_UINT16 bit_left, NJ_UINT16 bit_data,
2252                                NJ_UINT32 top, NJ_DIC_HANDLE handle,
2253                                NJ_UINT32 * ret_bottom)
2254{
2255    NJ_UINT8 *node;
2256    NJ_UINT16 idx_cnt;
2257    NJ_UINT32 data_offset;
2258    NJ_UINT16 pos, j, bit_all;
2259    NJ_UINT32 data_l;
2260    NJ_UINT8 bottom_flg = 0;
2261    NJ_UINT8 *stem_data;
2262    NJ_UINT32 bottom, next;
2263
2264
2265
2266    bottom = top;
2267
2268    if (NJ_CHAR_STRLEN_IS_0(yomi)) {
2269        node = node_mid;
2270
2271    } else {
2272
2273        node = now;
2274        if (NODE_LEFT_EXIST(node)) {
2275
2276            if (NODE_IDX_EXIST(node)) {
2277                bit_all = 8;
2278            } else {
2279                bit_all = 4;
2280            }
2281
2282            pos = (NJ_UINT16) (bit_all >> 3);
2283            data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos));
2284
2285
2286            j = (NJ_UINT16) (bit_all & 0x0007);
2287            node += GET_BITFIELD_32(data_l, j, bit_left);
2288
2289        } else {
2290            bottom_flg = 1;
2291        }
2292    }
2293
2294
2295    if (!bottom_flg) {
2296        while (node < data_top) {
2297
2298            if (!NODE_TERM(node)) {
2299
2300                if (NODE_IDX_EXIST(node)) {
2301                    bit_all = 8;
2302                    idx_cnt = NODE_IDX_CNT(node);
2303                } else {
2304                    bit_all = 4;
2305                    idx_cnt = 1;
2306                }
2307
2308
2309                if (NODE_LEFT_EXIST(node)) {
2310                    bit_all += bit_left;
2311                }
2312
2313
2314                if (NODE_DATA_EXIST(node)) {
2315                    bit_all += bit_data;
2316                }
2317
2318
2319                node += GET_BIT_TO_BYTE(bit_all + (idx_cnt * 8));
2320            } else {
2321
2322                if (!NODE_LEFT_EXIST(node)) {
2323
2324                    if (NODE_DATA_EXIST(node)) {
2325
2326                        if (NODE_IDX_EXIST(node)) {
2327                            bit_all = 8;
2328                        } else {
2329                            bit_all = 4;
2330                        }
2331
2332                        pos = (NJ_UINT16) (bit_all >> 3);
2333                        data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos));
2334
2335
2336                        j = (NJ_UINT16) (bit_all & 0x0007);
2337                        data_offset = GET_BITFIELD_32(data_l, j, bit_data);
2338
2339                        bottom = data_offset;
2340                        break;
2341                    } else {
2342                        return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_DIC_BROKEN);
2343                    }
2344
2345                } else {
2346
2347                    if (NODE_IDX_EXIST(node)) {
2348                        bit_all = 8;
2349                    } else {
2350                        bit_all = 4;
2351                    }
2352
2353                    pos = (NJ_UINT16) (bit_all >> 3);
2354                    data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos));
2355
2356
2357                    j = (NJ_UINT16) (bit_all & 0x0007);
2358
2359
2360                    node += GET_BITFIELD_32(data_l, j, bit_left);
2361                }
2362            }
2363        }
2364    }
2365
2366    stem_data = data_top + bottom;
2367
2368    while (!(STEM_TERMINETER(stem_data))) {
2369        next = get_stem_next(handle, stem_data);
2370        stem_data += next;
2371    }
2372    *ret_bottom = (NJ_UINT32) (stem_data - data_top);
2373
2374    return 1;
2375}
2376
2377static NJ_INT16 bdic_search_fore_data2(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 hidx)
2378{
2379    NJ_UINT8 *data, *data_top, *bottom, *data_end;
2380    NJ_INT16 i = 0;
2381    NJ_INT16 hindo = 0;
2382    NJ_UINT32 current = loctset->loct.current;
2383
2384
2385    NJ_SEARCH_CACHE *psrhCache = condition->ds->dic[hidx].srhCache;
2386
2387    NJ_UINT16 top_abIdx;
2388    NJ_UINT16 bottom_abIdx;
2389    NJ_UINT16 count_abIdx;
2390    NJ_UINT16 current_abIdx;
2391    NJ_UINT16 old_abIdx;
2392    NJ_UINT8 freq_flag = 0;
2393    NJ_INT16 save_hindo = 0;
2394    NJ_UINT16 save_abIdx = 0;
2395    NJ_UINT16 abPtrIdx;
2396    NJ_UINT16 m;
2397    NJ_INT16 ret;
2398    NJ_INT16 loop_check;
2399
2400    NJ_UINT16 abIdx;
2401    NJ_UINT16 abIdx_old;
2402    NJ_UINT16 hindo_max, hindo_tmp;
2403    NJ_UINT32 hindo_max_data, hindo_tmp_data;
2404    NJ_UINT16 abIdx_current;
2405
2406
2407
2408
2409    if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) {
2410        loctset->loct.status = NJ_ST_SEARCH_READY;
2411        loctset->loct.current_info = CURRENT_INFO_SET;
2412        return 1;
2413    }
2414
2415    if (NJ_GET_AIMAI_FROM_SCACHE(psrhCache)) {
2416        NJ_UNSET_AIMAI_TO_SCACHE(psrhCache);
2417
2418        data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle);
2419        if (condition->operation == NJ_CUR_OP_FORE) {
2420            if (condition->ylen) {
2421
2422                abPtrIdx = condition->yclen;
2423
2424
2425                abIdx = psrhCache->keyPtr[abPtrIdx];
2426                abIdx_old = psrhCache->keyPtr[abPtrIdx - 1];
2427                if ((abIdx > NJ_SEARCH_CACHE_SIZE) || (abIdx_old >= NJ_SEARCH_CACHE_SIZE)) {
2428
2429                    return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN);
2430                }
2431
2432                if (condition->mode == NJ_CUR_MODE_FREQ) {
2433                    hindo_max = 0;
2434                    hindo_max_data = 0;
2435                    abIdx_current = abIdx_old;
2436
2437                    for (m = abIdx_old; m < abIdx; m++) {
2438
2439                        data = data_top + psrhCache->storebuff[m].top;
2440
2441                        hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) +
2442                                                           get_stem_hindo(loctset->loct.handle, data)));
2443
2444                        hindo_tmp = 0;
2445                        hindo_tmp_data = 0;
2446                        current = 0;
2447
2448
2449                        while (data <= (data_top + psrhCache->storebuff[m].bottom)) {
2450
2451                            if (hindo > hindo_tmp) {
2452                                hindo_tmp = hindo;
2453                                hindo_tmp_data = current;
2454                            }
2455
2456
2457                            i = get_stem_next(loctset->loct.handle, data);
2458                            current += i;
2459                            data += i;
2460
2461
2462                            hindo = (NJ_UINT16) *((NJ_UINT8 *) (HINDO_NO_TOP_ADDR(loctset->loct.handle) +
2463                                                                get_stem_hindo(loctset->loct.handle, data)));
2464
2465                        }
2466
2467
2468                        psrhCache->storebuff[m].current = hindo_tmp_data;
2469
2470
2471                        if (hindo_tmp > hindo_max) {
2472                            hindo_max = hindo_tmp;
2473                            hindo_max_data = hindo_tmp_data;
2474                            abIdx_current = m;
2475                        }
2476                    }
2477                } else {
2478
2479                    abIdx_current = abIdx_old;
2480
2481
2482                    data = data_top + psrhCache->storebuff[abIdx_current].top;
2483
2484                    hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
2485                                                       + get_stem_hindo(loctset->loct.handle, data)));
2486
2487                    hindo_max = hindo;
2488                    hindo_max_data = 0;
2489                }
2490
2491
2492                loctset->loct.top = psrhCache->storebuff[abIdx_current].top;
2493                loctset->loct.bottom = psrhCache->storebuff[abIdx_current].bottom;
2494
2495                loctset->cache_freq = CALCULATE_HINDO(hindo_max, loctset->dic_freq.base,
2496                                                      loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
2497                loctset->loct.current = hindo_max_data;
2498                loctset->loct.current_cache = (NJ_UINT8)abIdx_current;
2499
2500
2501                psrhCache->viewCnt = 1;
2502            } else {
2503
2504                data = data_top + loctset->loct.top;
2505
2506                hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) +
2507                                                   get_stem_hindo(loctset->loct.handle, data)));
2508
2509                hindo_max = hindo;
2510                hindo_max_data = 0;
2511
2512                if (condition->mode == NJ_CUR_MODE_FREQ) {
2513
2514
2515                    i = get_stem_next(loctset->loct.handle, data);
2516                    current = i;
2517                    data += i;
2518
2519
2520                    while (data <= (data_top + loctset->loct.bottom)) {
2521
2522
2523                        hindo = (NJ_UINT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) +
2524                                                          get_stem_hindo(loctset->loct.handle, data)));
2525
2526
2527                        if (hindo > hindo_max) {
2528                            hindo_max = hindo;
2529                            hindo_max_data = current;
2530                        }
2531
2532
2533                        i = get_stem_next(loctset->loct.handle, data);
2534                        current += i;
2535                        data += i;
2536                    }
2537                }
2538                loctset->cache_freq = CALCULATE_HINDO(hindo_max,
2539                                                      loctset->dic_freq.base,
2540                                                      loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
2541                loctset->loct.current = hindo_max_data;
2542            }
2543        }
2544        return 1;
2545    }
2546
2547
2548    data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle);
2549
2550
2551    data = data_top + loctset->loct.top + loctset->loct.current;
2552
2553
2554
2555    bottom = data_top + loctset->loct.bottom;
2556
2557    if (NJ_GET_DIC_FMT(loctset->loct.handle) == NJ_DIC_FMT_KANAKAN) {
2558        data_end = loctset->loct.handle
2559            + NJ_DIC_COMMON_HEADER_SIZE
2560            + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_DATA_SIZE)
2561            + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_EXT_SIZE)
2562            - NJ_DIC_ID_LEN;
2563    } else {
2564        data_end = CAND_IDX_AREA_TOP_ADDR(loctset->loct.handle);
2565    }
2566
2567    if (condition->mode == NJ_CUR_MODE_FREQ) {
2568
2569
2570        abPtrIdx = condition->yclen;
2571
2572
2573        bottom_abIdx = psrhCache->keyPtr[abPtrIdx];
2574        top_abIdx = psrhCache->keyPtr[abPtrIdx - 1];
2575        if ((bottom_abIdx > NJ_SEARCH_CACHE_SIZE) || (top_abIdx >= NJ_SEARCH_CACHE_SIZE)) {
2576
2577            return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN);
2578        }
2579
2580
2581        count_abIdx = bottom_abIdx - top_abIdx;
2582        if (!count_abIdx) {
2583            loctset->loct.status = NJ_ST_SEARCH_END;
2584            return 0;
2585        }
2586
2587        old_abIdx = loctset->loct.current_cache;
2588
2589        loop_check = 0;
2590
2591
2592        ret = bdic_get_next_data(data_top, data_end, loctset, psrhCache, old_abIdx);
2593
2594        if (ret == loctset->cache_freq) {
2595
2596            psrhCache->viewCnt++;
2597            if (psrhCache->viewCnt <= NJ_CACHE_VIEW_CNT) {
2598
2599                loctset->loct.status = NJ_ST_SEARCH_READY;
2600                loctset->loct.current_info = CURRENT_INFO_SET;
2601                loctset->loct.current = psrhCache->storebuff[old_abIdx].current;
2602                loctset->loct.current_cache = (NJ_UINT8)old_abIdx;
2603                return 1;
2604            } else {
2605
2606                freq_flag = 1;
2607                psrhCache->viewCnt = 0;
2608            }
2609        } else {
2610            if (ret == -1) {
2611
2612                loop_check++;
2613            }
2614            save_hindo = ret;
2615            save_abIdx = old_abIdx;
2616        }
2617
2618
2619        current_abIdx = old_abIdx + 1;
2620        if (current_abIdx >= bottom_abIdx) {
2621
2622            current_abIdx = top_abIdx;
2623        }
2624
2625        while (loop_check != count_abIdx) {
2626
2627
2628            ret = bdic_get_word_freq(data_top, loctset, psrhCache, current_abIdx);
2629
2630            if ((ret == loctset->cache_freq) &&
2631                (loctset->loct.top == psrhCache->storebuff[current_abIdx].top) &&
2632                (loctset->loct.current == psrhCache->storebuff[current_abIdx].current)) {
2633                ret = bdic_get_next_data(data_top, data_end, loctset, psrhCache, current_abIdx);
2634            }
2635
2636            if (ret == loctset->cache_freq) {
2637
2638                loctset->loct.status = NJ_ST_SEARCH_READY;
2639                loctset->loct.current_info = CURRENT_INFO_SET;
2640                loctset->loct.top = psrhCache->storebuff[current_abIdx].top;
2641                loctset->loct.bottom = psrhCache->storebuff[current_abIdx].bottom;
2642                loctset->loct.current = psrhCache->storebuff[current_abIdx].current;
2643                loctset->loct.current_cache = (NJ_UINT8)current_abIdx;
2644                psrhCache->viewCnt = 1;
2645                return 1;
2646
2647            } else {
2648                if (ret == -1) {
2649
2650                    loop_check++;
2651                }
2652                if (save_hindo < ret) {
2653
2654                    save_hindo = ret;
2655                    save_abIdx = current_abIdx;
2656                }
2657            }
2658
2659
2660            current_abIdx++;
2661            if (current_abIdx >= bottom_abIdx) {
2662
2663                current_abIdx = top_abIdx;
2664            }
2665
2666
2667            if (current_abIdx == old_abIdx) {
2668                if (freq_flag == 1) {
2669
2670                    loctset->loct.status = NJ_ST_SEARCH_READY;
2671                    loctset->loct.current_info = CURRENT_INFO_SET;
2672                    loctset->loct.top = psrhCache->storebuff[current_abIdx].top;
2673                    loctset->loct.bottom = psrhCache->storebuff[current_abIdx].bottom;
2674                    loctset->loct.current = psrhCache->storebuff[current_abIdx].current;
2675                    loctset->loct.current_cache = (NJ_UINT8)current_abIdx;
2676                    psrhCache->viewCnt = 1;
2677                    return 1;
2678                } else if (save_hindo != -1) {
2679
2680                    loctset->cache_freq = save_hindo;
2681                    loctset->loct.status = NJ_ST_SEARCH_READY;
2682                    loctset->loct.current_info = CURRENT_INFO_SET;
2683                    loctset->loct.top = psrhCache->storebuff[save_abIdx].top;
2684                    loctset->loct.bottom = psrhCache->storebuff[save_abIdx].bottom;
2685                    loctset->loct.current = psrhCache->storebuff[save_abIdx].current;
2686                    loctset->loct.current_cache = (NJ_UINT8)save_abIdx;
2687                    psrhCache->viewCnt = 1;
2688                    return 1;
2689                }
2690            }
2691        }
2692    } else {
2693
2694
2695
2696        i = get_stem_next(loctset->loct.handle, data);
2697        data += i;
2698        current += i;
2699
2700
2701        if (data > bottom) {
2702
2703            loctset->loct.status = NJ_ST_SEARCH_END;
2704            return 0;
2705        }
2706
2707
2708        hindo = (NJ_INT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
2709                                         + get_stem_hindo(loctset->loct.handle, data)));
2710        loctset->cache_freq = CALCULATE_HINDO(hindo, loctset->dic_freq.base,
2711                                              loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
2712        loctset->loct.status = NJ_ST_SEARCH_READY;
2713        loctset->loct.current_info = CURRENT_INFO_SET;
2714        loctset->loct.current = current;
2715        return 1;
2716    }
2717
2718    loctset->loct.status = NJ_ST_SEARCH_END;
2719    return 0;
2720}
2721
2722static NJ_INT16 bdic_get_next_data(NJ_UINT8 *data_top, NJ_UINT8 *data_end,
2723                                   NJ_SEARCH_LOCATION_SET *loctset,
2724                                   NJ_SEARCH_CACHE *psrhCache,
2725                                   NJ_UINT16 abIdx)
2726{
2727    NJ_UINT8 *data, *bottom;
2728    NJ_INT16 i = 0;
2729    NJ_INT16 hindo = 0;
2730    NJ_INT16 hindo_max = -1;
2731    NJ_UINT8 no_hit = 0;
2732    NJ_UINT32 current = psrhCache->storebuff[abIdx].current;
2733    NJ_UINT8 *current_org;
2734    NJ_UINT32 hindo_data = 0;
2735    NJ_INT16 freq_org = loctset->cache_freq;
2736
2737
2738    if (psrhCache->storebuff[abIdx].current == LOC_CURRENT_NO_ENTRY) {
2739        return (-1);
2740    }
2741
2742
2743    data = data_top + psrhCache->storebuff[abIdx].top + psrhCache->storebuff[abIdx].current;
2744
2745
2746    current_org = data;
2747
2748
2749    bottom = data_top + psrhCache->storebuff[abIdx].bottom;
2750
2751
2752
2753
2754    while (data < data_end) {
2755
2756        i = get_stem_next(loctset->loct.handle, data);
2757        data += i;
2758        current += i;
2759
2760
2761        if (data > bottom) {
2762            if ((freq_org == 0) || (no_hit == 1)) {
2763
2764                psrhCache->storebuff[abIdx].current = LOC_CURRENT_NO_ENTRY;
2765                return -1;
2766            }
2767
2768            freq_org -= 1;
2769
2770
2771            data = data_top + psrhCache->storebuff[abIdx].top;
2772            current = 0;
2773
2774            no_hit = 1;
2775        }
2776
2777
2778        if ((hindo_max != -1) && (data == current_org)) {
2779            psrhCache->storebuff[abIdx].current = hindo_data;
2780            return hindo_max;
2781        }
2782
2783
2784        hindo = (NJ_INT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
2785                                         + get_stem_hindo(loctset->loct.handle, data)));
2786
2787        hindo = CALCULATE_HINDO(hindo, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
2788
2789
2790        if (hindo == freq_org) {
2791            psrhCache->storebuff[abIdx].current = current;
2792            return hindo;
2793        }
2794
2795        if (hindo < freq_org) {
2796            if ((hindo > hindo_max) || ((hindo == hindo_max) && (current < hindo_data))) {
2797                hindo_max = hindo;
2798                hindo_data = current;
2799            }
2800        }
2801    }
2802
2803
2804    psrhCache->storebuff[abIdx].current = LOC_CURRENT_NO_ENTRY;
2805    return -1;
2806}
2807
2808static NJ_INT16 bdic_get_word_freq(NJ_UINT8 * data_top, NJ_SEARCH_LOCATION_SET * loctset,
2809                                   NJ_SEARCH_CACHE * psrhCache, NJ_UINT16 abIdx)
2810{
2811    NJ_UINT8 *data;
2812    NJ_INT16 hindo = 0;
2813
2814
2815    if (psrhCache->storebuff[abIdx].current != LOC_CURRENT_NO_ENTRY) {
2816
2817        data = data_top + psrhCache->storebuff[abIdx].top + psrhCache->storebuff[abIdx].current;
2818
2819
2820        hindo = (NJ_INT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
2821                                         + get_stem_hindo(loctset->loct.handle, data)));
2822
2823        hindo = CALCULATE_HINDO(hindo, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
2824
2825    } else {
2826
2827        hindo = -1;
2828    }
2829
2830    return hindo;
2831}
2832