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 
70 typedef 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 
84 static NJ_INT16 get_stem_next(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data);
85 static void get_stem_word(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set, NJ_UINT8 check);
86 static void get_stem_cand_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set);
87 static NJ_UINT16 get_stem_yomi_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data,STEM_DATA_SET *stem_set);
88 static NJ_UINT16 get_stem_yomi_size(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, NJ_UINT16 yomi_size);
89 static 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);
90 static NJ_INT16 search_node(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset);
91 static NJ_INT16 bdic_search_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset);
92 static NJ_INT16 bdic_search_fore_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset);
93 
94 static NJ_HINDO get_stem_hindo(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data);
95 
96 static NJ_INT16 search_node2(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset,
97                              NJ_UINT16 hidx);
98 static NJ_INT16 bdic_search_fore_data2(NJ_SEARCH_CONDITION *condition,
99                                        NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 hidx);
100 static 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);
109 static 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);
113 static 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);
116 static NJ_INT16 bdic_get_word_freq(NJ_UINT8 *data_top, NJ_SEARCH_LOCATION_SET *loctset,
117                                    NJ_SEARCH_CACHE *psrhCache, NJ_UINT16 abIdx);
118 
get_stem_hindo(NJ_DIC_HANDLE hdl,NJ_UINT8 * stem_data)119 static 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 
get_stem_next(NJ_DIC_HANDLE hdl,NJ_UINT8 * stem_data)148 static 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 
get_stem_word(NJ_DIC_HANDLE hdl,NJ_UINT8 * stem_data,STEM_DATA_SET * stem_set,NJ_UINT8 check)209 static 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 
get_stem_cand_data(NJ_DIC_HANDLE hdl,NJ_UINT8 * stem_data,STEM_DATA_SET * stem_set)349 static 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 
get_stem_yomi_data(NJ_DIC_HANDLE hdl,NJ_UINT8 * stem_data,STEM_DATA_SET * stem_set)390 static 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 
get_stem_yomi_size(NJ_DIC_HANDLE hdl,NJ_UINT8 * ydata,NJ_UINT16 yomi_size)447 static 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 
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)486 static 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 
search_node(NJ_SEARCH_CONDITION * condition,NJ_SEARCH_LOCATION_SET * loctset)550 static 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 
bdic_search_data(NJ_SEARCH_CONDITION * condition,NJ_SEARCH_LOCATION_SET * loctset)998 static 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 
bdic_search_fore_data(NJ_SEARCH_CONDITION * condition,NJ_SEARCH_LOCATION_SET * loctset)1048 static 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 
njd_b_search_word(NJ_SEARCH_CONDITION * con,NJ_SEARCH_LOCATION_SET * loctset)1181 NJ_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 
njd_b_get_word(NJ_SEARCH_LOCATION_SET * loctset,NJ_WORD * word)1322 NJ_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 
njd_b_get_candidate(NJ_WORD * word,NJ_CHAR * candidate,NJ_UINT16 size)1388 NJ_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 
njd_b_get_stroke(NJ_WORD * word,NJ_CHAR * stroke,NJ_UINT16 size)1483 NJ_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 
search_node2(NJ_SEARCH_CONDITION * condition,NJ_SEARCH_LOCATION_SET * loctset,NJ_UINT16 hidx)1539 static 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 
search_yomi_node(NJ_UINT8 operation,NJ_UINT8 * node,NJ_UINT8 * now,NJ_UINT16 idx_no,NJ_CHAR * yomi,NJ_UINT16 yomilen,NJ_UINT8 * root,NJ_UINT8 * node_mid,NJ_UINT16 bit_left,NJ_UINT16 bit_data,NJ_UINT8 * data_top,NJ_INT16 ytbl_cnt,NJ_UINT16 y,NJ_UINT8 * ytbl_top,NJ_CACHE_INFO * storebuf,NJ_UINT8 ** con_node,NJ_UINT32 * data_offset)1975 static 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 
get_node_bottom(NJ_CHAR * yomi,NJ_UINT8 * now,NJ_UINT8 * node_mid,NJ_UINT8 * data_top,NJ_UINT16 bit_left,NJ_UINT16 bit_data,NJ_UINT32 top,NJ_DIC_HANDLE handle,NJ_UINT32 * ret_bottom)2250 static 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 
bdic_search_fore_data2(NJ_SEARCH_CONDITION * condition,NJ_SEARCH_LOCATION_SET * loctset,NJ_UINT16 hidx)2377 static 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 
bdic_get_next_data(NJ_UINT8 * data_top,NJ_UINT8 * data_end,NJ_SEARCH_LOCATION_SET * loctset,NJ_SEARCH_CACHE * psrhCache,NJ_UINT16 abIdx)2722 static 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 
bdic_get_word_freq(NJ_UINT8 * data_top,NJ_SEARCH_LOCATION_SET * loctset,NJ_SEARCH_CACHE * psrhCache,NJ_UINT16 abIdx)2808 static 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