1 /*=============================================================================
\r
5 ===============================================================================
\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.
\r
8 / Redistribution and use in source and binary forms, with or without
\r
9 / modification, are permitted provided that the following conditions
\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
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
34 #include <winsock.h>
\r
35 #include <mbstring.h>
\r
36 #include <windowsx.h>
\r
39 #include "resource.h"
\r
43 #define CONV_ASCII 0 /* ASCII文字処理中 */
\r
44 #define CONV_KANJI 1 /* 漢字処理中 */
\r
45 #define CONV_KANA 2 /* 半角カタカナ処理中 */
\r
48 /*===== プロトタイプ =====*/
\r
50 static char *ConvEUCtoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);
\r
51 static char *ConvJIStoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);
\r
52 static char *ConvSJIStoEUCkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);
\r
53 static char *ConvSJIStoJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);
\r
54 static int HanKataToZen(char Ch);
\r
55 static int AskDakuon(char Ch, char Daku);
\r
57 static int CheckOnSJIS(uchar *Pos, uchar *Btm);
\r
58 static int CheckOnEUC(uchar *Pos, uchar *Btm);
\r
59 static int ConvertIBMExtendedChar(int code);
\r
64 /*----- 漢字コード変換のテストプログラム ------------------------------------*/
\r
66 void CodeCnvTest(void)
\r
69 #define BUFBUF2 BUFBUF+3
\r
79 // DoPrintf("---START ZEN");
\r
81 Strm1 = fopen("in.txt", "rb");
\r
82 Strm2 = fopen("out_zen.txt", "wb");
\r
84 InitCodeConvInfo(&cInfo);
\r
85 cInfo.KanaCnv = YES;
\r
88 while((Byte = fread(Buf, 1, BUFBUF, Strm1)) != 0)
\r
91 cInfo.StrLen = Byte;
\r
93 cInfo.BufSize = BUFBUF2;
\r
95 // DoPrintf("READ %d", Byte);
\r
99 // Continue = ConvEUCtoSJIS(&cInfo);
\r
100 // Continue = ConvJIStoSJIS(&cInfo);
\r
101 // Continue = ConvSJIStoEUC(&cInfo);
\r
102 // Continue = ConvSJIStoJIS(&cInfo);
\r
103 Continue = ConvSMBtoSJIS(&cInfo);
\r
104 // Continue = ConvSJIStoSMB_HEX(&cInfo);
\r
105 // Continue = ConvSJIStoSMB_CAP(&cInfo);
\r
107 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
108 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
111 while(Continue == YES);
\r
115 cInfo.BufSize = BUFBUF2;
\r
116 FlushRestData(&cInfo);
\r
117 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
118 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
125 // DoPrintf("---START HAN");
\r
127 Strm1 = fopen("in.txt", "rb");
\r
128 Strm2 = fopen("out_han.txt", "wb");
\r
130 InitCodeConvInfo(&cInfo);
\r
131 cInfo.KanaCnv = NO;
\r
134 while((Byte = fread(Buf, 1, BUFBUF, Strm1)) != 0)
\r
137 cInfo.StrLen = Byte;
\r
139 cInfo.BufSize = BUFBUF2;
\r
141 // DoPrintf("READ %d", Byte);
\r
145 // Continue = ConvEUCtoSJIS(&cInfo);
\r
146 // Continue = ConvJIStoSJIS(&cInfo);
\r
147 // Continue = ConvSJIStoEUC(&cInfo);
\r
148 // Continue = ConvSJIStoJIS(&cInfo);
\r
149 Continue = ConvSMBtoSJIS(&cInfo);
\r
150 // Continue = ConvSJIStoSMB_HEX(&cInfo);
\r
151 // Continue = ConvSJIStoSMB_CAP(&cInfo);
\r
152 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
153 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
156 while(Continue == YES);
\r
160 cInfo.BufSize = BUFBUF2;
\r
161 FlushRestData(&cInfo);
\r
162 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
163 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
168 // DoPrintf("---END");
\r
177 /*----- 改行コード変換のテストプログラム ------------------------------------*/
\r
179 void TermCodeCnvTest(void)
\r
182 #define BUFBUF2 BUFBUF
\r
184 TERMCODECONVINFO cInfo;
\r
186 char Buf2[BUFBUF2];
\r
192 // DoPrintf("---START");
\r
194 Strm1 = fopen("in.txt", "rb");
\r
195 Strm2 = fopen("out.txt", "wb");
\r
197 InitTermCodeConvInfo(&cInfo);
\r
199 while((Byte = fread(Buf, 1, BUFBUF, Strm1)) != 0)
\r
202 cInfo.StrLen = Byte;
\r
204 cInfo.BufSize = BUFBUF2;
\r
206 // DoPrintf("READ %d", Byte);
\r
210 Continue = ConvTermCodeToCRLF(&cInfo);
\r
212 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
213 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
216 while(Continue == YES);
\r
220 cInfo.BufSize = BUFBUF2;
\r
221 FlushRestTermCodeConvData(&cInfo);
\r
222 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
223 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
228 // DoPrintf("---END");
\r
245 /*----- 改行コード変換情報を初期化 --------------------------------------------
\r
248 * TERMCODECONVINFO *cInfo : 改行コード変換情報
\r
252 *----------------------------------------------------------------------------*/
\r
254 void InitTermCodeConvInfo(TERMCODECONVINFO *cInfo)
\r
261 /*----- 改行コード変換の残り情報を出力 ----------------------------------------
\r
264 * TERMCODECONVINFO *cInfo : 改行コード変換情報
\r
267 * int くり返しフラグ (=NO)
\r
271 *----------------------------------------------------------------------------*/
\r
273 int FlushRestTermCodeConvData(TERMCODECONVINFO *cInfo)
\r
279 if(cInfo->Term == 0x0D)
\r
282 cInfo->OutLen = Put - cInfo->Buf;
\r
288 /*----- 改行コードをCRLFに変換 -------------------------------------------------
\r
291 * TERMCODECONVINFO *cInfo : 改行コード変換情報
\r
294 * int くり返しフラグ (YES/NO)
\r
297 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
298 *----------------------------------------------------------------------------*/
\r
300 int ConvTermCodeToCRLF(TERMCODECONVINFO *cInfo)
\r
310 Limit = cInfo->Buf + cInfo->BufSize - 1;
\r
312 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
322 if(cInfo->Term == 0x0D)
\r
325 cInfo->Term = *Str++;
\r
331 if(cInfo->Term != 0x0D)
\r
336 if(cInfo->Term == 0x0D)
\r
345 cInfo->OutLen = Put - cInfo->Buf;
\r
351 /*----- 漢字コード変換情報を初期化 --------------------------------------------
\r
354 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
358 *----------------------------------------------------------------------------*/
\r
360 void InitCodeConvInfo(CODECONVINFO *cInfo)
\r
362 cInfo->KanaCnv = YES;
\r
364 cInfo->EscProc = 0;
\r
365 cInfo->KanjiMode = CONV_ASCII;
\r
366 cInfo->KanjiFst = 0;
\r
367 cInfo->KanaPrev = 0;
\r
368 cInfo->KanaProc = NULL;
\r
373 /*----- 漢字コード変換の残り情報を出力 ----------------------------------------
\r
376 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
379 * int くり返しフラグ (=NO)
\r
383 *----------------------------------------------------------------------------*/
\r
385 int FlushRestData(CODECONVINFO *cInfo)
\r
391 if(cInfo->KanaProc != NULL)
\r
392 Put = (cInfo->KanaProc)(cInfo, 0, Put);
\r
394 if(cInfo->KanjiFst != 0)
\r
395 *Put++ = cInfo->KanjiFst;
\r
396 if(cInfo->EscProc >= 1)
\r
397 *Put++ = cInfo->EscCode[0];
\r
398 if(cInfo->EscProc == 2)
\r
399 *Put++ = cInfo->EscCode[1];
\r
401 cInfo->OutLen = Put - cInfo->Buf;
\r
407 /*----- EUC漢字コードをSHIFT-JIS漢字コードに変換 ------------------------------
\r
410 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
413 * int くり返しフラグ (YES/NO)
\r
416 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
417 *----------------------------------------------------------------------------*/
\r
419 int ConvEUCtoSJIS(CODECONVINFO *cInfo)
\r
427 cInfo->KanaProc = &ConvEUCtoSJISkanaProc;
\r
432 Limit = cInfo->Buf + cInfo->BufSize - 2;
\r
434 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
442 if((*Str & 0x80) != 0)
\r
444 if(cInfo->KanjiFst == 0)
\r
445 cInfo->KanjiFst = *Str++;
\r
448 if((uchar)cInfo->KanjiFst == (uchar)0x8E) /* 半角カタカナ */
\r
450 Put = ConvEUCtoSJISkanaProc(cInfo, *Str++, Put);
\r
454 Put = ConvEUCtoSJISkanaProc(cInfo, 0, Put);
\r
456 Kcode = _mbcjistojms(((cInfo->KanjiFst & 0x7F) * 0x100) + (*Str++ & 0x7F));
\r
457 *Put++ = HIGH8(Kcode);
\r
458 *Put++ = LOW8(Kcode);
\r
460 cInfo->KanjiFst = 0;
\r
465 Put = ConvEUCtoSJISkanaProc(cInfo, 0, Put);
\r
467 if(cInfo->KanjiFst != 0)
\r
469 *Put++ = cInfo->KanjiFst;
\r
470 cInfo->KanjiFst = 0;
\r
477 cInfo->OutLen = Put - cInfo->Buf;
\r
483 /*----- EUC-->SHIFT-JIS漢字コードに変換の半角カタカナの処理 -------------------
\r
486 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
488 * char *Put : データセット位置
\r
492 *----------------------------------------------------------------------------*/
\r
494 static char *ConvEUCtoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)
\r
499 if(cInfo->KanaCnv == NO)
\r
506 if(cInfo->KanaPrev != 0)
\r
508 Daku = AskDakuon(cInfo->KanaPrev, Dt);
\r
510 Kcode = _mbcjistojms(HanKataToZen(cInfo->KanaPrev)) + Daku;
\r
511 *Put++ = HIGH8(Kcode);
\r
512 *Put++ = LOW8(Kcode);
\r
515 cInfo->KanaPrev = Dt;
\r
517 cInfo->KanaPrev = 0;
\r
520 cInfo->KanaPrev = Dt;
\r
526 /*----- JIS漢字コードをSHIFT-JIS漢字コードに変換 ------------------------------
\r
529 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
532 * int くり返しフラグ (YES/NO)
\r
535 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
537 * エスケープコードは、次のものに対応している
\r
538 * 漢字開始 <ESC>$B <ESC>$@
\r
540 * 漢字終了 <ESC>(B <ESC>(J <ESC>(H
\r
541 *----------------------------------------------------------------------------*/
\r
543 int ConvJIStoSJIS(CODECONVINFO *cInfo)
\r
551 cInfo->KanaProc = &ConvJIStoSJISkanaProc;
\r
556 Limit = cInfo->Buf + cInfo->BufSize - 3;
\r
558 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
566 if(cInfo->EscProc == 0)
\r
570 if(cInfo->KanjiFst != 0)
\r
572 *Put++ = cInfo->KanjiFst;
\r
573 cInfo->KanjiFst = 0;
\r
575 Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);
\r
577 cInfo->EscCode[cInfo->EscProc] = *Str++;
\r
582 if(cInfo->KanjiMode == CONV_KANA)
\r
584 if(cInfo->KanjiFst != 0)
\r
586 *Put++ = cInfo->KanjiFst;
\r
587 cInfo->KanjiFst = 0;
\r
590 if((*Str >= 0x21) && (*Str <= 0x5F))
\r
592 Put = ConvJIStoSJISkanaProc(cInfo, *Str++, Put);
\r
596 Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);
\r
600 else if(cInfo->KanjiMode == CONV_KANJI)
\r
602 Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);
\r
603 if((*Str >= 0x21) && (*Str <= 0x7E))
\r
605 if(cInfo->KanjiFst == 0)
\r
606 cInfo->KanjiFst = *Str++;
\r
609 Kcode = _mbcjistojms((cInfo->KanjiFst * 0x100) + *Str++);
\r
610 *Put++ = HIGH8(Kcode);
\r
611 *Put++ = LOW8(Kcode);
\r
612 cInfo->KanjiFst = 0;
\r
617 if(cInfo->KanjiFst == 0)
\r
621 *Put++ = cInfo->KanjiFst;
\r
623 cInfo->KanjiFst = 0;
\r
629 Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);
\r
634 else if(cInfo->EscProc == 1)
\r
636 if((*Str == '$') || (*Str == '('))
\r
638 cInfo->EscCode[cInfo->EscProc] = *Str++;
\r
643 *Put++ = cInfo->EscCode[0];
\r
645 cInfo->EscProc = 0;
\r
648 else if(cInfo->EscProc == 2)
\r
650 if((cInfo->EscCode[1] == '$') && ((*Str == 'B') || (*Str == '@')))
\r
651 cInfo->KanjiMode = CONV_KANJI;
\r
652 else if((cInfo->EscCode[1] == '(') && (*Str == 'I'))
\r
653 cInfo->KanjiMode = CONV_KANA;
\r
654 else if((cInfo->EscCode[1] == '(') && ((*Str == 'B') || (*Str == 'J') || (*Str == 'H')))
\r
655 cInfo->KanjiMode = CONV_ASCII;
\r
658 *Put++ = cInfo->EscCode[0];
\r
659 *Put++ = cInfo->EscCode[1];
\r
660 if((cInfo->KanjiMode == CONV_KANJI) && ((*Str >= 0x21) && (*Str <= 0x7E)))
\r
661 cInfo->KanjiFst = *Str;
\r
666 cInfo->EscProc = 0;
\r
671 cInfo->OutLen = Put - cInfo->Buf;
\r
677 /*----- JIS-->SHIFT-JIS漢字コードに変換の半角カタカナの処理 -------------------
\r
680 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
682 * char *Put : データセット位置
\r
686 *----------------------------------------------------------------------------*/
\r
688 static char *ConvJIStoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)
\r
693 Dt = (uchar)Dt + (uchar)0x80;
\r
694 if(cInfo->KanaCnv == NO)
\r
696 if((uchar)Dt != (uchar)0x80)
\r
701 if(cInfo->KanaPrev != 0)
\r
703 Daku = AskDakuon(cInfo->KanaPrev, Dt);
\r
704 Kcode = _mbcjistojms(HanKataToZen(cInfo->KanaPrev)) + Daku;
\r
705 *Put++ = HIGH8(Kcode);
\r
706 *Put++ = LOW8(Kcode);
\r
708 if((Daku == 0) && ((uchar)Dt != (uchar)0x80))
\r
709 cInfo->KanaPrev = Dt;
\r
711 cInfo->KanaPrev = 0;
\r
713 else if((uchar)Dt != (uchar)0x80)
\r
714 cInfo->KanaPrev = Dt;
\r
720 /*----- Samba-HEX/Samba-CAP漢字コードをSHIFT-JIS漢字コードに変換 --------------
\r
723 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
726 * int くり返しフラグ (YES/NO)
\r
729 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
730 * 分割された入力文字列の変換はサポートしていない
\r
731 * 半角カタカナの変換設定には対応していない
\r
732 *----------------------------------------------------------------------------*/
\r
734 int ConvSMBtoSJIS(CODECONVINFO *cInfo)
\r
744 Limit = cInfo->Buf + cInfo->BufSize - 2;
\r
746 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
754 if((*Str == SAMBA_HEX_TAG) && (cInfo->StrLen >= 3))
\r
756 if(isxdigit(*(Str+1)) && isxdigit(*(Str+2)))
\r
758 *Put++ = N2INT(hex2bin(*(Str+1)), hex2bin(*(Str+2)));
\r
760 cInfo->StrLen -= 2;
\r
770 cInfo->OutLen = Put - cInfo->Buf;
\r
776 /*----- SHIFT-JIS漢字コードをEUC漢字コードに変換 ------------------------------
\r
779 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
782 * int くり返しフラグ (YES/NO)
\r
785 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
786 *----------------------------------------------------------------------------*/
\r
788 int ConvSJIStoEUC(CODECONVINFO *cInfo)
\r
796 cInfo->KanaProc = &ConvSJIStoEUCkanaProc;
\r
801 Limit = cInfo->Buf + cInfo->BufSize - 2;
\r
803 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
811 if(cInfo->KanjiFst == 0)
\r
813 if((((uchar)*Str >= (uchar)0x81) && ((uchar)*Str <= (uchar)0x9F)) ||
\r
814 ((uchar)*Str >= (uchar)0xE0))
\r
816 Put = ConvSJIStoEUCkanaProc(cInfo, 0, Put);
\r
817 cInfo->KanjiFst = *Str++;
\r
819 else if(((uchar)*Str >= (uchar)0xA0) && ((uchar)*Str <= (uchar)0xDF))
\r
821 Put = ConvSJIStoEUCkanaProc(cInfo, *Str++, Put);
\r
825 Put = ConvSJIStoEUCkanaProc(cInfo, 0, Put);
\r
831 if((uchar)*Str >= (uchar)0x40)
\r
833 Kcode = ConvertIBMExtendedChar(((uchar)cInfo->KanjiFst * 0x100) + (uchar)*Str++);
\r
834 Kcode = _mbcjmstojis(Kcode);
\r
835 *Put++ = HIGH8(Kcode) | 0x80;
\r
836 *Put++ = LOW8(Kcode) | 0x80;
\r
840 *Put++ = cInfo->KanjiFst;
\r
843 cInfo->KanjiFst = 0;
\r
848 cInfo->OutLen = Put - cInfo->Buf;
\r
854 /*----- SHIFT-JIS-->EUC漢字コードに変換の半角カタカナの処理 -------------------
\r
857 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
859 * char *Put : データセット位置
\r
863 *----------------------------------------------------------------------------*/
\r
865 static char *ConvSJIStoEUCkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)
\r
870 if(cInfo->KanaCnv == NO)
\r
874 Kcode = 0x8E00 + (uchar)Dt;
\r
875 *Put++ = HIGH8(Kcode) | 0x80;
\r
876 *Put++ = LOW8(Kcode) | 0x80;
\r
881 if(cInfo->KanaPrev != 0)
\r
883 Daku = AskDakuon(cInfo->KanaPrev, Dt);
\r
884 Kcode = HanKataToZen(cInfo->KanaPrev) + Daku;
\r
885 *Put++ = HIGH8(Kcode) | 0x80;
\r
886 *Put++ = LOW8(Kcode) | 0x80;
\r
889 cInfo->KanaPrev = Dt;
\r
891 cInfo->KanaPrev = 0;
\r
894 cInfo->KanaPrev = Dt;
\r
900 /*----- SHIFT-JIS漢字コードをJIS漢字コードに変換 ------------------------------
\r
903 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
906 * int くり返しフラグ (YES/NO)
\r
909 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
911 * エスケープコードは、次のものを使用する
\r
915 *----------------------------------------------------------------------------*/
\r
917 int ConvSJIStoJIS(CODECONVINFO *cInfo)
\r
925 cInfo->KanaProc = &ConvSJIStoJISkanaProc;
\r
930 Limit = cInfo->Buf + cInfo->BufSize - 5;
\r
932 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
940 if(cInfo->KanjiFst == 0)
\r
942 if((((uchar)*Str >= (uchar)0x81) && ((uchar)*Str <= (uchar)0x9F)) ||
\r
943 ((uchar)*Str >= (uchar)0xE0))
\r
945 Put = ConvSJIStoJISkanaProc(cInfo, 0, Put);
\r
946 cInfo->KanjiFst = *Str++;
\r
948 else if(((uchar)*Str >= (uchar)0xA0) && ((uchar)*Str <= (uchar)0xDF))
\r
950 Put = ConvSJIStoJISkanaProc(cInfo, *Str++, Put);
\r
954 Put = ConvSJIStoJISkanaProc(cInfo, 0, Put);
\r
955 if(cInfo->KanjiMode != CONV_ASCII)
\r
960 cInfo->KanjiMode = CONV_ASCII;
\r
967 Put = ConvSJIStoJISkanaProc(cInfo, 0, Put);
\r
968 if((uchar)*Str >= (uchar)0x40)
\r
970 if(cInfo->KanjiMode != CONV_KANJI)
\r
975 cInfo->KanjiMode = CONV_KANJI;
\r
978 Kcode = ConvertIBMExtendedChar(((uchar)cInfo->KanjiFst * 0x100) + (uchar)*Str++);
\r
979 Kcode = _mbcjmstojis(Kcode);
\r
980 *Put++ = HIGH8(Kcode);
\r
981 *Put++ = LOW8(Kcode);
\r
985 if(cInfo->KanjiMode != CONV_ASCII)
\r
990 cInfo->KanjiMode = CONV_ASCII;
\r
992 *Put++ = cInfo->KanjiFst;
\r
995 cInfo->KanjiFst = 0;
\r
1000 cInfo->OutLen = Put - cInfo->Buf;
\r
1006 /*----- SHIFT-JIS-->JIS漢字コードに変換の半角カタカナの処理 -------------------
\r
1009 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
1011 * char *Put : データセット位置
\r
1014 * char *次のデータセット位置
\r
1015 *----------------------------------------------------------------------------*/
\r
1017 static char *ConvSJIStoJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)
\r
1022 if(cInfo->KanaCnv == NO)
\r
1026 if(cInfo->KanjiMode != CONV_KANA)
\r
1031 cInfo->KanjiMode = CONV_KANA;
\r
1033 *Put++ = (uchar)Dt - (uchar)0x80;
\r
1038 if(cInfo->KanaPrev != 0)
\r
1040 if(cInfo->KanjiMode != CONV_KANJI)
\r
1045 cInfo->KanjiMode = CONV_KANJI;
\r
1047 Daku = AskDakuon(cInfo->KanaPrev, Dt);
\r
1048 Kcode = HanKataToZen(cInfo->KanaPrev) + Daku;
\r
1049 *Put++ = HIGH8(Kcode);
\r
1050 *Put++ = LOW8(Kcode);
\r
1053 cInfo->KanaPrev = Dt;
\r
1055 cInfo->KanaPrev = 0;
\r
1058 cInfo->KanaPrev = Dt;
\r
1064 /*----- SHIFT-JIS漢字コードをSamba-HEX漢字コードに変換 ------------------------
\r
1067 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
1070 * int くり返しフラグ (YES/NO)
\r
1073 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
1074 * 分割された入力文字列の変換はサポートしていない
\r
1075 * 半角カタカナの変換設定には対応していない
\r
1076 *----------------------------------------------------------------------------*/
\r
1078 int ConvSJIStoSMB_HEX(CODECONVINFO *cInfo)
\r
1088 Limit = cInfo->Buf + cInfo->BufSize - 6;
\r
1090 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
1098 if((cInfo->StrLen >= 2) &&
\r
1099 ((((uchar)*Str >= (uchar)0x81) && ((uchar)*Str <= (uchar)0x9F)) ||
\r
1100 ((uchar)*Str >= (uchar)0xE0)))
\r
1102 sprintf(Put, "%c%02x%c%02x", SAMBA_HEX_TAG, (uchar)*Str, SAMBA_HEX_TAG, (uchar)*(Str+1));
\r
1107 else if((uchar)*Str >= (uchar)0x80)
\r
1109 sprintf(Put, "%c%02x", SAMBA_HEX_TAG, (uchar)*Str++);
\r
1117 cInfo->OutLen = Put - cInfo->Buf;
\r
1123 /*----- SHIFT-JIS漢字コードをSamba-CAP漢字コードに変換 ------------------------
\r
1126 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
1129 * int くり返しフラグ (YES/NO)
\r
1132 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
1133 * 分割された入力文字列の変換はサポートしていない
\r
1134 *----------------------------------------------------------------------------*/
\r
1136 int ConvSJIStoSMB_CAP(CODECONVINFO *cInfo)
\r
1146 Limit = cInfo->Buf + cInfo->BufSize - 6;
\r
1148 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
1156 if((uchar)*Str >= (uchar)0x80)
\r
1158 sprintf(Put, "%c%02x", SAMBA_HEX_TAG, (uchar)*Str++);
\r
1166 cInfo->OutLen = Put - cInfo->Buf;
\r
1172 /*----- 1バイトカタカナをJIS漢字コードに変換 ---------------------------------
\r
1175 * char Ch : 1バイトカタカナコード
\r
1179 *----------------------------------------------------------------------------*/
\r
1181 static int HanKataToZen(char Ch)
\r
1183 static const int Katakana[] = {
\r
1184 0x2121, 0x2123, 0x2156, 0x2157, 0x2122, 0x2126, 0x2572, 0x2521,
\r
1185 0x2523, 0x2525, 0x2527, 0x2529, 0x2563, 0x2565, 0x2567, 0x2543,
\r
1186 0x213C, 0x2522, 0x2524, 0x2526, 0x2528, 0x252A, 0x252B, 0x252D,
\r
1187 0x252F, 0x2531, 0x2533, 0x2535, 0x2537, 0x2539, 0x253B, 0x253D,
\r
1188 0x253F, 0x2541, 0x2544, 0x2546, 0x2548, 0x254A, 0x254B, 0x254C,
\r
1189 0x254D, 0x254E, 0x254F, 0x2552, 0x2555, 0x2558, 0x255B, 0x255E,
\r
1190 0x255F, 0x2560, 0x2561, 0x2562, 0x2564, 0x2566, 0x2568, 0x2569,
\r
1191 0x256A, 0x256B, 0x256C, 0x256D, 0x256F, 0x2573, 0x212B, 0x212C
\r
1194 return(Katakana[(uchar)Ch - (uchar)0xA0]);
\r
1198 /*----- 濁音/半濁音になる文字かチェック --------------------------------------
\r
1201 * char Ch : 1バイトカタカナコード
\r
1202 * char Daku : 濁点/半濁点
\r
1205 * int 文字コードに加える値 (0=濁音/半濁音にならない)
\r
1206 *----------------------------------------------------------------------------*/
\r
1208 static int AskDakuon(char Ch, char Daku)
\r
1213 if((uchar)Daku == (uchar)0xDE)
\r
1215 if((((uchar)Ch >= (uchar)0xB6) && ((uchar)Ch <= (uchar)0xC4)) ||
\r
1216 (((uchar)Ch >= (uchar)0xCA) && ((uchar)Ch <= (uchar)0xCE)))
\r
1221 else if((uchar)Daku == (uchar)0xDF)
\r
1223 if(((uchar)Ch >= (uchar)0xCA) && ((uchar)Ch <= (uchar)0xCE))
\r
1242 /*----- 文字列の漢字コードを調べ、Shift-JISに変換 -----------------------------
\r
1245 * char *Text : 文字列
\r
1246 * int Pref : SJIS/EUCの優先指定
\r
1247 * KANJI_SJIS / KANJI_EUC / KANJI_NOCNV=SJIS/EUCのチェックはしない
\r
1251 *----------------------------------------------------------------------------*/
\r
1253 void ConvAutoToSJIS(char *Text, int Pref)
\r
1257 CODECONVINFO cInfo;
\r
1259 Code = CheckKanjiCode(Text, strlen(Text), Pref);
\r
1260 if(Code != KANJI_SJIS)
\r
1262 Buf = malloc(strlen(Text)+1);
\r
1265 InitCodeConvInfo(&cInfo);
\r
1266 cInfo.KanaCnv = NO;
\r
1268 cInfo.StrLen = strlen(Text);
\r
1270 cInfo.BufSize = strlen(Text);
\r
1275 ConvJIStoSJIS(&cInfo);
\r
1279 ConvEUCtoSJIS(&cInfo);
\r
1283 *(Buf + cInfo.OutLen) = NUL;
\r
1284 strcpy(Text, Buf);
\r
1292 /*----- 使われている漢字コードを調べる ----------------------------------------
\r
1295 * char *Text : 文字列
\r
1296 * int Size : 文字列の長さ
\r
1297 * int Pref : SJIS/EUCの優先指定
\r
1298 * KANJI_SJIS / KANJI_EUC / KANJI_NOCNV=SJIS/EUCのチェックはしない
\r
1301 * int 漢字コード (KANJI_xxx)
\r
1302 *----------------------------------------------------------------------------*/
\r
1304 int CheckKanjiCode(char *Text, int Size, int Pref)
\r
1316 Btm = Text + Size;
\r
1318 /* JIS漢字コードのチェック */
\r
1320 while((Pos = memchr(Pos, 0x1b, Btm-Pos-2)) != NULL)
\r
1323 if((memcmp(Pos, "$B", 2) == 0) || /* <ESC>$B */
\r
1324 (memcmp(Pos, "$@", 2) == 0) || /* <ESC>$@ */
\r
1325 (memcmp(Pos, "(I", 2) == 0)) /* <ESC>(I */
\r
1332 /* EUCとSHIFT-JIS漢字コードのチェック */
\r
1335 if(Pref != KANJI_NOCNV)
\r
1341 PointSJIS = CheckOnSJIS(Pos, Btm);
\r
1342 PointEUC = CheckOnEUC(Pos, Btm);
\r
1343 if(PointSJIS > PointEUC)
\r
1348 if(PointSJIS < PointEUC)
\r
1353 if((Pos = memchr(Pos, '\n', Btm-Pos)) == NULL)
\r
1366 /*----- SHIFT-JISコードの可能性があるかチェック --------------------------------
\r
1369 * uchar *Pos : 文字列
\r
1370 * uchar *Btm : 文字列の末尾
\r
1376 * High 81-FF (A0-DFは半角) (EB以降はほとんど無い)
\r
1378 *----------------------------------------------------------------------------*/
\r
1380 static int CheckOnSJIS(uchar *Pos, uchar *Btm)
\r
1387 while((Point > 0) && (Pos < Btm) && (*Pos != '\n'))
\r
1389 if(FstOnTwo == YES)
\r
1391 if((*Pos < 0x40) || (*Pos > 0xFC)) /* 2バイト目は 0x40~0xFC */
\r
1395 else if(*Pos >= 0x81)
\r
1397 if((*Pos < 0xA0) || (*Pos > 0xDF)) /* 半角カナでなければ */
\r
1399 if(*Pos >= 0xEB) /* 1バイト目は0xEB以降はほとんど無い */
\r
1406 if(FstOnTwo == YES) /* 1バイト目で終わっているのはおかしい */
\r
1413 /*----- EUCコードの可能性があるかチェック -------------------------------------
\r
1416 * uchar *Pos : 文字列
\r
1417 * uchar *Btm : 文字列の末尾
\r
1425 *----------------------------------------------------------------------------*/
\r
1427 static int CheckOnEUC(uchar *Pos, uchar *Btm)
\r
1434 while((Point > 0) && (Pos < Btm) && (*Pos != '\n'))
\r
1438 if((*Pos < 0xA1) || (*Pos > 0xFE)) /* 2バイト目は 0xA1~0xFE */
\r
1442 else if(FstOnTwo == 2) /* 半角カナ */
\r
1444 if((*Pos < 0xA0) || (*Pos > 0xDF)) /* 2バイト目は 0xA0~0xDF */
\r
1450 if(*Pos == 0x8E) /* 0x8E??は半角カナ */
\r
1452 else if((*Pos >= 0xA1) && (*Pos <= 0xFE))
\r
1457 if(FstOnTwo != 0) /* 1バイト目で終わっているのはおかしい */
\r
1465 /*----- UTF-8N漢字コードをSHIFT-JIS漢字コードに変換 ------------------------------
\r
1468 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
1471 * int くり返しフラグ (YES/NO)
\r
1474 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
1475 *----------------------------------------------------------------------------*/
\r
1477 int ConvUTF8NtoSJIS(CODECONVINFO *cInfo)
\r
1481 char temp_string[2048];
\r
1482 int string_length;
\r
1486 // 生成される中間コードのサイズを調べる
\r
1487 string_length = MultiByteToWideChar(
\r
1488 CP_UTF8, // 変換先文字コード
\r
1490 cInfo->Str, // 変換元文字列
\r
1491 -1, // 変換元文字列バイト数(-1:自動)
\r
1492 NULL, // 変換した文字列の格納先
\r
1496 // サイズ0 or バッファサイズより大きい場合は
\r
1497 // cInfo->Bufの最初に'\0'を入れて、
\r
1498 // cInfo->BufSizeに0を入れて返す。
\r
1499 if( string_length == 0 ||
\r
1500 string_length >= 1024 ){
\r
1501 *(cInfo->Buf) = '\0';
\r
1502 cInfo->BufSize = 0;
\r
1506 // 中間コード(unicode)に変換
\r
1507 MultiByteToWideChar(
\r
1508 CP_UTF8, // 変換先文字コード
\r
1510 cInfo->Str, // 変換元文字列
\r
1511 -1, // 変換元文字列バイト数(-1:自動)
\r
1512 (unsigned short *)temp_string, // 変換した文字列の格納先
\r
1516 // 生成されるUTF-8コードのサイズを調べる
\r
1517 string_length = WideCharToMultiByte(
\r
1518 CP_ACP, // 変換先文字コード
\r
1520 (unsigned short *)temp_string, // 変換元文字列
\r
1521 -1, // 変換元文字列バイト数(-1:自動)
\r
1522 NULL, // 変換した文字列の格納先
\r
1527 // サイズ0 or 出力バッファサイズより大きい場合は、
\r
1528 // cInfo->Bufの最初に'\0'を入れて、
\r
1529 // cInfo->BufSizeに0を入れて返す。
\r
1530 if( string_length == 0 ||
\r
1531 string_length >= cInfo->BufSize ){
\r
1532 *(cInfo->Buf) = '\0';
\r
1533 cInfo->BufSize = 0;
\r
1538 cInfo->OutLen = string_length;
\r
1541 WideCharToMultiByte(
\r
1542 CP_ACP, // 変換先文字コード
\r
1544 (unsigned short *)temp_string, // 変換元文字列
\r
1545 -1, // 変換元文字列バイト数(-1:自動)
\r
1546 cInfo->Buf, // 変換した文字列の格納先(BOM:3bytes)
\r
1547 cInfo->BufSize, // 格納先サイズ
\r
1554 /*----- SHIFT-JIS漢字コードをUTF-8N漢字コードに変換 ------------------------------
\r
1557 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
1560 * int くり返しフラグ (YES/NO)
\r
1563 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
1564 *----------------------------------------------------------------------------*/
\r
1565 int ConvSJIStoUTF8N(CODECONVINFO *cInfo)
\r
1569 char temp_string[2048];
\r
1570 int string_length;
\r
1574 // 生成される中間コードのサイズを調べる
\r
1575 string_length = MultiByteToWideChar(
\r
1576 CP_ACP, // 変換先文字コード
\r
1578 cInfo->Str, // 変換元文字列
\r
1579 -1, // 変換元文字列バイト数(-1:自動)
\r
1580 NULL, // 変換した文字列の格納先
\r
1584 // サイズ0 or バッファサイズより大きい場合は、
\r
1585 // cInfo->Bufの最初に'\0'を入れて、
\r
1586 // cInfo->BufSizeに0を入れて返す。
\r
1587 if( string_length == 0 ||
\r
1588 string_length >= 1024 ){
\r
1589 *(cInfo->Buf) = '\0';
\r
1590 cInfo->BufSize = 0;
\r
1594 // 中間コード(unicode)に変換
\r
1595 MultiByteToWideChar(
\r
1596 CP_ACP, // 変換先文字コード
\r
1598 cInfo->Str, // 変換元文字列
\r
1599 -1, // 変換元文字列バイト数(-1:自動)
\r
1600 (unsigned short *)temp_string, // 変換した文字列の格納先
\r
1604 // 生成されるUTF-8コードのサイズを調べる
\r
1605 string_length = WideCharToMultiByte(
\r
1606 CP_UTF8, // 変換先文字コード
\r
1608 (unsigned short *)temp_string, // 変換元文字列
\r
1609 -1, // 変換元文字列バイト数(-1:自動)
\r
1610 NULL, // 変換した文字列の格納先
\r
1615 // サイズ0 or 出力バッファサイズより大きい場合は、
\r
1616 // cInfo->Bufの最初に'\0'を入れて、
\r
1617 // cInfo->BufSizeに0を入れて返す。
\r
1618 if( string_length == 0 ||
\r
1619 string_length >= cInfo->BufSize ){
\r
1620 *(cInfo->Buf) = '\0';
\r
1621 cInfo->BufSize = 0;
\r
1626 cInfo->OutLen = string_length;
\r
1629 // ↓付けちゃだめ コマンドにも追加されてしまう
\r
1630 // 出力文字列の先頭にBOM(byte order mark)をつける
\r
1631 *(cInfo->Buf) = (char)0xef;
\r
1632 *(cInfo->Buf+1) = (char)0xbb;
\r
1633 *(cInfo->Buf+2) = (char)0xbf;
\r
1637 WideCharToMultiByte(
\r
1638 CP_UTF8, // 変換先文字コード
\r
1640 (unsigned short *)temp_string, // 変換元文字列
\r
1641 -1, // 変換元文字列バイト数(-1:自動)
\r
1642 cInfo->Buf, // 変換した文字列の格納先(BOM:3bytes)
\r
1643 cInfo->BufSize, // 格納先サイズ
\r
1652 /*----- IBM拡張漢字をNEC選定IBM拡張漢字等に変換 -------------------------------
\r
1659 *----------------------------------------------------------------------------*/
\r
1660 static int ConvertIBMExtendedChar(int code)
\r
1662 if((code >= 0xfa40) && (code <= 0xfa49)) code -= (0xfa40 - 0xeeef);
\r
1663 else if((code >= 0xfa4a) && (code <= 0xfa53)) code -= (0xfa4a - 0x8754);
\r
1664 else if((code >= 0xfa54) && (code <= 0xfa57)) code -= (0xfa54 - 0xeef9);
\r
1665 else if(code == 0xfa58) code = 0x878a;
\r
1666 else if(code == 0xfa59) code = 0x8782;
\r
1667 else if(code == 0xfa5a) code = 0x8784;
\r
1668 else if(code == 0xfa5b) code = 0x879a;
\r
1669 else if((code >= 0xfa5c) && (code <= 0xfa7e)) code -= (0xfa5c - 0xed40);
\r
1670 else if((code >= 0xfa80) && (code <= 0xfa9b)) code -= (0xfa80 - 0xed63);
\r
1671 else if((code >= 0xfa9c) && (code <= 0xfafc)) code -= (0xfa9c - 0xed80);
\r
1672 else if((code >= 0xfb40) && (code <= 0xfb5b)) code -= (0xfb40 - 0xede1);
\r
1673 else if((code >= 0xfb5c) && (code <= 0xfb7e)) code -= (0xfb5c - 0xee40);
\r
1674 else if((code >= 0xfb80) && (code <= 0xfb9b)) code -= (0xfb80 - 0xee63);
\r
1675 else if((code >= 0xfb9c) && (code <= 0xfbfc)) code -= (0xfb9c - 0xee80);
\r
1676 else if((code >= 0xfc40) && (code <= 0xfc4b)) code -= (0xfc40 - 0xeee1);
\r