Index: trunk/ab5.0/ablib/src/Classes/System/Text/UTF8Encoding.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/Text/UTF8Encoding.ab	(revision 506)
+++ trunk/ab5.0/ablib/src/Classes/System/Text/UTF8Encoding.ab	(revision 676)
@@ -12,75 +12,48 @@
 	Inherits Encoder
 Protected
-	Override Sub ConvertCore(chars As *WCHAR, charCount As Long, bytes As *Byte, byteCount As Long, flush As Boolean,
-		ByRef bytesUsed As Long, ByRef charsUsed As Long, ByRef completed As Boolean)
-
-		Dim i As Long, j = 0 As Long
-		For i = 0 To ELM(charCount)
-			If chars[i] < &h80 Then
+	Override Sub EncodeImpl(src As *WCHAR, size As SIZE_T, s As IO.Stream, last As Boolean)
+		Dim i As Long
+		For i = 0 To ELM(size)
+			If buffer <> 0 Then
+				If _System_IsLowSurrogate(src[i]) Then
+					'UTF-16列からUnicodeコードポイントを復元
+					Dim c = (((buffer And &h3FF) As DWord << 10) Or (src[i] And &h3FF)) + &h10000
+					'4バイト変換
+					s.WriteByte(((c >> 18) Or &hf0) As Byte)
+					s.WriteByte(((c >> 12) And &h3F Or &h80) As Byte)
+					s.WriteByte(((c >> 6) And &h3F Or &h80) As Byte)
+					s.WriteByte((c And &h3F Or &h80) As Byte)
+				Else
+					writeReplacementChar(s)
+				End If
+				buffer = 0
+			ElseIf src[i] < &h80 Then
 				'1バイト変換
-				If j + 1 > byteCount Then
-					'バッファ不足
-					Goto *BufferOver
-				End If
-				bytes[j] = chars[i] As Byte
-				j++
-			ElseIf chars[i] < &h800 Then
+				s.WriteByte(src[i] As Byte)
+			ElseIf src[i] < &h800 Then
 				'2バイト変換
-				If j + 2 > byteCount Then
-					Goto *BufferOver
-				End If
-				bytes[j] = ((chars[i] >> 6) Or &hC0) As Byte
-				j++
-				bytes[j] = (chars[i] And &h3F Or &h80) As Byte
-				j++
-			ElseIf _System_IsHighSurrogate(chars[i]) Then
-				If i + 1 >= charCount Then
-					'バッファに貯め込む
-					If flush = False Then
-						buffer = chars[i]
-						Exit Sub
-					End If
-					'ToDo: chars[i + 1]が範囲外になる場合が考慮されていない
-				ElseIf _System_IsLowSurrogate(chars[i + 1]) = False Then
-					'EncoderFallback
-				End If
-				If j + 4 > byteCount Then
-					Goto *BufferOver
-				End If
-				'UTF-16列からUnicodeコードポイントを復元
-				Dim c = (((chars[i] And &h3FF) As DWord << 10) Or (chars[i + 1] And &h3FF)) + &h10000
-				'4バイト変換
-				bytes[j] = ((c >> 18) Or &hf0) As Byte
-				j++
-				bytes[j] = ((c >> 12) And &h3F Or &h80) As Byte
-				j++
-				bytes[j] = ((c >> 6) And &h3F Or &h80) As Byte
-				j++
-				bytes[j] = (c And &h3F Or &h80) As Byte
-				j++
-				i++
-			ElseIf _System_IsLowSurrogate(chars[i]) Then
-				'EncoderFallback
+				s.WriteByte(((src[i] >> 6) Or &hC0) As Byte)
+				s.WriteByte((src[i] And &h3F Or &h80) As Byte)
+			ElseIf _System_IsHighSurrogate(src[i]) Then
+				'バッファに貯め込む
+				buffer = src[i]
+			ElseIf _System_IsLowSurrogate(src[i]) Then
+				writeReplacementChar(s)
 			Else
 				'3バイト変換
-				If j + 3 > byteCount Then
-					Goto *BufferOver
-				End If
-				bytes[j] = ((chars[i] >> 12) Or &hE0) As Byte
-				j++
-				bytes[j] = ((chars[i] >> 6) And &h3F Or &h80) As Byte
-				j++
-				bytes[j] = (chars[i] And &h3F Or &h80) As Byte
-				j++
+				s.WriteByte(((src[i] >> 12) Or &hE0) As Byte)
+				s.WriteByte(((src[i] >> 6) And &h3F Or &h80) As Byte)
+				s.WriteByte((src[i] And &h3F Or &h80) As Byte)
 			End If
 		Next
