Reactos
1/***
2*tombbmbc.c - convert 1-byte code to and from 2-byte code
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7* _mbbtombc() - converts 1-byte code to corresponding 2-byte code
8* _mbctombb() - converts 2-byte code to corresponding 1-byte code
9*
10*******************************************************************************/
11#ifndef _MBCS
12 #error This file should only be compiled with _MBCS defined
13#endif
14
15#include <corecrt_internal_mbstring.h>
16#include <locale.h>
17
18
19#define ASCLOW 0x20
20#define ASCHIGH 0x7e
21
22#define SBLOW 0xA1
23#define SBHIGH 0xDF
24
25#define MBLIMIT 0x8396
26
27static unsigned short const mbbtable[] = {
28 /*20*/ 0x8140, 0x8149, 0x8168, 0x8194, 0x8190, 0x8193, 0x8195, 0x8166,
29 0x8169, 0x816a, 0x8196, 0x817b, 0x8143, 0x817c, 0x8144, 0x815e,
30 /*30*/ 0x824f, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8256,
31 0x8257, 0x8258, 0x8146, 0x8147, 0x8183, 0x8181, 0x8184, 0x8148,
32 /*40*/ 0x8197, 0x8260, 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266,
33 0x8267, 0x8268, 0x8269, 0x826a, 0x826b, 0x826c, 0x826d, 0x826e,
34 /*50*/ 0x826f, 0x8270, 0x8271, 0x8272, 0x8273, 0x8274, 0x8275, 0x8276,
35 0x8277, 0x8278, 0x8279, 0x816d, 0x818f, 0x816e, 0x814f, 0x8151,
36 /*60*/ 0x8165, 0x8281, 0x8282, 0x8283, 0x8284, 0x8285, 0x8286, 0x8287,
37 0x8288, 0x8289, 0x828a, 0x828b, 0x828c, 0x828d, 0x828e, 0x828f,
38 /*70*/ 0x8290, 0x8291, 0x8292, 0x8293, 0x8294, 0x8295, 0x8296, 0x8297,
39 0x8298, 0x8299, 0x829a, 0x816f, 0x8162, 0x8170, 0x8150,
40};
41
42static struct {
43 unsigned char asc;
44 char synonym;
45 unsigned short mbccode;
46} const mbctable[] = {
47 // ASCII Code | Synonym | KANJI Code
48//Katakana Table
49 { 0xA7, 1, 0x8340 }, // 'a'
50 { 0xB1, 1, 0x8341 }, // 'A'
51 { 0xA8, 1, 0x8342 }, // 'i'
52 { 0xB2, 1, 0x8343 }, // 'I'
53 { 0xA9, 1, 0x8344 }, // 'u'
54 { 0xB3, 1, 0x8345 }, // 'U'
55 { 0xAA, 1, 0x8346 }, // 'e'
56 { 0xB4, 1, 0x8347 }, // 'E'
57 { 0xAB, 1, 0x8348 }, // 'o'
58 { 0xB5, 1, 0x8349 }, // 'O'
59
60 { 0xB6, 2, 0x834A }, // 'KA'
61 { 0xB7, 2, 0x834C }, // 'KI'
62 { 0xB8, 2, 0x834E }, // 'KU'
63 { 0xB9, 2, 0x8350 }, // 'KE'
64 { 0xBA, 2, 0x8352 }, // 'KO'
65
66 { 0xBB, 2, 0x8354 }, // 'SA'
67 { 0xBC, 2, 0x8356 }, // 'SI'
68 { 0xBD, 2, 0x8358 }, // 'SU'
69 { 0xBE, 2, 0x835A }, // 'SE'
70 { 0xBF, 2, 0x835C }, // 'SO'
71
72 { 0xC0, 2, 0x835E }, // 'TA'
73 { 0xC1, 2, 0x8360 }, // 'CHI'
74 { 0xAF, 1, 0x8362 }, // 'tsu'
75 { 0xC2, 2, 0x8363 }, // 'TSU'
76 { 0xC3, 2, 0x8365 }, // 'TE''
77 { 0xC4, 2, 0x8367 }, // 'TO''
78
79 { 0xC5, 1, 0x8369 }, // 'NA'
80 { 0xC6, 1, 0x836A }, // 'NI'
81 { 0xC7, 1, 0x836B }, // 'NU'
82 { 0xC8, 1, 0x836C }, // 'NE'
83 { 0xC9, 1, 0x836D }, // 'NO'
84
85 { 0xCA, 3, 0x836E }, // 'HA'
86 { 0xCB, 3, 0x8371 }, // 'HI'
87 { 0xCC, 3, 0x8374 }, // 'FU'
88 { 0xCD, 3, 0x8377 }, // 'HE'
89 { 0xCE, 3, 0x837A }, // 'HO'
90
91 { 0xCF, 1, 0x837D }, // 'MA'
92 { 0xD0, 1, 0x837E }, // 'MI'
93 { 0xD1, 1, 0x8380 }, // 'MU'
94 { 0xD2, 1, 0x8381 }, // 'ME'
95 { 0xD3, 1, 0x8382 }, // 'MO'
96
97 { 0xAC, 1, 0x8383 }, // 'ya'
98 { 0xD4, 1, 0x8384 }, // 'YA'
99 { 0xAD, 1, 0x8385 }, // 'yu'
100 { 0xD5, 1, 0x8386 }, // 'YU'
101 { 0xAE, 1, 0x8387 }, // 'yo'
102 { 0xD6, 1, 0x8388 }, // 'YO'
103
104 { 0xD7, 1, 0x8389 }, // 'RA'
105 { 0xD8, 1, 0x838A }, // 'RI'
106 { 0xD9, 1, 0x838B }, // 'RU'
107 { 0xDA, 1, 0x838C }, // 'RE'
108 { 0xDB, 1, 0x838D }, // 'RO'
109
110 { 0xDC, 2, 0x838E }, // 'WA'
111 { 0xB2, 1, 0x8390 }, // 'I'
112 { 0xB4, 1, 0x8391 }, // 'E'
113
114 { 0xA6, 1, 0x8392 }, // 'WO'
115 { 0xDD, 1, 0x8393 }, // 'N'
116
117 { 0xB3, 1, 0x8394 }, // 'U'
118 { 0xB6, 1, 0x8395 }, // 'KA'
119 { 0xB9, 1, 0x8396 }, // 'KE'
120
121// Hiragana Table
122 { 0xA7, 1, 0x829F }, // 'a'
123 { 0xB1, 1, 0x82A0 }, // 'A'
124 { 0xA8, 1, 0x82A1 }, // 'i'
125 { 0xB2, 1, 0x82A2 }, // 'I'
126 { 0xA9, 1, 0x82A3 }, // 'u'
127 { 0xB3, 1, 0x82A4 }, // 'U'
128 { 0xAA, 1, 0x82A5 }, // 'e'
129 { 0xB4, 1, 0x82A6 }, // 'E'
130 { 0xAB, 1, 0x82A7 }, // 'o'
131 { 0xB5, 1, 0x82A8 }, // 'O'
132
133 { 0xB6, 2, 0x82A9 }, // 'KA'
134 { 0xB7, 2, 0x82AB }, // 'KI'
135 { 0xB8, 2, 0x82AD }, // 'KU'
136 { 0xB9, 2, 0x82AF }, // 'KE'
137 { 0xBA, 2, 0x82B1 }, // 'KO'
138
139 { 0xBB, 2, 0x82B3 }, // 'SA'
140 { 0xBC, 2, 0x82B5 }, // 'SI'
141 { 0xBD, 2, 0x82B7 }, // 'SU'
142 { 0xBE, 2, 0x82B9 }, // 'SE'
143 { 0xBF, 2, 0x82BB }, // 'SO'
144
145 { 0xC0, 2, 0x82BD }, // 'TA'
146 { 0xC1, 2, 0x82BF }, // 'CHI'
147 { 0xAF, 1, 0x82C1 }, // 'tsu'
148 { 0xC2, 2, 0x82C2 }, // 'TSU'
149 { 0xC3, 2, 0x82C4 }, // 'TE'
150 { 0xC4, 2, 0x82C6 }, // 'TO'
151
152 { 0xC5, 1, 0x82C8 }, // 'NA'
153 { 0xC6, 1, 0x82C9 }, // 'NI'
154 { 0xC7, 1, 0x82CA }, // 'NU'
155 { 0xC8, 1, 0x82CB }, // 'NE'
156 { 0xC9, 1, 0x82CC }, // 'NO'
157
158 { 0xCA, 3, 0x82CD }, // 'HA'
159 { 0xCB, 3, 0x82D0 }, // 'HI'
160 { 0xCC, 3, 0x82D3 }, // 'FU'
161 { 0xCD, 3, 0x82D6 }, // 'HE'
162 { 0xCE, 3, 0x82D9 }, // 'HO'
163
164 { 0xCF, 1, 0x82DC }, // 'MA'
165 { 0xD0, 1, 0x82DD }, // 'MI'
166 { 0xD1, 1, 0x82DE }, // 'MU'
167 { 0xD2, 1, 0x82DF }, // 'ME'
168 { 0xD3, 1, 0x82E0 }, // 'MO'
169
170 { 0xAC, 1, 0x82E1 }, // 'ya'
171 { 0xD4, 1, 0x82E2 }, // 'YA'
172 { 0xAD, 1, 0x82E3 }, // 'yu'
173 { 0xD5, 1, 0x82E4 }, // 'YU'
174 { 0xAE, 1, 0x82E5 }, // 'yo'
175 { 0xD6, 1, 0x82E6 }, // 'YO'
176
177 { 0xD7, 1, 0x82E7 }, // 'RA'
178 { 0xD8, 1, 0x82E8 }, // 'RI'
179 { 0xD9, 1, 0x82E9 }, // 'RU'
180 { 0xDA, 1, 0x82EA }, // 'RE'
181 { 0xDB, 1, 0x82EB }, // 'RO'
182
183 { 0xDC, 2, 0x82EC }, // 'WA'
184 { 0xB2, 1, 0x82EE }, // 'I'
185 { 0xB4, 1, 0x82EF }, // 'E'
186
187 { 0xA6, 1, 0x82F0 }, // 'WO'
188 { 0xDD, 1, 0x82F1 }, // 'N'
189
190 { 0x20, 1, 0x8140 }, // ' '
191// { 0xA0, 1, 0x8140 }, // ' '
192 { 0xA1, 1, 0x8142 }, //
193 { 0xA2, 1, 0x8175 }, //
194 { 0xA3, 1, 0x8176 }, //
195 { 0xA4, 1, 0x8141 }, //
196 { 0xA5, 1, 0x8145 }, //
197 { 0xB0, 1, 0x815b }, // '-'
198 { 0xDE, 1, 0x814a }, //
199 { 0xDF, 1, 0x814b }, //
200
201 { 0, 0, 0 } // == End of Table
202
203};
204
205/***
206*unsigned int _mbbtombc(c) - convert mbbvalue to mbcvalue.
207*
208*Purpose:
209* Converts mbbvalue (1-byte) to corresponding mbcvalue code (2-byte).
210*
211*Entry:
212* unsigned int c - mbbvalue character code to be converted.
213*
214*Exit:
215* Returns corresponding mbbvalue (2-byte).
216*
217*Exceptions:
218* Returns c if corresponding 2-byte code does not exist.
219*
220*******************************************************************************/
221
222extern "C" unsigned int __cdecl _mbbtombc_l(
223 unsigned int c,
224 _locale_t plocinfo
225 )
226{
227 int i;
228 _LocaleUpdate _loc_update(plocinfo);
229
230 if (_loc_update.GetLocaleT()->mbcinfo->mbcodepage != _KANJI_CP)
231 return (c);
232
233 /* If c is in the ASCII range, then look up the corresponding value
234 * in the mbbtable. */
235
236 if (c >= ASCLOW && c <= ASCHIGH)
237 return (mbbtable[c-ASCLOW]);
238
239 /* Exception for KANJI */
240
241 if (c == 0xdc)
242 return( 0x838f );
243
244 /* If c is a Katakana character, lookup in mbctable. */
245
246 if (c >= SBLOW && c <= SBHIGH)
247 {
248 for(i = 0; mbctable[i].asc != 0; i++)
249 {
250 if ( c == (unsigned int)mbctable[i].asc ) {
251 c = (unsigned int)mbctable[i].mbccode ;
252 break;
253 }
254 }
255 }
256
257 return(c);
258}
259
260extern "C" unsigned int (__cdecl _mbbtombc)(
261 unsigned int c
262 )
263{
264 return _mbbtombc_l(c, nullptr);
265}
266
267/***
268*unsigned int _mbctombb(c) - convert mbcvalue to mbbvalue.
269*
270*Purpose:
271* Converts mbcvalue (2-byte) to corresponding mbbvalue (1-byte).
272*
273*Entry:
274* unsigned int c - mbcvalue character code to convert.
275*
276*Exit:
277* Returns corresponding mbbvalue (1-byte).
278*
279*Exceptions:
280* Returns c if corresponding 1-byte code does not exist.
281*
282*******************************************************************************/
283
284extern "C" unsigned int __cdecl _mbctombb_l(
285 unsigned int c,
286 _locale_t plocinfo
287 )
288{
289 int i;
290 int result;
291 _LocaleUpdate _loc_update(plocinfo);
292
293 if (_loc_update.GetLocaleT()->mbcinfo->mbcodepage != _KANJI_CP)
294 return (c);
295
296 /* Check to see if c is in the ASCII range. */
297
298 for (i = 0; i <= ASCHIGH - ASCLOW; i++)
299 {
300 if (c == (unsigned int)mbbtable[i])
301 return((unsigned int)i + ASCLOW);
302 }
303
304
305 /* If c is a valid MBCS value, search the mbctable for value. */
306
307 if ( c <= MBLIMIT )
308 {
309 for (i = 0; mbctable[i].asc ; i++)
310 {
311 result = (int)c - (int)mbctable[i].mbccode;
312 if (result == 0)
313 return( (unsigned int)mbctable[i].asc );
314 else if (((c & 0xff00) == (unsigned int)(mbctable[i].mbccode & 0xff00))
315 && (result > 0)
316 && ((result - mbctable[i].synonym) < 0))
317 return( (unsigned int)mbctable[i].asc );
318 }
319 }
320
321 return(c);
322}
323
324extern "C" unsigned int (__cdecl _mbctombb)(
325 unsigned int c
326 )
327{
328 return _mbctombb_l(c, nullptr);
329}