[Ttssh2-commit] [7966] CommTextOutW(),CommTextEchoW()実装

Back to archive index
scmno****@osdn***** scmno****@osdn*****
2019年 8月 15日 (木) 23:03:55 JST


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 {}
 


Ttssh2-commit メーリングリストの案内
Back to archive index