1 /*
2  * Copyright (c) 1991-1994  Sony Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL SONY CORPORATION BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Except as contained in this notice, the name of Sony Corporation
24  * shall not be used in advertising or otherwise to promote the sale, use
25  * or other dealings in this Software without prior written authorization
26  * from Sony Corporation.
27  *
28  */
29 
30 /*
31  * $SonyRCSfile: study.c,v $
32  * $SonyRevision: 1.1 $
33  * $SonyDate: 1994/06/03 08:02:38 $
34  */
35 
36 
37 #include <string.h>
38 #include "sj_kcnv.h"
39 
40 #include "sj_kanakan.h"
41 
42 Int
study(STDYOUT * stdy)43 study(STDYOUT *stdy)
44 {
45 	STDYOUT		outp;
46 	STDYIN		*p1;
47 	STDYIN		*p2;
48 	Int		wcnt;
49 	Int		ret;
50 	TypeDicSeg	seg;
51 	TypeDicOfs	ofs;
52 	TypeStyNum	nm;
53 	TypeStyNum	wi;
54 
55 	if (!StudyExist()) return StudyNoDict;
56 
57 	memcpy((Uchar *)&outp, (Uchar *)stdy, sizeof(outp));
58 
59 	if (outp.stdy1.offset == 0) return StudyNotStudy;
60 
61 	p1 = srchstdy(outp.stdy1.seg, outp.stdy1.offset, outp.stdy1.dicid);
62 	if (p1) {
63 		nm = p1 -> styno;
64 
65 		for (wcnt = StudyCount, p2 = StudyDict ; wcnt-- ; p2++) {
66 			if (p2 -> styno < nm) p2 -> styno++;
67 		}
68 
69 		p1 -> styno  = 1;
70 
71 		if (outp.sttfg) p1 -> sttkj  = outp.stdy1.sttkj;
72 		if (outp.ka_fg) p1 -> ka_kj  = outp.stdy1.ka_kj;
73 
74 		p1 -> nmflg = outp.stdy1.nmflg;
75 
76 		putstydic();
77 
78 		return StudyNormEnd;
79 	}
80 
81 
82 	if (StudyCount >= StudyMax) {
83 
84 		p1 = StudyDict; p2 = NULL; wi = 0;
85 		for (wcnt = StudyMax ; wcnt-- ; p1++) {
86 			if ((nm = p1 -> styno + 1) > wi) {
87 				wi = nm;
88 				p2 = p1;
89 			}
90 
91 			p1 -> styno = nm;
92 		}
93 
94 		if (p2) {
95 			mvmemi((Uchar *)(p2 + 1), (Uchar *)p2,
96 				(StudyTail - p2) * StudyRecSize);
97 			StudyCount -= 1;
98 		}
99 		else
100 			return StudyError;
101 
102 		ret = StudyFullArea;
103 	}
104 	else {
105 		p1 = StudyDict;
106 		for (wcnt = StudyCount ; wcnt-- ; p1++) p1 -> styno++;
107 
108 		ret = StudyNormEnd;
109 	}
110 
111 	p1 = StudyDict;
112 	seg = outp.stdy1.seg;
113 	for (wcnt = StudyCount ; wcnt && (p1 -> seg < seg) ; ) {
114 		wcnt--; p1++;
115 	}
116 
117 	ofs = outp.stdy1.offset;
118 	while (wcnt-- && (p1 -> seg == seg)) {
119 		if (p1 -> offset > ofs) break;
120 		p1++;
121 	}
122 
123 	mvmemd((Uchar *)(StudyTail - 1), (Uchar *)StudyTail,
124 			(Uchar *)(StudyTail - 1) - (Uchar *)p1);
125 	p1 -> offset = outp.stdy1.offset;
126 	p1 -> seg    = outp.stdy1.seg;
127 	p1 -> dicid  = outp.stdy1.dicid;
128 	p1 -> styno  = 1;
129 	p1 -> sttkj  = (outp.sttfg) ? outp.stdy1.sttkj : 0;
130 	p1 -> ka_kj  = (outp.ka_fg) ? outp.stdy1.ka_kj : 0;
131 	p1 -> nmflg  = outp.stdy1.nmflg;
132 	StudyCount += 1;
133 
134 	putstydic();
135 
136 	return ret;
137 }
138 
139 STDYIN *
srchstdy(TypeDicSeg seg,TypeDicOfs ofs,TypeDicID dicid)140 srchstdy(TypeDicSeg seg, TypeDicOfs ofs, TypeDicID dicid)
141 {
142 	Int	high;
143 	Int	mid;
144 	Int	low;
145 	STDYIN	*ptr;
146 
147 
148 	if (!StudyExist()) return NULL;
149 
150 	if (!StudyCount || !ofs) return NULL;
151 
152 	low = 0;
153 	high = StudyCount - 1;
154 
155 	for ( ; ; ) {
156 		mid = ((low + high) >> 1);
157 
158 		if (StudyDict[mid].seg > seg)
159 			high = mid - 1;
160 
161 		else if (StudyDict[mid].seg < seg)
162 			low = mid + 1;
163 
164 		else
165 			break;
166 
167 		if (low > high) return NULL;
168 	}
169 
170 	low = mid + 1;
171 	ptr = &StudyDict[mid];
172 	while (ptr -> seg == seg) {
173 		if (ptr -> offset < ofs) break;
174 		if (ptr -> dicid == dicid && ptr -> offset == ofs) return ptr;
175 		if (!mid--) break;
176 		ptr--;
177 	}
178 
179 	ptr = &StudyDict[low];
180 	mid = StudyCount - low;
181 	while (mid-- && ptr -> seg == seg) {
182 		if (ptr -> offset > ofs) break;
183 		if (ptr -> dicid == dicid && ptr -> offset == ofs) return ptr;
184 		ptr++;
185 	}
186 
187 	return NULL;
188 }
189 
190