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
35 //#include <winsock.h>
\r
36 #include <winsock2.h>
\r
37 #include <mbstring.h>
\r
38 #include <windowsx.h>
\r
43 #include "resource.h"
\r
47 #define CONV_ASCII 0 /* ASCII文字処理中 */
\r
48 #define CONV_KANJI 1 /* 漢字処理中 */
\r
49 #define CONV_KANA 2 /* 半角カタカナ処理中 */
\r
52 /*===== プロトタイプ =====*/
\r
54 static char *ConvEUCtoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);
\r
55 static char *ConvJIStoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);
\r
56 static char *ConvSJIStoEUCkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);
\r
57 static char *ConvSJIStoJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put);
\r
58 static int HanKataToZen(char Ch);
\r
59 static int AskDakuon(char Ch, char Daku);
\r
61 static int CheckOnSJIS(uchar *Pos, uchar *Btm);
\r
62 static int CheckOnEUC(uchar *Pos, uchar *Btm);
\r
63 static int ConvertIBMExtendedChar(int code);
\r
66 typedef enum _NORM_FORM
\r
68 NormalizationOther = 0,
\r
69 NormalizationC = 0x1,
\r
70 NormalizationD = 0x2,
\r
71 NormalizationKC = 0x5,
\r
72 NormalizationKD = 0x6
\r
75 typedef int (WINAPI* _NormalizeString)(NORM_FORM, LPCWSTR, int, LPWSTR, int);
\r
77 HMODULE hUnicodeNormalizationDll;
\r
78 _NormalizeString p_NormalizeString;
\r
81 /*----- 漢字コード変換のテストプログラム ------------------------------------*/
\r
83 void CodeCnvTest(void)
\r
86 #define BUFBUF2 BUFBUF+3
\r
96 // DoPrintf("---START ZEN");
\r
98 Strm1 = fopen("in.txt", "rb");
\r
99 Strm2 = fopen("out_zen.txt", "wb");
\r
101 InitCodeConvInfo(&cInfo);
\r
102 cInfo.KanaCnv = YES;
\r
105 while((Byte = fread(Buf, 1, BUFBUF, Strm1)) != 0)
\r
108 cInfo.StrLen = Byte;
\r
110 cInfo.BufSize = BUFBUF2;
\r
112 // DoPrintf("READ %d", Byte);
\r
116 // Continue = ConvEUCtoSJIS(&cInfo);
\r
117 // Continue = ConvJIStoSJIS(&cInfo);
\r
118 // Continue = ConvSJIStoEUC(&cInfo);
\r
119 // Continue = ConvSJIStoJIS(&cInfo);
\r
120 Continue = ConvSMBtoSJIS(&cInfo);
\r
121 // Continue = ConvSJIStoSMB_HEX(&cInfo);
\r
122 // Continue = ConvSJIStoSMB_CAP(&cInfo);
\r
124 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
125 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
128 while(Continue == YES);
\r
132 cInfo.BufSize = BUFBUF2;
\r
133 FlushRestData(&cInfo);
\r
134 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
135 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
142 // DoPrintf("---START HAN");
\r
144 Strm1 = fopen("in.txt", "rb");
\r
145 Strm2 = fopen("out_han.txt", "wb");
\r
147 InitCodeConvInfo(&cInfo);
\r
148 cInfo.KanaCnv = NO;
\r
151 while((Byte = fread(Buf, 1, BUFBUF, Strm1)) != 0)
\r
154 cInfo.StrLen = Byte;
\r
156 cInfo.BufSize = BUFBUF2;
\r
158 // DoPrintf("READ %d", Byte);
\r
162 // Continue = ConvEUCtoSJIS(&cInfo);
\r
163 // Continue = ConvJIStoSJIS(&cInfo);
\r
164 // Continue = ConvSJIStoEUC(&cInfo);
\r
165 // Continue = ConvSJIStoJIS(&cInfo);
\r
166 Continue = ConvSMBtoSJIS(&cInfo);
\r
167 // Continue = ConvSJIStoSMB_HEX(&cInfo);
\r
168 // Continue = ConvSJIStoSMB_CAP(&cInfo);
\r
169 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
170 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
173 while(Continue == YES);
\r
177 cInfo.BufSize = BUFBUF2;
\r
178 FlushRestData(&cInfo);
\r
179 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
180 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
185 // DoPrintf("---END");
\r
194 /*----- 改行コード変換のテストプログラム ------------------------------------*/
\r
196 void TermCodeCnvTest(void)
\r
199 #define BUFBUF2 BUFBUF
\r
201 TERMCODECONVINFO cInfo;
\r
203 char Buf2[BUFBUF2];
\r
209 // DoPrintf("---START");
\r
211 Strm1 = fopen("in.txt", "rb");
\r
212 Strm2 = fopen("out.txt", "wb");
\r
214 InitTermCodeConvInfo(&cInfo);
\r
216 while((Byte = fread(Buf, 1, BUFBUF, Strm1)) != 0)
\r
219 cInfo.StrLen = Byte;
\r
221 cInfo.BufSize = BUFBUF2;
\r
223 // DoPrintf("READ %d", Byte);
\r
227 Continue = ConvTermCodeToCRLF(&cInfo);
\r
229 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
230 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
233 while(Continue == YES);
\r
237 cInfo.BufSize = BUFBUF2;
\r
238 FlushRestTermCodeConvData(&cInfo);
\r
239 fwrite(Buf2, cInfo.OutLen, 1, Strm2);
\r
240 // DoPrintf("WRITE %d", cInfo.OutLen);
\r
245 // DoPrintf("---END");
\r
262 /*----- 改行コード変換情報を初期化 --------------------------------------------
\r
265 * TERMCODECONVINFO *cInfo : 改行コード変換情報
\r
269 *----------------------------------------------------------------------------*/
\r
271 void InitTermCodeConvInfo(TERMCODECONVINFO *cInfo)
\r
278 /*----- 改行コード変換の残り情報を出力 ----------------------------------------
\r
281 * TERMCODECONVINFO *cInfo : 改行コード変換情報
\r
284 * int くり返しフラグ (=NO)
\r
288 *----------------------------------------------------------------------------*/
\r
290 int FlushRestTermCodeConvData(TERMCODECONVINFO *cInfo)
\r
296 if(cInfo->Term == 0x0D)
\r
299 cInfo->OutLen = Put - cInfo->Buf;
\r
305 /*----- 改行コードをCRLFに変換 -------------------------------------------------
\r
308 * TERMCODECONVINFO *cInfo : 改行コード変換情報
\r
311 * int くり返しフラグ (YES/NO)
\r
314 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
315 *----------------------------------------------------------------------------*/
\r
317 int ConvTermCodeToCRLF(TERMCODECONVINFO *cInfo)
\r
327 Limit = cInfo->Buf + cInfo->BufSize - 1;
\r
329 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
339 if(cInfo->Term == 0x0D)
\r
342 cInfo->Term = *Str++;
\r
348 if(cInfo->Term != 0x0D)
\r
353 if(cInfo->Term == 0x0D)
\r
362 cInfo->OutLen = Put - cInfo->Buf;
\r
368 /*----- 漢字コード変換情報を初期化 --------------------------------------------
\r
371 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
375 *----------------------------------------------------------------------------*/
\r
377 void InitCodeConvInfo(CODECONVINFO *cInfo)
\r
379 cInfo->KanaCnv = YES;
\r
381 cInfo->EscProc = 0;
\r
382 cInfo->KanjiMode = CONV_ASCII;
\r
383 cInfo->KanjiFst = 0;
\r
384 cInfo->KanaPrev = 0;
\r
385 cInfo->KanaProc = NULL;
\r
387 cInfo->EscUTF8Len = 0;
\r
388 cInfo->EscFlush = NO;
\r
389 cInfo->FlushProc = NULL;
\r
394 /*----- 漢字コード変換の残り情報を出力 ----------------------------------------
\r
397 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
400 * int くり返しフラグ (=NO)
\r
404 *----------------------------------------------------------------------------*/
\r
406 int FlushRestData(CODECONVINFO *cInfo)
\r
411 if(cInfo->FlushProc != NULL)
\r
413 cInfo->EscFlush = YES;
\r
414 return cInfo->FlushProc(cInfo);
\r
419 if(cInfo->KanaProc != NULL)
\r
420 Put = (cInfo->KanaProc)(cInfo, 0, Put);
\r
422 if(cInfo->KanjiFst != 0)
\r
423 *Put++ = cInfo->KanjiFst;
\r
424 if(cInfo->EscProc >= 1)
\r
425 *Put++ = cInfo->EscCode[0];
\r
426 if(cInfo->EscProc == 2)
\r
427 *Put++ = cInfo->EscCode[1];
\r
429 cInfo->OutLen = Put - cInfo->Buf;
\r
436 int ConvNoConv(CODECONVINFO *cInfo)
\r
440 if(cInfo->BufSize >= cInfo->StrLen)
\r
441 cInfo->OutLen = cInfo->StrLen;
\r
444 cInfo->OutLen = cInfo->BufSize;
\r
447 memcpy(cInfo->Buf, cInfo->Str, sizeof(char) * cInfo->OutLen);
\r
448 cInfo->Str += cInfo->OutLen;
\r
449 cInfo->StrLen -= cInfo->OutLen;
\r
453 /*----- EUC漢字コードをSHIFT-JIS漢字コードに変換 ------------------------------
\r
456 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
459 * int くり返しフラグ (YES/NO)
\r
462 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
463 *----------------------------------------------------------------------------*/
\r
465 int ConvEUCtoSJIS(CODECONVINFO *cInfo)
\r
473 cInfo->KanaProc = &ConvEUCtoSJISkanaProc;
\r
478 Limit = cInfo->Buf + cInfo->BufSize - 2;
\r
480 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
488 if((*Str & 0x80) != 0)
\r
490 if(cInfo->KanjiFst == 0)
\r
491 cInfo->KanjiFst = *Str++;
\r
494 if((uchar)cInfo->KanjiFst == (uchar)0x8E) /* 半角カタカナ */
\r
496 Put = ConvEUCtoSJISkanaProc(cInfo, *Str++, Put);
\r
500 Put = ConvEUCtoSJISkanaProc(cInfo, 0, Put);
\r
502 Kcode = _mbcjistojms(((cInfo->KanjiFst & 0x7F) * 0x100) + (*Str++ & 0x7F));
\r
503 *Put++ = HIGH8(Kcode);
\r
504 *Put++ = LOW8(Kcode);
\r
506 cInfo->KanjiFst = 0;
\r
511 Put = ConvEUCtoSJISkanaProc(cInfo, 0, Put);
\r
513 if(cInfo->KanjiFst != 0)
\r
515 *Put++ = cInfo->KanjiFst;
\r
516 cInfo->KanjiFst = 0;
\r
523 cInfo->OutLen = Put - cInfo->Buf;
\r
529 /*----- EUC-->SHIFT-JIS漢字コードに変換の半角カタカナの処理 -------------------
\r
532 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
534 * char *Put : データセット位置
\r
538 *----------------------------------------------------------------------------*/
\r
540 static char *ConvEUCtoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)
\r
545 if(cInfo->KanaCnv == NO)
\r
552 if(cInfo->KanaPrev != 0)
\r
554 Daku = AskDakuon(cInfo->KanaPrev, Dt);
\r
556 Kcode = _mbcjistojms(HanKataToZen(cInfo->KanaPrev)) + Daku;
\r
557 *Put++ = HIGH8(Kcode);
\r
558 *Put++ = LOW8(Kcode);
\r
561 cInfo->KanaPrev = Dt;
\r
563 cInfo->KanaPrev = 0;
\r
566 cInfo->KanaPrev = Dt;
\r
572 /*----- JIS漢字コードをSHIFT-JIS漢字コードに変換 ------------------------------
\r
575 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
578 * int くり返しフラグ (YES/NO)
\r
581 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
583 * エスケープコードは、次のものに対応している
\r
584 * 漢字開始 <ESC>$B <ESC>$@
\r
586 * 漢字終了 <ESC>(B <ESC>(J <ESC>(H
\r
587 *----------------------------------------------------------------------------*/
\r
589 int ConvJIStoSJIS(CODECONVINFO *cInfo)
\r
597 cInfo->KanaProc = &ConvJIStoSJISkanaProc;
\r
602 Limit = cInfo->Buf + cInfo->BufSize - 3;
\r
604 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
612 if(cInfo->EscProc == 0)
\r
616 if(cInfo->KanjiFst != 0)
\r
618 *Put++ = cInfo->KanjiFst;
\r
619 cInfo->KanjiFst = 0;
\r
621 Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);
\r
623 cInfo->EscCode[cInfo->EscProc] = *Str++;
\r
628 if(cInfo->KanjiMode == CONV_KANA)
\r
630 if(cInfo->KanjiFst != 0)
\r
632 *Put++ = cInfo->KanjiFst;
\r
633 cInfo->KanjiFst = 0;
\r
636 if((*Str >= 0x21) && (*Str <= 0x5F))
\r
638 Put = ConvJIStoSJISkanaProc(cInfo, *Str++, Put);
\r
642 Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);
\r
646 else if(cInfo->KanjiMode == CONV_KANJI)
\r
648 Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);
\r
649 if((*Str >= 0x21) && (*Str <= 0x7E))
\r
651 if(cInfo->KanjiFst == 0)
\r
652 cInfo->KanjiFst = *Str++;
\r
655 Kcode = _mbcjistojms((cInfo->KanjiFst * 0x100) + *Str++);
\r
656 *Put++ = HIGH8(Kcode);
\r
657 *Put++ = LOW8(Kcode);
\r
658 cInfo->KanjiFst = 0;
\r
663 if(cInfo->KanjiFst == 0)
\r
667 *Put++ = cInfo->KanjiFst;
\r
669 cInfo->KanjiFst = 0;
\r
675 Put = ConvJIStoSJISkanaProc(cInfo, 0, Put);
\r
680 else if(cInfo->EscProc == 1)
\r
682 if((*Str == '$') || (*Str == '('))
\r
684 cInfo->EscCode[cInfo->EscProc] = *Str++;
\r
689 *Put++ = cInfo->EscCode[0];
\r
691 cInfo->EscProc = 0;
\r
694 else if(cInfo->EscProc == 2)
\r
696 if((cInfo->EscCode[1] == '$') && ((*Str == 'B') || (*Str == '@')))
\r
697 cInfo->KanjiMode = CONV_KANJI;
\r
698 else if((cInfo->EscCode[1] == '(') && (*Str == 'I'))
\r
699 cInfo->KanjiMode = CONV_KANA;
\r
700 else if((cInfo->EscCode[1] == '(') && ((*Str == 'B') || (*Str == 'J') || (*Str == 'H')))
\r
701 cInfo->KanjiMode = CONV_ASCII;
\r
704 *Put++ = cInfo->EscCode[0];
\r
705 *Put++ = cInfo->EscCode[1];
\r
706 if((cInfo->KanjiMode == CONV_KANJI) && ((*Str >= 0x21) && (*Str <= 0x7E)))
\r
707 cInfo->KanjiFst = *Str;
\r
712 cInfo->EscProc = 0;
\r
717 cInfo->OutLen = Put - cInfo->Buf;
\r
723 /*----- JIS-->SHIFT-JIS漢字コードに変換の半角カタカナの処理 -------------------
\r
726 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
728 * char *Put : データセット位置
\r
732 *----------------------------------------------------------------------------*/
\r
734 static char *ConvJIStoSJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)
\r
739 Dt = (uchar)Dt + (uchar)0x80;
\r
740 if(cInfo->KanaCnv == NO)
\r
742 if((uchar)Dt != (uchar)0x80)
\r
747 if(cInfo->KanaPrev != 0)
\r
749 Daku = AskDakuon(cInfo->KanaPrev, Dt);
\r
750 Kcode = _mbcjistojms(HanKataToZen(cInfo->KanaPrev)) + Daku;
\r
751 *Put++ = HIGH8(Kcode);
\r
752 *Put++ = LOW8(Kcode);
\r
754 if((Daku == 0) && ((uchar)Dt != (uchar)0x80))
\r
755 cInfo->KanaPrev = Dt;
\r
757 cInfo->KanaPrev = 0;
\r
759 else if((uchar)Dt != (uchar)0x80)
\r
760 cInfo->KanaPrev = Dt;
\r
766 /*----- Samba-HEX/Samba-CAP漢字コードをSHIFT-JIS漢字コードに変換 --------------
\r
769 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
772 * int くり返しフラグ (YES/NO)
\r
775 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
776 * 分割された入力文字列の変換はサポートしていない
\r
777 * 半角カタカナの変換設定には対応していない
\r
778 *----------------------------------------------------------------------------*/
\r
780 int ConvSMBtoSJIS(CODECONVINFO *cInfo)
\r
790 Limit = cInfo->Buf + cInfo->BufSize - 2;
\r
792 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
800 if((*Str == SAMBA_HEX_TAG) && (cInfo->StrLen >= 3))
\r
802 if(isxdigit(*(Str+1)) && isxdigit(*(Str+2)))
\r
804 *Put++ = N2INT(hex2bin(*(Str+1)), hex2bin(*(Str+2)));
\r
806 cInfo->StrLen -= 2;
\r
816 cInfo->OutLen = Put - cInfo->Buf;
\r
822 /*----- SHIFT-JIS漢字コードをEUC漢字コードに変換 ------------------------------
\r
825 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
828 * int くり返しフラグ (YES/NO)
\r
831 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
832 *----------------------------------------------------------------------------*/
\r
834 int ConvSJIStoEUC(CODECONVINFO *cInfo)
\r
842 cInfo->KanaProc = &ConvSJIStoEUCkanaProc;
\r
847 Limit = cInfo->Buf + cInfo->BufSize - 2;
\r
849 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
857 if(cInfo->KanjiFst == 0)
\r
859 if((((uchar)*Str >= (uchar)0x81) && ((uchar)*Str <= (uchar)0x9F)) ||
\r
860 ((uchar)*Str >= (uchar)0xE0))
\r
862 Put = ConvSJIStoEUCkanaProc(cInfo, 0, Put);
\r
863 cInfo->KanjiFst = *Str++;
\r
865 else if(((uchar)*Str >= (uchar)0xA0) && ((uchar)*Str <= (uchar)0xDF))
\r
867 Put = ConvSJIStoEUCkanaProc(cInfo, *Str++, Put);
\r
871 Put = ConvSJIStoEUCkanaProc(cInfo, 0, Put);
\r
877 if((uchar)*Str >= (uchar)0x40)
\r
879 Kcode = ConvertIBMExtendedChar(((uchar)cInfo->KanjiFst * 0x100) + (uchar)*Str++);
\r
880 Kcode = _mbcjmstojis(Kcode);
\r
881 *Put++ = HIGH8(Kcode) | 0x80;
\r
882 *Put++ = LOW8(Kcode) | 0x80;
\r
886 *Put++ = cInfo->KanjiFst;
\r
889 cInfo->KanjiFst = 0;
\r
894 cInfo->OutLen = Put - cInfo->Buf;
\r
900 /*----- SHIFT-JIS-->EUC漢字コードに変換の半角カタカナの処理 -------------------
\r
903 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
905 * char *Put : データセット位置
\r
909 *----------------------------------------------------------------------------*/
\r
911 static char *ConvSJIStoEUCkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)
\r
916 if(cInfo->KanaCnv == NO)
\r
920 Kcode = 0x8E00 + (uchar)Dt;
\r
921 *Put++ = HIGH8(Kcode) | 0x80;
\r
922 *Put++ = LOW8(Kcode) | 0x80;
\r
927 if(cInfo->KanaPrev != 0)
\r
929 Daku = AskDakuon(cInfo->KanaPrev, Dt);
\r
930 Kcode = HanKataToZen(cInfo->KanaPrev) + Daku;
\r
931 *Put++ = HIGH8(Kcode) | 0x80;
\r
932 *Put++ = LOW8(Kcode) | 0x80;
\r
935 cInfo->KanaPrev = Dt;
\r
937 cInfo->KanaPrev = 0;
\r
940 cInfo->KanaPrev = Dt;
\r
946 /*----- SHIFT-JIS漢字コードをJIS漢字コードに変換 ------------------------------
\r
949 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
952 * int くり返しフラグ (YES/NO)
\r
955 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
957 * エスケープコードは、次のものを使用する
\r
961 *----------------------------------------------------------------------------*/
\r
963 int ConvSJIStoJIS(CODECONVINFO *cInfo)
\r
971 cInfo->KanaProc = &ConvSJIStoJISkanaProc;
\r
976 Limit = cInfo->Buf + cInfo->BufSize - 5;
\r
978 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
986 if(cInfo->KanjiFst == 0)
\r
988 if((((uchar)*Str >= (uchar)0x81) && ((uchar)*Str <= (uchar)0x9F)) ||
\r
989 ((uchar)*Str >= (uchar)0xE0))
\r
991 Put = ConvSJIStoJISkanaProc(cInfo, 0, Put);
\r
992 cInfo->KanjiFst = *Str++;
\r
994 else if(((uchar)*Str >= (uchar)0xA0) && ((uchar)*Str <= (uchar)0xDF))
\r
996 Put = ConvSJIStoJISkanaProc(cInfo, *Str++, Put);
\r
1000 Put = ConvSJIStoJISkanaProc(cInfo, 0, Put);
\r
1001 if(cInfo->KanjiMode != CONV_ASCII)
\r
1006 cInfo->KanjiMode = CONV_ASCII;
\r
1013 Put = ConvSJIStoJISkanaProc(cInfo, 0, Put);
\r
1014 if((uchar)*Str >= (uchar)0x40)
\r
1016 if(cInfo->KanjiMode != CONV_KANJI)
\r
1021 cInfo->KanjiMode = CONV_KANJI;
\r
1024 Kcode = ConvertIBMExtendedChar(((uchar)cInfo->KanjiFst * 0x100) + (uchar)*Str++);
\r
1025 Kcode = _mbcjmstojis(Kcode);
\r
1026 *Put++ = HIGH8(Kcode);
\r
1027 *Put++ = LOW8(Kcode);
\r
1031 if(cInfo->KanjiMode != CONV_ASCII)
\r
1036 cInfo->KanjiMode = CONV_ASCII;
\r
1038 *Put++ = cInfo->KanjiFst;
\r
1041 cInfo->KanjiFst = 0;
\r
1046 cInfo->OutLen = Put - cInfo->Buf;
\r
1052 /*----- SHIFT-JIS-->JIS漢字コードに変換の半角カタカナの処理 -------------------
\r
1055 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
1057 * char *Put : データセット位置
\r
1060 * char *次のデータセット位置
\r
1061 *----------------------------------------------------------------------------*/
\r
1063 static char *ConvSJIStoJISkanaProc(CODECONVINFO *cInfo, char Dt, char *Put)
\r
1068 if(cInfo->KanaCnv == NO)
\r
1072 if(cInfo->KanjiMode != CONV_KANA)
\r
1077 cInfo->KanjiMode = CONV_KANA;
\r
1079 *Put++ = (uchar)Dt - (uchar)0x80;
\r
1084 if(cInfo->KanaPrev != 0)
\r
1086 if(cInfo->KanjiMode != CONV_KANJI)
\r
1091 cInfo->KanjiMode = CONV_KANJI;
\r
1093 Daku = AskDakuon(cInfo->KanaPrev, Dt);
\r
1094 Kcode = HanKataToZen(cInfo->KanaPrev) + Daku;
\r
1095 *Put++ = HIGH8(Kcode);
\r
1096 *Put++ = LOW8(Kcode);
\r
1099 cInfo->KanaPrev = Dt;
\r
1101 cInfo->KanaPrev = 0;
\r
1104 cInfo->KanaPrev = Dt;
\r
1110 /*----- SHIFT-JIS漢字コードをSamba-HEX漢字コードに変換 ------------------------
\r
1113 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
1116 * int くり返しフラグ (YES/NO)
\r
1119 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
1120 * 分割された入力文字列の変換はサポートしていない
\r
1121 * 半角カタカナの変換設定には対応していない
\r
1122 *----------------------------------------------------------------------------*/
\r
1124 int ConvSJIStoSMB_HEX(CODECONVINFO *cInfo)
\r
1134 Limit = cInfo->Buf + cInfo->BufSize - 6;
\r
1136 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
1144 if((cInfo->StrLen >= 2) &&
\r
1145 ((((uchar)*Str >= (uchar)0x81) && ((uchar)*Str <= (uchar)0x9F)) ||
\r
1146 ((uchar)*Str >= (uchar)0xE0)))
\r
1148 sprintf(Put, "%c%02x%c%02x", SAMBA_HEX_TAG, (uchar)*Str, SAMBA_HEX_TAG, (uchar)*(Str+1));
\r
1153 else if((uchar)*Str >= (uchar)0x80)
\r
1155 sprintf(Put, "%c%02x", SAMBA_HEX_TAG, (uchar)*Str++);
\r
1163 cInfo->OutLen = Put - cInfo->Buf;
\r
1169 /*----- SHIFT-JIS漢字コードをSamba-CAP漢字コードに変換 ------------------------
\r
1172 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
1175 * int くり返しフラグ (YES/NO)
\r
1178 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
1179 * 分割された入力文字列の変換はサポートしていない
\r
1180 *----------------------------------------------------------------------------*/
\r
1182 int ConvSJIStoSMB_CAP(CODECONVINFO *cInfo)
\r
1192 Limit = cInfo->Buf + cInfo->BufSize - 6;
\r
1194 for(; cInfo->StrLen > 0; cInfo->StrLen--)
\r
1202 if((uchar)*Str >= (uchar)0x80)
\r
1204 sprintf(Put, "%c%02x", SAMBA_HEX_TAG, (uchar)*Str++);
\r
1212 cInfo->OutLen = Put - cInfo->Buf;
\r
1218 /*----- 1バイトカタカナをJIS漢字コードに変換 ---------------------------------
\r
1221 * char Ch : 1バイトカタカナコード
\r
1225 *----------------------------------------------------------------------------*/
\r
1227 static int HanKataToZen(char Ch)
\r
1229 static const int Katakana[] = {
\r
1230 0x2121, 0x2123, 0x2156, 0x2157, 0x2122, 0x2126, 0x2572, 0x2521,
\r
1231 0x2523, 0x2525, 0x2527, 0x2529, 0x2563, 0x2565, 0x2567, 0x2543,
\r
1232 0x213C, 0x2522, 0x2524, 0x2526, 0x2528, 0x252A, 0x252B, 0x252D,
\r
1233 0x252F, 0x2531, 0x2533, 0x2535, 0x2537, 0x2539, 0x253B, 0x253D,
\r
1234 0x253F, 0x2541, 0x2544, 0x2546, 0x2548, 0x254A, 0x254B, 0x254C,
\r
1235 0x254D, 0x254E, 0x254F, 0x2552, 0x2555, 0x2558, 0x255B, 0x255E,
\r
1236 0x255F, 0x2560, 0x2561, 0x2562, 0x2564, 0x2566, 0x2568, 0x2569,
\r
1237 0x256A, 0x256B, 0x256C, 0x256D, 0x256F, 0x2573, 0x212B, 0x212C
\r
1240 return(Katakana[(uchar)Ch - (uchar)0xA0]);
\r
1244 /*----- 濁音/半濁音になる文字かチェック --------------------------------------
\r
1247 * char Ch : 1バイトカタカナコード
\r
1248 * char Daku : 濁点/半濁点
\r
1251 * int 文字コードに加える値 (0=濁音/半濁音にならない)
\r
1252 *----------------------------------------------------------------------------*/
\r
1254 static int AskDakuon(char Ch, char Daku)
\r
1259 if((uchar)Daku == (uchar)0xDE)
\r
1261 if((((uchar)Ch >= (uchar)0xB6) && ((uchar)Ch <= (uchar)0xC4)) ||
\r
1262 (((uchar)Ch >= (uchar)0xCA) && ((uchar)Ch <= (uchar)0xCE)))
\r
1267 else if((uchar)Daku == (uchar)0xDF)
\r
1269 if(((uchar)Ch >= (uchar)0xCA) && ((uchar)Ch <= (uchar)0xCE))
\r
1288 /*----- 文字列の漢字コードを調べ、Shift-JISに変換 -----------------------------
\r
1291 * char *Text : 文字列
\r
1292 * int Pref : SJIS/EUCの優先指定
\r
1293 * KANJI_SJIS / KANJI_EUC / KANJI_NOCNV=SJIS/EUCのチェックはしない
\r
1297 *----------------------------------------------------------------------------*/
\r
1299 void ConvAutoToSJIS(char *Text, int Pref)
\r
1303 CODECONVINFO cInfo;
\r
1305 Code = CheckKanjiCode(Text, strlen(Text), Pref);
\r
1306 if(Code != KANJI_SJIS)
\r
1308 Buf = malloc(strlen(Text)+1);
\r
1311 InitCodeConvInfo(&cInfo);
\r
1312 cInfo.KanaCnv = NO;
\r
1314 cInfo.StrLen = strlen(Text);
\r
1316 cInfo.BufSize = strlen(Text);
\r
1321 ConvJIStoSJIS(&cInfo);
\r
1325 ConvEUCtoSJIS(&cInfo);
\r
1329 *(Buf + cInfo.OutLen) = NUL;
\r
1330 strcpy(Text, Buf);
\r
1338 /*----- 使われている漢字コードを調べる ----------------------------------------
\r
1341 * char *Text : 文字列
\r
1342 * int Size : 文字列の長さ
\r
1343 * int Pref : SJIS/EUCの優先指定
\r
1344 * KANJI_SJIS / KANJI_EUC / KANJI_NOCNV=SJIS/EUCのチェックはしない
\r
1347 * int 漢字コード (KANJI_xxx)
\r
1348 *----------------------------------------------------------------------------*/
\r
1350 int CheckKanjiCode(char *Text, int Size, int Pref)
\r
1362 Btm = Text + Size;
\r
1364 /* JIS漢字コードのチェック */
\r
1366 while((Pos = memchr(Pos, 0x1b, Btm-Pos-2)) != NULL)
\r
1369 if((memcmp(Pos, "$B", 2) == 0) || /* <ESC>$B */
\r
1370 (memcmp(Pos, "$@", 2) == 0) || /* <ESC>$@ */
\r
1371 (memcmp(Pos, "(I", 2) == 0)) /* <ESC>(I */
\r
1378 /* EUCとSHIFT-JIS漢字コードのチェック */
\r
1381 if(Pref != KANJI_NOCNV)
\r
1387 PointSJIS = CheckOnSJIS(Pos, Btm);
\r
1388 PointEUC = CheckOnEUC(Pos, Btm);
\r
1389 if(PointSJIS > PointEUC)
\r
1394 if(PointSJIS < PointEUC)
\r
1399 if((Pos = memchr(Pos, '\n', Btm-Pos)) == NULL)
\r
1412 /*----- SHIFT-JISコードの可能性があるかチェック --------------------------------
\r
1415 * uchar *Pos : 文字列
\r
1416 * uchar *Btm : 文字列の末尾
\r
1422 * High 81-FF (A0-DFは半角) (EB以降はほとんど無い)
\r
1424 *----------------------------------------------------------------------------*/
\r
1426 static int CheckOnSJIS(uchar *Pos, uchar *Btm)
\r
1433 while((Point > 0) && (Pos < Btm) && (*Pos != '\n'))
\r
1435 if(FstOnTwo == YES)
\r
1437 if((*Pos < 0x40) || (*Pos > 0xFC)) /* 2バイト目は 0x40~0xFC */
\r
1441 else if(*Pos >= 0x81)
\r
1443 if((*Pos < 0xA0) || (*Pos > 0xDF)) /* 半角カナでなければ */
\r
1445 if(*Pos >= 0xEB) /* 1バイト目は0xEB以降はほとんど無い */
\r
1452 if(FstOnTwo == YES) /* 1バイト目で終わっているのはおかしい */
\r
1459 /*----- EUCコードの可能性があるかチェック -------------------------------------
\r
1462 * uchar *Pos : 文字列
\r
1463 * uchar *Btm : 文字列の末尾
\r
1471 *----------------------------------------------------------------------------*/
\r
1473 static int CheckOnEUC(uchar *Pos, uchar *Btm)
\r
1480 while((Point > 0) && (Pos < Btm) && (*Pos != '\n'))
\r
1484 if((*Pos < 0xA1) || (*Pos > 0xFE)) /* 2バイト目は 0xA1~0xFE */
\r
1488 else if(FstOnTwo == 2) /* 半角カナ */
\r
1490 if((*Pos < 0xA0) || (*Pos > 0xDF)) /* 2バイト目は 0xA0~0xDF */
\r
1496 if(*Pos == 0x8E) /* 0x8E??は半角カナ */
\r
1498 else if((*Pos >= 0xA1) && (*Pos <= 0xFE))
\r
1503 if(FstOnTwo != 0) /* 1バイト目で終わっているのはおかしい */
\r
1511 /*----- UTF-8漢字コードをSHIFT-JIS漢字コードに変換 ------------------------------
\r
1514 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
1517 * int くり返しフラグ (YES/NO)
\r
1520 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
1521 *----------------------------------------------------------------------------*/
\r
1524 // UTF-8からShift_JISへの変換後のバイト列が確定可能な長さを変換後の長さで返す
\r
1525 // バイナリ UTF-8 戻り値 Shift_JIS
\r
1526 // E3 81 82 E3 81 84 あい -> 2 82 A0 あ+結合文字の先頭バイトの可能性(い゛等)
\r
1527 // E3 81 82 E3 81 あ+E3 81 -> 0 結合文字の先頭バイトの可能性
\r
1528 // E3 81 82 E3 あ+E3 -> 0 結合文字の先頭バイトの可能性
\r
1529 // E3 81 82 あ -> 0 結合文字の先頭バイトの可能性
\r
1530 int ConvUTF8NtoSJIS_TruncateToDelimiter(char* pUTF8, int UTF8Length, int* pNewUTF8Length)
\r
1535 int NewSJISLength;
\r
1536 int NewUTF16Length;
\r
1537 // UTF-8の場合、不完全な文字は常に変換されない
\r
1538 // バイナリ UTF-8 バイナリ UTF-16 LE
\r
1539 // E3 81 82 E3 81 84 あい -> 42 30 44 30 あい
\r
1540 // E3 81 82 E3 81 あ+E3 81 -> 42 30 あ
\r
1541 // E3 81 82 E3 あ+E3 -> 42 30 あ
\r
1542 UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, NULL, 0);
\r
1543 if(!(pUTF16 = (wchar_t*)malloc(sizeof(wchar_t) * UTF16Length)))
\r
1545 // Shift_JISへ変換した時に文字数が増減する位置がUnicode結合文字の区切り
\r
1546 UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, pUTF16, UTF16Length);
\r
1547 SJISLength = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);
\r
1548 NewSJISLength = SJISLength;
\r
1549 while(UTF8Length > 0 && NewSJISLength >= SJISLength)
\r
1552 UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, pUTF16, UTF16Length);
\r
1553 NewSJISLength = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);
\r
1556 // UTF-16 LE変換した時に文字数が増減する位置がUTF-8の区切り
\r
1557 if(pNewUTF8Length)
\r
1559 NewUTF16Length = UTF16Length;
\r
1560 while(UTF8Length > 0 && NewUTF16Length >= UTF16Length)
\r
1563 NewUTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, NULL, 0);
\r
1565 if(UTF16Length > 0)
\r
1567 *pNewUTF8Length = UTF8Length;
\r
1569 return NewSJISLength;
\r
1572 int ConvUTF8NtoSJIS(CODECONVINFO *cInfo)
\r
1576 // char temp_string[2048];
\r
1577 // int string_length;
\r
1580 // 終端のNULLを含むバグを修正
\r
1588 // 生成される中間コードのサイズを調べる
\r
1589 // string_length = MultiByteToWideChar(
\r
1590 // CP_UTF8, // 変換先文字コード
\r
1591 // 0, // フラグ(0:なし)
\r
1592 // cInfo->Str, // 変換元文字列
\r
1593 // -1, // 変換元文字列バイト数(-1:自動)
\r
1594 // NULL, // 変換した文字列の格納先
\r
1597 // 前回の変換不能な残りの文字列を入力の先頭に結合
\r
1598 SrcLength = cInfo->StrLen + cInfo->EscUTF8Len;
\r
1599 if(!(pSrc = (char*)malloc(sizeof(char) * (SrcLength + 1))))
\r
1601 *(cInfo->Buf) = '\0';
\r
1602 cInfo->BufSize = 0;
\r
1605 memcpy(pSrc, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);
\r
1606 memcpy(pSrc + cInfo->EscUTF8Len, cInfo->Str, sizeof(char) * cInfo->StrLen);
\r
1607 *(pSrc + SrcLength) = '\0';
\r
1608 if(cInfo->EscFlush == NO)
\r
1610 // バッファに収まらないため変換文字数を半減
\r
1611 while(SrcLength > 0 && ConvUTF8NtoSJIS_TruncateToDelimiter(pSrc, SrcLength, &SrcLength) > cInfo->BufSize)
\r
1613 SrcLength = SrcLength / 2;
\r
1616 UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pSrc, SrcLength, NULL, 0);
\r
1618 // サイズ0 or バッファサイズより大きい場合は
\r
1619 // cInfo->Bufの最初に'\0'を入れて、
\r
1620 // cInfo->BufSizeに0を入れて返す。
\r
1621 // if( string_length == 0 ||
\r
1622 // string_length >= 1024 ){
\r
1623 // *(cInfo->Buf) = '\0';
\r
1624 // cInfo->BufSize = 0;
\r
1625 // return(Continue);
\r
1627 if(!(pUTF16 = (wchar_t*)malloc(sizeof(wchar_t) * UTF16Length)))
\r
1630 *(cInfo->Buf) = '\0';
\r
1631 cInfo->BufSize = 0;
\r
1635 // 中間コード(unicode)に変換
\r
1636 // MultiByteToWideChar(
\r
1637 // CP_UTF8, // 変換先文字コード
\r
1638 // 0, // フラグ(0:なし)
\r
1639 // cInfo->Str, // 変換元文字列
\r
1640 // -1, // 変換元文字列バイト数(-1:自動)
\r
1641 // (unsigned short *)temp_string, // 変換した文字列の格納先
\r
1644 MultiByteToWideChar(CP_UTF8, 0, pSrc, SrcLength, pUTF16, UTF16Length);
\r
1646 // 生成されるUTF-8コードのサイズを調べる
\r
1647 // string_length = WideCharToMultiByte(
\r
1648 // CP_ACP, // 変換先文字コード
\r
1649 // 0, // フラグ(0:なし)
\r
1650 // (unsigned short *)temp_string, // 変換元文字列
\r
1651 // -1, // 変換元文字列バイト数(-1:自動)
\r
1652 // NULL, // 変換した文字列の格納先
\r
1657 // サイズ0 or 出力バッファサイズより大きい場合は、
\r
1658 // cInfo->Bufの最初に'\0'を入れて、
\r
1659 // cInfo->BufSizeに0を入れて返す。
\r
1660 // if( string_length == 0 ||
\r
1661 // string_length >= cInfo->BufSize ){
\r
1662 // *(cInfo->Buf) = '\0';
\r
1663 // cInfo->BufSize = 0;
\r
1664 // return(Continue);
\r
1668 // cInfo->OutLen = string_length;
\r
1671 // WideCharToMultiByte(
\r
1672 // CP_ACP, // 変換先文字コード
\r
1673 // 0, // フラグ(0:なし)
\r
1674 // (unsigned short *)temp_string, // 変換元文字列
\r
1675 // -1, // 変換元文字列バイト数(-1:自動)
\r
1676 // cInfo->Buf, // 変換した文字列の格納先(BOM:3bytes)
\r
1677 // cInfo->BufSize, // 格納先サイズ
\r
1680 cInfo->OutLen = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);
\r
1681 cInfo->Str += SrcLength - cInfo->EscUTF8Len;
\r
1682 cInfo->StrLen -= SrcLength - cInfo->EscUTF8Len;
\r
1683 cInfo->EscUTF8Len = 0;
\r
1684 if(ConvUTF8NtoSJIS_TruncateToDelimiter(cInfo->Str, cInfo->StrLen, NULL) > 0)
\r
1688 // 変換不能なため次の入力の先頭に結合
\r
1689 memcpy(cInfo->EscUTF8, cInfo->Str, sizeof(char) * cInfo->StrLen);
\r
1690 cInfo->EscUTF8Len = cInfo->StrLen;
\r
1691 cInfo->Str += cInfo->StrLen;
\r
1692 cInfo->StrLen = 0;
\r
1693 cInfo->FlushProc = ConvUTF8NtoSJIS;
\r
1703 /*----- SHIFT-JIS漢字コードをUTF-8漢字コードに変換 ------------------------------
\r
1706 * CODECONVINFO *cInfo : 漢字コード変換情報
\r
1709 * int くり返しフラグ (YES/NO)
\r
1712 * くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと
\r
1713 *----------------------------------------------------------------------------*/
\r
1714 int ConvSJIStoUTF8N(CODECONVINFO *cInfo)
\r
1718 // char temp_string[2048];
\r
1719 int string_length;
\r
1722 // 終端のNULLを含むバグを修正
\r
1731 // 生成される中間コードのサイズを調べる
\r
1732 // string_length = MultiByteToWideChar(
\r
1733 // CP_ACP, // 変換先文字コード
\r
1734 // 0, // フラグ(0:なし)
\r
1735 // cInfo->Str, // 変換元文字列
\r
1736 // -1, // 変換元文字列バイト数(-1:自動)
\r
1737 // NULL, // 変換した文字列の格納先
\r
1740 // 前回の変換不能な残りの文字列を入力の先頭に結合
\r
1741 SrcLength = cInfo->StrLen + cInfo->EscUTF8Len;
\r
1742 if(!(pSrc = (char*)malloc(sizeof(char) * (SrcLength + 1))))
\r
1744 *(cInfo->Buf) = '\0';
\r
1745 cInfo->BufSize = 0;
\r
1748 memcpy(pSrc, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);
\r
1749 memcpy(pSrc + cInfo->EscUTF8Len, cInfo->Str, sizeof(char) * cInfo->StrLen);
\r
1750 *(pSrc + SrcLength) = '\0';
\r
1751 if(cInfo->EscFlush == NO)
\r
1753 // Shift_JISの場合、不完全な文字でも変換されることがあるため、末尾の不完全な部分を削る
\r
1755 while(Count < SrcLength)
\r
1757 if(((unsigned char)*(pSrc + Count) >= 0x81 && (unsigned char)*(pSrc + Count) <= 0x9f) || (unsigned char)*(pSrc + Count) >= 0xe0)
\r
1759 if((unsigned char)*(pSrc + Count + 1) >= 0x40)
\r
1763 if(Count + 2 > SrcLength)
\r
1771 SrcLength = Count;
\r
1773 UTF16Length = MultiByteToWideChar(CP_ACP, 0, pSrc, SrcLength, NULL, 0);
\r
1775 // サイズ0 or バッファサイズより大きい場合は、
\r
1776 // cInfo->Bufの最初に'\0'を入れて、
\r
1777 // cInfo->BufSizeに0を入れて返す。
\r
1778 // if( string_length == 0 ||
\r
1779 // string_length >= 1024 ){
\r
1780 // *(cInfo->Buf) = '\0';
\r
1781 // cInfo->BufSize = 0;
\r
1782 // return(Continue);
\r
1784 if(!(pUTF16 = (wchar_t*)malloc(sizeof(wchar_t) * UTF16Length)))
\r
1787 *(cInfo->Buf) = '\0';
\r
1788 cInfo->BufSize = 0;
\r
1792 // 中間コード(unicode)に変換
\r
1793 // MultiByteToWideChar(
\r
1794 // CP_ACP, // 変換先文字コード
\r
1795 // 0, // フラグ(0:なし)
\r
1796 // cInfo->Str, // 変換元文字列
\r
1797 // -1, // 変換元文字列バイト数(-1:自動)
\r
1798 // (unsigned short *)temp_string, // 変換した文字列の格納先
\r
1801 MultiByteToWideChar(CP_ACP, 0, pSrc, SrcLength, pUTF16, UTF16Length);
\r
1803 // 生成されるUTF-8コードのサイズを調べる
\r
1804 // string_length = WideCharToMultiByte(
\r
1805 // CP_UTF8, // 変換先文字コード
\r
1806 // 0, // フラグ(0:なし)
\r
1807 // (unsigned short *)temp_string, // 変換元文字列
\r
1808 // -1, // 変換元文字列バイト数(-1:自動)
\r
1809 // NULL, // 変換した文字列の格納先
\r
1813 string_length = WideCharToMultiByte(CP_UTF8, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);
\r
1815 // サイズ0 or 出力バッファサイズより大きい場合は、
\r
1816 // cInfo->Bufの最初に'\0'を入れて、
\r
1817 // cInfo->BufSizeに0を入れて返す。
\r
1818 // if( string_length == 0 ||
\r
1819 // string_length >= cInfo->BufSize ){
\r
1820 // *(cInfo->Buf) = '\0';
\r
1821 // cInfo->BufSize = 0;
\r
1822 // return(Continue);
\r
1826 // cInfo->OutLen = string_length;
\r
1829 // ↓付けちゃだめ コマンドにも追加されてしまう
\r
1830 // 出力文字列の先頭にBOM(byte order mark)をつける
\r
1831 *(cInfo->Buf) = (char)0xef;
\r
1832 *(cInfo->Buf+1) = (char)0xbb;
\r
1833 *(cInfo->Buf+2) = (char)0xbf;
\r
1837 // WideCharToMultiByte(
\r
1838 // CP_UTF8, // 変換先文字コード
\r
1839 // 0, // フラグ(0:なし)
\r
1840 // (unsigned short *)temp_string, // 変換元文字列
\r
1841 // -1, // 変換元文字列バイト数(-1:自動)
\r
1842 // cInfo->Buf, // 変換した文字列の格納先(BOM:3bytes)
\r
1843 // cInfo->BufSize, // 格納先サイズ
\r
1846 cInfo->OutLen = WideCharToMultiByte(CP_UTF8, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);
\r
1847 // バッファに収まらないため変換文字数を半減
\r
1848 while(cInfo->OutLen == 0 && UTF16Length > 0)
\r
1850 UTF16Length = UTF16Length / 2;
\r
1851 cInfo->OutLen = WideCharToMultiByte(CP_UTF8, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);
\r
1853 // 変換された元の文字列での文字数を取得
\r
1854 Count = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);
\r
1856 UTF16Length = MultiByteToWideChar(CP_ACP, 0, pSrc + Count, SrcLength - Count, NULL, 0);
\r
1857 cInfo->Str += Count - cInfo->EscUTF8Len;
\r
1858 cInfo->StrLen -= Count - cInfo->EscUTF8Len;
\r
1859 cInfo->EscUTF8Len = 0;
\r
1860 if(UTF16Length > 0)
\r
1864 // 変換不能なため次の入力の先頭に結合
\r
1865 memcpy(cInfo->EscUTF8, cInfo->Str, sizeof(char) * cInfo->StrLen);
\r
1866 cInfo->EscUTF8Len = cInfo->StrLen;
\r
1867 cInfo->Str += cInfo->StrLen;
\r
1868 cInfo->StrLen = 0;
\r
1869 cInfo->FlushProc = ConvSJIStoUTF8N;
\r
1881 int ConvUTF8NtoUTF8HFSX(CODECONVINFO *cInfo)
\r
1899 if(IsUnicodeNormalizationDllLoaded() == NO)
\r
1900 return ConvNoConv(cInfo);
\r
1902 SrcLength = cInfo->StrLen + cInfo->EscUTF8Len;
\r
1903 if(!(pSrc = (char*)malloc(sizeof(char) * (SrcLength + 1))))
\r
1905 *(cInfo->Buf) = '\0';
\r
1906 cInfo->BufSize = 0;
\r
1909 memcpy(pSrc, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);
\r
1910 memcpy(pSrc + cInfo->EscUTF8Len, cInfo->Str, sizeof(char) * cInfo->StrLen);
\r
1911 *(pSrc + SrcLength) = '\0';
\r
1912 cInfo->OutLen = 0;
\r
1914 pSrcEnd = pSrc + SrcLength;
\r
1916 pDstCur = cInfo->Buf;
\r
1917 pDstEnd = cInfo->Buf + cInfo->BufSize;
\r
1918 while(pSrcCur < pSrcEnd)
\r
1920 Code = GetNextCharM(pSrcCur, pSrcEnd, (LPCSTR*)&pSrcNext);
\r
1921 if(Code == 0x80000000)
\r
1923 if(pSrcNext == pSrcEnd)
\r
1927 else if((Code >= 0x00002000 && Code <= 0x00002fff)
\r
1928 || (Code >= 0x0000f900 && Code <= 0x0000faff)
\r
1929 || (Code >= 0x0002f800 && Code <= 0x0002faff))
\r
1932 Count = PutNextCharM(pDstCur, pDstEnd, &pDstCur, Code);
\r
1934 cInfo->OutLen += Count;
\r
1944 // Normalization Form Dに変換
\r
1945 Count = MultiByteToWideChar(CP_UTF8, 0, pSrcCur, (int)(pSrcNext - pSrcCur), Temp1, 4);
\r
1946 Count = p_NormalizeString(NormalizationD, Temp1, Count, Temp2, 4);
\r
1947 Count = WideCharToMultiByte(CP_UTF8, 0, Temp2, Count, Temp3, 16, NULL, NULL);
\r
1949 Temp3End = Temp3 + Count;
\r
1951 while(Temp3Cur < Temp3End)
\r
1953 Code = GetNextCharM(Temp3Cur, Temp3End, (LPCSTR*)&Temp3Cur);
\r
1954 Count = PutNextCharM(pDstCur, pDstEnd, &pDstCur, Code);
\r
1956 TempCount += Count;
\r
1964 cInfo->OutLen += TempCount;
\r
1966 pSrcCur = pSrcNext;
\r
1968 cInfo->Str += (int)(pSrcCur - pSrc) - cInfo->EscUTF8Len;
\r
1969 cInfo->StrLen -= (int)(pSrcCur - pSrc) - cInfo->EscUTF8Len;
\r
1970 cInfo->EscUTF8Len = 0;
\r
1972 if(Continue == NO)
\r
1974 memcpy(cInfo->EscUTF8, cInfo->Str, sizeof(char) * cInfo->StrLen);
\r
1975 cInfo->EscUTF8Len = cInfo->StrLen;
\r
1976 cInfo->Str += cInfo->StrLen;
\r
1977 cInfo->StrLen = 0;
\r
1978 cInfo->FlushProc = ConvUTF8NtoUTF8HFSX;
\r
1984 // 確認するまで複数個のバッファを用いた変換には用いないこと
\r
1985 // UTF-8 Nomalization Form DからCへの変換後のバイト列が確定可能な長さを変換後のコードポイントの個数で返す
\r
1987 // E3 81 82 E3 81 84 あい -> 1 あ+結合文字の先頭バイトの可能性(い゛等)
\r
1988 // E3 81 82 E3 81 あ+E3 81 -> 0 結合文字の先頭バイトの可能性
\r
1989 // E3 81 82 E3 あ+E3 -> 0 結合文字の先頭バイトの可能性
\r
1990 // E3 81 82 あ -> 0 結合文字の先頭バイトの可能性
\r
1991 int ConvUTF8HFSXtoUTF8N_TruncateToDelimiter(char* pUTF8, int UTF8Length, int* pNewUTF8Length)
\r
1995 int UTF16HFSXLength;
\r
1996 wchar_t* pUTF16HFSX;
\r
1999 int NewUTF16Length;
\r
2000 UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, NULL, 0);
\r
2001 if(!(pUTF16 = (wchar_t*)malloc(sizeof(wchar_t) * UTF16Length)))
\r
2003 UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, pUTF16, UTF16Length);
\r
2004 UTF16HFSXLength = p_NormalizeString(NormalizationC, pUTF16, UTF16Length, NULL, 0);
\r
2005 if(!(pUTF16HFSX = (wchar_t*)malloc(sizeof(wchar_t) * UTF16HFSXLength)))
\r
2010 UTF16HFSXLength = p_NormalizeString(NormalizationC, pUTF16, UTF16Length, pUTF16HFSX, UTF16HFSXLength);
\r
2011 // 変換した時にコードポイントの個数が増減する位置がUnicode結合文字の区切り
\r
2012 CodeCount = GetCodeCountW(pUTF16HFSX, UTF16HFSXLength);
\r
2013 NewCodeCount = CodeCount;
\r
2014 while(UTF8Length > 0 && NewCodeCount >= CodeCount)
\r
2017 UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, pUTF16, UTF16Length);
\r
2018 UTF16HFSXLength = p_NormalizeString(NormalizationC, pUTF16, UTF16Length, pUTF16HFSX, UTF16HFSXLength);
\r
2019 NewCodeCount = GetCodeCountW(pUTF16HFSX, UTF16HFSXLength);
\r
2023 // UTF-16 LE変換した時に文字数が増減する位置がUTF-8の区切り
\r
2024 if(pNewUTF8Length)
\r
2026 NewUTF16Length = UTF16Length;
\r
2027 while(UTF8Length > 0 && NewUTF16Length >= UTF16Length)
\r
2030 NewUTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, NULL, 0);
\r
2032 if(UTF16Length > 0)
\r
2034 *pNewUTF8Length = UTF8Length;
\r
2036 return NewCodeCount;
\r
2039 int ConvUTF8HFSXtoUTF8N(CODECONVINFO *cInfo)
\r
2046 int UTF16HFSXLength;
\r
2047 wchar_t* pUTF16HFSX;
\r
2048 CODECONVINFO Temp;
\r
2050 if(IsUnicodeNormalizationDllLoaded() == NO)
\r
2051 return ConvNoConv(cInfo);
\r
2053 // 前回の変換不能な残りの文字列を入力の先頭に結合
\r
2054 SrcLength = cInfo->StrLen + cInfo->EscUTF8Len;
\r
2055 if(!(pSrc = (char*)malloc(sizeof(char) * (SrcLength + 1))))
\r
2057 *(cInfo->Buf) = '\0';
\r
2058 cInfo->BufSize = 0;
\r
2061 memcpy(pSrc, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);
\r
2062 memcpy(pSrc + cInfo->EscUTF8Len, cInfo->Str, sizeof(char) * cInfo->StrLen);
\r
2063 *(pSrc + SrcLength) = '\0';
\r
2064 UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pSrc, SrcLength, NULL, 0);
\r
2065 if(!(pUTF16 = (wchar_t*)malloc(sizeof(wchar_t) * UTF16Length)))
\r
2068 *(cInfo->Buf) = '\0';
\r
2069 cInfo->BufSize = 0;
\r
2072 MultiByteToWideChar(CP_UTF8, 0, pSrc, SrcLength, pUTF16, UTF16Length);
\r
2073 UTF16HFSXLength = p_NormalizeString(NormalizationC, pUTF16, UTF16Length, NULL, 0);
\r
2074 if(!(pUTF16HFSX = (wchar_t*)malloc(sizeof(wchar_t) * UTF16HFSXLength)))
\r
2078 *(cInfo->Buf) = '\0';
\r
2079 cInfo->BufSize = 0;
\r
2082 UTF16HFSXLength = p_NormalizeString(NormalizationC, pUTF16, UTF16Length, pUTF16HFSX, UTF16HFSXLength);
\r
2083 cInfo->OutLen = WideCharToMultiByte(CP_UTF8, 0, pUTF16HFSX, UTF16HFSXLength, cInfo->Buf, cInfo->BufSize, NULL, NULL);
\r
2084 if(cInfo->OutLen == 0 && UTF16HFSXLength > 0)
\r
2086 // バッファに収まらないため変換文字数を半減
\r
2088 Temp.StrLen = cInfo->StrLen / 2;
\r
2089 ConvUTF8HFSXtoUTF8N(&Temp);
\r
2090 cInfo->OutLen = Temp.OutLen;
\r
2091 Count = cInfo->StrLen / 2 + cInfo->EscUTF8Len - Temp.StrLen - Temp.EscUTF8Len;
\r
2092 cInfo->Str += Count - cInfo->EscUTF8Len;
\r
2093 cInfo->StrLen -= Count - cInfo->EscUTF8Len;
\r
2094 cInfo->EscUTF8Len = 0;
\r
2098 cInfo->Str += SrcLength - cInfo->EscUTF8Len;
\r
2099 cInfo->StrLen -= SrcLength - cInfo->EscUTF8Len;
\r
2100 cInfo->EscUTF8Len = 0;
\r
2102 if(ConvUTF8HFSXtoUTF8N_TruncateToDelimiter(cInfo->Str, cInfo->StrLen, NULL) > 0)
\r
2106 // 変換不能なため次の入力の先頭に結合
\r
2107 memcpy(cInfo->EscUTF8, cInfo->Str, sizeof(char) * cInfo->StrLen);
\r
2108 cInfo->EscUTF8Len = cInfo->StrLen;
\r
2109 cInfo->Str += cInfo->StrLen;
\r
2110 cInfo->StrLen = 0;
\r
2111 cInfo->FlushProc = ConvUTF8HFSXtoUTF8N;
\r
2121 /*----- IBM拡張漢字をNEC選定IBM拡張漢字等に変換 -------------------------------
\r
2128 *----------------------------------------------------------------------------*/
\r
2129 static int ConvertIBMExtendedChar(int code)
\r
2131 if((code >= 0xfa40) && (code <= 0xfa49)) code -= (0xfa40 - 0xeeef);
\r
2132 else if((code >= 0xfa4a) && (code <= 0xfa53)) code -= (0xfa4a - 0x8754);
\r
2133 else if((code >= 0xfa54) && (code <= 0xfa57)) code -= (0xfa54 - 0xeef9);
\r
2134 else if(code == 0xfa58) code = 0x878a;
\r
2135 else if(code == 0xfa59) code = 0x8782;
\r
2136 else if(code == 0xfa5a) code = 0x8784;
\r
2137 else if(code == 0xfa5b) code = 0x879a;
\r
2138 else if((code >= 0xfa5c) && (code <= 0xfa7e)) code -= (0xfa5c - 0xed40);
\r
2139 else if((code >= 0xfa80) && (code <= 0xfa9b)) code -= (0xfa80 - 0xed63);
\r
2140 else if((code >= 0xfa9c) && (code <= 0xfafc)) code -= (0xfa9c - 0xed80);
\r
2141 else if((code >= 0xfb40) && (code <= 0xfb5b)) code -= (0xfb40 - 0xede1);
\r
2142 else if((code >= 0xfb5c) && (code <= 0xfb7e)) code -= (0xfb5c - 0xee40);
\r
2143 else if((code >= 0xfb80) && (code <= 0xfb9b)) code -= (0xfb80 - 0xee63);
\r
2144 else if((code >= 0xfb9c) && (code <= 0xfbfc)) code -= (0xfb9c - 0xee80);
\r
2145 else if((code >= 0xfc40) && (code <= 0xfc4b)) code -= (0xfc40 - 0xeee1);
\r
2150 int LoadUnicodeNormalizationDll()
\r
2153 char CurDir[FMAX_PATH+1];
\r
2154 char SysDir[FMAX_PATH+1];
\r
2156 if(GetCurrentDirectory(FMAX_PATH, CurDir) > 0)
\r
2158 if(GetSystemDirectory(SysDir, FMAX_PATH) > 0)
\r
2160 if(SetCurrentDirectory(SysDir))
\r
2162 if((hUnicodeNormalizationDll = LoadLibrary("normaliz.dll")) != NULL)
\r
2164 if((p_NormalizeString = (_NormalizeString)GetProcAddress(hUnicodeNormalizationDll, "NormalizeString")) != NULL)
\r
2165 Sts = FFFTP_SUCCESS;
\r
2167 SetCurrentDirectory(CurDir);
\r
2174 void FreeUnicodeNormalizationDll()
\r
2176 if(hUnicodeNormalizationDll != NULL)
\r
2177 FreeLibrary(hUnicodeNormalizationDll);
\r
2178 hUnicodeNormalizationDll = NULL;
\r
2179 p_NormalizeString = NULL;
\r
2182 int IsUnicodeNormalizationDllLoaded()
\r
2186 if(hUnicodeNormalizationDll != NULL && p_NormalizeString != NULL)
\r
2187 Sts = FFFTP_SUCCESS;
\r