-
-		Exit Sub
-	*BufferOver
-		'バッファ不足
-		Throw New ArgumentException("Buffer is not enough.", "bytes")
 	End Sub
 
 Private
+	' U+FFFD Replacement CharacterのUTF-8表現、EF BF BDを書き込む。
+	Sub writeReplacementChar(s As IO.Stream)
+		Dim rc[2] = [&hef, &hbf, &hbd] As Byte
+		s.Write(rc, 0, Len(rc))
+	End Sub
+
 	buffer As WCHAR
 End Class
@@ -89,80 +62,70 @@
 	Inherits Decoder
 Protected
-	Override Sub ConvertCore(bytes As *Byte, byteCount As Long, chars As *WCHAR, charCount As Long, flush As Boolean,
-		ByRef bytesUsed As Long, ByRef charsUsed As Long, ByRef completed As Boolean)
-		Dim i As Long, j = 0 As Long
-		For i = 0 To ELM(byteCount)
-			If state = 0 Then
-				If bytes[i] <= &h80 Then
+	Override Function DecodeImpl(dst As Collections.Generic.List<WCHAR>, s As IO.Stream) As Boolean
+		Dim i As Long
+		For i = 0 To DefalultDecodingBufferSize - 1 'ELM
+			Dim b = s.ReadByte()
+			If b = -1 Then
+				DecodeImpl = False
+				Exit Function
+			ElseIf state = 0 Then
+				If b <= &h80 Then
 					'1バイト変換
-					If j = charCount Then Goto *BufferOver
-					chars[j] = bytes[i]
-					j++
-				ElseIf bytes[i] < &hC0 Then
-					'マルチバイトの2バイト目以降
-					'DecoderFallback完成までの暫定
-					If j = charCount Then Goto *BufferOver
-					chars[j] = &hfffd
-					j++
-				ElseIf bytes[i] < &hD0 Then
+					dst.Add(b As WCHAR)
+				ElseIf b < &hC0 Then
+					'先頭バイトがなく、いきなりマルチバイトの2バイト目以降
+					dst.Add(&hFFFD As WCHAR)
+				ElseIf b < &hD0 Then
 					'2バイト文字の始まり
 					last = 2
-					buf = bytes[i] And &h3f
-					state++
-				ElseIf bytes[i] < &hF0 Then
+					buffer = b And &h3F
+					state++
+				ElseIf b < &hF0 Then
 					'3バイト文字の始まり
 					last = 3
-					buf = bytes[i] And &h1f
-					state++
-				Else
+					buffer = b And &h1F
+					state++
+				ElseIf b < &hF8 Then
 					'4バイト文字の始まり
 					last = 4
-					buf = bytes[i] And &h0f
-					state++
+					buffer = b And &h0F
+					state++
+				Else
+					'現在のUTF-8は4バイトを超える表現を認めていない。
+					dst.Add(&hFFFD As WCHAR)
 				End If
 			Else
-				If &h80 <= bytes[i] And bytes[i] < &hC0 Then
+				If &h80 <= b And b < &hC0 Then
 					'マルチバイト文字の2バイト目以降
-					buf <<= 6
-					buf Or= bytes[i] And &h3F
+					buffer <<= 6
+					buffer Or= b And &h3F
 					state++
 					If state = last Then '最終バイトに到達
-						If state = 2 And buf >= &h80 Then
-							chars[j] = buf As WCHAR
-							j++
-						ElseIf state = 3 And buf >= &h800 And buf < &hD800 And &hE0000 >= buf Then
-							chars[j] = buf As WCHAR
-							j++
-						ElseIf state = 4 And buf <= &h10ffff Then
-							buf -= &h10000
-							chars[j] = (&hD800 Or (buf >> 10)) As WCHAR
-							j++
-							chars[j] = (&hDC00 Or (buf And &h3FF)) As WCHAR
-							j++
+						If state = 2 And buffer >= &h80 Then
+							dst.Add(buffer As WCHAR)
+						ElseIf state = 3 And buffer >= &h800 And buffer < &hD800 And &hE0000 >= buffer Then
+							dst.Add(buffer As WCHAR)
+						ElseIf state = 4 And buffer <= &h10FFFF Then
+							buffer -= &h10000
+							dst.Add((&hD800 Or (buffer >> 10)) As WCHAR)
+							dst.Add((&hDC00 Or (buffer And &h3FF)) As WCHAR)
 						Else
