OSDN Git Service

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