Index: trunk/ab5.0/ablib/src/Classes/System/IO/StreamReader.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/StreamReader.ab	(revision 668)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/StreamReader.ab	(revision 676)
@@ -1,3 +1,5 @@
 'Classes/System/IO/StreamReader.ab
+
+'ToDo: コンソールで入力待ちになる問題への対処
 
 Namespace System
@@ -38,5 +40,4 @@
 	End Function
 
-
 Protected
 	/*
@@ -58,34 +59,11 @@
 	*/
 	Override Function Underflow() As Boolean
-		Dim wcBuf[4095] As WCHAR
-		Dim mbBuf[4095] As SByte
-		Dim pNext = mbBuf As PSTR
-		Dim mbBufSize = Len(buf)
-		If leadByte <> 0 Then
-			pNext[0] = leadByte
-			leadByte = 0
-			pNext++
-			mbBufSize--
-		End If
-		Dim mbLen = s.Read(pNext As *Byte, 0, mbBufSize)
-		If mbLen = 0 Then
-			Underflow = False
-			Exit Function
-		End If
-		Do
-			Dim q = CharNextExA(cp, pNext, 0)
-			If q = pNext Then
-				Exit Do
-			End If
-			pNext = q As PSTR
-		Loop
-		If pNext <> mbBuf + mbLen Then
-			leadByte = mbBuf[mbLen - 1]
-		End If
-		Dim wcLen = MultiByteToWideChar(cp, 0, mbBuf, (pNext - mbBuf) As Long, wcBuf, 4095)
-		Dim s = New String(wcBuf, wcLen)
 		Dim buf = Buffer
+		Dim tmp = New Collections.Generic.List<WCHAR>
+		Underflow = decoder.Decode(tmp, s)
+		'ToDo: 非UNICODEのとき、
+		' サロゲートペアや結合文字列 (Combining Character Sequence)の途中でバッファが途切れている場合に対応する
+		Dim s = New String(tmp.Data, tmp.Count)
 		buf.Append(s)
-		Underflow = True
 	End Function
 Private
@@ -97,11 +75,9 @@
 	Sub init(str As Stream)
 		s = str
-		cp  = CP_ACP '暫定。
-		leadByte = 0
+		decoder = New Text.Detail.WindowsCodePageDecoder(CP_ACP)
 	End Sub
 
 	s As Stream
-	cp As Word
-	leadByte As Byte
+	decoder As Text.Decoder
 End Class
 
Index: trunk/ab5.0/ablib/src/Classes/System/IO/StreamWriter.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/StreamWriter.ab	(revision 668)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/StreamWriter.ab	(revision 676)
@@ -41,20 +41,35 @@
 
 	Override Sub Flush()
-		Dim buf = Buffer()
-		Dim pws As PCWSTR
-		Dim size = GetWCStr(buf.ToString(), pws)
-		Dim pwsEnd = VarPtr(pws[size])
-		Dim charConverted As Long
-		Dim byteBuf[4095] As Byte
-		Dim byteSize As Long
-		Dim completed As Boolean
-		Do
-			Dim converted As Long
-			encoder.Convert(pws, size, byteBuf, Len(byteBuf), False, charConverted, byteSize, completed)
-			s.Write(byteBuf, 0, byteSize)
-			pws = VarPtr(pws[charConverted])
-			size -= charConverted
-		Loop Until pws = pwsEnd
-		buf.Length = 0
+		Flush(False)
+	End Sub
+
+	Sub Flush(last As Boolean)
+#ifdef UNICODE
+		encoder.Encode(StrPtr(buf), buf.Length As SIZE_T, s, last)
+		buf.Remove(0, buf.Length As SIZE_T)
+#else
+		Dim p = StrPtr(buf)
+		Dim i = 0 As SIZE_T
+		Dim mbLen = 0 As SIZE_T
+		While i <= buf.Length
+			mbLen = i
+			'ヌル文字で終わっていないので、CharNextは使えない
+			If IsDBCSLeadByte(p[i]) Then
+				i += 2
+			Else
+				i += 1
+			End If
+		Wend
+		Dim wcBuf As PCWSTR
+		Dim wcLen = GetStr(p, mbLen, wcBuf)
+		encoder.Encode(wcBuf, wcLen, s, last)
+		buf.Remove(0, mbLen)
+		If last Then
+			If buf.Length <> 0 Then
+				s.WriteByte(Asc("?"))
+				buf.Length = 0	
+			End If
+		End If
+#endif
 	End Sub
 