-							'DecoderFallback
-							If j = charCount Then Goto *BufferOver
-							chars[j] = &hfffd
-							j++
+							'最短形式でないもの、4バイト形式で10FFFFを超えるコードポイントのもの
+							dst.Add(&hfffd As WCHAR)
 						End If
 						state = 0
 					End If
 				Else
-					'3, 4バイト文字の先頭
-					'DecoderFallback
-					If j = charCount Then Goto *BufferOver
-					chars[j] = &hfffd
-					j++
+					'マルチバイト文字の途中なのに、それ以外のバイトが現れた場合
+					dst.Add(&hFFFD As WCHAR)
+					state = 0
 				End If
 			End If
 		Next
-		Exit Sub
-	*BufferOver
-		'バッファ不足
-		Throw New ArgumentException("Buffer is not enough.", "bytes")
-	End Sub
+		DecodeImpl = True
+	End Function
 
 Private
-	buf As DWord
+	buffer As DWord
 	state As Long
 	last As Long
@@ -180,47 +143,29 @@
 	Inherits Encoding
 Public
-
 	Override Function Clone() As Object
-		Dim c = New UTF8Encoding
-		c.DecoderFallback = This.DecoderFallback
-		c.EncoderFallback = This.EncoderFallback
-		Return c
+		Clone = New UTF8Encoding
 	End Function
 
 	Override Function GetDecoder() As Decoder
 		GetDecoder = New Detail.UTF8Decoder
-'		GetDecoder.Fallback = DecoderFallback
 	End Function
 
 	Override Function GetEncoder() As Encoder
 		GetEncoder = New Detail.UTF8Encoder
-'		GetEncoder.Fallback = EncoderFallback
 	End Function
 
 	Override Function GetMaxByteCount(charCount As Long) As Long
-		Return charCount * 3
+		GetMaxByteCount = charCount * 3
 		'全てがUTF-8で3バイトになる文字の場合が最大。
 
-		'UTF-8で4バイトになる列は、UTF-16だとサロゲートペアで表現するので、
-		'1単位あたりでは2バイトしか食わないことになる。
+		'なお、UTF-8で4バイトになる列は、UTF-16だとサロゲートペアで表現するので、
+		'1単位あたりでは2バイトしか食わないことになり、最大ではない。
 	End Function
 
 	Override Function GetMaxCharCount(byteCount As Long) As Long
 		'全てU+7F以下の文字だけだった場合
-		Return byteCount
-	End Function
-Protected
-	Override Function GetBytesCountCore(s As *WCHAR, n As Long) As Long
-	End Function
-
-	Override Function GetBytesCore(chars As *WCHAR, charCount As Long, bytes As *Byte, byteCount As Long) As Long
-	End Function
-
-	Override Function GetCharsCountCore(s As *Byte, n As Long) As Long
-	End Function
-
-	Override Function GetCharsCore(bytes As *Byte, byteCount As Long, chars As *WCHAR, charCount As Long) As Long
-	End Function
-Public
+		GetMaxCharCount = byteCount
+	End Function
+
 	Override Function GetPreamble() As *Byte
 		Return bom
@@ -230,13 +175,5 @@
 		Return Len(bom)
 	End Function
-
-	Override Function IsAlwaysNormalized() As Boolean
-		IsAlwaysNormalized = False
-	End Function
-
-	Override Function IsAlwaysNormalized(f As NormalizationForm) As Boolean
-		IsAlwaysNormalized = False
-	End Function
-
+/*
 	Override Function BodyName() As String
 		Return "utf-8"
@@ -258,4 +195,18 @@
 		Return False
 	End Function
+*/
+Protected
+	Override Function GetBytesCountCore(src As *WCHAR, srcCount As Long) As Long
+	End Function
+
+	Override Function GetBytesCore(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long) As Long
+	End Function
+
+	Override Function GetCharsCountCore(src As *Byte, srcCount As Long) As Long
+	End Function
+
+	Override Function GetCharsCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long) As Long
+	End Function
+
 Private
 	Static bom[2] = [&hEF, &hBB, &hBF] As Byte
