Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * EUC_JP, SJIS and MULE_INTERNAL
4 : *
5 : * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
6 : * Portions Copyright (c) 1994, Regents of the University of California
7 : *
8 : * IDENTIFICATION
9 : * src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/euc_jp_and_sjis.c
10 : *
11 : *-------------------------------------------------------------------------
12 : */
13 :
14 : #include "postgres.h"
15 : #include "fmgr.h"
16 : #include "mb/pg_wchar.h"
17 :
18 : /*
19 : * SJIS alternative code.
20 : * this code is used if a mapping EUC -> SJIS is not defined.
21 : */
22 : #define PGSJISALTCODE 0x81ac
23 : #define PGEUCALTCODE 0xa2ae
24 :
25 : /*
26 : * conversion table between SJIS UDC (IBM kanji) and EUC_JP
27 : */
28 : #include "sjis.map"
29 :
30 12 : PG_MODULE_MAGIC;
31 :
32 6 : PG_FUNCTION_INFO_V1(euc_jp_to_sjis);
33 6 : PG_FUNCTION_INFO_V1(sjis_to_euc_jp);
34 6 : PG_FUNCTION_INFO_V1(euc_jp_to_mic);
35 12 : PG_FUNCTION_INFO_V1(mic_to_euc_jp);
36 6 : PG_FUNCTION_INFO_V1(sjis_to_mic);
37 12 : PG_FUNCTION_INFO_V1(mic_to_sjis);
38 :
39 : /* ----------
40 : * conv_proc(
41 : * INTEGER, -- source encoding id
42 : * INTEGER, -- destination encoding id
43 : * CSTRING, -- source string (null terminated C string)
44 : * CSTRING, -- destination string (null terminated C string)
45 : * INTEGER, -- source string length
46 : * BOOL -- if true, don't throw an error if conversion fails
47 : * ) returns INTEGER;
48 : *
49 : * Returns the number of bytes successfully converted.
50 : * ----------
51 : */
52 :
53 : static int sjis2mic(const unsigned char *sjis, unsigned char *p, int len, bool noError);
54 : static int mic2sjis(const unsigned char *mic, unsigned char *p, int len, bool noError);
55 : static int euc_jp2mic(const unsigned char *euc, unsigned char *p, int len, bool noError);
56 : static int mic2euc_jp(const unsigned char *mic, unsigned char *p, int len, bool noError);
57 : static int euc_jp2sjis(const unsigned char *euc, unsigned char *p, int len, bool noError);
58 : static int sjis2euc_jp(const unsigned char *sjis, unsigned char *p, int len, bool noError);
59 :
60 : Datum
61 6 : euc_jp_to_sjis(PG_FUNCTION_ARGS)
62 : {
63 6 : unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
64 6 : unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
65 6 : int len = PG_GETARG_INT32(4);
66 6 : bool noError = PG_GETARG_BOOL(5);
67 : int converted;
68 :
69 6 : CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_JP, PG_SJIS);
70 :
71 6 : converted = euc_jp2sjis(src, dest, len, noError);
72 :
73 6 : PG_RETURN_INT32(converted);
74 : }
75 :
76 : Datum
77 6 : sjis_to_euc_jp(PG_FUNCTION_ARGS)
78 : {
79 6 : unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
80 6 : unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
81 6 : int len = PG_GETARG_INT32(4);
82 6 : bool noError = PG_GETARG_BOOL(5);
83 : int converted;
84 :
85 6 : CHECK_ENCODING_CONVERSION_ARGS(PG_SJIS, PG_EUC_JP);
86 :
87 6 : converted = sjis2euc_jp(src, dest, len, noError);
88 :
89 6 : PG_RETURN_INT32(converted);
90 : }
91 :
92 : Datum
93 6 : euc_jp_to_mic(PG_FUNCTION_ARGS)
94 : {
95 6 : unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
96 6 : unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
97 6 : int len = PG_GETARG_INT32(4);
98 6 : bool noError = PG_GETARG_BOOL(5);
99 : int converted;
100 :
101 6 : CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_JP, PG_MULE_INTERNAL);
102 :
103 6 : converted = euc_jp2mic(src, dest, len, noError);
104 :
105 6 : PG_RETURN_INT32(converted);
106 : }
107 :
108 : Datum
109 330 : mic_to_euc_jp(PG_FUNCTION_ARGS)
110 : {
111 330 : unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
112 330 : unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
113 330 : int len = PG_GETARG_INT32(4);
114 330 : bool noError = PG_GETARG_BOOL(5);
115 : int converted;
116 :
117 330 : CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_EUC_JP);
118 :
119 330 : converted = mic2euc_jp(src, dest, len, noError);
120 :
121 186 : PG_RETURN_INT32(converted);
122 : }
123 :
124 : Datum
125 6 : sjis_to_mic(PG_FUNCTION_ARGS)
126 : {
127 6 : unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
128 6 : unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
129 6 : int len = PG_GETARG_INT32(4);
130 6 : bool noError = PG_GETARG_BOOL(5);
131 : int converted;
132 :
133 6 : CHECK_ENCODING_CONVERSION_ARGS(PG_SJIS, PG_MULE_INTERNAL);
134 :
135 6 : converted = sjis2mic(src, dest, len, noError);
136 :
137 6 : PG_RETURN_INT32(converted);
138 : }
139 :
140 : Datum
141 330 : mic_to_sjis(PG_FUNCTION_ARGS)
142 : {
143 330 : unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
144 330 : unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
145 330 : int len = PG_GETARG_INT32(4);
146 330 : bool noError = PG_GETARG_BOOL(5);
147 : int converted;
148 :
149 330 : CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_SJIS);
150 :
151 330 : converted = mic2sjis(src, dest, len, noError);
152 :
153 186 : PG_RETURN_INT32(converted);
154 : }
155 :
156 : /*
157 : * SJIS ---> MIC
158 : */
159 : static int
160 6 : sjis2mic(const unsigned char *sjis, unsigned char *p, int len, bool noError)
161 : {
162 6 : const unsigned char *start = sjis;
163 : int c1,
164 : c2,
165 : i,
166 : k,
167 : k2;
168 :
169 24 : while (len > 0)
170 : {
171 18 : c1 = *sjis;
172 18 : if (c1 >= 0xa1 && c1 <= 0xdf)
173 : {
174 : /* JIS X0201 (1 byte kana) */
175 0 : *p++ = LC_JISX0201K;
176 0 : *p++ = c1;
177 0 : sjis++;
178 0 : len--;
179 : }
180 18 : else if (IS_HIGHBIT_SET(c1))
181 : {
182 : /*
183 : * JIS X0208, X0212, user defined extended characters
184 : */
185 0 : if (len < 2 || !ISSJISHEAD(c1) || !ISSJISTAIL(sjis[1]))
186 : {
187 0 : if (noError)
188 0 : break;
189 0 : report_invalid_encoding(PG_SJIS, (const char *) sjis, len);
190 : }
191 0 : c2 = sjis[1];
192 0 : k = (c1 << 8) + c2;
193 0 : if (k >= 0xed40 && k < 0xf040)
194 : {
195 : /* NEC selection IBM kanji */
196 0 : for (i = 0;; i++)
197 : {
198 0 : k2 = ibmkanji[i].nec;
199 0 : if (k2 == 0xffff)
200 0 : break;
201 0 : if (k2 == k)
202 : {
203 0 : k = ibmkanji[i].sjis;
204 0 : c1 = (k >> 8) & 0xff;
205 0 : c2 = k & 0xff;
206 : }
207 : }
208 : }
209 :
210 0 : if (k < 0xeb3f)
211 : {
212 : /* JIS X0208 */
213 0 : *p++ = LC_JISX0208;
214 0 : *p++ = ((c1 & 0x3f) << 1) + 0x9f + (c2 > 0x9e);
215 0 : *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
216 : }
217 0 : else if ((k >= 0xeb40 && k < 0xf040) || (k >= 0xfc4c && k <= 0xfcfc))
218 : {
219 : /* NEC selection IBM kanji - Other undecided justice */
220 0 : *p++ = LC_JISX0208;
221 0 : *p++ = PGEUCALTCODE >> 8;
222 0 : *p++ = PGEUCALTCODE & 0xff;
223 : }
224 0 : else if (k >= 0xf040 && k < 0xf540)
225 : {
226 : /*
227 : * UDC1 mapping to X0208 85 ku - 94 ku JIS code 0x7521 -
228 : * 0x7e7e EUC 0xf5a1 - 0xfefe
229 : */
230 0 : *p++ = LC_JISX0208;
231 0 : c1 -= 0x6f;
232 0 : *p++ = ((c1 & 0x3f) << 1) + 0xf3 + (c2 > 0x9e);
233 0 : *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
234 : }
235 0 : else if (k >= 0xf540 && k < 0xfa40)
236 : {
237 : /*
238 : * UDC2 mapping to X0212 85 ku - 94 ku JIS code 0x7521 -
239 : * 0x7e7e EUC 0x8ff5a1 - 0x8ffefe
240 : */
241 0 : *p++ = LC_JISX0212;
242 0 : c1 -= 0x74;
243 0 : *p++ = ((c1 & 0x3f) << 1) + 0xf3 + (c2 > 0x9e);
244 0 : *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
245 : }
246 0 : else if (k >= 0xfa40)
247 : {
248 : /*
249 : * mapping IBM kanji to X0208 and X0212
250 : */
251 0 : for (i = 0;; i++)
252 : {
253 0 : k2 = ibmkanji[i].sjis;
254 0 : if (k2 == 0xffff)
255 0 : break;
256 0 : if (k2 == k)
257 : {
258 0 : k = ibmkanji[i].euc;
259 0 : if (k >= 0x8f0000)
260 : {
261 0 : *p++ = LC_JISX0212;
262 0 : *p++ = 0x80 | ((k & 0xff00) >> 8);
263 0 : *p++ = 0x80 | (k & 0xff);
264 : }
265 : else
266 : {
267 0 : *p++ = LC_JISX0208;
268 0 : *p++ = 0x80 | (k >> 8);
269 0 : *p++ = 0x80 | (k & 0xff);
270 : }
271 : }
272 : }
273 : }
274 0 : sjis += 2;
275 0 : len -= 2;
276 : }
277 : else
278 : { /* should be ASCII */
279 18 : if (c1 == 0)
280 : {
281 0 : if (noError)
282 0 : break;
283 0 : report_invalid_encoding(PG_SJIS, (const char *) sjis, len);
284 : }
285 18 : *p++ = c1;
286 18 : sjis++;
287 18 : len--;
288 : }
289 : }
290 6 : *p = '\0';
291 :
292 6 : return sjis - start;
293 : }
294 :
295 : /*
296 : * MIC ---> SJIS
297 : */
298 : static int
299 330 : mic2sjis(const unsigned char *mic, unsigned char *p, int len, bool noError)
300 : {
301 330 : const unsigned char *start = mic;
302 : int c1,
303 : c2,
304 : k,
305 : l;
306 :
307 672 : while (len > 0)
308 : {
309 630 : c1 = *mic;
310 630 : if (!IS_HIGHBIT_SET(c1))
311 : {
312 : /* ASCII */
313 324 : if (c1 == 0)
314 : {
315 36 : if (noError)
316 18 : break;
317 18 : report_invalid_encoding(PG_MULE_INTERNAL,
318 : (const char *) mic, len);
319 : }
320 288 : *p++ = c1;
321 288 : mic++;
322 288 : len--;
323 288 : continue;
324 : }
325 306 : l = pg_encoding_verifymbchar(PG_MULE_INTERNAL, (const char *) mic, len);
326 306 : if (l < 0)
327 : {
328 144 : if (noError)
329 72 : break;
330 72 : report_invalid_encoding(PG_MULE_INTERNAL,
331 : (const char *) mic, len);
332 : }
333 162 : if (c1 == LC_JISX0201K)
334 0 : *p++ = mic[1];
335 162 : else if (c1 == LC_JISX0208)
336 : {
337 54 : c1 = mic[1];
338 54 : c2 = mic[2];
339 54 : k = (c1 << 8) | (c2 & 0xff);
340 54 : if (k >= 0xf5a1)
341 : {
342 : /* UDC1 */
343 0 : c1 -= 0x54;
344 0 : *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1) + 0x6f;
345 : }
346 : else
347 54 : *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1);
348 54 : *p++ = c2 - ((c1 & 1) ? ((c2 < 0xe0) ? 0x61 : 0x60) : 2);
349 : }
350 108 : else if (c1 == LC_JISX0212)
351 : {
352 : int i,
353 : k2;
354 :
355 0 : c1 = mic[1];
356 0 : c2 = mic[2];
357 0 : k = c1 << 8 | c2;
358 0 : if (k >= 0xf5a1)
359 : {
360 : /* UDC2 */
361 0 : c1 -= 0x54;
362 0 : *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1) + 0x74;
363 0 : *p++ = c2 - ((c1 & 1) ? ((c2 < 0xe0) ? 0x61 : 0x60) : 2);
364 : }
365 : else
366 : {
367 : /* IBM kanji */
368 0 : for (i = 0;; i++)
369 : {
370 0 : k2 = ibmkanji[i].euc & 0xffff;
371 0 : if (k2 == 0xffff)
372 : {
373 0 : *p++ = PGSJISALTCODE >> 8;
374 0 : *p++ = PGSJISALTCODE & 0xff;
375 0 : break;
376 : }
377 0 : if (k2 == k)
378 : {
379 0 : k = ibmkanji[i].sjis;
380 0 : *p++ = k >> 8;
381 0 : *p++ = k & 0xff;
382 0 : break;
383 : }
384 : }
385 : }
386 : }
387 : else
388 : {
389 108 : if (noError)
390 54 : break;
391 54 : report_untranslatable_char(PG_MULE_INTERNAL, PG_SJIS,
392 : (const char *) mic, len);
393 : }
394 54 : mic += l;
395 54 : len -= l;
396 : }
397 186 : *p = '\0';
398 :
399 186 : return mic - start;
400 : }
401 :
402 : /*
403 : * EUC_JP ---> MIC
404 : */
405 : static int
406 6 : euc_jp2mic(const unsigned char *euc, unsigned char *p, int len, bool noError)
407 : {
408 6 : const unsigned char *start = euc;
409 : int c1;
410 : int l;
411 :
412 24 : while (len > 0)
413 : {
414 18 : c1 = *euc;
415 18 : if (!IS_HIGHBIT_SET(c1))
416 : {
417 : /* ASCII */
418 18 : if (c1 == 0)
419 : {
420 0 : if (noError)
421 0 : break;
422 0 : report_invalid_encoding(PG_EUC_JP,
423 : (const char *) euc, len);
424 : }
425 18 : *p++ = c1;
426 18 : euc++;
427 18 : len--;
428 18 : continue;
429 : }
430 0 : l = pg_encoding_verifymbchar(PG_EUC_JP, (const char *) euc, len);
431 0 : if (l < 0)
432 : {
433 0 : if (noError)
434 0 : break;
435 0 : report_invalid_encoding(PG_EUC_JP,
436 : (const char *) euc, len);
437 : }
438 0 : if (c1 == SS2)
439 : { /* 1 byte kana? */
440 0 : *p++ = LC_JISX0201K;
441 0 : *p++ = euc[1];
442 : }
443 0 : else if (c1 == SS3)
444 : { /* JIS X0212 kanji? */
445 0 : *p++ = LC_JISX0212;
446 0 : *p++ = euc[1];
447 0 : *p++ = euc[2];
448 : }
449 : else
450 : { /* kanji? */
451 0 : *p++ = LC_JISX0208;
452 0 : *p++ = c1;
453 0 : *p++ = euc[1];
454 : }
455 0 : euc += l;
456 0 : len -= l;
457 : }
458 6 : *p = '\0';
459 :
460 6 : return euc - start;
461 : }
462 :
463 : /*
464 : * MIC ---> EUC_JP
465 : */
466 : static int
467 330 : mic2euc_jp(const unsigned char *mic, unsigned char *p, int len, bool noError)
468 : {
469 330 : const unsigned char *start = mic;
470 : int c1;
471 : int l;
472 :
473 672 : while (len > 0)
474 : {
475 630 : c1 = *mic;
476 630 : if (!IS_HIGHBIT_SET(c1))
477 : {
478 : /* ASCII */
479 324 : if (c1 == 0)
480 : {
481 36 : if (noError)
482 18 : break;
483 18 : report_invalid_encoding(PG_MULE_INTERNAL,
484 : (const char *) mic, len);
485 : }
486 288 : *p++ = c1;
487 288 : mic++;
488 288 : len--;
489 288 : continue;
490 : }
491 306 : l = pg_encoding_verifymbchar(PG_MULE_INTERNAL, (const char *) mic, len);
492 306 : if (l < 0)
493 : {
494 144 : if (noError)
495 72 : break;
496 72 : report_invalid_encoding(PG_MULE_INTERNAL,
497 : (const char *) mic, len);
498 : }
499 162 : if (c1 == LC_JISX0201K)
500 : {
501 0 : *p++ = SS2;
502 0 : *p++ = mic[1];
503 : }
504 162 : else if (c1 == LC_JISX0212)
505 : {
506 0 : *p++ = SS3;
507 0 : *p++ = mic[1];
508 0 : *p++ = mic[2];
509 : }
510 162 : else if (c1 == LC_JISX0208)
511 : {
512 54 : *p++ = mic[1];
513 54 : *p++ = mic[2];
514 : }
515 : else
516 : {
517 108 : if (noError)
518 54 : break;
519 54 : report_untranslatable_char(PG_MULE_INTERNAL, PG_EUC_JP,
520 : (const char *) mic, len);
521 : }
522 54 : mic += l;
523 54 : len -= l;
524 : }
525 186 : *p = '\0';
526 :
527 186 : return mic - start;
528 : }
529 :
530 : /*
531 : * EUC_JP -> SJIS
532 : */
533 : static int
534 6 : euc_jp2sjis(const unsigned char *euc, unsigned char *p, int len, bool noError)
535 : {
536 6 : const unsigned char *start = euc;
537 : int c1,
538 : c2,
539 : k;
540 : int l;
541 :
542 24 : while (len > 0)
543 : {
544 18 : c1 = *euc;
545 18 : if (!IS_HIGHBIT_SET(c1))
546 : {
547 : /* ASCII */
548 18 : if (c1 == 0)
549 : {
550 0 : if (noError)
551 0 : break;
552 0 : report_invalid_encoding(PG_EUC_JP,
553 : (const char *) euc, len);
554 : }
555 18 : *p++ = c1;
556 18 : euc++;
557 18 : len--;
558 18 : continue;
559 : }
560 0 : l = pg_encoding_verifymbchar(PG_EUC_JP, (const char *) euc, len);
561 0 : if (l < 0)
562 : {
563 0 : if (noError)
564 0 : break;
565 0 : report_invalid_encoding(PG_EUC_JP,
566 : (const char *) euc, len);
567 : }
568 0 : if (c1 == SS2)
569 : {
570 : /* hankaku kana? */
571 0 : *p++ = euc[1];
572 : }
573 0 : else if (c1 == SS3)
574 : {
575 : /* JIS X0212 kanji? */
576 0 : c1 = euc[1];
577 0 : c2 = euc[2];
578 0 : k = c1 << 8 | c2;
579 0 : if (k >= 0xf5a1)
580 : {
581 : /* UDC2 */
582 0 : c1 -= 0x54;
583 0 : *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1) + 0x74;
584 0 : *p++ = c2 - ((c1 & 1) ? ((c2 < 0xe0) ? 0x61 : 0x60) : 2);
585 : }
586 : else
587 : {
588 : int i,
589 : k2;
590 :
591 : /* IBM kanji */
592 0 : for (i = 0;; i++)
593 : {
594 0 : k2 = ibmkanji[i].euc & 0xffff;
595 0 : if (k2 == 0xffff)
596 : {
597 0 : *p++ = PGSJISALTCODE >> 8;
598 0 : *p++ = PGSJISALTCODE & 0xff;
599 0 : break;
600 : }
601 0 : if (k2 == k)
602 : {
603 0 : k = ibmkanji[i].sjis;
604 0 : *p++ = k >> 8;
605 0 : *p++ = k & 0xff;
606 0 : break;
607 : }
608 : }
609 : }
610 : }
611 : else
612 : {
613 : /* JIS X0208 kanji? */
614 0 : c2 = euc[1];
615 0 : k = (c1 << 8) | (c2 & 0xff);
616 0 : if (k >= 0xf5a1)
617 : {
618 : /* UDC1 */
619 0 : c1 -= 0x54;
620 0 : *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1) + 0x6f;
621 : }
622 : else
623 0 : *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1);
624 0 : *p++ = c2 - ((c1 & 1) ? ((c2 < 0xe0) ? 0x61 : 0x60) : 2);
625 : }
626 0 : euc += l;
627 0 : len -= l;
628 : }
629 6 : *p = '\0';
630 :
631 6 : return euc - start;
632 : }
633 :
634 : /*
635 : * SJIS ---> EUC_JP
636 : */
637 : static int
638 6 : sjis2euc_jp(const unsigned char *sjis, unsigned char *p, int len, bool noError)
639 : {
640 6 : const unsigned char *start = sjis;
641 : int c1,
642 : c2,
643 : i,
644 : k,
645 : k2;
646 : int l;
647 :
648 24 : while (len > 0)
649 : {
650 18 : c1 = *sjis;
651 18 : if (!IS_HIGHBIT_SET(c1))
652 : {
653 : /* ASCII */
654 18 : if (c1 == 0)
655 : {
656 0 : if (noError)
657 0 : break;
658 0 : report_invalid_encoding(PG_SJIS,
659 : (const char *) sjis, len);
660 : }
661 18 : *p++ = c1;
662 18 : sjis++;
663 18 : len--;
664 18 : continue;
665 : }
666 0 : l = pg_encoding_verifymbchar(PG_SJIS, (const char *) sjis, len);
667 0 : if (l < 0)
668 : {
669 0 : if (noError)
670 0 : break;
671 0 : report_invalid_encoding(PG_SJIS,
672 : (const char *) sjis, len);
673 : }
674 0 : if (c1 >= 0xa1 && c1 <= 0xdf)
675 : {
676 : /* JIS X0201 (1 byte kana) */
677 0 : *p++ = SS2;
678 0 : *p++ = c1;
679 : }
680 : else
681 : {
682 : /*
683 : * JIS X0208, X0212, user defined extended characters
684 : */
685 0 : c2 = sjis[1];
686 0 : k = (c1 << 8) + c2;
687 0 : if (k >= 0xed40 && k < 0xf040)
688 : {
689 : /* NEC selection IBM kanji */
690 0 : for (i = 0;; i++)
691 : {
692 0 : k2 = ibmkanji[i].nec;
693 0 : if (k2 == 0xffff)
694 0 : break;
695 0 : if (k2 == k)
696 : {
697 0 : k = ibmkanji[i].sjis;
698 0 : c1 = (k >> 8) & 0xff;
699 0 : c2 = k & 0xff;
700 : }
701 : }
702 : }
703 :
704 0 : if (k < 0xeb3f)
705 : {
706 : /* JIS X0208 */
707 0 : *p++ = ((c1 & 0x3f) << 1) + 0x9f + (c2 > 0x9e);
708 0 : *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
709 : }
710 0 : else if ((k >= 0xeb40 && k < 0xf040) || (k >= 0xfc4c && k <= 0xfcfc))
711 : {
712 : /* NEC selection IBM kanji - Other undecided justice */
713 0 : *p++ = PGEUCALTCODE >> 8;
714 0 : *p++ = PGEUCALTCODE & 0xff;
715 : }
716 0 : else if (k >= 0xf040 && k < 0xf540)
717 : {
718 : /*
719 : * UDC1 mapping to X0208 85 ku - 94 ku JIS code 0x7521 -
720 : * 0x7e7e EUC 0xf5a1 - 0xfefe
721 : */
722 0 : c1 -= 0x6f;
723 0 : *p++ = ((c1 & 0x3f) << 1) + 0xf3 + (c2 > 0x9e);
724 0 : *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
725 : }
726 0 : else if (k >= 0xf540 && k < 0xfa40)
727 : {
728 : /*
729 : * UDC2 mapping to X0212 85 ku - 94 ku JIS code 0x7521 -
730 : * 0x7e7e EUC 0x8ff5a1 - 0x8ffefe
731 : */
732 0 : *p++ = SS3;
733 0 : c1 -= 0x74;
734 0 : *p++ = ((c1 & 0x3f) << 1) + 0xf3 + (c2 > 0x9e);
735 0 : *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
736 : }
737 0 : else if (k >= 0xfa40)
738 : {
739 : /*
740 : * mapping IBM kanji to X0208 and X0212
741 : *
742 : */
743 0 : for (i = 0;; i++)
744 : {
745 0 : k2 = ibmkanji[i].sjis;
746 0 : if (k2 == 0xffff)
747 0 : break;
748 0 : if (k2 == k)
749 : {
750 0 : k = ibmkanji[i].euc;
751 0 : if (k >= 0x8f0000)
752 : {
753 0 : *p++ = SS3;
754 0 : *p++ = 0x80 | ((k & 0xff00) >> 8);
755 0 : *p++ = 0x80 | (k & 0xff);
756 : }
757 : else
758 : {
759 0 : *p++ = 0x80 | (k >> 8);
760 0 : *p++ = 0x80 | (k & 0xff);
761 : }
762 : }
763 : }
764 : }
765 : }
766 0 : sjis += l;
767 0 : len -= l;
768 : }
769 6 : *p = '\0';
770 :
771 6 : return sjis - start;
772 : }
|