@@ -62,6 +77,5 @@
 	Override Sub Dispose(disposing As Boolean)
 		If disposing Then
-			Flush()
-			flushLast()
+			Flush(True)
 			s.Dispose()
 		End If
@@ -73,20 +87,7 @@
 		buf = New Text.StringBuilder(4096)
 		'暫定。正式版ではUTF-8を標準とする。
-		encoding = New Text.Detail.WindowsCodePageEncoding(CP_ACP)
-		encoder = encoding.GetEncoder()
+		encoder = New Text.Detail.WindowsCodePageEncoder(CP_ACP)
 	End Sub
 
-	Sub flushLast()
-		Dim charConverted As Long
-		Dim byteBuf[63] As Byte
-		Dim byteSize As Long
-		Dim completed As Boolean
-		Do
-			encoder.Convert(0, 0, byteBuf, Len(byteBuf), False, charConverted, byteSize, completed)
-			s.Write(byteBuf, 0, byteSize)
-		Loop Until completed
-	End Sub
-
-	encoding As Text.Encoding
 	encoder As Text.Encoder
 	s As System.IO.Stream
Index: trunk/ab5.0/ablib/src/Classes/System/IO/StringReader.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/StringReader.ab	(revision 668)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/StringReader.ab	(revision 676)
@@ -16,5 +16,5 @@
 	@date 2008/02/26
 	@auther Egtra
-	@param str 読み取る基となる文字列。
+	@param str 読み取る元となる文字列。
 	@exception ArgumentNullException strがNothingのとき。
 	*/
@@ -23,14 +23,6 @@
 			Throw New ArgumentNullException("str")
 		End If
-		Buffer.Append(str)
-	End Sub
-
-
-Protected
-	/*
-	@date 2008/02/26
-	@auther Egtra
-	*/
-	Override Sub Dispose(disposing As Boolean)
+		Dim b = Buffer
+		b.Append(str)
 	End Sub
 End Class
Index: trunk/ab5.0/ablib/src/Classes/System/IO/TextReader.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/TextReader.ab	(revision 668)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/TextReader.ab	(revision 676)
@@ -22,4 +22,6 @@
 	Virtual Function Peek() As Long
 		If pos >= buf.Length Then
+			buf.Length = 0
+			pos = 0
 			If Not Underflow() Then
 				Peek = -1
@@ -114,4 +116,6 @@
 		Wend
 		ReadToEnd = buf.ToString()
+		buf.Length = 0
+		pos = 0
 	End Function
 
@@ -141,4 +145,5 @@
 	@auther Egtra
 	@return 内部バッファ
+	内部バッファの既存の要素は、一切の変更をしないこと。また、空であるという仮定を置かないこと。
 	*/
 	Function Buffer() As Text.StringBuilder
@@ -151,4 +156,5 @@
 	*/
 	Function ReadImpl(buffer As *Char, count As Long) As Long
+		'ToDo 適当なところでバッファの読み取り済みの部分を除去する処理を入れる（現在Peekのみ）。
 		Dim p = StrPtr(buf)
 		While buf.Length - pos < count
@@ -156,5 +162,5 @@
 		Wend
 		ReadImpl = Math.Min(buf.Length - pos, count)
-		ActiveBasic.Strings.ChrCopy(buffer, VarPtr(p[pos]), ReadImpl As SIZE_T)
+		ActiveBasic.Strings.ChrCopy(buffer, VarPtr(p[pos]) As *Char, ReadImpl As SIZE_T)
 		pos += ReadImpl
 	End Function
