OSDN Git Service

Modify documents.
[ffftp/ffftp.git] / codecnv.c
1 /*=============================================================================\r
2 *\r
3 *                                                       漢字コード変換/改行コード変換\r
4 *\r
5 ===============================================================================\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.\r
7 /\r
8 / Redistribution and use in source and binary forms, with or without \r
9 / modification, are permitted provided that the following conditions \r
10 / are met:\r
11 /\r
12 /  1. Redistributions of source code must retain the above copyright \r
13 /     notice, this list of conditions and the following disclaimer.\r
14 /  2. Redistributions in binary form must reproduce the above copyright \r
15 /     notice, this list of conditions and the following disclaimer in the \r
16 /     documentation and/or other materials provided with the distribution.\r
17 /\r
18 / THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR \r
19 / IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES \r
20 / OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
21 / IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
22 / INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
23 / BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
24 / USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
25 / ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
26 / (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF \r
27 / THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
28 /============================================================================*/\r
29 \r
30 #define STRICT\r
31 #include <stdio.h>\r
32 #include <stdlib.h>\r
33 #include <string.h>\r
34 // IPv6対応\r
35 //#include <winsock.h>\r
36 #include <winsock2.h>\r
37 #include <mbstring.h>\r
38 #include <windowsx.h>\r
39 \r
40 #include "common.h"\r
41 #include "resource.h"\r
42 \r
43 \r
44 \r
45 #define CONV_ASCII              0               /* ASCII文字処理中 */\r
46 #define CONV_KANJI              1               /* 漢字処理中 */\r
47 #define CONV_KANA               2               /* 半角カタカナ処理中 */\r
48 \r
49 \r
50 /*===== プロトタイプ =====*/\r
51 \r
52 static char *ConvEUCtoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);\r
53 static char *ConvJIStoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);\r
54 static char *ConvSJIStoEUCkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);\r
55 static char *ConvSJIStoJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);\r
56 static int HanKataToZen(char Ch);\r
57 static int AskDakuon(char Ch, char Daku);\r
58 \r
59 static int CheckOnSJIS(uchar *Pos, uchar *Btm);\r
60 static int CheckOnEUC(uchar *Pos, uchar *Btm);\r
61 static int ConvertIBMExtendedChar(int code);\r
62 \r
63 \r
64 \r
65 #if 0\r
66 /*----- 漢字コード変換のテストプログラム ------------------------------------*/\r
67 \r
68 void CodeCnvTest(void)\r
69 {\r
70         #define BUFBUF  43\r
71         #define BUFBUF2 BUFBUF+3\r
72 \r
73         CODECONVINFO cInfo;\r
74         char Buf[BUFBUF];\r
75         char Buf2[BUFBUF2];\r
76         FILE *Strm1;\r
77         FILE *Strm2;\r
78         int Byte;\r
79         int Continue;\r
80 \r
81 //      DoPrintf("---START ZEN");\r
82 \r
83         Strm1 = fopen("in.txt", "rb");\r
84         Strm2 = fopen("out_zen.txt", "wb");\r
85 \r
86         InitCodeConvInfo(&cInfo);\r
87         cInfo.KanaCnv = YES;\r
88 \r
89 \r
90         while((Byte = fread(Buf, 1, BUFBUF, Strm1)) != 0)\r
91         {\r
92                 cInfo.Str = Buf;\r
93                 cInfo.StrLen = Byte;\r
94                 cInfo.Buf = Buf2;\r
95                 cInfo.BufSize = BUFBUF2;\r
96 \r
97 //              DoPrintf("READ %d", Byte);\r
98 \r
99                 do\r
100                 {\r
101 //                      Continue = ConvEUCtoSJIS(&cInfo);\r
102 //                      Continue = ConvJIStoSJIS(&cInfo);\r
103 //                      Continue = ConvSJIStoEUC(&cInfo);\r
104 //                      Continue = ConvSJIStoJIS(&cInfo);\r
105                         Continue = ConvSMBtoSJIS(&cInfo);\r
106 //                      Continue = ConvSJIStoSMB_HEX(&cInfo);\r
107 //                      Continue = ConvSJIStoSMB_CAP(&cInfo);\r
108 \r
109                         fwrite(Buf2, cInfo.OutLen, 1, Strm2);\r
110 //                      DoPrintf("WRITE %d", cInfo.OutLen);\r
111 \r
112                 }\r
113                 while(Continue == YES);\r
114         }\r
115 \r
116         cInfo.Buf = Buf2;\r
117         cInfo.BufSize = BUFBUF2;\r
118         FlushRestData(&cInfo);\r
119         fwrite(Buf2, cInfo.OutLen, 1, Strm2);\r
120 //      DoPrintf("WRITE %d", cInfo.OutLen);\r
121 \r
122 \r
123         fclose(Strm1);\r
124         fclose(Strm2);\r
125 \r
126 \r
127 //      DoPrintf("---START HAN");\r
128 \r
129         Strm1 = fopen("in.txt", "rb");\r
130         Strm2 = fopen("out_han.txt", "wb");\r
131 \r
132         InitCodeConvInfo(&cInfo);\r
133         cInfo.KanaCnv = NO;\r
134 \r
135 \r
136         while((Byte = fread(Buf, 1, BUFBUF, Strm1)) != 0)\r
137         {\r
138                 cInfo.Str = Buf;\r
139                 cInfo.StrLen = Byte;\r
140                 cInfo.Buf = Buf2;\r
141                 cInfo.BufSize = BUFBUF2;\r
142 \r
143 //              DoPrintf("READ %d", Byte);\r
144 \r
145                 do\r
146                 {\r
147 //                      Continue = ConvEUCtoSJIS(&cInfo);\r
148 //                      Continue = ConvJIStoSJIS(&cInfo);\r
149 //                      Continue = ConvSJIStoEUC(&cInfo);\r
150 //                      Continue = ConvSJIStoJIS(&cInfo);\r
151                         Continue = ConvSMBtoSJIS(&cInfo);\r
152 //                      Continue = ConvSJIStoSMB_HEX(&cInfo);\r
153 //                      Continue = ConvSJIStoSMB_CAP(&cInfo);\r
154                         fwrite(Buf2, cInfo.OutLen, 1, Strm2);\r
155 //                      DoPrintf("WRITE %d", cInfo.OutLen);\r
156 \r
157                 }\r
158                 while(Continue == YES);\r
159         }\r
160 \r
161         cInfo.Buf = Buf2;\r
162         cInfo.BufSize = BUFBUF2;\r
163         FlushRestData(&cInfo);\r
164         fwrite(Buf2, cInfo.OutLen, 1, Strm2);\r
165 //      DoPrintf("WRITE %d", cInfo.OutLen);\r
166 \r
167         fclose(Strm1);\r
168         fclose(Strm2);\r
169 \r
170 //      DoPrintf("---END");\r
171 \r
172         return;\r
173 }\r
174 #endif\r
175 \r
176 \r
177 \r
178 #if 0\r
179 /*----- 改行コード変換のテストプログラム ------------------------------------*/\r
180 \r
181 void TermCodeCnvTest(void)\r
182 {\r
183         #define BUFBUF  10\r
184         #define BUFBUF2 BUFBUF\r
185 \r
186         TERMCODECONVINFO cInfo;\r
187         char Buf[BUFBUF];\r
188         char Buf2[BUFBUF2];\r
189         FILE *Strm1;\r
190         FILE *Strm2;\r
191         int Byte;\r
192         int Continue;\r
193 \r
194 //      DoPrintf("---START");\r
195 \r
196         Strm1 = fopen("in.txt", "rb");\r
197         Strm2 = fopen("out.txt", "wb");\r
198 \r
199         InitTermCodeConvInfo(&cInfo);\r
200 \r
201         while((Byte = fread(Buf, 1, BUFBUF, Strm1)) != 0)\r
202         {\r
203                 cInfo.Str = Buf;\r
204                 cInfo.StrLen = Byte;\r
205                 cInfo.Buf = Buf2;\r
206                 cInfo.BufSize = BUFBUF2;\r
207 \r
208 //              DoPrintf("READ %d", Byte);\r
209 \r
210                 do\r
211                 {\r
212                         Continue = ConvTermCodeToCRLF(&cInfo);\r
213 \r
214                         fwrite(Buf2, cInfo.OutLen, 1, Strm2);\r
215 //                      DoPrintf("WRITE %d", cInfo.OutLen);\r
216 \r
217                 }\r
218                 while(Continue == YES);\r
219         }\r
220 \r
221         cInfo.Buf = Buf2;\r
222         cInfo.BufSize = BUFBUF2;\r
223         FlushRestTermCodeConvData(&cInfo);\r
224         fwrite(Buf2, cInfo.OutLen, 1, Strm2);\r
225 //      DoPrintf("WRITE %d", cInfo.OutLen);\r
226 \r
227         fclose(Strm1);\r
228         fclose(Strm2);\r
229 \r
230 //      DoPrintf("---END");\r
231 \r
232         return;\r
233 }\r
234 #endif\r
235 \r
236 \r
237 \r
238 \r
239 \r
240 \r
241 \r
242 \r
243 \r
244 \r
245 \r
246 \r
247 /*----- 改行コード変換情報を初期化 --------------------------------------------\r
248 *\r
249 *       Parameter\r
250 *               TERMCODECONVINFO *cInfo : 改行コード変換情報\r
251 *\r
252 *       Return Value\r
253 *               なし\r
254 *----------------------------------------------------------------------------*/\r
255 \r
256 void InitTermCodeConvInfo(TERMCODECONVINFO *cInfo)\r
257 {\r
258         cInfo->Term = 0;\r
259         return;\r
260 }\r
261 \r
262 \r
263 /*----- 改行コード変換の残り情報を出力 ----------------------------------------\r
264 *\r
265 *       Parameter\r
266 *               TERMCODECONVINFO *cInfo : 改行コード変換情報\r
267 *\r
268 *       Return Value\r
269 *               int くり返しフラグ (=NO)\r
270 *\r
271 *       Note\r
272 *               改行コード変換の最後に呼ぶ事\r
273 *----------------------------------------------------------------------------*/\r
274 \r
275 int FlushRestTermCodeConvData(TERMCODECONVINFO *cInfo)\r
276 {\r
277         char *Put;\r
278 \r
279         Put = cInfo->Buf;\r
280 \r
281         if(cInfo->Term == 0x0D)\r
282                 *Put++ = 0x0A;\r
283 \r
284         cInfo->OutLen = Put - cInfo->Buf;\r
285 \r
286         return(NO);\r
287 }\r
288 \r
289 \r
290 /*----- 改行コードをCRLFに変換 -------------------------------------------------\r
291 *\r
292 *       Parameter\r
293 *               TERMCODECONVINFO *cInfo : 改行コード変換情報\r
294 *\r
295 *       Return Value\r
296 *               int くり返しフラグ (YES/NO)\r
297 *\r
298 *       Note\r
299 *               くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
300 *----------------------------------------------------------------------------*/\r
301 \r
302 int ConvTermCodeToCRLF(TERMCODECONVINFO *cInfo)\r
303 {\r
304         char *Str;\r
305         char *Put;\r
306         char *Limit;\r
307         int Continue;\r
308 \r
309         Continue = NO;\r
310         Str = cInfo->Str;\r
311         Put = cInfo->Buf;\r
312         Limit = cInfo->Buf + cInfo->BufSize - 1;\r
313 \r
314         for(; cInfo->StrLen > 0; cInfo->StrLen--)\r
315         {\r
316                 if(Put >= Limit)\r
317                 {\r
318                         Continue = YES;\r
319                         break;\r
320                 }\r
321 \r
322                 if(*Str == 0x0D)\r
323                 {\r
324                         if(cInfo->Term == 0x0D)\r
325                                 *Put++ = 0x0A;\r
326                         *Put++ = 0x0D;\r
327                         cInfo->Term = *Str++;\r
328                 }\r
329                 else\r
330                 {\r
331                         if(*Str == 0x0A)\r
332                         {\r
333                                 if(cInfo->Term != 0x0D)\r
334                                         *Put++ = 0x0D;\r
335                         }\r
336                         else\r
337                         {\r
338                                 if(cInfo->Term == 0x0D)\r
339                                         *Put++ = 0x0A;\r
340                         }\r
341                         cInfo->Term = 0;\r
342                         *Put++ = *Str++;\r
343                 }\r
344         }\r
345 \r
346         cInfo->Str = Str;\r
347         cInfo->OutLen = Put - cInfo->Buf;\r
348 \r
349         return(Continue);\r
350 }\r
351 \r
352 \r
353 /*----- 漢字コード変換情報を初期化 --------------------------------------------\r
354 *\r
355 *       Parameter\r
356 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
357 *\r
358 *       Return Value\r
359 *               なし\r
360 *----------------------------------------------------------------------------*/\r
361 \r
362 void InitCodeConvInfo(CODECONVINFO *cInfo)\r
363 {\r
364         cInfo->KanaCnv = YES;\r
365 \r
366         cInfo->EscProc = 0;\r
367         cInfo->KanjiMode = CONV_ASCII;\r
368         cInfo->KanjiFst = 0;\r
369         cInfo->KanaPrev = 0;\r
370         cInfo->KanaProc = NULL;\r
371         // UTF-8対応\r
372         cInfo->EscUTF8Len = 0;\r
373         return;\r
374 }\r
375 \r
376 \r
377 /*----- 漢字コード変換の残り情報を出力 ----------------------------------------\r
378 *\r
379 *       Parameter\r
380 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
381 *\r
382 *       Return Value\r
383 *               int くり返しフラグ (=NO)\r
384 *\r
385 *       Note\r
386 *               漢字コード変換の最後に呼ぶ事\r
387 *----------------------------------------------------------------------------*/\r
388 \r
389 int FlushRestData(CODECONVINFO *cInfo)\r
390 {\r
391         char *Put;\r
392 \r
393         Put = cInfo->Buf;\r
394 \r
395         if(cInfo->KanaProc != NULL)\r
396                 Put = (cInfo->KanaProc)(cInfo, 0, Put);\r
397 \r
398         if(cInfo->KanjiFst != 0)\r
399                 *Put++ = cInfo->KanjiFst;\r
400         if(cInfo->EscProc >= 1)\r
401                 *Put++ = cInfo->EscCode[0];\r
402         if(cInfo->EscProc == 2)\r
403                 *Put++ = cInfo->EscCode[1];\r
404         // UTF-8対応\r
405         memcpy(Put, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);\r
406         Put += cInfo->EscUTF8Len;\r
407 \r
408         cInfo->OutLen = Put - cInfo->Buf;\r
409 \r
410         return(NO);\r
411 }\r
412 \r
413 \r
414 /*----- EUC漢字コードをSHIFT-JIS漢字コードに変換 ------------------------------\r
415 *\r
416 *       Parameter\r
417 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
418 *\r
419 *       Return Value\r
420 *               int くり返しフラグ (YES/NO)\r
421 *\r
422 *       Note\r
423 *               くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
424 *----------------------------------------------------------------------------*/\r
425 \r
426 int ConvEUCtoSJIS(CODECONVINFO *cInfo)\r
427 {\r
428         int Kcode;\r
429         char *Str;\r
430         char *Put;\r
431         char *Limit;\r
432         int Continue;\r
433 \r
434         cInfo->KanaProc = &ConvEUCtoSJISkanaProc;\r
435 \r
436         Continue = NO;\r
437         Str = cInfo->Str;\r
438         Put = cInfo->Buf;\r
439         Limit = cInfo->Buf + cInfo->BufSize - 2;\r
440 \r
441         for(; cInfo->StrLen > 0; cInfo->StrLen--)\r
442         {\r
443                 if(Put >= Limit)\r
444                 {\r
445                         Continue = YES;\r
446                         break;\r
447                 }\r
448 \r
449                 if((*Str & 0x80) != 0)\r
450                 {\r
451                         if(cInfo->KanjiFst == 0)\r
452                                 cInfo->KanjiFst = *Str++;\r
453                         else\r
454                         {\r
455                                 if((uchar)cInfo->KanjiFst == (uchar)0x8E)       /* 半角カタカナ */\r
456                                 {\r
457                                         Put = ConvEUCtoSJISkanaProc(cInfo, *Str++, Put);\r
458                                 }\r
459                                 else\r
460                                 {\r
461                                         Put = ConvEUCtoSJISkanaProc(cInfo, 0, Put);\r
462 \r
463                                         Kcode = _mbcjistojms(((cInfo->KanjiFst & 0x7F) * 0x100) + (*Str++ & 0x7F));\r
464                                         *Put++ = HIGH8(Kcode);\r
465                                         *Put++ = LOW8(Kcode);\r
466                                 }\r
467                                 cInfo->KanjiFst = 0;\r
468                         }\r
469                 }\r
470                 else\r
471                 {\r
472                         Put = ConvEUCtoSJISkanaProc(cInfo, 0, Put);\r
473 \r
474                         if(cInfo->KanjiFst != 0)\r
475                         {\r
476                                 *Put++ = cInfo->KanjiFst;\r
477                                 cInfo->KanjiFst = 0;\r
478                         }\r
479                         *Put++ = *Str++;\r
480                 }\r
481         }\r
482 \r
483         cInfo->Str = Str;\r
484         cInfo->OutLen = Put - cInfo->Buf;\r
485 \r
486         return(Continue);\r
487 }\r
488 \r
489 \r
490 /*----- EUC-->SHIFT-JIS漢字コードに変換の半角カタカナの処理 -------------------\r
491 *\r
492 *       Parameter\r
493 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
494 *               char Dt : 文字\r
495 *               char *Put : データセット位置\r
496 *\r
497 *       Return Value\r
498 *               char *次のデータセット位置\r
499 *----------------------------------------------------------------------------*/\r
500 \r
501 static char *ConvEUCtoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)\r
502 {\r
503         int Kcode;\r
504         int Daku;\r
505 \r
506         if(cInfo->KanaCnv == NO)\r
507         {\r
508                 if(Dt != 0)\r
509                         *Put++ = Dt;\r
510         }\r
511         else\r
512         {\r
513                 if(cInfo->KanaPrev != 0)\r
514                 {\r
515                         Daku = AskDakuon(cInfo->KanaPrev, Dt);\r
516 \r
517                         Kcode = _mbcjistojms(HanKataToZen(cInfo->KanaPrev)) + Daku;\r
518                         *Put++ = HIGH8(Kcode);\r
519                         *Put++ = LOW8(Kcode);\r
520 \r
521                         if(Daku == 0)\r
522                                 cInfo->KanaPrev = Dt;\r
523                         else\r
524                                 cInfo->KanaPrev = 0;\r
525                 }\r
526                 else\r
527                         cInfo->KanaPrev = Dt;\r
528         }\r
529         return(Put);\r
530 }\r
531 \r
532 \r
533 /*----- JIS漢字コードをSHIFT-JIS漢字コードに変換 ------------------------------\r
534 *\r
535 *       Parameter\r
536 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
537 *\r
538 *       Return Value\r
539 *               int くり返しフラグ (YES/NO)\r
540 *\r
541 *       Note\r
542 *               くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
543 *\r
544 *               エスケープコードは、次のものに対応している\r
545 *                       漢字開始            <ESC>$B         <ESC>$@\r
546 *                       半角カナ開始      <ESC>(I\r
547 *                       漢字終了            <ESC>(B         <ESC>(J         <ESC>(H\r
548 *----------------------------------------------------------------------------*/\r
549 \r
550 int ConvJIStoSJIS(CODECONVINFO *cInfo)\r
551 {\r
552         int Kcode;\r
553         char *Str;\r
554         char *Put;\r
555         char *Limit;\r
556         int Continue;\r
557 \r
558         cInfo->KanaProc = &ConvJIStoSJISkanaProc;\r
559 \r
560         Continue = NO;\r
561         Str = cInfo->Str;\r
562         Put = cInfo->Buf;\r
563         Limit = cInfo->Buf + cInfo->BufSize - 3;\r
564 \r
565         for(; cInfo->StrLen > 0; cInfo->StrLen--)\r
566         {\r
567                 if(Put >= Limit)\r
568                 {\r
569                         Continue = YES;\r
570                         break;\r
571                 }\r
572 \r
573                 if(cInfo->EscProc == 0)\r
574                 {\r
575                         if(*Str == 0x1B)\r
576                         {\r
577                                 if(cInfo->KanjiFst != 0)\r
578                                 {\r
579                                         *Put++ = cInfo->KanjiFst;\r
580                                         cInfo->KanjiFst = 0;\r
581                                 }\r
582                                 Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);\r
583 \r
584                                 cInfo->EscCode[cInfo->EscProc] = *Str++;\r
585                                 cInfo->EscProc++;\r
586                         }\r
587                         else\r
588                         {\r
589                                 if(cInfo->KanjiMode == CONV_KANA)\r
590                                 {\r
591                                         if(cInfo->KanjiFst != 0)\r
592                                         {\r
593                                                 *Put++ = cInfo->KanjiFst;\r
594                                                 cInfo->KanjiFst = 0;\r
595                                         }\r
596 \r
597                                         if((*Str >= 0x21) && (*Str <= 0x5F))\r
598                                         {\r
599                                                 Put = ConvJIStoSJISkanaProc(cInfo, *Str++, Put);\r
600                                         }\r
601                                         else\r
602                                         {\r
603                                                 Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);\r
604                                                 *Put++ = *Str++;\r
605                                         }\r
606                                 }\r
607                                 else if(cInfo->KanjiMode == CONV_KANJI)\r
608                                 {\r
609                                         Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);\r
610                                         if((*Str >= 0x21) && (*Str <= 0x7E))\r
611                                         {\r
612                                                 if(cInfo->KanjiFst == 0)\r
613                                                         cInfo->KanjiFst = *Str++;\r
614                                                 else\r
615                                                 {\r
616                                                         Kcode = _mbcjistojms((cInfo->KanjiFst * 0x100) + *Str++);\r
617                                                         *Put++ = HIGH8(Kcode);\r
618                                                         *Put++ = LOW8(Kcode);\r
619                                                         cInfo->KanjiFst = 0;\r
620                                                 }\r
621                                         }\r
622                                         else\r
623                                         {\r
624                                                 if(cInfo->KanjiFst == 0)\r
625                                                         *Put++ = *Str++;\r
626                                                 else\r
627                                                 {\r
628                                                         *Put++ = cInfo->KanjiFst;\r
629                                                         *Put++ = *Str++;\r
630                                                         cInfo->KanjiFst = 0;\r
631                                                 }\r
632                                         }\r
633                                 }\r
634                                 else\r
635                                 {\r
636                                         Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);\r
637                                         *Put++ = *Str++;\r
638                                 }\r
639                         }\r
640                 }\r
641                 else if(cInfo->EscProc == 1)\r
642                 {\r
643                         if((*Str == '$') || (*Str == '('))\r
644                         {\r
645                                 cInfo->EscCode[cInfo->EscProc] = *Str++;\r
646                                 cInfo->EscProc++;\r
647                         }\r
648                         else\r
649                         {\r
650                                 *Put++ = cInfo->EscCode[0];\r
651                                 *Put++ = *Str++;\r
652                                 cInfo->EscProc = 0;\r
653                         }\r
654                 }\r
655                 else if(cInfo->EscProc == 2)\r
656                 {\r
657                         if((cInfo->EscCode[1] == '$') && ((*Str == 'B') || (*Str == '@')))\r
658                                 cInfo->KanjiMode = CONV_KANJI;\r
659                         else if((cInfo->EscCode[1] == '(') && (*Str == 'I'))\r
660                                 cInfo->KanjiMode = CONV_KANA;\r
661                         else if((cInfo->EscCode[1] == '(') && ((*Str == 'B') || (*Str == 'J') || (*Str == 'H')))\r
662                                 cInfo->KanjiMode = CONV_ASCII;\r
663                         else\r
664                         {\r
665                                 *Put++ = cInfo->EscCode[0];\r
666                                 *Put++ = cInfo->EscCode[1];\r
667                                 if((cInfo->KanjiMode == CONV_KANJI) && ((*Str >= 0x21) && (*Str <= 0x7E)))\r
668                                         cInfo->KanjiFst = *Str;\r
669                                 else\r
670                                         *Put++ = *Str;\r
671                         }\r
672                         Str++;\r
673                         cInfo->EscProc = 0;\r
674                 }\r
675         }\r
676 \r
677         cInfo->Str = Str;\r
678         cInfo->OutLen = Put - cInfo->Buf;\r
679 \r
680         return(Continue);\r
681 }\r
682 \r
683 \r
684 /*----- JIS-->SHIFT-JIS漢字コードに変換の半角カタカナの処理 -------------------\r
685 *\r
686 *       Parameter\r
687 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
688 *               char Dt : 文字\r
689 *               char *Put : データセット位置\r
690 *\r
691 *       Return Value\r
692 *               char *次のデータセット位置\r
693 *----------------------------------------------------------------------------*/\r
694 \r
695 static char *ConvJIStoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)\r
696 {\r
697         int Kcode;\r
698         int Daku;\r
699 \r
700         Dt = (uchar)Dt + (uchar)0x80;\r
701         if(cInfo->KanaCnv == NO)\r
702         {\r
703                 if((uchar)Dt != (uchar)0x80)\r
704                         *Put++ = Dt;\r
705         }\r
706         else\r
707         {\r
708                 if(cInfo->KanaPrev != 0)\r
709                 {\r
710                         Daku = AskDakuon(cInfo->KanaPrev, Dt);\r
711                         Kcode = _mbcjistojms(HanKataToZen(cInfo->KanaPrev)) + Daku;\r
712                         *Put++ = HIGH8(Kcode);\r
713                         *Put++ = LOW8(Kcode);\r
714 \r
715                         if((Daku == 0) && ((uchar)Dt != (uchar)0x80))\r
716                                 cInfo->KanaPrev = Dt;\r
717                         else\r
718                                 cInfo->KanaPrev = 0;\r
719                 }\r
720                 else if((uchar)Dt != (uchar)0x80)\r
721                         cInfo->KanaPrev = Dt;\r
722         }\r
723         return(Put);\r
724 }\r
725 \r
726 \r
727 /*----- Samba-HEX/Samba-CAP漢字コードをSHIFT-JIS漢字コードに変換 --------------\r
728 *\r
729 *       Parameter\r
730 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
731 *\r
732 *       Return Value\r
733 *               int くり返しフラグ (YES/NO)\r
734 *\r
735 *       Note\r
736 *               くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
737 *               分割された入力文字列の変換はサポートしていない\r
738 *               半角カタカナの変換設定には対応していない\r
739 *----------------------------------------------------------------------------*/\r
740 \r
741 int ConvSMBtoSJIS(CODECONVINFO *cInfo)\r
742 {\r
743         char *Str;\r
744         char *Put;\r
745         char *Limit;\r
746         int Continue;\r
747 \r
748         Continue = NO;\r
749         Str = cInfo->Str;\r
750         Put = cInfo->Buf;\r
751         Limit = cInfo->Buf + cInfo->BufSize - 2;\r
752 \r
753         for(; cInfo->StrLen > 0; cInfo->StrLen--)\r
754         {\r
755                 if(Put >= Limit)\r
756                 {\r
757                         Continue = YES;\r
758                         break;\r
759                 }\r
760 \r
761                 if((*Str == SAMBA_HEX_TAG) && (cInfo->StrLen >= 3))\r
762                 {\r
763                         if(isxdigit(*(Str+1)) && isxdigit(*(Str+2)))\r
764                         {\r
765                                 *Put++ = N2INT(hex2bin(*(Str+1)), hex2bin(*(Str+2)));\r
766                                 Str += 3;\r
767                                 cInfo->StrLen -= 2;\r
768                         }\r
769                         else\r
770                                 *Put++ = *Str++;\r
771                 }\r
772                 else\r
773                         *Put++ = *Str++;\r
774         }\r
775 \r
776         cInfo->Str = Str;\r
777         cInfo->OutLen = Put - cInfo->Buf;\r
778 \r
779         return(Continue);\r
780 }\r
781 \r
782 \r
783 /*----- SHIFT-JIS漢字コードをEUC漢字コードに変換 ------------------------------\r
784 *\r
785 *       Parameter\r
786 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
787 *\r
788 *       Return Value\r
789 *               int くり返しフラグ (YES/NO)\r
790 *\r
791 *       Note\r
792 *               くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
793 *----------------------------------------------------------------------------*/\r
794 \r
795 int ConvSJIStoEUC(CODECONVINFO *cInfo)\r
796 {\r
797         int Kcode;\r
798         char *Str;\r
799         char *Put;\r
800         char *Limit;\r
801         int Continue;\r
802 \r
803         cInfo->KanaProc = &ConvSJIStoEUCkanaProc;\r
804 \r
805         Continue = NO;\r
806         Str = cInfo->Str;\r
807         Put = cInfo->Buf;\r
808         Limit = cInfo->Buf + cInfo->BufSize - 2;\r
809 \r
810         for(; cInfo->StrLen > 0; cInfo->StrLen--)\r
811         {\r
812                 if(Put >= Limit)\r
813                 {\r
814                         Continue = YES;\r
815                         break;\r
816                 }\r
817 \r
818                 if(cInfo->KanjiFst == 0)\r
819                 {\r
820                         if((((uchar)*Str >= (uchar)0x81) && ((uchar)*Str <= (uchar)0x9F)) ||\r
821                            ((uchar)*Str >= (uchar)0xE0))\r
822                         {\r
823                                 Put = ConvSJIStoEUCkanaProc(cInfo, 0, Put);\r
824                                 cInfo->KanjiFst = *Str++;\r
825                         }\r
826                         else if(((uchar)*Str >= (uchar)0xA0) && ((uchar)*Str <= (uchar)0xDF))\r
827                         {\r
828                                 Put = ConvSJIStoEUCkanaProc(cInfo, *Str++, Put);\r
829                         }\r
830                         else\r
831                         {\r
832                                 Put = ConvSJIStoEUCkanaProc(cInfo, 0, Put);\r
833                                 *Put++ = *Str++;\r
834                         }\r
835                 }\r
836                 else\r
837                 {\r
838                         if((uchar)*Str >= (uchar)0x40)\r
839                         {\r
840                                 Kcode = ConvertIBMExtendedChar(((uchar)cInfo->KanjiFst * 0x100) + (uchar)*Str++);\r
841                                 Kcode = _mbcjmstojis(Kcode);\r
842                                 *Put++ = HIGH8(Kcode) | 0x80;\r
843                                 *Put++ = LOW8(Kcode) | 0x80;\r
844                         }\r
845                         else\r
846                         {\r
847                                 *Put++ = cInfo->KanjiFst;\r
848                                 *Put++ = *Str++;\r
849                         }\r
850                         cInfo->KanjiFst = 0;\r
851                 }\r
852         }\r
853 \r
854         cInfo->Str = Str;\r
855         cInfo->OutLen = Put - cInfo->Buf;\r
856 \r
857         return(Continue);\r
858 }\r
859 \r
860 \r
861 /*----- SHIFT-JIS-->EUC漢字コードに変換の半角カタカナの処理 -------------------\r
862 *\r
863 *       Parameter\r
864 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
865 *               char Dt : 文字\r
866 *               char *Put : データセット位置\r
867 *\r
868 *       Return Value\r
869 *               char *次のデータセット位置\r
870 *----------------------------------------------------------------------------*/\r
871 \r
872 static char *ConvSJIStoEUCkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)\r
873 {\r
874         int Kcode;\r
875         int Daku;\r
876 \r
877         if(cInfo->KanaCnv == NO)\r
878         {\r
879                 if(Dt != 0)\r
880                 {\r
881                         Kcode = 0x8E00 + (uchar)Dt;\r
882                         *Put++ = HIGH8(Kcode) | 0x80;\r
883                         *Put++ = LOW8(Kcode) | 0x80;\r
884                 }\r
885         }\r
886         else\r
887         {\r
888                 if(cInfo->KanaPrev != 0)\r
889                 {\r
890                         Daku = AskDakuon(cInfo->KanaPrev, Dt);\r
891                         Kcode = HanKataToZen(cInfo->KanaPrev) + Daku;\r
892                         *Put++ = HIGH8(Kcode) | 0x80;\r
893                         *Put++ = LOW8(Kcode) | 0x80;\r
894 \r
895                         if(Daku == 0)\r
896                                 cInfo->KanaPrev = Dt;\r
897                         else\r
898                                 cInfo->KanaPrev = 0;\r
899                 }\r
900                 else\r
901                         cInfo->KanaPrev = Dt;\r
902         }\r
903         return(Put);\r
904 }\r
905 \r
906 \r
907 /*----- SHIFT-JIS漢字コードをJIS漢字コードに変換 ------------------------------\r
908 *\r
909 *       Parameter\r
910 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
911 *\r
912 *       Return Value\r
913 *               int くり返しフラグ (YES/NO)\r
914 *\r
915 *       Note\r
916 *               くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
917 *\r
918 *               エスケープコードは、次のものを使用する\r
919 *                       漢字開始            <ESC>$B\r
920 *                       半角カナ開始      <ESC>(I\r
921 *                       漢字終了            <ESC>(B\r
922 *----------------------------------------------------------------------------*/\r
923 \r
924 int ConvSJIStoJIS(CODECONVINFO *cInfo)\r
925 {\r
926         int Kcode;\r
927         char *Str;\r
928         char *Put;\r
929         char *Limit;\r
930         int Continue;\r
931 \r
932         cInfo->KanaProc = &ConvSJIStoJISkanaProc;\r
933 \r
934         Continue = NO;\r
935         Str = cInfo->Str;\r
936         Put = cInfo->Buf;\r
937         Limit = cInfo->Buf + cInfo->BufSize - 5;\r
938 \r
939         for(; cInfo->StrLen > 0; cInfo->StrLen--)\r
940         {\r
941                 if(Put >= Limit)\r
942                 {\r
943                         Continue = YES;\r
944                         break;\r
945                 }\r
946 \r
947                 if(cInfo->KanjiFst == 0)\r
948                 {\r
949                         if((((uchar)*Str >= (uchar)0x81) && ((uchar)*Str <= (uchar)0x9F)) ||\r
950                            ((uchar)*Str >= (uchar)0xE0))\r
951                         {\r
952                                 Put = ConvSJIStoJISkanaProc(cInfo, 0, Put);\r
953                                 cInfo->KanjiFst = *Str++;\r
954                         }\r
955                         else if(((uchar)*Str >= (uchar)0xA0) && ((uchar)*Str <= (uchar)0xDF))\r
956                         {\r
957                                 Put = ConvSJIStoJISkanaProc(cInfo, *Str++, Put);\r
958                         }\r
959                         else\r
960                         {\r
961                                 Put = ConvSJIStoJISkanaProc(cInfo, 0, Put);\r
962                                 if(cInfo->KanjiMode != CONV_ASCII)\r
963                                 {\r
964                                         *Put++ = 0x1B;\r
965                                         *Put++ = '(';\r
966                                         *Put++ = 'B';\r
967                                         cInfo->KanjiMode = CONV_ASCII;\r
968                                 }\r
969                                 *Put++ = *Str++;\r
970                         }\r
971                 }\r
972                 else\r
973                 {\r
974                         Put = ConvSJIStoJISkanaProc(cInfo, 0, Put);\r
975                         if((uchar)*Str >= (uchar)0x40)\r
976                         {\r
977                                 if(cInfo->KanjiMode != CONV_KANJI)\r
978                                 {\r
979                                         *Put++ = 0x1B;\r
980                                         *Put++ = '$';\r
981                                         *Put++ = 'B';\r
982                                         cInfo->KanjiMode = CONV_KANJI;\r
983                                 }\r
984 \r
985                                 Kcode = ConvertIBMExtendedChar(((uchar)cInfo->KanjiFst * 0x100) + (uchar)*Str++);\r
986                                 Kcode = _mbcjmstojis(Kcode);\r
987                                 *Put++ = HIGH8(Kcode);\r
988                                 *Put++ = LOW8(Kcode);\r
989                         }\r
990                         else\r
991                         {\r
992                                 if(cInfo->KanjiMode != CONV_ASCII)\r
993                                 {\r
994                                         *Put++ = 0x1B;\r
995                                         *Put++ = '(';\r
996                                         *Put++ = 'B';\r
997                                         cInfo->KanjiMode = CONV_ASCII;\r
998                                 }\r
999                                 *Put++ = cInfo->KanjiFst;\r
1000                                 *Put++ = *Str++;\r
1001                         }\r
1002                         cInfo->KanjiFst = 0;\r
1003                 }\r
1004         }\r
1005 \r
1006         cInfo->Str = Str;\r
1007         cInfo->OutLen = Put - cInfo->Buf;\r
1008 \r
1009         return(Continue);\r
1010 }\r
1011 \r
1012 \r
1013 /*----- SHIFT-JIS-->JIS漢字コードに変換の半角カタカナの処理 -------------------\r
1014 *\r
1015 *       Parameter\r
1016 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
1017 *               char Dt : 文字\r
1018 *               char *Put : データセット位置\r
1019 *\r
1020 *       Return Value\r
1021 *               char *次のデータセット位置\r
1022 *----------------------------------------------------------------------------*/\r
1023 \r
1024 static char *ConvSJIStoJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)\r
1025 {\r
1026         int Kcode;\r
1027         int Daku;\r
1028 \r
1029         if(cInfo->KanaCnv == NO)\r
1030         {\r
1031                 if(Dt != 0)\r
1032                 {\r
1033                         if(cInfo->KanjiMode != CONV_KANA)\r
1034                         {\r
1035                                 *Put++ = 0x1B;\r
1036                                 *Put++ = '(';\r
1037                                 *Put++ = 'I';\r
1038                                 cInfo->KanjiMode = CONV_KANA;\r
1039                         }\r
1040                         *Put++ = (uchar)Dt - (uchar)0x80;\r
1041                 }\r
1042         }\r
1043         else\r
1044         {\r
1045                 if(cInfo->KanaPrev != 0)\r
1046                 {\r
1047                         if(cInfo->KanjiMode != CONV_KANJI)\r
1048                         {\r
1049                                 *Put++ = 0x1B;\r
1050                                 *Put++ = '$';\r
1051                                 *Put++ = 'B';\r
1052                                 cInfo->KanjiMode = CONV_KANJI;\r
1053                         }\r
1054                         Daku = AskDakuon(cInfo->KanaPrev, Dt);\r
1055                         Kcode = HanKataToZen(cInfo->KanaPrev) + Daku;\r
1056                         *Put++ = HIGH8(Kcode);\r
1057                         *Put++ = LOW8(Kcode);\r
1058 \r
1059                         if(Daku == 0)\r
1060                                 cInfo->KanaPrev = Dt;\r
1061                         else\r
1062                                 cInfo->KanaPrev = 0;\r
1063                 }\r
1064                 else\r
1065                         cInfo->KanaPrev = Dt;\r
1066         }\r
1067         return(Put);\r
1068 }\r
1069 \r
1070 \r
1071 /*----- SHIFT-JIS漢字コードをSamba-HEX漢字コードに変換 ------------------------\r
1072 *\r
1073 *       Parameter\r
1074 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
1075 *\r
1076 *       Return Value\r
1077 *               int くり返しフラグ (YES/NO)\r
1078 *\r
1079 *       Note\r
1080 *               くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
1081 *               分割された入力文字列の変換はサポートしていない\r
1082 *               半角カタカナの変換設定には対応していない\r
1083 *----------------------------------------------------------------------------*/\r
1084 \r
1085 int ConvSJIStoSMB_HEX(CODECONVINFO *cInfo)\r
1086 {\r
1087         char *Str;\r
1088         char *Put;\r
1089         char *Limit;\r
1090         int Continue;\r
1091 \r
1092         Continue = NO;\r
1093         Str = cInfo->Str;\r
1094         Put = cInfo->Buf;\r
1095         Limit = cInfo->Buf + cInfo->BufSize - 6;\r
1096 \r
1097         for(; cInfo->StrLen > 0; cInfo->StrLen--)\r
1098         {\r
1099                 if(Put >= Limit)\r
1100                 {\r
1101                         Continue = YES;\r
1102                         break;\r
1103                 }\r
1104 \r
1105                 if((cInfo->StrLen >= 2) &&\r
1106                    ((((uchar)*Str >= (uchar)0x81) && ((uchar)*Str <= (uchar)0x9F)) ||\r
1107                     ((uchar)*Str >= (uchar)0xE0)))\r
1108                 {\r
1109                         sprintf(Put, "%c%02x%c%02x", SAMBA_HEX_TAG, (uchar)*Str, SAMBA_HEX_TAG, (uchar)*(Str+1));\r
1110                         Str += 2;\r
1111                         Put += 6;\r
1112                         cInfo->StrLen--;\r
1113                 }\r
1114                 else if((uchar)*Str >= (uchar)0x80)\r
1115                 {\r
1116                         sprintf(Put, "%c%02x", SAMBA_HEX_TAG, (uchar)*Str++);\r
1117                         Put += 3;\r
1118                 }\r
1119                 else\r
1120                         *Put++ = *Str++;\r
1121         }\r
1122 \r
1123         cInfo->Str = Str;\r
1124         cInfo->OutLen = Put - cInfo->Buf;\r
1125 \r
1126         return(Continue);\r
1127 }\r
1128 \r
1129 \r
1130 /*----- SHIFT-JIS漢字コードをSamba-CAP漢字コードに変換 ------------------------\r
1131 *\r
1132 *       Parameter\r
1133 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
1134 *\r
1135 *       Return Value\r
1136 *               int くり返しフラグ (YES/NO)\r
1137 *\r
1138 *       Note\r
1139 *               くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
1140 *               分割された入力文字列の変換はサポートしていない\r
1141 *----------------------------------------------------------------------------*/\r
1142 \r
1143 int ConvSJIStoSMB_CAP(CODECONVINFO *cInfo)\r
1144 {\r
1145         char *Str;\r
1146         char *Put;\r
1147         char *Limit;\r
1148         int Continue;\r
1149 \r
1150         Continue = NO;\r
1151         Str = cInfo->Str;\r
1152         Put = cInfo->Buf;\r
1153         Limit = cInfo->Buf + cInfo->BufSize - 6;\r
1154 \r
1155         for(; cInfo->StrLen > 0; cInfo->StrLen--)\r
1156         {\r
1157                 if(Put >= Limit)\r
1158                 {\r
1159                         Continue = YES;\r
1160                         break;\r
1161                 }\r
1162 \r
1163                 if((uchar)*Str >= (uchar)0x80)\r
1164                 {\r
1165                         sprintf(Put, "%c%02x", SAMBA_HEX_TAG, (uchar)*Str++);\r
1166                         Put += 3;\r
1167                 }\r
1168                 else\r
1169                         *Put++ = *Str++;\r
1170         }\r
1171 \r
1172         cInfo->Str = Str;\r
1173         cInfo->OutLen = Put - cInfo->Buf;\r
1174 \r
1175         return(Continue);\r
1176 }\r
1177 \r
1178 \r
1179 /*----- 1バイトカタカナをJIS漢字コードに変換 ---------------------------------\r
1180 *\r
1181 *       Parameter\r
1182 *               char Ch : 1バイトカタカナコード\r
1183 *\r
1184 *       Return Value\r
1185 *               int JIS漢字コード\r
1186 *----------------------------------------------------------------------------*/\r
1187 \r
1188 static int HanKataToZen(char Ch)\r
1189 {\r
1190         static const int Katakana[] = {\r
1191                 0x2121, 0x2123, 0x2156, 0x2157, 0x2122, 0x2126, 0x2572, 0x2521, \r
1192                 0x2523, 0x2525, 0x2527, 0x2529, 0x2563, 0x2565, 0x2567, 0x2543, \r
1193                 0x213C, 0x2522, 0x2524, 0x2526, 0x2528, 0x252A, 0x252B, 0x252D, \r
1194                 0x252F, 0x2531, 0x2533, 0x2535, 0x2537, 0x2539, 0x253B, 0x253D, \r
1195                 0x253F, 0x2541, 0x2544, 0x2546, 0x2548, 0x254A, 0x254B, 0x254C, \r
1196                 0x254D, 0x254E, 0x254F, 0x2552, 0x2555, 0x2558, 0x255B, 0x255E, \r
1197                 0x255F, 0x2560, 0x2561, 0x2562, 0x2564, 0x2566, 0x2568, 0x2569, \r
1198                 0x256A, 0x256B, 0x256C, 0x256D, 0x256F, 0x2573, 0x212B, 0x212C\r
1199         };\r
1200 \r
1201         return(Katakana[(uchar)Ch - (uchar)0xA0]);\r
1202 }\r
1203 \r
1204 \r
1205 /*----- 濁音/半濁音になる文字かチェック --------------------------------------\r
1206 *\r
1207 *       Parameter\r
1208 *               char Ch : 1バイトカタカナコード\r
1209 *               char Daku : 濁点/半濁点\r
1210 *\r
1211 *       Return Value\r
1212 *               int 文字コードに加える値 (0=濁音/半濁音にならない)\r
1213 *----------------------------------------------------------------------------*/\r
1214 \r
1215 static int AskDakuon(char Ch, char Daku)\r
1216 {\r
1217         int Ret;\r
1218 \r
1219         Ret = 0;\r
1220         if((uchar)Daku == (uchar)0xDE)\r
1221         {\r
1222                 if((((uchar)Ch >= (uchar)0xB6) && ((uchar)Ch <= (uchar)0xC4)) ||\r
1223                    (((uchar)Ch >= (uchar)0xCA) && ((uchar)Ch <= (uchar)0xCE)))\r
1224                 {\r
1225                         Ret = 1;\r
1226                 }\r
1227         }\r
1228         else if((uchar)Daku == (uchar)0xDF)\r
1229         {\r
1230                 if(((uchar)Ch >= (uchar)0xCA) && ((uchar)Ch <= (uchar)0xCE))\r
1231                 {\r
1232                         Ret = 2;\r
1233                 }\r
1234         }\r
1235         return(Ret);\r
1236 }\r
1237 \r
1238 \r
1239 \r
1240 \r
1241 \r
1242 \r
1243 \r
1244 \r
1245 \r
1246 \r
1247 \r
1248 \r
1249 /*----- 文字列の漢字コードを調べ、Shift-JISに変換 -----------------------------\r
1250 *\r
1251 *       Parameter\r
1252 *               char *Text : 文字列\r
1253 *               int Pref : SJIS/EUCの優先指定\r
1254 *                     KANJI_SJIS / KANJI_EUC / KANJI_NOCNV=SJIS/EUCのチェックはしない\r
1255 *\r
1256 *       Return Value\r
1257 *               なし\r
1258 *----------------------------------------------------------------------------*/\r
1259 \r
1260 void ConvAutoToSJIS(char *Text, int Pref)\r
1261 {\r
1262         int Code;\r
1263         char *Buf;\r
1264         CODECONVINFO cInfo;\r
1265 \r
1266         Code = CheckKanjiCode(Text, strlen(Text), Pref);\r
1267         if(Code != KANJI_SJIS)\r
1268         {\r
1269                 Buf = malloc(strlen(Text)+1);\r
1270                 if(Buf != NULL)\r
1271                 {\r
1272                         InitCodeConvInfo(&cInfo);\r
1273                         cInfo.KanaCnv = NO;\r
1274                         cInfo.Str = Text;\r
1275                         cInfo.StrLen = strlen(Text);\r
1276                         cInfo.Buf = Buf;\r
1277                         cInfo.BufSize = strlen(Text);\r
1278 \r
1279                         switch(Code)\r
1280                         {\r
1281                                 case KANJI_JIS :\r
1282                                         ConvJIStoSJIS(&cInfo);\r
1283                                         break;\r
1284 \r
1285                                 case KANJI_EUC :\r
1286                                         ConvEUCtoSJIS(&cInfo);\r
1287                                         break;\r
1288                         }\r
1289 \r
1290                         *(Buf + cInfo.OutLen) = NUL;\r
1291                         strcpy(Text, Buf);\r
1292                         free(Buf);\r
1293                 }\r
1294         }\r
1295         return;\r
1296 }\r
1297 \r
1298 \r
1299 /*----- 使われている漢字コードを調べる ----------------------------------------\r
1300 *\r
1301 *       Parameter\r
1302 *               char *Text : 文字列\r
1303 *               int Size : 文字列の長さ\r
1304 *               int Pref : SJIS/EUCの優先指定\r
1305 *                     KANJI_SJIS / KANJI_EUC / KANJI_NOCNV=SJIS/EUCのチェックはしない\r
1306 *\r
1307 *       Return Value\r
1308 *               int 漢字コード (KANJI_xxx)\r
1309 *----------------------------------------------------------------------------*/\r
1310 \r
1311 int CheckKanjiCode(char *Text, int Size, int Pref)\r
1312 {\r
1313         uchar *Pos;\r
1314         uchar *Btm;\r
1315         int Ret;\r
1316         int PointSJIS;\r
1317         int PointEUC;\r
1318 \r
1319         Ret = KANJI_SJIS;\r
1320         if(Size >= 2)\r
1321         {\r
1322                 Ret = -1;\r
1323                 Btm = Text + Size;\r
1324 \r
1325                 /* JIS漢字コードのチェック */\r
1326                 Pos = Text;\r
1327                 while((Pos = memchr(Pos, 0x1b, Btm-Pos-2)) != NULL)\r
1328                 {\r
1329                         Pos++;\r
1330                         if((memcmp(Pos, "$B", 2) == 0) ||       /* <ESC>$B */\r
1331                            (memcmp(Pos, "$@", 2) == 0) ||       /* <ESC>$@ */\r
1332                            (memcmp(Pos, "(I", 2) == 0))         /* <ESC>(I */\r
1333                         {\r
1334                                 Ret = KANJI_JIS;\r
1335                                 break;\r
1336                         }\r
1337                 }\r
1338 \r
1339                 /* EUCとSHIFT-JIS漢字コードのチェック */\r
1340                 if(Ret == -1)\r
1341                 {\r
1342                         if(Pref != KANJI_NOCNV)\r
1343                         {\r
1344                                 Ret = Pref;\r
1345                                 Pos = Text;\r
1346                                 while(Pos < Btm)\r
1347                                 {\r
1348                                         PointSJIS = CheckOnSJIS(Pos, Btm);\r
1349                                         PointEUC = CheckOnEUC(Pos, Btm);\r
1350                                         if(PointSJIS > PointEUC)\r
1351                                         {\r
1352                                                 Ret = KANJI_SJIS;\r
1353                                                 break;\r
1354                                         }\r
1355                                         if(PointSJIS < PointEUC)\r
1356                                         {\r
1357                                                 Ret = KANJI_EUC;\r
1358                                                 break;\r
1359                                         }\r
1360                                         if((Pos = memchr(Pos, '\n', Btm-Pos)) == NULL)\r
1361                                                 break;\r
1362                                         Pos++;\r
1363                                 }\r
1364                         }\r
1365                         else\r
1366                                 Ret = KANJI_SJIS;\r
1367                 }\r
1368         }\r
1369         return(Ret);\r
1370 }\r
1371 \r
1372 \r
1373 /*----- SHIFT-JISコードの可能性があるかチェック --------------------------------\r
1374 *\r
1375 *       Parameter\r
1376 *               uchar *Pos : 文字列\r
1377 *               uchar *Btm : 文字列の末尾\r
1378 *\r
1379 *       Return Value\r
1380 *               int 得点\r
1381 *\r
1382 *       Note\r
1383 *               High    81-FF (A0-DFは半角)  (EB以降はほとんど無い)\r
1384 *               Low             40-FC\r
1385 *----------------------------------------------------------------------------*/\r
1386 \r
1387 static int CheckOnSJIS(uchar *Pos, uchar *Btm)\r
1388 {\r
1389         int FstOnTwo;\r
1390         int Point;\r
1391 \r
1392         FstOnTwo = NO;\r
1393         Point = 100;\r
1394         while((Point > 0) && (Pos < Btm) && (*Pos != '\n'))\r
1395         {\r
1396                 if(FstOnTwo == YES)\r
1397                 {\r
1398                         if((*Pos < 0x40) || (*Pos > 0xFC))      /* 2バイト目は 0x40~0xFC */\r
1399                                 Point = 0;\r
1400                         FstOnTwo = NO;\r
1401                 }\r
1402                 else if(*Pos >= 0x81)\r
1403                 {\r
1404                         if((*Pos < 0xA0) || (*Pos > 0xDF))      /* 半角カナでなければ */\r
1405                         {\r
1406                                 if(*Pos >= 0xEB)                /* 1バイト目は0xEB以降はほとんど無い */\r
1407                                         Point -= 50;\r
1408                                 FstOnTwo = YES;\r
1409                         }\r
1410                 }\r
1411                 Pos++;\r
1412         }\r
1413         if(FstOnTwo == YES)             /* 1バイト目で終わっているのはおかしい  */\r
1414                 Point = 0;\r
1415 \r
1416         return(Point);\r
1417 }\r
1418 \r
1419 \r
1420 /*----- EUCコードの可能性があるかチェック -------------------------------------\r
1421 *\r
1422 *       Parameter\r
1423 *               uchar *Pos : 文字列\r
1424 *               uchar *Btm : 文字列の末尾\r
1425 *\r
1426 *       Return Value\r
1427 *               int 得点\r
1428 *\r
1429 *       Note\r
1430 *               High    A1-FE , 8E\r
1431 *               Low             A1-FE\r
1432 *----------------------------------------------------------------------------*/\r
1433 \r
1434 static int CheckOnEUC(uchar *Pos, uchar *Btm)\r
1435 {\r
1436         int FstOnTwo;\r
1437         int Point;\r
1438 \r
1439         FstOnTwo = 0;\r
1440         Point = 100;\r
1441         while((Point > 0) && (Pos < Btm) && (*Pos != '\n'))\r
1442         {\r
1443                 if(FstOnTwo == 1)\r
1444                 {\r
1445                         if((*Pos < 0xA1) || (*Pos > 0xFE))      /* 2バイト目は 0xA1~0xFE */\r
1446                                 Point = 0;\r
1447                         FstOnTwo = 0;\r
1448                 }\r
1449                 else if(FstOnTwo == 2)          /* 半角カナ */\r
1450                 {\r
1451                         if((*Pos < 0xA0) || (*Pos > 0xDF))      /* 2バイト目は 0xA0~0xDF */\r
1452                                 Point = 0;\r
1453                         FstOnTwo = 0;\r
1454                 }\r
1455                 else\r
1456                 {\r
1457                         if(*Pos == 0x8E)                /* 0x8E??は半角カナ */\r
1458                                 FstOnTwo = 2;\r
1459                         else if((*Pos >= 0xA1) && (*Pos <= 0xFE))\r
1460                                 FstOnTwo = 1;\r
1461                 }\r
1462                 Pos++;\r
1463         }\r
1464         if(FstOnTwo != 0)               /* 1バイト目で終わっているのはおかしい  */\r
1465                 Point = 0;\r
1466 \r
1467         return(Point);\r
1468 }\r
1469 \r
1470 \r
1471 // UTF-8対応 ここから↓\r
1472 /*----- UTF-8漢字コードをSHIFT-JIS漢字コードに変換 ------------------------------\r
1473 *\r
1474 *       Parameter\r
1475 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
1476 *\r
1477 *       Return Value\r
1478 *               int くり返しフラグ (YES/NO)\r
1479 *\r
1480 *       Note\r
1481 *               くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
1482 *----------------------------------------------------------------------------*/\r
1483 \r
1484 int ConvUTF8NtoSJIS(CODECONVINFO *cInfo)\r
1485 {\r
1486         int Continue;\r
1487 \r
1488 //      char temp_string[2048];\r
1489         int string_length;\r
1490 \r
1491         // 大きいサイズに対応\r
1492         // 終端のNULLを含むバグを修正\r
1493         int SrcLength;\r
1494         char* pSrc;\r
1495         wchar_t* pUTF16;\r
1496         int UTF16Length;\r
1497         int Count;\r
1498 \r
1499         Continue = NO;\r
1500 \r
1501         // 生成される中間コードのサイズを調べる\r
1502 //      string_length = MultiByteToWideChar(\r
1503 //                                              CP_UTF8,                // 変換先文字コード\r
1504 //                                              0,                              // フラグ(0:なし)\r
1505 //                                              cInfo->Str,             // 変換元文字列\r
1506 //                                              -1,                             // 変換元文字列バイト数(-1:自動)\r
1507 //                                              NULL,                   // 変換した文字列の格納先\r
1508 //                                              0                               // 格納先サイズ\r
1509 //                                      );\r
1510         // 前回の変換不能な残りの文字列を入力の先頭に結合\r
1511         SrcLength = cInfo->StrLen + cInfo->EscUTF8Len;\r
1512         if(!(pSrc = (char*)malloc(sizeof(char) * (SrcLength + 1))))\r
1513         {\r
1514                 *(cInfo->Buf) = '\0';\r
1515                 cInfo->BufSize = 0;\r
1516                 return Continue;\r
1517         }\r
1518         memcpy(pSrc, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);\r
1519         memcpy(pSrc + cInfo->EscUTF8Len, cInfo->Str, sizeof(char) * cInfo->StrLen);\r
1520         *(pSrc + SrcLength) = '\0';\r
1521         // UTF-8の場合、不完全な文字は常に変換されない\r
1522         UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pSrc, SrcLength, NULL, 0);\r
1523 \r
1524         // サイズ0 or バッファサイズより大きい場合は\r
1525         // cInfo->Bufの最初に'\0'を入れて、\r
1526         // cInfo->BufSizeに0を入れて返す。\r
1527 //      if( string_length == 0 ||\r
1528 //              string_length >= 1024 ){\r
1529 //              *(cInfo->Buf) = '\0';\r
1530 //              cInfo->BufSize = 0;\r
1531 //              return(Continue);\r
1532 //      }\r
1533         if(!(pUTF16 = (wchar_t*)malloc(sizeof(wchar_t) * UTF16Length)))\r
1534         {\r
1535                 free(pSrc);\r
1536                 *(cInfo->Buf) = '\0';\r
1537                 cInfo->BufSize = 0;\r
1538                 return Continue;\r
1539         }\r
1540 \r
1541         // 中間コード(unicode)に変換\r
1542 //      MultiByteToWideChar(\r
1543 //              CP_UTF8,                                                // 変換先文字コード\r
1544 //              0,                                                              // フラグ(0:なし)\r
1545 //              cInfo->Str,                                             // 変換元文字列\r
1546 //              -1,                                                             // 変換元文字列バイト数(-1:自動)\r
1547 //              (unsigned short *)temp_string,  // 変換した文字列の格納先\r
1548 //              1024                                                    // 格納先サイズ\r
1549 //      );\r
1550         MultiByteToWideChar(CP_UTF8, 0, pSrc, SrcLength, pUTF16, UTF16Length);\r
1551 \r
1552         // 生成されるUTF-8コードのサイズを調べる\r
1553 //      string_length = WideCharToMultiByte(\r
1554 //                                              CP_ACP,                 // 変換先文字コード\r
1555 //                                              0,                              // フラグ(0:なし)\r
1556 //                                              (unsigned short *)temp_string,  // 変換元文字列\r
1557 //                                              -1,                             // 変換元文字列バイト数(-1:自動)\r
1558 //                                              NULL,                   // 変換した文字列の格納先\r
1559 //                                              0,                              // 格納先サイズ\r
1560 //                                              NULL,NULL\r
1561 //                                      );\r
1562         string_length = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);\r
1563 \r
1564         // サイズ0 or 出力バッファサイズより大きい場合は、\r
1565         // cInfo->Bufの最初に'\0'を入れて、\r
1566         // cInfo->BufSizeに0を入れて返す。\r
1567 //      if( string_length == 0 ||\r
1568 //              string_length >= cInfo->BufSize ){\r
1569 //              *(cInfo->Buf) = '\0';\r
1570 //              cInfo->BufSize = 0;\r
1571 //              return(Continue);\r
1572 //      }\r
1573 \r
1574         // 出力サイズを設定\r
1575 //      cInfo->OutLen = string_length;\r
1576 \r
1577         // UTF-8コードに変換\r
1578 //      WideCharToMultiByte(\r
1579 //              CP_ACP,                                                 // 変換先文字コード\r
1580 //              0,                                                              // フラグ(0:なし)\r
1581 //              (unsigned short *)temp_string,  // 変換元文字列\r
1582 //              -1,                                                             // 変換元文字列バイト数(-1:自動)\r
1583 //              cInfo->Buf,                                             // 変換した文字列の格納先(BOM:3bytes)\r
1584 //              cInfo->BufSize,                                 // 格納先サイズ\r
1585 //              NULL,NULL\r
1586 //      );\r
1587         cInfo->OutLen = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);\r
1588         // バッファに収まらないため変換文字数を半減\r
1589         while(cInfo->OutLen == 0 && UTF16Length > 0)\r
1590         {\r
1591                 UTF16Length = UTF16Length / 2;\r
1592                 cInfo->OutLen = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);\r
1593         }\r
1594         // 変換された元の文字列での文字数を取得\r
1595         Count = WideCharToMultiByte(CP_UTF8, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);\r
1596         // 変換可能な残りの文字数を取得\r
1597         UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pSrc + Count, SrcLength - Count, NULL, 0);\r
1598         cInfo->Str += Count - cInfo->EscUTF8Len;\r
1599         cInfo->StrLen -= Count - cInfo->EscUTF8Len;\r
1600         cInfo->EscUTF8Len = 0;\r
1601         if(UTF16Length > 0)\r
1602                 Continue = YES;\r
1603         else\r
1604         {\r
1605                 // 変換不能なため次の入力の先頭に結合\r
1606                 memcpy(cInfo->EscUTF8, cInfo->Str, sizeof(char) * cInfo->StrLen);\r
1607                 cInfo->EscUTF8Len = cInfo->StrLen;\r
1608                 cInfo->Str += cInfo->StrLen;\r
1609                 cInfo->StrLen = 0;\r
1610                 Continue = NO;\r
1611         }\r
1612 \r
1613         free(pSrc);\r
1614         free(pUTF16);\r
1615 \r
1616         return(Continue);\r
1617 }\r
1618 \r
1619 /*----- SHIFT-JIS漢字コードをUTF-8漢字コードに変換 ------------------------------\r
1620 *\r
1621 *       Parameter\r
1622 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
1623 *\r
1624 *       Return Value\r
1625 *               int くり返しフラグ (YES/NO)\r
1626 *\r
1627 *       Note\r
1628 *               くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
1629 *----------------------------------------------------------------------------*/\r
1630 int ConvSJIStoUTF8N(CODECONVINFO *cInfo)\r
1631 {\r
1632         int Continue;\r
1633 \r
1634 //      char temp_string[2048];\r
1635         int string_length;\r
1636 \r
1637         // 大きいサイズに対応\r
1638         // 終端のNULLを含むバグを修正\r
1639         int SrcLength;\r
1640         char* pSrc;\r
1641         wchar_t* pUTF16;\r
1642         int UTF16Length;\r
1643         int Count;\r
1644 \r
1645         Continue = NO;\r
1646 \r
1647         // 生成される中間コードのサイズを調べる\r
1648 //      string_length = MultiByteToWideChar(\r
1649 //                                              CP_ACP,                 // 変換先文字コード\r
1650 //                                              0,                              // フラグ(0:なし)\r
1651 //                                              cInfo->Str,             // 変換元文字列\r
1652 //                                              -1,                             // 変換元文字列バイト数(-1:自動)\r
1653 //                                              NULL,                   // 変換した文字列の格納先\r
1654 //                                              0                               // 格納先サイズ\r
1655 //                                      );\r
1656         // 前回の変換不能な残りの文字列を入力の先頭に結合\r
1657         SrcLength = cInfo->StrLen + cInfo->EscUTF8Len;\r
1658         if(!(pSrc = (char*)malloc(sizeof(char) * (SrcLength + 1))))\r
1659         {\r
1660                 *(cInfo->Buf) = '\0';\r
1661                 cInfo->BufSize = 0;\r
1662                 return Continue;\r
1663         }\r
1664         memcpy(pSrc, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);\r
1665         memcpy(pSrc + cInfo->EscUTF8Len, cInfo->Str, sizeof(char) * cInfo->StrLen);\r
1666         *(pSrc + SrcLength) = '\0';\r
1667         // Shift_JISの場合、不完全な文字でも変換されることがあるため、末尾の不完全な部分を削る\r
1668         Count = 0;\r
1669         while(Count < SrcLength)\r
1670         {\r
1671                 if(((unsigned char)*(pSrc + Count) >= 0x81 && (unsigned char)*(pSrc + Count) <= 0x9f) || (unsigned char)*(pSrc + Count) >= 0xe0)\r
1672                 {\r
1673                         if((unsigned char)*(pSrc + Count + 1) >= 0x40)\r
1674                                 Count += 2;\r
1675                         else\r
1676                         {\r
1677                                 if(Count + 2 > SrcLength)\r
1678                                         break;\r
1679                                 Count += 1;\r
1680                         }\r
1681                 }\r
1682                 else\r
1683                         Count += 1;\r
1684         }\r
1685         SrcLength = Count;\r
1686         UTF16Length = MultiByteToWideChar(CP_ACP, 0, pSrc, SrcLength, NULL, 0);\r
1687 \r
1688         // サイズ0 or バッファサイズより大きい場合は、\r
1689         // cInfo->Bufの最初に'\0'を入れて、\r
1690         // cInfo->BufSizeに0を入れて返す。\r
1691 //      if( string_length == 0 ||\r
1692 //              string_length >= 1024 ){\r
1693 //              *(cInfo->Buf) = '\0';\r
1694 //              cInfo->BufSize = 0;\r
1695 //              return(Continue);\r
1696 //      }\r
1697         if(!(pUTF16 = (wchar_t*)malloc(sizeof(wchar_t) * UTF16Length)))\r
1698         {\r
1699                 free(pSrc);\r
1700                 *(cInfo->Buf) = '\0';\r
1701                 cInfo->BufSize = 0;\r
1702                 return Continue;\r
1703         }\r
1704 \r
1705         // 中間コード(unicode)に変換\r
1706 //      MultiByteToWideChar(\r
1707 //              CP_ACP,                                                 // 変換先文字コード\r
1708 //              0,                                                              // フラグ(0:なし)\r
1709 //              cInfo->Str,                                             // 変換元文字列\r
1710 //              -1,                                                             // 変換元文字列バイト数(-1:自動)\r
1711 //              (unsigned short *)temp_string,  // 変換した文字列の格納先\r
1712 //              1024                                                    // 格納先サイズ\r
1713 //      );\r
1714         MultiByteToWideChar(CP_ACP, 0, pSrc, SrcLength, pUTF16, UTF16Length);\r
1715 \r
1716         // 生成されるUTF-8コードのサイズを調べる\r
1717 //      string_length = WideCharToMultiByte(\r
1718 //                                              CP_UTF8,                // 変換先文字コード\r
1719 //                                              0,                              // フラグ(0:なし)\r
1720 //                                              (unsigned short *)temp_string,  // 変換元文字列\r
1721 //                                              -1,                             // 変換元文字列バイト数(-1:自動)\r
1722 //                                              NULL,                   // 変換した文字列の格納先\r
1723 //                                              0,                              // 格納先サイズ\r
1724 //                                              NULL,NULL\r
1725 //                                      );\r
1726         string_length = WideCharToMultiByte(CP_UTF8, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);\r
1727 \r
1728         // サイズ0 or 出力バッファサイズより大きい場合は、\r
1729         // cInfo->Bufの最初に'\0'を入れて、\r
1730         // cInfo->BufSizeに0を入れて返す。\r
1731 //      if( string_length == 0 ||\r
1732 //              string_length >= cInfo->BufSize ){\r
1733 //              *(cInfo->Buf) = '\0';\r
1734 //              cInfo->BufSize = 0;\r
1735 //              return(Continue);\r
1736 //      }\r
1737 \r
1738         // 出力サイズを設定\r
1739 //      cInfo->OutLen = string_length;\r
1740 \r
1741         /*\r
1742         // ↓付けちゃだめ コマンドにも追加されてしまう\r
1743         // 出力文字列の先頭にBOM(byte order mark)をつける\r
1744         *(cInfo->Buf) = (char)0xef;\r
1745         *(cInfo->Buf+1) = (char)0xbb;\r
1746         *(cInfo->Buf+2) = (char)0xbf;\r
1747         */\r
1748 \r
1749         // UTF-8コードに変換\r
1750 //      WideCharToMultiByte(\r
1751 //              CP_UTF8,                                                // 変換先文字コード\r
1752 //              0,                                                              // フラグ(0:なし)\r
1753 //              (unsigned short *)temp_string,  // 変換元文字列\r
1754 //              -1,                                                             // 変換元文字列バイト数(-1:自動)\r
1755 //              cInfo->Buf,                                     // 変換した文字列の格納先(BOM:3bytes)\r
1756 //              cInfo->BufSize,                                 // 格納先サイズ\r
1757 //              NULL,NULL\r
1758 //      );\r
1759         cInfo->OutLen = WideCharToMultiByte(CP_UTF8, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);\r
1760         // バッファに収まらないため変換文字数を半減\r
1761         while(cInfo->OutLen == 0 && UTF16Length > 0)\r
1762         {\r
1763                 UTF16Length = UTF16Length / 2;\r
1764                 cInfo->OutLen = WideCharToMultiByte(CP_UTF8, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);\r
1765         }\r
1766         // 変換された元の文字列での文字数を取得\r
1767         Count = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);\r
1768         // 変換可能な残りの文字数を取得\r
1769         UTF16Length = MultiByteToWideChar(CP_ACP, 0, pSrc + Count, SrcLength - Count, NULL, 0);\r
1770         cInfo->Str += Count - cInfo->EscUTF8Len;\r
1771         cInfo->StrLen -= Count - cInfo->EscUTF8Len;\r
1772         cInfo->EscUTF8Len = 0;\r
1773         if(UTF16Length > 0)\r
1774                 Continue = YES;\r
1775         else\r
1776         {\r
1777                 // 変換不能なため次の入力の先頭に結合\r
1778                 memcpy(cInfo->EscUTF8, cInfo->Str, sizeof(char) * cInfo->StrLen);\r
1779                 cInfo->EscUTF8Len = cInfo->StrLen;\r
1780                 cInfo->Str += cInfo->StrLen;\r
1781                 cInfo->StrLen = 0;\r
1782                 Continue = NO;\r
1783         }\r
1784 \r
1785         free(pSrc);\r
1786         free(pUTF16);\r
1787 \r
1788         return(Continue);\r
1789 }\r
1790 // UTF-8対応 ここまで↑\r
1791 \r
1792 \r
1793 /*----- IBM拡張漢字をNEC選定IBM拡張漢字等に変換 -------------------------------\r
1794 *\r
1795 *       Parameter\r
1796 *               code    漢字コード\r
1797 *\r
1798 *       Return Value\r
1799 *               int 漢字コード\r
1800 *----------------------------------------------------------------------------*/\r
1801 static int ConvertIBMExtendedChar(int code)\r
1802 {\r
1803         if((code >= 0xfa40) && (code <= 0xfa49))                code -= (0xfa40 - 0xeeef);\r
1804         else if((code >= 0xfa4a) && (code <= 0xfa53))   code -= (0xfa4a - 0x8754);\r
1805         else if((code >= 0xfa54) && (code <= 0xfa57))   code -= (0xfa54 - 0xeef9);\r
1806         else if(code == 0xfa58)                                                 code = 0x878a;\r
1807         else if(code == 0xfa59)                                                 code = 0x8782;\r
1808         else if(code == 0xfa5a)                                                 code = 0x8784;\r
1809         else if(code == 0xfa5b)                                                 code = 0x879a;\r
1810         else if((code >= 0xfa5c) && (code <= 0xfa7e))   code -= (0xfa5c - 0xed40);\r
1811         else if((code >= 0xfa80) && (code <= 0xfa9b))   code -= (0xfa80 - 0xed63);\r
1812         else if((code >= 0xfa9c) && (code <= 0xfafc))   code -= (0xfa9c - 0xed80);\r
1813         else if((code >= 0xfb40) && (code <= 0xfb5b))   code -= (0xfb40 - 0xede1);\r
1814         else if((code >= 0xfb5c) && (code <= 0xfb7e))   code -= (0xfb5c - 0xee40);\r
1815         else if((code >= 0xfb80) && (code <= 0xfb9b))   code -= (0xfb80 - 0xee63);\r
1816         else if((code >= 0xfb9c) && (code <= 0xfbfc))   code -= (0xfb9c - 0xee80);\r
1817         else if((code >= 0xfc40) && (code <= 0xfc4b))   code -= (0xfc40 - 0xeee1);\r
1818         return code;\r
1819 }\r
1820 \r