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