Revision: 7966 https://osdn.net/projects/ttssh2/scm/svn/commits/7966 Author: zmatsuo Date: 2019-08-15 23:03:55 +0900 (Thu, 15 Aug 2019) Log Message: ----------- CommTextOutW(),CommTextEchoW()実装 - wchar_tを入力して、必要な文字コードで出力 - 出力/入力バッファへの書き込みを関数化した Modified Paths: -------------- branches/unicode_buf/teraterm/ttpcmn/ttcmn.c -------------- next part -------------- Modified: branches/unicode_buf/teraterm/ttpcmn/ttcmn.c =================================================================== --- branches/unicode_buf/teraterm/ttpcmn/ttcmn.c 2019-08-15 14:03:32 UTC (rev 7965) +++ branches/unicode_buf/teraterm/ttpcmn/ttcmn.c 2019-08-15 14:03:55 UTC (rev 7966) @@ -41,6 +41,7 @@ #include <locale.h> #include <htmlhelp.h> #include <assert.h> +#include <crtdbg.h> #define DllExport __declspec(dllexport) #include "language.h" @@ -1461,7 +1462,7 @@ return c; } -int WINAPI CommRawOut(PComVar cv, PCHAR B, int C) +int WINAPI CommRawOut(PComVar cv, /*const*/ PCHAR B, int C) { int a; @@ -1521,9 +1522,91 @@ return i; } +/** + * \x83f\x81[\x83^(\x95\xB6\x8E\x9A\x97\xF1)\x82\xF0\x8Fo\x97̓o\x83b\x83t\x83@\x82֏\x91\x82\xAB\x8D\x9E\x82\xDE + * + * \x8Ew\x92\xE8\x83f\x81[\x83^\x82\xAA\x82\xB7\x82ׂď\x91\x82\xAB\x8D\x9E\x82߂Ȃ\xA2\x8Fꍇ\x82͏\x91\x82\xAB\x8D\x9E\x82܂Ȃ\xA2 + * CommRawOut() \x82͏\x91\x82\xAB\x8D\x9E\x82߂镪\x82\xBE\x82\xAF\x8F\x91\x82\xAB\x8D\x9E\x82\xDE + * + * @retval TRUE \x8Fo\x97͂ł\xAB\x82\xBD + * @retval FALSE \x8Fo\x97͂ł\xAB\x82Ȃ\xA9\x82\xC1\x82\xBD(buffer full) + */ +static BOOL WriteOutBuff(PComVar cv, const char *TempStr, int TempLen) +{ + BOOL output; + + if (TempLen == 0) { + // \x92\xB7\x82\xB30\x82ŏ\x91\x82\xAB\x8D\x9E\x82݂ɗ\x88\x82\xE9\x8Fꍇ\x82\xA0\x82\xE8 + return TRUE; + } + + output = FALSE; + if (cv->TelLineMode) { + const BOOL Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0; + if (!Full) { + output = TRUE; + memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen); + cv->LineModeBuffCount += TempLen; + if (cv->Flush) { + cv->FlushLen = cv->LineModeBuffCount; + } + } + if (cv->FlushLen > 0) { + const int OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen); + cv->FlushLen -= OutLen; + cv->LineModeBuffCount -= OutLen; + memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount); + } + cv->Flush = FALSE; + } + else { + const BOOL Full = OutBuffSize-cv->OutBuffCount-TempLen < 0; + if (! Full) { + output = TRUE; + CommRawOut(cv, (char *)TempStr, TempLen); + } + } + return output; +} + +/** + * \x83f\x81[\x83^(\x95\xB6\x8E\x9A\x97\xF1)\x82\xF0\x93\xFC\x97̓o\x83b\x83t\x83@\x82֏\x91\x82\xAB\x8D\x9E\x82\xDE + * \x93\xFC\x97̓o\x83b\x83t\x83@\x82֓\xFC\x82\xEA\x82\xE9 -> \x83G\x83R\x81[\x82\xB3\x82\xEA\x82\xE9 + * + * @retval TRUE \x8Fo\x97͂ł\xAB\x82\xBD + * @retval FALSE \x8Fo\x97͂ł\xAB\x82Ȃ\xA9\x82\xC1\x82\xBD(buffer full) + */ +static BOOL WriteInBuff(PComVar cv, const char *TempStr, int TempLen) +{ + BOOL Full; + + if (TempLen == 0) { + return TRUE; + } + + Full = InBuffSize-cv->InBuffCount-TempLen < 0; + if (! Full) { + memcpy(&(cv->InBuff[cv->InBuffCount]),TempStr,TempLen); + cv->InBuffCount = cv->InBuffCount + TempLen; + return TRUE; + } + return FALSE; +} + +/** + * \x93\xFC\x97̓o\x83b\x83t\x83@\x82̐擪\x82ɋ\xAA\x82\xA0\x82\xC1\x82\xBD\x82\xE7\x8Bl\x82߂\xE9 + */ +static void PackInBuff(PComVar cv) +{ + if ( (cv->InPtr>0) && (cv->InBuffCount>0) ) { + memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount); + cv->InPtr = 0; + } +} + int WINAPI CommBinaryBuffOut(PComVar cv, PCHAR B, int C) { - int a, i, Len, OutLen; + int a, i, Len; char d[3]; if ( ! cv->Ready ) { @@ -1550,37 +1633,12 @@ d[Len++] = '\xff'; } - if (cv->TelLineMode) { - if (OutBuffSize - cv->LineModeBuffCount - Len >= 0) { - memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), d, Len); - cv->LineModeBuffCount += Len; - if (cv->Flush) { - cv->FlushLen = cv->LineModeBuffCount; - } - a = 1; - } - else { - a = 0; - } - if (cv->FlushLen > 0) { - OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen); - cv->FlushLen -= OutLen; - cv->LineModeBuffCount -= OutLen; - memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount); - } - cv->Flush = FALSE; + if (WriteOutBuff(cv, d, Len)) { + a = 1; + i++; + } else { + a = 0; } - else { - if ( OutBuffSize - cv->OutBuffCount - Len >= 0 ) { - CommRawOut(cv, d, Len); - a = 1; - } - else { - a = 0; - } - } - - i += a; } return i; } @@ -1606,12 +1664,13 @@ // static int TextOutMBCS(PComVar cv, PCHAR B, int C) { - int i, TempLen, OutLen; + int i, TempLen; WORD K; char TempStr[12]; - int SendCodeNew; BYTE d; - BOOL Full, KanjiFlagNew; + BOOL Full; + int SendCodeNew; // \x91\x97\x90M\x83R\x81[\x83h + BOOL KanjiFlagNew; // TRUE=\x8E\x9F\x82̕\xB6\x8E\x9A\x82ƍ\x87\x82킹\x82Ċ\xBF\x8E\x9A\x82Ƃ\xB7\x82\xE9 Full = FALSE; i = 0; @@ -1769,49 +1828,14 @@ } } // if (cv->SendKanjiFlag) else if ... else ... end - if (cv->TelLineMode) { - if (TempLen == 0) { - i++; - cv->SendCode = SendCodeNew; - cv->SendKanjiFlag = KanjiFlagNew; - } - else { - Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0; - if (!Full) { - i++; - cv->SendCode = SendCodeNew; - cv->SendKanjiFlag = KanjiFlagNew; - memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen); - cv->LineModeBuffCount += TempLen; - if (cv->Flush) { - cv->FlushLen = cv->LineModeBuffCount; - } - } - } - if (cv->FlushLen > 0) { - OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen); - cv->FlushLen -= OutLen; - cv->LineModeBuffCount -= OutLen; - memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount); - } - cv->Flush = FALSE; + if (WriteOutBuff(cv, TempStr, TempLen)) { + i++; // 1\x95\xB6\x8E\x9A\x8F\x88\x97\x9D\x82\xB5\x82\xBD + // \x8A\xBF\x8E\x9A\x82̏\xF3\x91Ԃ\xF0\x95ۑ\xB6\x82\xB7\x82\xE9 + cv->SendCode = SendCodeNew; + cv->SendKanjiFlag = KanjiFlagNew; + } else { + Full = TRUE; } - else { - if (TempLen == 0) { - i++; - cv->SendCode = SendCodeNew; - cv->SendKanjiFlag = KanjiFlagNew; - } - else { - Full = OutBuffSize-cv->OutBuffCount-TempLen < 0; - if (! Full) { - i++; - cv->SendCode = SendCodeNew; - cv->SendKanjiFlag = KanjiFlagNew; - CommRawOut(cv,TempStr,TempLen); - } - } - } } // end of "while {}" @@ -1820,7 +1844,7 @@ int WINAPI CommTextOut(PComVar cv, PCHAR B, int C) { - int i, TempLen, OutLen; + int i, TempLen; char TempStr[12]; BYTE d; BOOL Full; @@ -1891,175 +1915,400 @@ } } + if (WriteOutBuff(cv, TempStr, TempLen)) { + i++; // 1\x95\xB6\x8E\x9A\x8F\x88\x97\x9D\x82\xB5\x82\xBD + } else { + Full = TRUE; + } + + } // end of while {} + + return i; +} + +/** + * @retval true \x93\xFA\x96{\x8C\xEA\x82̔\xBC\x8Ap\x83J\x83^\x83J\x83i + * @retval false \x82\xBB\x82̑\xBC + */ +static BOOL IsHalfWidthKatakana(unsigned int u32) +{ + // Halfwidth CJK punctuation (U+FF61\x81`FF64) + // Halfwidth Katakana variants (U+FF65\x81`FF9F) + return (0xff61 <= u32 && u32 <= 0xff9f); +} + +/** + * \x8Fo\x97͗p\x81A TODO echo\x97p\x82\xF0\x8D\xEC\x82\xE9 + * @param cv + * @param u32 \x93\xFC\x97͕\xB6\x8E\x9A + * @param check_only TRUE\x82ŏ\x88\x97\x9D\x82͍s\x82킸\x81A + * @param TempStr \x8Fo\x97͕\xB6\x8E\x9A\x90\x94 + * @param StrLen TempStr\x82ւ̏o\x97͕\xB6\x8E\x9A\x90\x94 + * @retval \x8F\x88\x97\x9D\x82\xF0\x8Ds\x82\xC1\x82\xBD + */ +static BOOL OutControl(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen) +{ + const wchar_t d = u32; + size_t TempLen = 0; + BOOL retval = FALSE; + if (check_only == TRUE) { + /* \x83`\x83F\x83b\x83N\x82̂\xDD */ + if (d == CR || d == BS || d == 0x15/*ctrl-u*/) { + return TRUE; + } else { + return FALSE; + } + } + if (d==CR) { + TempStr[TempLen++] = 0x0d; + if (cv->CRSend==IdCRLF) { + TempStr[TempLen++] = 0x0a; + } + else if ((cv->CRSend ==IdCR) && + cv->TelFlag && ! cv->TelBinSend) { + TempStr[TempLen++] = 0; + } + else if (cv->CRSend == IdLF) { + TempStr[TempLen-1] = 0x0a; + } if (cv->TelLineMode) { - Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0; - if (!Full) { - i++; - memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen); - cv->LineModeBuffCount += TempLen; - if (cv->Flush) { - cv->FlushLen = cv->LineModeBuffCount; - } + cv->Flush = TRUE; + } + retval = TRUE; + } + else if (d== BS) { + if (cv->TelLineMode) { + if (cv->FlushLen < cv->LineModeBuffCount) { + cv->LineModeBuffCount--; } - if (cv->FlushLen > 0) { - OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen); - cv->FlushLen -= OutLen; - cv->LineModeBuffCount -= OutLen; - memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount); - } - cv->Flush = FALSE; } else { - Full = OutBuffSize - cv->OutBuffCount - TempLen < 0; - if (! Full) { - i++; - CommRawOut(cv,TempStr,TempLen); - } + TempStr[TempLen++] = BS; } - } // end of while {} - - return i; + retval = TRUE; + } + else if (d==0x15) { // ctrl-u + if (cv->TelLineMode) { + cv->LineModeBuffCount = cv->FlushLen; + } + else { + TempStr[TempLen++] = 0x15; + } + retval = TRUE; + } + *StrLen = TempLen; + return retval; } +static BOOL ControlEcho(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen) +{ + const wchar_t d = u32; + size_t TempLen = 0; + BOOL retval = FALSE; + if (check_only == TRUE) { + /* \x83`\x83F\x83b\x83N\x82̂\xDD */ + if (d == CR || (d == 0x15/*ctrl-u*/ && cv->TelLineMode)) { + return TRUE; + } else { + return FALSE; + } + } + if (d==CR) { + TempStr[TempLen++] = 0x0d; + if (cv->CRSend==IdCRLF) { + TempStr[TempLen++] = 0x0a; + } + else if ((cv->CRSend ==IdCR) && cv->TelFlag && ! cv->TelBinSend) { + TempStr[TempLen++] = 0; + } + else if (cv->CRSend == IdLF) { + TempStr[TempLen-1] = 0x0a; + } + retval = TRUE; + } + else if (d==0x15/*ctrl-u*/ && cv->TelLineMode) { + // Move to top of line (CHA "\033[G") and erase line (EL "\033[K") + memcpy(TempStr, "\033[G\033[K", 6); + TempLen += 6; + retval = TRUE; + } + *StrLen = TempLen; + return retval; +} /** - * CommTextOut() \x82\xCC wchar_t \x94\xC5 - * \x8D\xA1\x82̏\x8AIME\x82\xA9\x82炵\x82\xA9\x8Eg\x82\xC1\x82Ă\xA2\x82Ȃ\xA2\x82\xBD\x82\xDF - * \x90\xA7\x8C\xE4\x83R\x81[\x83h\x8Cn\x82͖\xA2\x83e\x83X\x83g + * \x8Fo\x97͗p\x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8D쐬\x82\xB7\x82\xE9 + * + * @retval \x8F\xC1\x94\x82\xBD\x95\xB6\x8E\x9A\x90\x94 */ -int WINAPI CommTextOutW(PComVar cv, const wchar_t *B, int C) +typedef struct { + int KanjiCode; // [in]\x8Fo\x97͕\xB6\x8E\x9A\x83R\x81[\x83h(sjis,jis\x82Ȃ\xC7) + BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen); + // state\x82\xF0\x95ۑ\xB6\x82\xB7\x82\xE9\x95K\x97v\x82\xAA\x82\xA0\x82镶\x8E\x9A\x83R\x81[\x83h\x82Ŏg\x97p + BOOL JIS7Katakana; // [in](Kanji JIS)kana + int SendCode; // [in,out](Kanji JIS)\x92\xBC\x91O\x82̑\x97\x90M\x83R\x81[\x83h Ascii/Kana/Kanji + BOOL KanjiFlag; // [in,out](MBCS)\x92\xBC\x91O\x82\xCC1byte\x82\xAA\x8A\xBF\x8E\x9A\x82\xBE\x82\xC1\x82\xBD\x82\xA9?(2byte\x95\xB6\x8E\x9A\x82\xBE\x82\xC1\x82\xBD\x82\xA9?) + BYTE KanjiFirst; // [in,out](MBCS)\x92\xBC\x91O\x82\xCC1byte +} OutputCharState; + +/** + * unicode(UTF-16)\x82\xA9\x82\xE7unicode(UTF-32)\x82\xF01\x95\xB6\x8E\x9A\x8E\xE6\x82\xE8\x8Fo\x82\xB5\x82\xC4 + * \x8Fo\x97̓f\x81[\x83^(TempStr)\x82\xF0\x8D쐬\x82\xB7\x82\xE9 + */ +static size_t MakeOutputString(PComVar cv, OutputCharState *states, + const wchar_t *B, int C, + char *TempStr, int *TempLen_) { -#if 1 - if (cv->KanjiCodeSend == IdUTF8 || cv->Language == IdUtf8) { - int i, TempLen; - char TempStr[12]; - wchar_t d; - BOOL Full; + BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen) + = states->ControlOut; +// + int TempLen = 0; + size_t TempLen2; + size_t output_char_count; // \x8F\xC1\x94\x82\xBD\x95\xB6\x8E\x9A\x90\x94 - Full = FALSE; - i = 0; - while (! Full && (i < C)) { - TempLen = 0; - d = B[i]; + // UTF-32 \x82\xF01\x95\xB6\x8E\x9A\x8E\xE6\x82\xE8\x8Fo\x82\xB7 + unsigned int u32; + size_t u16_len = UTF16ToUTF32(B, C, &u32); + if (u16_len == 0) { + // \x83f\x83R\x81[\x83h\x82ł\xAB\x82Ȃ\xA2? \x82\xA0\x82蓾\x82Ȃ\xA2\x82̂ł\xCD? + assert(FALSE); + u32 = '?'; + u16_len = 1; + } + output_char_count = u16_len; - if (d==CR) { - TempStr[TempLen++] = 0x0d; - if (cv->CRSend==IdCRLF) { - TempStr[TempLen++] = 0x0a; + // \x8Ae\x8E\xED\x83V\x83t\x83g\x8F\xF3\x91Ԃ\xF0\x92ʏ\xED\x82ɖ߂\xB7 + if (u32 < 0x100 || ControlOut(cv, u32, TRUE, NULL, NULL)) { + if (cv->Language == IdJapanese && states->KanjiCode == IdJIS) { + // \x8D\xA1\x82̂Ƃ\xB1\x82\xEB\x81A\x93\xFA\x96{\x8C\xEA,JIS\x82\xB5\x82\xA9\x82Ȃ\xA2 + if (cv->SendCode == IdKanji) { + // \x8A\xBF\x8E\x9A\x82ł͂Ȃ\xA2\x82̂ŁA\x8A\xBF\x8E\x9AOUT + TempStr[TempLen++] = 0x1B; + TempStr[TempLen++] = '('; + switch (cv->KanjiOut) { + case IdKanjiOutJ: + TempStr[TempLen++] = 'J'; + break; + case IdKanjiOutH: + TempStr[TempLen++] = 'H'; + break; + default: + TempStr[TempLen++] = 'B'; } - else if ((cv->CRSend ==IdCR) && - cv->TelFlag && ! cv->TelBinSend) { - TempStr[TempLen++] = 0; - } - else if (cv->CRSend == IdLF) { - TempStr[TempLen-1] = 0x0a; - } - if (cv->TelLineMode) { - cv->Flush = TRUE; - } } - else if (d== BS) { - if (cv->TelLineMode) { - if (cv->FlushLen < cv->LineModeBuffCount) { - cv->LineModeBuffCount--; - } + + if (states->JIS7Katakana == 1) { + if (cv->SendCode == IdKatakana) { + TempStr[TempLen++] = SO; } - else { - TempStr[TempLen++] = BS; - } } - else if (d==0x15) { // ctrl-u - if (cv->TelLineMode) { - cv->LineModeBuffCount = cv->FlushLen; - } - else { - TempStr[TempLen++] = 0x15; - } - } - else if (d>=0x80) { - unsigned int u32; - size_t u16_len = UTF16ToUTF32(&B[i], C - i, &u32); - if (u16_len == 0) { - // \x83f\x83R\x81[\x83h\x82ł\xAB\x82Ȃ\xA2\x95\xB6\x8E\x9A - TempStr[0] = '?'; - TempLen = 1; - i++; + + states->SendCode = IdASCII; + } + } + + // 1\x95\xB6\x8E\x9A\x8F\x88\x97\x9D\x82\xB7\x82\xE9 + if (ControlOut(cv, u32, FALSE, TempStr, &TempLen2)) { + // \x93\xC1\x95ʂȕ\xB6\x8E\x9A\x82\xF0\x8F\x88\x97\x9D\x82\xB5\x82\xBD + TempLen += TempLen2; + output_char_count = 1; + } else if (cv->Language == IdUtf8 || + (cv->Language == IdJapanese && states->KanjiCode == IdUTF8) || + (cv->Language == IdKorean && states->KanjiCode == IdUTF8)) + { + // UTF-8 \x82ŏo\x97\xCD + size_t utf8_len = sizeof(TempStr); + utf8_len = UTF32ToUTF8(u32, TempStr, utf8_len); + TempLen += utf8_len; + } else if (cv->Language == IdJapanese && *cv->CodePage == 932) { + // \x93\xFA\x96{\x8C\xEA + // \x82܂\xB8 CP932(SJIS) \x82ɕϊ\xB7\x82\xB5\x82Ă\xA9\x82\xE7\x8Fo\x97\xCD + char mb_char[2]; + size_t mb_len = sizeof(mb_char); + mb_len = UTF32ToMBCP(u32, 932, mb_char, mb_len); + if (mb_len == 0) { + // SJIS\x82ɕϊ\xB7\x82ł\xAB\x82Ȃ\xA2 + TempStr[TempLen++] = '?'; + } else { + switch (states->KanjiCode) { + case IdEUC: + // TODO \x94\xBC\x8Ap\x83J\x83i + if (mb_len == 1) { + TempStr[TempLen++] = mb_char[0]; } else { - size_t utf8_len = sizeof(TempStr); - utf8_len = UTF32ToUTF8(u32, TempStr, utf8_len); - TempLen += utf8_len; - i += u16_len; + WORD K; + K = (((WORD)(unsigned char)mb_char[0]) << 8) + + (WORD)(unsigned char)mb_char[1]; + K = SJIS2EUC(K); + TempStr[TempLen++] = HIBYTE(K); + TempStr[TempLen++] = LOBYTE(K); } - } - - if (cv->TelLineMode) { - if (TempLen > 0) { - Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0; - if (!Full) { - memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen); - cv->LineModeBuffCount += TempLen; - if (cv->Flush) { - cv->FlushLen = cv->LineModeBuffCount; + break; + case IdJIS: + if (u32 < 0x100) { + // ASCII + TempStr[TempLen++] = mb_char[0]; + states->SendCode = IdASCII; + } else if (IsHalfWidthKatakana(u32)) { + // \x94\xBC\x8Ap\x83J\x83^\x83J\x83i + if (states->JIS7Katakana==1) { + if (cv->SendCode != IdKatakana) { + TempStr[TempLen++] = SI; } + TempStr[TempLen++] = mb_char[0] & 0x7f; } else { - // !? - assert(FALSE); + TempStr[TempLen++] = mb_char[0]; } + states->SendCode = IdKatakana; + } else { + // \x8A\xBF\x8E\x9A + WORD K; + K = (((WORD)(unsigned char)mb_char[0]) << 8) + + (WORD)(unsigned char)mb_char[1]; + K = SJIS2JIS(K); + if (states->SendCode != IdKanji) { + // \x8A\xBF\x8E\x9AIN + TempStr[TempLen++] = 0x1B; + TempStr[TempLen++] = '$'; + if (cv->KanjiIn == IdKanjiInB) { + TempStr[TempLen++] = 'B'; + } + else { + TempStr[TempLen++] = '@'; + } + states->SendCode = IdKanji; + } + TempStr[TempLen++] = HIBYTE(K); + TempStr[TempLen++] = LOBYTE(K); } - if (cv->FlushLen > 0) { - int OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen); - cv->FlushLen -= OutLen; - cv->LineModeBuffCount -= OutLen; - memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount); + break; + case IdSJIS: + if (mb_len == 1) { + TempStr[TempLen++] = mb_char[0]; + } else { + TempStr[TempLen++] = mb_char[0]; + TempStr[TempLen++] = mb_char[1]; } - cv->Flush = FALSE; + break; + default: + assert(FALSE); + break; } - else { - if (TempLen > 0) { - Full = OutBuffSize -cv->OutBuffCount -TempLen < 0; - if (! Full) { - CommRawOut(cv,TempStr,TempLen); - } else { - // !? - assert(FALSE); - } - } - } + } + } else if (cv->Language == IdRussian) { + /* \x82܂\xB8CP1251\x82ɕϊ\xB7\x82\xB5\x82ďo\x97\xCD */ + char mb_char[2]; + size_t mb_len = sizeof(mb_char); + BYTE b; + mb_len = UTF32ToMBCP(u32, 1251, mb_char, mb_len); + if (mb_len != 1) { + b = '?'; + } else { + b = RussConv(IdWindows, cv->RussHost, mb_char[0]); + } + TempStr[TempLen++] = b; + } else if (cv->Language == IdKorean && *cv->CodePage == 51949) { + /* CP51949\x82ɕϊ\xB7\x82\xB5\x82ďo\x97\xCD */ + char mb_char[2]; + size_t mb_len = sizeof(mb_char); + mb_len = UTF32ToMBCP(u32, 51949, mb_char, mb_len); + if (mb_len == 0) { + TempStr[TempLen++] = '?'; + } + else if (mb_len == 1) { + TempStr[TempLen++] = mb_char[0]; + } else { + TempStr[TempLen++] = mb_char[0]; + TempStr[TempLen++] = mb_char[1]; + } + } else if (cv->Language == IdEnglish) { + TempStr[TempLen++] = u32; + } else { + // CodePage\x82ŕϊ\xB7 + char mb_char[2]; + size_t mb_len = sizeof(mb_char); + mb_len = UTF32ToMBCP(u32, *cv->CodePage, mb_char, mb_len); + if (mb_len == 0) { + TempStr[TempLen++] = '?'; + } + else if (mb_len == 1) { + TempStr[TempLen++] = mb_char[0]; + } else { + TempStr[TempLen++] = mb_char[0]; + TempStr[TempLen++] = mb_char[1]; + } + } - } // end of "while {}" + *TempLen_ = TempLen; + return output_char_count; +} - return i; - } -#endif - { - int CodePage = *cv->CodePage; - size_t mb_len; - int r; - char *mb_str = _WideCharToMultiByte(B, C, CodePage, &mb_len); - if (mb_str == NULL) { - r = 0; +/** + * CommTextOut() \x82\xCC wchar_t \x94\xC5 + * + * @retval \x8Fo\x97͕\xB6\x8E\x9A\x90\x94(wchar_t\x92P\x88\xCA) + */ +int WINAPI CommTextOutW(PComVar cv, const wchar_t *B, int C) +{ + char TempStr[12]; + BOOL Full = FALSE; + int i = 0; + while (! Full && (i < C)) { + // \x8Fo\x97͗p\x83f\x81[\x83^\x82\xF0\x8D쐬 + int TempLen = 0; + size_t output_char_count; // \x8F\xC1\x94\x82\xBD\x95\xB6\x8E\x9A\x90\x94 + OutputCharState state; + state.KanjiCode = cv->KanjiCodeSend; + state.ControlOut = OutControl; + state.SendCode = cv->SendCode; + state.JIS7Katakana = cv->JIS7KatakanaSend; + output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen); + + // \x83f\x81[\x83^\x82\xF0\x8Fo\x97̓o\x83b\x83t\x83@\x82\xD6 + if (WriteOutBuff(cv, TempStr, TempLen)) { + i += output_char_count; // output_char_count \x95\xB6\x8E\x9A\x90\x94 \x8F\x88\x97\x9D\x82\xB5\x82\xBD + // \x8A\xBF\x8E\x9A\x82̏\xF3\x91Ԃ\xF0\x95ۑ\xB6\x82\xB7\x82\xE9 + cv->SendCode = state.SendCode; } else { - r = CommTextOut(cv, mb_str, mb_len); - free(mb_str); + Full = TRUE; } - return r; - } + } // end of "while {}" + _CrtCheckMemory(); + return i; } -// TODO: UTF-16\x82\xA9\x82璼\x90ڕϊ\xB7\x82\xB5\x82ďo\x97͂\xB7\x82\xE9 +/** + * CommTextEcho() \x82\xCC wchar_t \x94\xC5 + * + * @retval \x8Fo\x97͕\xB6\x8E\x9A\x90\x94(wchar_t\x92P\x88\xCA) + */ int WINAPI CommTextEchoW(PComVar cv, const wchar_t *B, int C) { - int CodePage = *cv->CodePage; - size_t mb_len; - int r; - char *mb_str = _WideCharToMultiByte(B, C, CodePage, &mb_len); - if (mb_str == NULL) { - r = 0; - } else { - r = CommTextEcho(cv, mb_str, mb_len); - free(mb_str); - } - return r; + char TempStr[12]; + BOOL Full = FALSE; + int i = 0; + while (! Full && (i < C)) { + // \x8Fo\x97͗p\x83f\x81[\x83^\x82\xF0\x8D쐬 + int TempLen = 0; + size_t output_char_count; // \x8F\xC1\x94\x82\xBD\x95\xB6\x8E\x9A\x90\x94 + OutputCharState state; + state.KanjiCode = cv->KanjiCodeEcho; + state.ControlOut = ControlEcho; + state.SendCode = cv->EchoCode; + state.JIS7Katakana = cv->JIS7KatakanaEcho; + output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen); + + // \x83f\x81[\x83^\x82\xF0\x8Fo\x97̓o\x83b\x83t\x83@\x82\xD6 + if (WriteInBuff(cv, TempStr, TempLen)) { + i += output_char_count; // output_char_count \x95\xB6\x8E\x9A\x90\x94 \x8F\x88\x97\x9D\x82\xB5\x82\xBD + // \x8A\xBF\x8E\x9A\x82̏\xF3\x91Ԃ\xF0\x95ۑ\xB6\x82\xB7\x82\xE9 + cv->EchoCode = state.SendCode; + } else { + Full = TRUE; + } + } // end of "while {}" + _CrtCheckMemory(); + return i; } int WINAPI CommBinaryEcho(PComVar cv, PCHAR B, int C) @@ -2070,10 +2319,7 @@ if ( ! cv->Ready ) return C; - if ( (cv->InPtr>0) && (cv->InBuffCount>0) ) { - memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount); - cv->InPtr = 0; - } + PackInBuff(cv); i = 0; a = 1; @@ -2094,14 +2340,12 @@ Len++; } - if ( InBuffSize-cv->InBuffCount-Len >=0 ) { - memcpy(&(cv->InBuff[cv->InBuffCount]),d,Len); - cv->InBuffCount = cv->InBuffCount + Len; + if (WriteInBuff(cv, d, Len)) { a = 1; + i++; + } else { + a = 0; } - else - a = 0; - i = i + a; } return i; } @@ -2260,21 +2504,13 @@ } } // if (cv->EchoKanjiFlag) else if ... else ... end - if (TempLen == 0) { + if (WriteInBuff(cv, TempStr, TempLen)) { i++; cv->EchoCode = EchoCodeNew; cv->EchoKanjiFlag = KanjiFlagNew; + } else { + Full = FALSE; } - else { - Full = InBuffSize-cv->InBuffCount-TempLen < 0; - if (! Full) { - i++; - cv->EchoCode = EchoCodeNew; - cv->EchoKanjiFlag = KanjiFlagNew; - memcpy(&(cv->InBuff[cv->InBuffCount]),TempStr,TempLen); - cv->InBuffCount = cv->InBuffCount + TempLen; - } - } } // end of "while {}" @@ -2292,10 +2528,7 @@ return C; } - if ( (cv->InPtr>0) && (cv->InBuffCount>0) ) { - memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount); - cv->InPtr = 0; - } + PackInBuff(cv); switch (cv->Language) { case IdUtf8: @@ -2347,11 +2580,10 @@ } } - Full = InBuffSize-cv->InBuffCount-TempLen < 0; - if (! Full) { + if(WriteInBuff(cv, TempStr,TempLen)) { i++; - memcpy(&(cv->InBuff[cv->InBuffCount]),TempStr,TempLen); - cv->InBuffCount = cv->InBuffCount + TempLen; + } else { + Full = TRUE; } } // end of while {}