OSDN Git Service

Change to specify explicitly code pages.
[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                 SJISLength = NewSJISLength;\r
1521                 NewSJISLength = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);\r
1522         }\r
1523         free(pUTF16);\r
1524         // UTF-16 LE変換した時に文字数が増減する位置がUTF-8の区切り\r
1525         NewUTF16Length = UTF16Length;\r
1526         while(UTF8Length > 0 && NewUTF16Length >= UTF16Length)\r
1527         {\r
1528                 UTF8Length--;\r
1529                 UTF16Length = NewUTF16Length;\r
1530                 NewUTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, NULL, 0);\r
1531         }\r
1532         if(pNewUTF8Length)\r
1533         {\r
1534                 if(UTF16Length > 0)\r
1535                         UTF8Length++;\r
1536                 *pNewUTF8Length = UTF8Length;\r
1537         }\r
1538         return NewSJISLength;\r
1539 }\r
1540 \r
1541 int ConvUTF8NtoSJIS(CODECONVINFO *cInfo)\r
1542 {\r
1543         int Continue;\r
1544 \r
1545 //      char temp_string[2048];\r
1546 //      int string_length;\r
1547 \r
1548         // 大きいサイズに対応\r
1549         // 終端のNULLを含むバグを修正\r
1550         int SrcLength;\r
1551         char* pSrc;\r
1552         wchar_t* pUTF16;\r
1553         int UTF16Length;\r
1554 \r
1555         Continue = NO;\r
1556 \r
1557         // 生成される中間コードのサイズを調べる\r
1558 //      string_length = MultiByteToWideChar(\r
1559 //                                              CP_UTF8,                // 変換先文字コード\r
1560 //                                              0,                              // フラグ(0:なし)\r
1561 //                                              cInfo->Str,             // 変換元文字列\r
1562 //                                              -1,                             // 変換元文字列バイト数(-1:自動)\r
1563 //                                              NULL,                   // 変換した文字列の格納先\r
1564 //                                              0                               // 格納先サイズ\r
1565 //                                      );\r
1566         // 前回の変換不能な残りの文字列を入力の先頭に結合\r
1567         SrcLength = cInfo->StrLen + cInfo->EscUTF8Len;\r
1568         if(!(pSrc = (char*)malloc(sizeof(char) * (SrcLength + 1))))\r
1569         {\r
1570                 *(cInfo->Buf) = '\0';\r
1571                 cInfo->BufSize = 0;\r
1572                 return Continue;\r
1573         }\r
1574         memcpy(pSrc, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);\r
1575         memcpy(pSrc + cInfo->EscUTF8Len, cInfo->Str, sizeof(char) * cInfo->StrLen);\r
1576         *(pSrc + SrcLength) = '\0';\r
1577         if(cInfo->EscFlush == NO)\r
1578         {\r
1579                 // バッファに収まらないため変換文字数を半減\r
1580                 while(SrcLength > 0 && ConvUTF8NtoSJIS_TruncateToDelimiter(pSrc, SrcLength, &SrcLength) > cInfo->BufSize)\r
1581                 {\r
1582                         SrcLength = SrcLength / 2;\r
1583                 }\r
1584         }\r
1585         // UTF-8の場合、不完全な文字は常に変換されない\r
1586         UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pSrc, SrcLength, NULL, 0);\r
1587 \r
1588         // サイズ0 or バッファサイズより大きい場合は\r
1589         // cInfo->Bufの最初に'\0'を入れて、\r
1590         // cInfo->BufSizeに0を入れて返す。\r
1591 //      if( string_length == 0 ||\r
1592 //              string_length >= 1024 ){\r
1593 //              *(cInfo->Buf) = '\0';\r
1594 //              cInfo->BufSize = 0;\r
1595 //              return(Continue);\r
1596 //      }\r
1597         if(!(pUTF16 = (wchar_t*)malloc(sizeof(wchar_t) * UTF16Length)))\r
1598         {\r
1599                 free(pSrc);\r
1600                 *(cInfo->Buf) = '\0';\r
1601                 cInfo->BufSize = 0;\r
1602                 return Continue;\r
1603         }\r
1604 \r
1605         // 中間コード(unicode)に変換\r
1606 //      MultiByteToWideChar(\r
1607 //              CP_UTF8,                                                // 変換先文字コード\r
1608 //              0,                                                              // フラグ(0:なし)\r
1609 //              cInfo->Str,                                             // 変換元文字列\r
1610 //              -1,                                                             // 変換元文字列バイト数(-1:自動)\r
1611 //              (unsigned short *)temp_string,  // 変換した文字列の格納先\r
1612 //              1024                                                    // 格納先サイズ\r
1613 //      );\r
1614         MultiByteToWideChar(CP_UTF8, 0, pSrc, SrcLength, pUTF16, UTF16Length);\r
1615 \r
1616         // 生成されるUTF-8コードのサイズを調べる\r
1617 //      string_length = WideCharToMultiByte(\r
1618 //                                              CP_ACP,                 // 変換先文字コード\r
1619 //                                              0,                              // フラグ(0:なし)\r
1620 //                                              (unsigned short *)temp_string,  // 変換元文字列\r
1621 //                                              -1,                             // 変換元文字列バイト数(-1:自動)\r
1622 //                                              NULL,                   // 変換した文字列の格納先\r
1623 //                                              0,                              // 格納先サイズ\r
1624 //                                              NULL,NULL\r
1625 //                                      );\r
1626 \r
1627         // サイズ0 or 出力バッファサイズより大きい場合は、\r
1628         // cInfo->Bufの最初に'\0'を入れて、\r
1629         // cInfo->BufSizeに0を入れて返す。\r
1630 //      if( string_length == 0 ||\r
1631 //              string_length >= cInfo->BufSize ){\r
1632 //              *(cInfo->Buf) = '\0';\r
1633 //              cInfo->BufSize = 0;\r
1634 //              return(Continue);\r
1635 //      }\r
1636 \r
1637         // 出力サイズを設定\r
1638 //      cInfo->OutLen = string_length;\r
1639 \r
1640         // UTF-8コードに変換\r
1641 //      WideCharToMultiByte(\r
1642 //              CP_ACP,                                                 // 変換先文字コード\r
1643 //              0,                                                              // フラグ(0:なし)\r
1644 //              (unsigned short *)temp_string,  // 変換元文字列\r
1645 //              -1,                                                             // 変換元文字列バイト数(-1:自動)\r
1646 //              cInfo->Buf,                                             // 変換した文字列の格納先(BOM:3bytes)\r
1647 //              cInfo->BufSize,                                 // 格納先サイズ\r
1648 //              NULL,NULL\r
1649 //      );\r
1650         cInfo->OutLen = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);\r
1651         cInfo->Str += SrcLength - cInfo->EscUTF8Len;\r
1652         cInfo->StrLen -= SrcLength - cInfo->EscUTF8Len;\r
1653         cInfo->EscUTF8Len = 0;\r
1654         if(ConvUTF8NtoSJIS_TruncateToDelimiter(cInfo->Str, cInfo->StrLen, NULL) > 0)\r
1655                 Continue = YES;\r
1656         else\r
1657         {\r
1658                 // 変換不能なため次の入力の先頭に結合\r
1659                 memcpy(cInfo->EscUTF8, cInfo->Str, sizeof(char) * cInfo->StrLen);\r
1660                 cInfo->EscUTF8Len = cInfo->StrLen;\r
1661                 cInfo->Str += cInfo->StrLen;\r
1662                 cInfo->StrLen = 0;\r
1663                 cInfo->FlushProc = ConvUTF8NtoSJIS;\r
1664                 Continue = NO;\r
1665         }\r
1666 \r
1667         free(pSrc);\r
1668         free(pUTF16);\r
1669 \r
1670         return(Continue);\r
1671 }\r
1672 \r
1673 /*----- SHIFT-JIS漢字コードをUTF-8漢字コードに変換 ------------------------------\r
1674 *\r
1675 *       Parameter\r
1676 *               CODECONVINFO *cInfo : 漢字コード変換情報\r
1677 *\r
1678 *       Return Value\r
1679 *               int くり返しフラグ (YES/NO)\r
1680 *\r
1681 *       Note\r
1682 *               くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
1683 *----------------------------------------------------------------------------*/\r
1684 int ConvSJIStoUTF8N(CODECONVINFO *cInfo)\r
1685 {\r
1686         int Continue;\r
1687 \r
1688 //      char temp_string[2048];\r
1689         int string_length;\r
1690 \r
1691         // 大きいサイズに対応\r
1692         // 終端のNULLを含むバグを修正\r
1693         int SrcLength;\r
1694         char* pSrc;\r
1695         wchar_t* pUTF16;\r
1696         int UTF16Length;\r
1697         int Count;\r
1698 \r
1699         Continue = NO;\r
1700 \r
1701         // 生成される中間コードのサイズを調べる\r
1702 //      string_length = MultiByteToWideChar(\r
1703 //                                              CP_ACP,                 // 変換先文字コード\r
1704 //                                              0,                              // フラグ(0:なし)\r
1705 //                                              cInfo->Str,             // 変換元文字列\r
1706 //                                              -1,                             // 変換元文字列バイト数(-1:自動)\r
1707 //                                              NULL,                   // 変換した文字列の格納先\r
1708 //                                              0                               // 格納先サイズ\r
1709 //                                      );\r
1710         // 前回の変換不能な残りの文字列を入力の先頭に結合\r
1711         SrcLength = cInfo->StrLen + cInfo->EscUTF8Len;\r
1712         if(!(pSrc = (char*)malloc(sizeof(char) * (SrcLength + 1))))\r
1713         {\r
1714                 *(cInfo->Buf) = '\0';\r
1715                 cInfo->BufSize = 0;\r
1716                 return Continue;\r
1717         }\r
1718         memcpy(pSrc, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);\r
1719         memcpy(pSrc + cInfo->EscUTF8Len, cInfo->Str, sizeof(char) * cInfo->StrLen);\r
1720         *(pSrc + SrcLength) = '\0';\r
1721         if(cInfo->EscFlush == NO)\r
1722         {\r
1723                 // Shift_JISの場合、不完全な文字でも変換されることがあるため、末尾の不完全な部分を削る\r
1724                 Count = 0;\r
1725                 while(Count < SrcLength)\r
1726                 {\r
1727                         if(((unsigned char)*(pSrc + Count) >= 0x81 && (unsigned char)*(pSrc + Count) <= 0x9f) || (unsigned char)*(pSrc + Count) >= 0xe0)\r
1728                         {\r
1729                                 if((unsigned char)*(pSrc + Count + 1) >= 0x40)\r
1730                                         Count += 2;\r
1731                                 else\r
1732                                 {\r
1733                                         if(Count + 2 > SrcLength)\r
1734                                                 break;\r
1735                                         Count += 1;\r
1736                                 }\r
1737                         }\r
1738                         else\r
1739                                 Count += 1;\r
1740                 }\r
1741                 SrcLength = Count;\r
1742         }\r
1743         UTF16Length = MultiByteToWideChar(CP_ACP, 0, pSrc, SrcLength, NULL, 0);\r
1744 \r
1745         // サイズ0 or バッファサイズより大きい場合は、\r
1746         // cInfo->Bufの最初に'\0'を入れて、\r
1747         // cInfo->BufSizeに0を入れて返す。\r
1748 //      if( string_length == 0 ||\r
1749 //              string_length >= 1024 ){\r
1750 //              *(cInfo->Buf) = '\0';\r
1751 //              cInfo->BufSize = 0;\r
1752 //              return(Continue);\r
1753 //      }\r
1754         if(!(pUTF16 = (wchar_t*)malloc(sizeof(wchar_t) * UTF16Length)))\r
1755         {\r
1756                 free(pSrc);\r
1757                 *(cInfo->Buf) = '\0';\r
1758                 cInfo->BufSize = 0;\r
1759                 return Continue;\r
1760         }\r
1761 \r
1762         // 中間コード(unicode)に変換\r
1763 //      MultiByteToWideChar(\r
1764 //              CP_ACP,                                                 // 変換先文字コード\r
1765 //              0,                                                              // フラグ(0:なし)\r
1766 //              cInfo->Str,                                             // 変換元文字列\r
1767 //              -1,                                                             // 変換元文字列バイト数(-1:自動)\r
1768 //              (unsigned short *)temp_string,  // 変換した文字列の格納先\r
1769 //              1024                                                    // 格納先サイズ\r
1770 //      );\r
1771         MultiByteToWideChar(CP_ACP, 0, pSrc, SrcLength, pUTF16, UTF16Length);\r
1772 \r
1773         // 生成されるUTF-8コードのサイズを調べる\r
1774 //      string_length = WideCharToMultiByte(\r
1775 //                                              CP_UTF8,                // 変換先文字コード\r
1776 //                                              0,                              // フラグ(0:なし)\r
1777 //                                              (unsigned short *)temp_string,  // 変換元文字列\r
1778 //                                              -1,                             // 変換元文字列バイト数(-1:自動)\r
1779 //                                              NULL,                   // 変換した文字列の格納先\r
1780 //                                              0,                              // 格納先サイズ\r
1781 //                                              NULL,NULL\r
1782 //                                      );\r
1783         string_length = WideCharToMultiByte(CP_UTF8, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);\r
1784 \r
1785         // サイズ0 or 出力バッファサイズより大きい場合は、\r
1786         // cInfo->Bufの最初に'\0'を入れて、\r
1787         // cInfo->BufSizeに0を入れて返す。\r
1788 //      if( string_length == 0 ||\r
1789 //              string_length >= cInfo->BufSize ){\r
1790 //              *(cInfo->Buf) = '\0';\r
1791 //              cInfo->BufSize = 0;\r
1792 //              return(Continue);\r
1793 //      }\r
1794 \r
1795         // 出力サイズを設定\r
1796 //      cInfo->OutLen = string_length;\r
1797 \r
1798         /*\r
1799         // ↓付けちゃだめ コマンドにも追加されてしまう\r
1800         // 出力文字列の先頭にBOM(byte order mark)をつける\r
1801         *(cInfo->Buf) = (char)0xef;\r
1802         *(cInfo->Buf+1) = (char)0xbb;\r
1803         *(cInfo->Buf+2) = (char)0xbf;\r
1804         */\r
1805 \r
1806         // UTF-8コードに変換\r
1807 //      WideCharToMultiByte(\r
1808 //              CP_UTF8,                                                // 変換先文字コード\r
1809 //              0,                                                              // フラグ(0:なし)\r
1810 //              (unsigned short *)temp_string,  // 変換元文字列\r
1811 //              -1,                                                             // 変換元文字列バイト数(-1:自動)\r
1812 //              cInfo->Buf,                                     // 変換した文字列の格納先(BOM:3bytes)\r
1813 //              cInfo->BufSize,                                 // 格納先サイズ\r
1814 //              NULL,NULL\r
1815 //      );\r
1816         cInfo->OutLen = WideCharToMultiByte(CP_UTF8, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);\r
1817         // バッファに収まらないため変換文字数を半減\r
1818         while(cInfo->OutLen == 0 && UTF16Length > 0)\r
1819         {\r
1820                 UTF16Length = UTF16Length / 2;\r
1821                 cInfo->OutLen = WideCharToMultiByte(CP_UTF8, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);\r
1822         }\r
1823         // 変換された元の文字列での文字数を取得\r
1824         Count = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);\r
1825         // 変換可能な残りの文字数を取得\r
1826         UTF16Length = MultiByteToWideChar(CP_ACP, 0, pSrc + Count, SrcLength - Count, NULL, 0);\r
1827         cInfo->Str += Count - cInfo->EscUTF8Len;\r
1828         cInfo->StrLen -= Count - cInfo->EscUTF8Len;\r
1829         cInfo->EscUTF8Len = 0;\r
1830         if(UTF16Length > 0)\r
1831                 Continue = YES;\r
1832         else\r
1833         {\r
1834                 // 変換不能なため次の入力の先頭に結合\r
1835                 memcpy(cInfo->EscUTF8, cInfo->Str, sizeof(char) * cInfo->StrLen);\r
1836                 cInfo->EscUTF8Len = cInfo->StrLen;\r
1837                 cInfo->Str += cInfo->StrLen;\r
1838                 cInfo->StrLen = 0;\r
1839                 cInfo->FlushProc = ConvSJIStoUTF8N;\r
1840                 Continue = NO;\r
1841         }\r
1842 \r
1843         free(pSrc);\r
1844         free(pUTF16);\r
1845 \r
1846         return(Continue);\r
1847 }\r
1848 // UTF-8対応 ここまで↑\r
1849 \r
1850 \r
1851 /*----- IBM拡張漢字をNEC選定IBM拡張漢字等に変換 -------------------------------\r
1852 *\r
1853 *       Parameter\r
1854 *               code    漢字コード\r
1855 *\r
1856 *       Return Value\r
1857 *               int 漢字コード\r
1858 *----------------------------------------------------------------------------*/\r
1859 static int ConvertIBMExtendedChar(int code)\r
1860 {\r
1861         if((code >= 0xfa40) && (code <= 0xfa49))                code -= (0xfa40 - 0xeeef);\r
1862         else if((code >= 0xfa4a) && (code <= 0xfa53))   code -= (0xfa4a - 0x8754);\r
1863         else if((code >= 0xfa54) && (code <= 0xfa57))   code -= (0xfa54 - 0xeef9);\r
1864         else if(code == 0xfa58)                                                 code = 0x878a;\r
1865         else if(code == 0xfa59)                                                 code = 0x8782;\r
1866         else if(code == 0xfa5a)                                                 code = 0x8784;\r
1867         else if(code == 0xfa5b)                                                 code = 0x879a;\r
1868         else if((code >= 0xfa5c) && (code <= 0xfa7e))   code -= (0xfa5c - 0xed40);\r
1869         else if((code >= 0xfa80) && (code <= 0xfa9b))   code -= (0xfa80 - 0xed63);\r
1870         else if((code >= 0xfa9c) && (code <= 0xfafc))   code -= (0xfa9c - 0xed80);\r
1871         else if((code >= 0xfb40) && (code <= 0xfb5b))   code -= (0xfb40 - 0xede1);\r
1872         else if((code >= 0xfb5c) && (code <= 0xfb7e))   code -= (0xfb5c - 0xee40);\r
1873         else if((code >= 0xfb80) && (code <= 0xfb9b))   code -= (0xfb80 - 0xee63);\r
1874         else if((code >= 0xfb9c) && (code <= 0xfbfc))   code -= (0xfb9c - 0xee80);\r
1875         else if((code >= 0xfc40) && (code <= 0xfc4b))   code -= (0xfc40 - 0xeee1);\r
1876         return code;\r
1877 }\r
1878 \r