Index: trunk/ab5.0/ablib/src/Classes/System/Text/Encoding.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/Text/Encoding.ab	(revision 581)
+++ trunk/ab5.0/ablib/src/Classes/System/Text/Encoding.ab	(revision 653)
@@ -13,5 +13,5 @@
 
 なお、このクラスで、文字列の長さやバッファの大きさを指定するときには、
-1 chars = 2バイト（UTF-16符号単位）、1 bytes = 1バイトの単位で指定する。
+1 WCHAR = 2バイト（UTF-16符号単位）、1 Byte = 1バイトの単位で指定する。
 
 */
@@ -22,5 +22,7 @@
 	@brief	簡易的複製を作成する。
 	*/
-	Abstract Function Clone() As Object
+	Virtual Function Clone() As Object
+		Clone = This
+	End Function
 
 '	Override Function Equals(y As Object) As Boolean
@@ -32,304 +34,181 @@
 Public
 	Sub Encoding()
-		decoderFallback = New DecoderReplacementFallback
 	End Sub
 
 	/*!
 	@brief	符号化して得られる文字列の長さを計算する。
-	@param[in] s	対象文字列
-	@param[in] n	sの長さ
+	@param[in] src	対象文字列
+	@param[in] srcCount	srcの長さ
 	@return	符号化して得られる文字列の長さ
 	@date	2007/12/08
 	*/
-	Function GetBytesCount(s As *WCHAR, n As Long) As Long
-		If s = 0 Then
-			Throw New ArgumentNullException("Encoding.GetBytesCount: An argument is null value.", "s")
-		ElseIf n < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetBytesCount: An argument is out of range value.", "n")
-		End If
-		Return GetBytesCountCore(s, n)
+	Function GetBytesCount(src As *WCHAR, srcCount As Long) As Long
+		If src = 0 Then
+			Throw New ArgumentNullException("src")
+		ElseIf srcCount < 0 Then
+			Throw New ArgumentOutOfRangeException("srcCount")
+		End If
+		Return GetBytesCountCore(src, srcCount)
 	End Function
 #ifdef UNICODE
 	/*!
 	@brief	符号化して得られる文字列の長さを計算する。
-	@param[in] s	対象文字列
+	@param[in] src	対象文字列
 	@return	符号化して得られる文字列の長さ
 	@date	2007/12/08
 	*/
-	Function GetBytesCount(s As String) As Long
-		If ActiveBasic.IsNothing(s) Then
-			Throw New ArgumentNullException("Encoding.GetBytesCount: An argument is null value.", "s")
-		End If
-		Return GetBytesCountCore(StrPtr(s), s.Length)
+	Function GetBytesCount(src As String) As Long
+		If ActiveBasic.IsNothing(src) Then
+			Throw New ArgumentNullException("src")
+		End If
+		Return GetBytesCountCore(StrPtr(src), src.Length)
 	End Function
 #endif
-	/*!
-	@brief	符号化して得られる文字列の長さを計算する。
-	@param[in] s	対象文字列
-	@param[in] index	開始位置
-	@param[in] count	符号化する文字の数
+
+Private
+	/*!
+	@brief	GetBytesCountの実装を行う。
+	@param[in] src	対象文字列
+	@param[in] srcCount	srcの長さ
 	@return	符号化して得られる文字列の長さ
 	@date	2007/12/08
 	*/
-	Function GetBytesCount(s As *WCHAR, index As Long, count As Long) As Long
-		If s = 0 Then
-			Throw New ArgumentNullException("Encoding.GetBytesCount: An argument is null value.", "s")
-		ElseIf index < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetBytesCount: An argument is out of range value.", "index")
-		ElseIf count < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetBytesCount: An argument is out of range value.", "count")
-		End If
-		Return GetBytesCountCore(VarPtr(s[index]), count)
-	End Function
-Protected
-	/*!
-	@brief	GetBytesCountの実装を行う。
-	@param[in] s	対象文字列
-	@param[in] n	sの長さ
+	Function GetBytesCountCore(src As *WCHAR, srcCount As Long) As Long
+		Dim enc = GetEncoder()
+		GetBytesCountCore = enc.GetBytesCount(src, srcCount, True)
+	End Function
+Public
+	/*!
+	@brief	符号化する。
+	@param[in] src	入力
+	@param[in] srcCount	srcの長さ
+	@param[out] dst	出力
+	@param[in] dstCount	dstのバッファの大きさ
+	@return dstに書き込まれたバイト数
+	@date	2007/12/08
+	*/
+	Function GetBytes(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long) As Long
+		If src = 0 Then
+			Throw New ArgumentNullException("src")
+		ElseIf dst = 0 Then
+			Throw New ArgumentNullException("dst")
+		ElseIf srcCount < 0 Then
+			Throw New ArgumentOutOfRangeException("srcCount")
+		ElseIf dstCount < 0 Then
+			Throw New ArgumentOutOfRangeException("dstCount")
+		End If
+
+		Return GetBytesCore(src, srcCount, dst, dstCount)
+	End Function
+
+Private
+	/*!
+	@brief	GetBytesの処理を行う。
+	@param[in] src	入力
+	@param[in] srcCount	srcの長さ
+	@param[out] dst	出力
+	@param[in] dstCount	dstのバッファの大きさ
+	@return dstに書き込まれたバイト数
+	@exception ArgumentException	バッファの大きさが足りない
+	@date	2007/12/08
+	*/
+	Function GetBytesCore(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long) As Long
+		GetBytesCore = GetEncoder().GetBytes(src, srcCount, dst, dstCount, True)
+	End Function
+Public
+	/*!
+	@brief	復号して得られる文字列の長さを計算する。
+	@param[in] src	対象文字列
+	@param[in] srcCount	srcの長さ
+	@return	復号して得られる文字列の長さ
+	@date	2007/12/08
+	*/
+	Function GetCharsCount(src As *Byte, srcCount As Long) As Long
+		If src = 0 Then
+			Throw New ArgumentNullException("src")
+		ElseIf srcCount < 0 Then
+			Throw New ArgumentOutOfRangeException("srcCount")
+		End If
+		Return GetCharsCountCore(src, srcCount)
+	End Function
+
+Private
+	/*!
+	@brief	GetCharsCountの処理を行う。
+	@param[in] src	対象文字列
+	@param[in] srcCount	srcの長さ
 	@return	符号化して得られる文字列の長さ
 	@date	2007/12/08
 	*/
-	Abstract Function GetBytesCountCore(s As *WCHAR, n As Long) As Long
-Public
-	/*!
-	@brief	符号化する。
-	@param[in] chars	入力
-	@param[in] charCount	charsの長さ
-	@param[out] bytes	出力
-	@param[in] byteCount	bytesのバッファの大きさ
-	@return bytesに書き込まれたバイト数
-	@date	2007/12/08
-	*/
-	Function GetBytes(chars As *WCHAR, charCount As Long, bytes As *Byte, byteCount As Long) As Long
-		If chars = 0 Then
-			Throw New ArgumentNullException("Encoding.GetBytes: An argument is null value.", "chars")
-		ElseIf bytes = 0 Then
-			Throw New ArgumentNullException("Encoding.GetBytes: An argument is null value.", "bytes")
-		ElseIf charCount < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetBytes: An argument is out of range value.", "charCount")
-		ElseIf byteCount < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetBytes: An argument is out of range value.", "byteCount")
-		End If
-
-		Return GetBytesCore(chars, charCount, bytes, byteCount)
-	End Function
-	/*!
-	@brief	符号化する。
-	@param[in] chars	入力
-	@param[in] index	charsの開始位置
-	@param[in] count	符号化する文字の数
-	@param[out] bytes	出力
-	@param[in] byteCount	bytesのバッファの大きさ
-	@return bytesに書き込まれたバイト数
-	@date	2007/12/08
-	*/
-	Function GetBytes(chars As *WCHAR, index As Long, count As Long, bytes As *Byte, byteCount As Long) As Long
-		If chars = 0 Then
-			Throw New ArgumentNullException("Encoding.GetBytes: An argument is null value.", "chars")
-		ElseIf bytes = 0 Then
-			Throw New ArgumentNullException("Encoding.GetBytes: An argument is null value.", "bytes")
-		ElseIf index < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetBytesCount: An argument is out of range value.", "index")
-		ElseIf count < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetBytesCount: An argument is out of range value.", "count")
-		ElseIf byteCount < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetBytes: An argument is out of range value.", "byteCount")
-		End If
-
-		Return GetBytesCore(VarPtr(chars[index]), count, bytes, byteCount)
-	End Function
+	Function GetCharsCountCore(src As *Byte, srcCount As Long) As Long
+		Dim dec = GetDecoder()
+		GetCharsCountCore = dec.GetCharsCount(src, srcCount, True)
+	End Function
+Public
+	/*!
+	@brief	復号する。
+	@param[in] src	入力
+	@param[in] srcCount	srcの長さ
+	@param[out] dst	出力
+	@param[in] dstCount	srcのバッファの大きさ
+	@return dstに書き込まれたバイト数
+	@date	2007/12/08
+	*/
+	Function GetChars(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long) As Long
+		If dst = 0 Then
+			Throw New ArgumentNullException("dst")
+		ElseIf src = 0 Then
+			Throw New ArgumentNullException("src")
+		ElseIf dstCount < 0 Then
+			Throw New ArgumentOutOfRangeException("dstCount")
+		ElseIf srcCount < 0 Then
+			Throw New ArgumentOutOfRangeException("srcCount")
+		End If
+
+		Return GetCharsCore(src, srcCount, dst, dstCount)
+	End Function
+
+Private
+	/*!
+	@brief	GetCharsの処理を行う。
+	@param[in] src	入力
+	@param[in] srcCount	srcの長さ
+	@param[out] dst	出力
+	@param[in] dstCount	dstのバッファの大きさ
+	@return dstに書き込まれたバイト数
+	@exception ArgumentException	バッファの大きさが足りない
+	@date	2007/12/08
+	*/
+	Function GetCharsCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long) As Long
+		GetCharsCore = GetDecoder().GetChars(src, srcCount, dst, dstCount, True)
+	End Function
+Public
 #ifdef UNICODE
 	/*!
-	@brief	符号化する。
-	@param[in] s	入力
-	@param[in] index	sの開始位置
-	@param[in] count	符号化する文字の数
-	@param[out] bytes	出力
-	@param[in] byteCount	bytesのバッファの大きさ
-	@return bytesに書き込まれたバイト数
-	@date	2007/12/08
-	*/
-	Function GetBytes(s As String, index As Long, count As Long, bytes As *Byte, byteCount As Long) As Long
-		If ActiveBasic.IsNothing(s) Then
-			Throw New ArgumentNullException("Encoding.GetBytes: An argument is null value.", "chars")
-		ElseIf bytes = 0 Then
-			Throw New ArgumentNullException("Encoding.GetBytes: An argument is null value.", "bytes")
-		ElseIf index < 0 Or index >= s.Length Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetBytes: An argument is out of range value.", "index")
-		ElseIf count < 0 Or index + count >= s.Length Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetBytes: An argument is out of range value.", "count")
-		ElseIf byteCount < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetBytes: An argument is out of range value.", "byteCount")
-		End If
-		Dim p = StrPtr(s)
-		Return GetBytesCore(VarPtr(p[index]), count, bytes, byteCount)
+	@brief	復号し、Stringで結果を返す。
+	@param[in] src	入力
+	@param[in] srcCount	srcの長さ
+	@return	変換結果の文字列
+	@date	2007/12/08
+	*/
+	Function GetString(src As *Byte, srcCount As Long) As String
+		If src = 0 Then
+			Throw New ArgumentNullException("src")
+		ElseIf srcCount < 0 Then
+			Throw New ArgumentOutOfRangeException("srcCount")
+		End If
+		GetString = getStringCore(src, srcCount)
+	End Function
+
+Private
+	Function getStringCore(src As *Byte, srcCount As Long) As String
+		Dim sb = New StringBuilder
+		Dim bufCount = GetMaxCharCount(srcCount)
+		sb.Length = bufCount
+		Dim len = GetCharsCore(src, srcCount, StrPtr(sb), bufCount)
+		sb.Length = len
+		getStringCore = sb.ToString()
 	End Function
 #endif
-Protected
-	/*!
-	@brief	GetBytesの処理を行う。
-	@param[in] chars	入力
-	@param[in] charCount	charsの長さ
-	@param[out] bytes	出力
-	@param[in] byteCount	bytesのバッファの大きさ
-	@return bytesに書き込まれたバイト数
-	@exception ArgumentException	バッファの大きさが足りない
-	@exception EncoderFallbackException	フォールバックが発生した
-	@date	2007/12/08
-	*/
-	Abstract Function GetBytesCore(chars As *WCHAR, charCount As Long, bytes As *Byte, byteCount As Long) As Long
-
-Public
-	/*!
-	@brief	復号して得られる文字列の長さを計算する。
-	@param[in] s	対象文字列
-	@param[in] n	sの長さ
-	@return	復号して得られる文字列の長さ
-	@date	2007/12/08
-	*/
-	Function GetCharsCount(s As *Byte, n As Long) As Long
-		If s = 0 Then
-			Throw New ArgumentNullException("Encoding.GetCharsCount: An argument is null value.", "s")
-		ElseIf n < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetCharsCount: An argument is out of range value.", "n")
-		End If
-		Return GetCharsCountCore(s, n)
-	End Function
-	/*!
-	@brief	復号して得られる文字列の長さを計算する。
-	@param[in] s	対象文字列
-	@param[in] index	開始位置
-	@param[in] count	符号化する文字の数
-	@return	符号化して得られる文字列の長さ
-	@date	2007/12/08
-	*/
-	Function GetCharsCount(s As *Byte, index As Long, count As Long) As Long
-		If s = 0 Then
-			Throw New ArgumentNullException("Encoding.GetCharsCount: An argument is null value.", "s")
-		ElseIf index < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetCharsCount: An argument is out of range value.", "index")
-		ElseIf count < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetCharsCount: An argument is out of range value.", "count")
-		End If
-		Return GetCharsCountCore(VarPtr(s[index]), count)
-	End Function
-Protected
-	/*!
-	@brief	GetCharsCountの処理を行う。
-	@param[in] s	対象文字列
-	@param[in] n	sの長さ
-	@return	符号化して得られる文字列の長さ
-	@date	2007/12/08
-	*/
-	Abstract Function GetCharsCountCore(s As *Byte, n As Long) As Long
-	/*!
-	*/
-Public
-	/*!
-	@brief	復号する。
-	@param[in] bytes	入力
-	@param[in] byteCount	charsの長さ
-	@param[out] chars	出力
-	@param[in] charCount	bytesのバッファの大きさ
-	@return bytesに書き込まれたバイト数
-	@date	2007/12/08
-	*/
-	Function GetChars(bytes As *Byte, byteCount As Long, chars As *WCHAR, charCount As Long) As Long
-		If chars = 0 Then
-			Throw New ArgumentNullException("Encoding.GetChars: An argument is null value.", "chars")
-		ElseIf bytes = 0 Then
-			Throw New ArgumentNullException("Encoding.GetChars: An argument is null value.", "bytes")
-		ElseIf charCount < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetChars: An argument is out of range value.", "charCount")
-		ElseIf byteCount < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetChars: An argument is out of range value.", "byteCount")
-		End If
-
-		Return GetCharsCore(bytes, byteCount, chars, charCount)
-	End Function
-	/*!
-	@brief	復号する。
-	@param[in] bytes	入力
-	@param[in] index	charsの開始位置
-	@param[in] count	符号化する文字の数
-	@param[out] chars	出力
-	@param[in] charCount	bytesのバッファの大きさ
-	@return bytesに書き込まれたバイト数
-	@date	2007/12/08
-	*/
-	Function GetChars(bytes As *Byte, index As Long, count As Long, chars As *WCHAR, charCount As Long) As Long
-		If chars = 0 Then
-			Throw New ArgumentNullException("Encoding.GetChars: An argument is null value.", "chars")
-		ElseIf bytes = 0 Then
-			Throw New ArgumentNullException("Encoding.GetChars: An argument is null value.", "bytes")
-		ElseIf index < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetChars: An argument is out of range value.", "index")
-		ElseIf count < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetChars: An argument is out of range value.", "count")
-		ElseIf charCount < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetChars: An argument is out of range value.", "byteCount")
-		End If
-
-		Return GetCharsCore(VarPtr(bytes[index]), count, chars, charCount)
-	End Function
-Protected
-	/*!
-	@brief	GetCharsの処理を行う。
-	@param[in] bytes	入力
-	@param[in] byteCount	charsの長さ
-	@param[out] chars	出力
-	@param[in] charCount	bytesのバッファの大きさ
-	@return bytesに書き込まれたバイト数
-	@exception ArgumentException	バッファの大きさが足りない
-	@exception EncoderFallbackException	フォールバックが発生した
-	@date	2007/12/08
-	*/
-	Abstract Function GetCharsCore(bytes As *Byte, byteCount As Long, chars As *WCHAR, charCount As Long) As Long
-Public
-#ifdef UNICODE
-	/*!
-	@brief	復号し、Stringで結果を返す。
-	@param[in] bytes	入力
-	@param[in] byteCount	charsの長さ
-	@return	変換結果の文字列
-	@date	2007/12/08
-	*/
-	Function GetString(bytes As *Byte, byteCount As Long) As String
-		If bytes = 0 Then
-			Throw New ArgumentNullException("Encoding.GetString: An argument is null value.", "bytes")
-		ElseIf byteCount < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetString: An argument is out of range value.", "byteCount")
-		End If
-		Return getStringCore(bytes, byteCount)
-	End Function
-	/*!
-	@brief	復号し、Stringで結果を返す。
-	@param[in] bytes	入力
-	@param[in] index	charsの開始位置
-	@param[in] count	符号化する文字の数
-	@return	変換結果の文字列
-	@date	2007/12/08
-	*/
-	Function GetString(bytes As *Byte, index As Long, count As Long) As String
-		If bytes = 0 Then
-			Throw New ArgumentNullException("Encoding.GetString: An argument is null value.", "bytes")
-		ElseIf index < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetString: An argument is out of range value.", "index")
-		ElseIf count < 0 Then
-			Throw New ArgumentOutOfRangeException("Encoding.GetString: An argument is out of range value.", "count")
-		End If
-		Return getStringCore(VarPtr(bytes[index]), count)
-	End Function
-Private
-
-	Function getStringCore(bytes As *Byte, byteCount As Long) As String
-		Dim sb = New StringBuilder
-		Dim bufSize = GetMaxCharCount(byteCount)
-		sb.Length = bufSize
-		Dim len = GetCharsCore(bytes, byteCount, StrPtr(sb), bufSize)
-		sb.Length = len
-		getStringCore = sb.ToString
-	End Function
-#endif
 
 Public
@@ -347,14 +226,14 @@
 	@brief	ある長さの文字列を符号化して得られるバイト列の最大の長さを返す。
 	*/
-	Abstract Function GetMaxByteCount(charCount As Long) As Long
+	Abstract Function GetMaxByteCount(srcCount As Long) As Long
 
 	/*!
 	@brief	ある長さのバイト列を復号して得られる文字列の最大の長さを返す。
 	*/
-	Abstract Function GetMaxCharCount(charCount As Long) As Long
+	Abstract Function GetMaxCharCount(srcCount As Long) As Long
 
 	/*!
 	@brief	符号化された文字列の先頭につける識別文字列の取得
-	ようするにUTFのBOM
+	ようするにUTFのBOM。
 	*/
 	Virtual Function GetPreamble() As *Byte
@@ -369,16 +248,6 @@
 	End Function
 
-	/*!
-	@brief	正規化されるかどうか。
-	*/
-	Abstract Function IsAlwaysNormalized() As Boolean
-
-	/*!
-	@brief	指定された方式で正規化されるかどうか。
-	*/
-	Abstract Function IsAlwaysNormalized(form As NormalizationForm) As Boolean
-
-	Abstract Function BodyName() As String
-	Abstract Function HeaderName() As String
+'	Abstract Function BodyName() As String
+'	Abstract Function HeaderName() As String
 
 	/*!
@@ -391,39 +260,14 @@
 '	Abstract Function WindowsCodePage() As Long
 
-	Function DecoderFallback() As DecoderFallback
-		Return decoderFallback
-	End Function
-
-	Sub DecoderFallback(f As DecoderFallback)
-		If ActiveBasic.IsNothing(f) Then
-			Throw New ArgumentNullException("f")
-		End If
-		decoderFallback = f
-	End Sub
-
-	Function EncoderFallback() As EncoderFallback
-		Return encoderFallback
-	End Function
-
-	Sub EncoderFallback(f As EncoderFallback)
-		If ActiveBasic.IsNothing(f) Then
-			Throw New ArgumentNullException("f")
-		End If
-		encoderFallback = f
-	End Sub
-
-Private
-	decoderFallback As DecoderFallback
-	encoderFallback As EncoderFallback
 Public
 	/*!
 	@brief	この符号化形式の名前の取得。
 	*/
-	Abstract Function EncodingName() As String
+'	Abstract Function EncodingName() As String
 
 	/*!
 	@brief	この符号化形式のIANA登録名の取得。
 	*/
-	Abstract Function WebName() As String
+'	Abstract Function WebName() As String
 
 '	Abstract Function IsBrowserDisplay() As Boolean
@@ -432,10 +276,8 @@
 '	Abstract Function IsMailNewsSave() As Boolean
 
-'	Abstract Function IsReadOnly() Boolean
-
 	/*!
 	@brief	この符号化形式が、1バイト文字だけを使う（複数バイト文字を使わない）かどうか。
 	*/
-	Abstract Function IsSingleByte() As Boolean
+'	Abstract Function IsSingleByte() As Boolean
 
 	'GetPreamble
@@ -450,39 +292,27 @@
 	@exception ArgumentNullException	srcEncoding, dstEncoding, bytesの少なくとも1つ以上がNothing/NULLのとき。
 	@exception ArgumentOutOfRangeException	sizeが明らかに範囲外（負の値など）のとき。
-	@exception DecoderFallbackException
-	@exception EncoderFallbackException
-	*/
-	Static Function Convert(srcEncoding As Encoding, dstEncoding As Encoding, bytes As *Byte, size As Long) As *Byte
-	End Function
+	*/
+'	Static Function Convert(srcEncoding As Encoding, dstEncoding As Encoding, bytes As *Byte, size As Long) As *Byte
+'	End Function
 	
-	Static Function Convert(srcEncoding As Encoding, dstEncoding As Encoding, bytes As *Byte, index As Long, count As Long) As *Byte
-	End Function
+'	Static Function Convert(srcEncoding As Encoding, dstEncoding As Encoding, bytes As *Byte, index As Long, count As Long) As *Byte
+'	End Function
 
 	/*!
 	@brief	指定したコードページ用のEncodingインスタンスの取得。
 	*/
-	Static Function GetEncoding(codepage As Long) As Encoding
-	End Function
-'	Static Function GetEncoding(codepage As Long, encoderFallback As EncoderFallback, decoderFallback As DecoderFallback) As Encoding
+'	Static Function GetEncoding(codepage As Long) As Encoding
 '	End Function
 	/*!
 	@brief	指定した符号化形式名用のEncodingインスタンスの取得。
 	*/
-	Static Function GetEncoding(name As String) As Encoding
-	End Function
-'	Static Function GetEncoding(name As String, encoderFallback As EncoderFallback, decoderFallback As DecoderFallback) As Encoding
+'	Static Function GetEncoding(name As String) As Encoding
 '	End Function
-
-	/*!
-	@brief	システム既定のANSIコードページ用のEncodingインスタンスの取得。
+	/*!
+	@brief	システムで標準のANSIコードページ用のEncodingインスタンスの取得。
 	*/
 	Static Function Default() As Encoding
 	End Function
 	/*!
-	@brief	UTF-7用のEncodingインスタンスの取得。
-	*/
-	Static Function UTF7() As Encoding
-	End Function
-	/*!
 	@brief	UTF-8用のEncodingインスタンスの取得。
 	*/
@@ -498,9 +328,4 @@
 	*/
 	Static Function UTF16BE() As Encoding
-	End Function
-	/*!
-	@brief	UTF-32LE用のEncodingインスタンスの取得。
-	*/
-	Static Function UTF32() As Encoding
 	End Function
 End Class
@@ -515,122 +340,92 @@
 	/*!
 	@brief	変換する
-	@param[in] bytes	入力
-	@param[in] byteIndex 入力開始位置
-	@param[in] byteCount 入力要素数
-	@param[out] chars	出力
-	@param[in] charIndex 出力開始位置
-	@param[in] charCount 出力要素数
+	@param[in] src	入力
+	@param[in] srcCount 入力要素数
+	@param[out] dst	出力
+	@param[in] dstCount 出力要素数
 	@param[in] flush	終了後に内部状態を初期化するかどうか
-	@param[out] charsUsed	使用された入力の要素数
-	@param[out] bytesUsed	出力の内、実際に書き込まれた要素数
+	@param[out] srcUsed	使用された入力の要素数
+	@param[out] dstUsed	出力の内、実際に書き込まれた要素数
 	@param[out] completed	入力の全ての文字が変換に使われたかどうか
 	*/
-	Sub Convert(bytes As *Byte, byteIndex As Long, byteCount As Long,
-		chars As *WCHAR, charIndex As Long, charCount As Long, flush As Boolean,
-		ByRef bytesUsed As Long, ByRef charsUsed As Long, ByRef completed As Boolean)
-
-		If bytes = 0 Then
-			Throw New ArgumentNullException("bytes")
-		ElseIf byteIndex < 0 Then
-			Throw New ArgumentOutOfRangeException("byteIndex")
-		ElseIf byteCount < 0 Then
-			Throw New ArgumentOutOfRangeException("byteCount")
-		ElseIf chars = 0 Then
-			Throw New ArgumentNullException("chars")
-		ElseIf charIndex < 0 Then
-			Throw New ArgumentOutOfRangeException("charIndex")
-		ElseIf charCount < 0 Then
-			Throw New ArgumentOutOfRangeException("charCount")
-		End If
-		ConvertCore(VarPtr(bytes[byteIndex]), byteCount, VarPtr(chars[charIndex]), charCount, flush, bytesUsed, charsUsed, completed)
-	End Sub
-
-	/*!
-	@overload Sub Convert(bytes As *Byte, byteIndex As Long, byteCount As Long,
-		chars As *WCHAR, charIndex As Long, charCount As Long, flush As Boolean,
-		ByRef bytesUsed As Long, ByRef charsUsed As Long, ByRef completed As Boolean)
-	*/
-	Sub Convert(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)
-
-		If bytes = 0 Then
-			Throw New ArgumentNullException("bytes")
-		ElseIf byteCount < 0 Then
-			Throw New ArgumentOutOfRangeException("byteCount")
-		ElseIf chars = 0 Then
-			Throw New ArgumentNullException("chars")
-		ElseIf charCount < 0 Then
-			Throw New ArgumentOutOfRangeException("charCount")
-		End If
-		ConvertCore(bytes, byteCount, chars, charCount, flush, bytesUsed, charsUsed, completed)
+	Sub Convert(src As *Byte, srcCount As Long,
+		dst As *WCHAR, dstCount As Long, flush As Boolean,
+		ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
+
+		If src = 0 Then
+			Throw New ArgumentNullException("src")
+		ElseIf srcCount < 0 Then
+			Throw New ArgumentOutOfRangeException("srcCount")
+		ElseIf dst = 0 Then
+			Throw New ArgumentNullException("dst")
+		ElseIf dstCount < 0 Then
+			Throw New ArgumentOutOfRangeException("dstCount")
+		End If
+		ConvertCore(src, srcCount, dst, dstCount, flush, srcUsed, dstUsed, completed)
 	End Sub
 
 	/*!
 	@brief	変換する
-	@param[in] bytes	入力
-	@param[in] byteIndex 入力開始位置
-	@param[in] byteCount 入力要素数
-	@param[out] chars	出力
-	@param[in] charIndex 出力開始位置
-	@param[in] charCount 出力要素数
+	@param[in] src	入力
+	@param[in] srcCount 入力要素数
+	@param[out] dst	出力
+	@param[in] dstCount 出力要素数
 	@param[in] flush	終了後に内部状態を初期化するかどうか
-	@return	出力の内、実際に書き込まれた要素数
-	*/
-	Function GetChars(bytes As *Byte, byteIndex As Long, byteCount As Long, chars As *WCHAR, charIndex As Long, charCount As Long, flush As Boolean) As Long
-		Dim bytesUsed As Long
+	@return 出力の内、実際に書き込まれた要素数
+	*/
+	Function GetChars(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long, flush As Boolean) As Long
+		Dim srcUsed As Long
 		Dim completed As Boolean
-		Convert(bytes, byteIndex, byteCount, chars, charIndex, charCount, flush, bytesUsed, GetChars, completed)
-	End Function
-
-	/*!
-	@overload Function GetChars(bytes As *Byte, byteIndex As Long, byteCount As Long, chars As *WCHAR, charIndex As Long, charCount As Long, flush As Boolean) As Long
-	*/
-	Function GetChars(bytes As *Byte, byteCount As Long, chars As *WCHAR, charCount As Long, flush As Boolean) As Long
-		Dim bytesUsed As Long
-		Dim completed As Boolean
-		Convert(bytes, byteCount, chars, charCount, flush, bytesUsed, GetChars, completed)
-	End Function
-
-	/*!
-	@overload Function GetChars(bytes As *Byte, byteIndex As Long, byteCount As Long, chars As *WCHAR, charIndex As Long, charCount As Long, flush As Boolean) As Long
-	*/
-	Function GetChars(bytes As *Byte, byteIndex As Long, byteCount As Long, chars As *WCHAR, charIndex As Long, charCount As Long) As Long
-		GetChars = GetChars(bytes, byteIndex, byteCount, chars, charIndex, charCount, False)
-	End Function
-
-	/*!
-	@brief	フォールバックの取得
-	*/
-	Function Fallback() As DecoderFallback
-		Return fallback
-	End Function
-
-	/*!
-	@brief	フォールバックの設定
-	*/
-	Sub Fallback(newFallback As DecoderFallback)
-		If ActiveBasic.IsNothing(newFallback) Then
-			Throw New ArgumentNullException("newFallback")
-		End If
-		fallback = newFallback
-	End Sub
+		Convert(src, srcCount, dst, dstCount, flush, srcUsed, GetChars, completed)
+		If srcUsed < srcCount Then
+			Throw New ArgumentException("src", "buffer is too small")
+		End If
+	End Function
+
+	/*!
+	@brief	変換すると何文字になるか数える
+	@param[in] src	入力
+	@param[in] srcCount 入力要素数
+	@param[in] flush	終了後に内部状態を初期化するとして計算するかどうか
+	@return	必要な文字数
+	*/
+	Function GetCharsCount(src As *Byte, srcCount As Long, flush As Boolean) As Long
+		If src = 0 Then
+			Throw New ArgumentNullException("src")
+		ElseIf srcCount < 0 Then
+			Throw New ArgumentOutOfRangeException("srcCount")
+		End If
+		GetCharsCountCore(src, srcCount, flush)
+	End Function
+
+	/*!
+	@brief	内部状態を初期状態に戻す
+	*/
+	Virtual Sub Reset()
+	End Sub
+
 Protected
 	/*!
-	@brief	実際に変換するメソッド
-	@param[in] bytes	入力
-	@param[in] byteCount 入力要素数
-	@param[out] chars	出力
-	@param[in] charCount 出力要素数
+	@brief	実際に変換する
+	@param[in] src	入力
+	@param[in] srcCount 入力要素数
+	@param[out] dst	出力
+	@param[in] dstCount 出力要素数
 	@param[in] flush	終了後に内部状態を初期化するかどうか
-	@param[out] charsUsed	使用された入力の要素数
-	@param[out] bytesUsed	出力の内、実際に書き込まれた要素数
+	@param[out] dstUsed	使用された入力の要素数
+	@param[out] srcUsed	出力の内、実際に書き込まれた要素数
 	@param[out] completed	入力の全ての文字が変換に使われたかどうか
 	*/
-	Abstract 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)
-
-Private
-	fallback As DecoderFallback
+	Abstract Sub ConvertCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long, flush As Boolean,
+		ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
+
+	/*!
+	@brief	変換すると何文字になるか数える
+	@param[in] src	入力
+	@param[in] srcCount 入力要素数
+	@param[in] flush	終了後に内部状態を初期化するとして計算するかどうか
+	@return	必要な文字数
+	*/
+	Abstract Function GetCharsCountCore(src As *Byte, srcCount As Long, flush As Boolean) As Long
 End Class
 
@@ -644,122 +439,92 @@
 	/*!
 	@brief	変換する
-	@param[in] chars	入力
-	@param[in] charIndex 入力開始位置
-	@param[in] charCount 入力要素数
-	@param[out] bytes	出力
-	@param[in] byteIndex 出力開始位置
-	@param[in] byteCount 出力要素数
+	@param[in] src	入力
+	@param[in] srcCount 入力要素数
+	@param[out] dst	出力
+	@param[in] dstCount 出力要素数
 	@param[in] flush	終了後に内部状態を初期化するかどうか
-	@param[out] charsUsed	使用された入力の要素数
-	@param[out] bytesUsed	出力の内、実際に書き込まれた要素数
+	@param[out] srcUsed	使用された入力の要素数
+	@param[out] dstUsed	出力の内、実際に書き込まれた要素数
 	@param[out] completed	入力の全ての文字が変換に使われたかどうか
 	*/
-	Sub Convert(chars As *WCHAR, charIndex As Long, charCount As Long,
-		bytes As *Byte, byteIndex As Long, byteCount As Long, flush As Boolean,
-		ByRef charsUsed As Long, ByRef bytesUsed As Long, ByRef completed As Boolean)
-
-		If chars = 0 Then
-			Throw New ArgumentNullException("chars")
-		ElseIf charIndex < 0 Then
-			Throw New ArgumentOutOfRangeException("charIndex")
-		ElseIf charCount < 0 Then
-			Throw New ArgumentOutOfRangeException("charCount")
-		ElseIf bytes = 0 Then
-			Throw New ArgumentNullException("bytes")
-		ElseIf byteIndex < 0 Then
-			Throw New ArgumentOutOfRangeException("byteIndex")
-		ElseIf byteCount < 0 Then
-			Throw New ArgumentOutOfRangeException("byteCount")
-		End If
-		ConvertCore(VarPtr(chars[charIndex]), charCount, VarPtr(bytes[byteIndex]), byteCount, flush, charsUsed, bytesUsed, completed)
-	End Sub
-
-	/*!
-	@overload Sub Convert(chars As *WCHAR, charIndex As Long, charCount As Long,
-		bytes As *Byte, byteIndex As Long, byteCount As Long, flush As Boolean,
-		ByRef charsUsed As Long, ByRef bytesUsed As Long, ByRef completed As Boolean)
-	*/
-	Sub Convert(chars As *WCHAR, charCount As Long,
-		bytes As *Byte, byteCount As Long, flush As Boolean,
-		ByRef charsUsed As Long, ByRef bytesUsed As Long, ByRef completed As Boolean)
-
-		If chars = 0 Then
-			Throw New ArgumentNullException("chars")
-		ElseIf charCount < 0 Then
-			Throw New ArgumentOutOfRangeException("charCount")
-		ElseIf bytes = 0 Then
-			Throw New ArgumentNullException("bytes")
-		ElseIf byteCount < 0 Then
-			Throw New ArgumentOutOfRangeException("byteCount")
-		End If
-		ConvertCore(chars, charCount, bytes, byteCount, flush, charsUsed, bytesUsed, completed)
+	Sub Convert(src As *WCHAR, srcCount As Long,
+		dst As *Byte, dstCount As Long, flush As Boolean,
+		ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
+
+		If src = 0 Then
+			Throw New ArgumentNullException("src")
+		ElseIf srcCount < 0 Then
+			Throw New ArgumentOutOfRangeException("srcCount")
+		ElseIf dst = 0 Then
+			Throw New ArgumentNullException("dst")
+		ElseIf dstCount < 0 Then
+			Throw New ArgumentOutOfRangeException("dstCount")
+		End If
+		ConvertCore(src, srcCount, dst, dstCount, flush, srcUsed, dstUsed, completed)
 	End Sub
 
 	/*!
 	@brief	変換する
-	@param[in] chars	入力
-	@param[in] charIndex 入力開始位置
-	@param[in] charCount 入力要素数
-	@param[out] bytes	出力
-	@param[in] byteIndex 出力開始位置
-	@param[in] byteCount 出力要素数
+	@param[in] src	入力
+	@param[in] srcCount 入力要素数
+	@param[out] dst	出力
+	@param[in] dstCount 出力要素数
 	@param[in] flush	終了後に内部状態を初期化するかどうか
-	@return bytesUsed	出力の内、実際に書き込まれた要素数
-	*/
-	Function GetBytes(chars As *WCHAR, charIndex As Long, charCount As Long, bytes As *Byte, byteIndex As Long, byteCount As Long, flush As Boolean) As Long
-		Dim charsUsed As Long
+	@return 出力の内、実際に書き込まれた要素数
+	*/
+	Function GetBytes(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long, flush As Boolean) As Long
+		Dim srcUsed As Long
 		Dim completed As Boolean
-		Convert(chars, charIndex, charCount, bytes, byteIndex, byteCount, flush, charsUsed, GetBytes, completed)
-	End Function
-
-	/*!
-	@overload Function GetBytes(chars As *WCHAR, charIndex As Long, charCount As Long, bytes As *Byte, byteIndex As Long, byteCount As Long, flush As Boolean) As Long
-	*/
-	Function GetBytes(chars As *WCHAR, charCount As Long, bytes As *Byte, byteCount As Long, flush As Boolean) As Long
-		Dim charsUsed As Long
-		Dim completed As Boolean
-		Convert(chars, charCount, bytes, byteCount, flush, charsUsed, GetBytes, completed)
-	End Function
-
-	/*!
-	@overload Function GetBytes(chars As *WCHAR, charIndex As Long, charCount As Long, bytes As *Byte, byteIndex As Long, byteCount As Long, flush As Boolean) As Long
-	*/
-	Function GetBytes(chars As *WCHAR, charIndex As Long, charCount As Long, bytes As *Byte, byteIndex As Long, byteCount As Long) As Long
-		GetBytes = GetBytes(chars, charIndex, charCount, bytes, byteIndex, byteCount, False)
-	End Function
-
-	/*!
-	@brief	フォールバックの取得
-	*/
-	Function Fallback() As EncoderFallback
-		Return fallback
-	End Function
-
-	/*!
-	@brief	フォールバックの設定
-	*/
-	Sub Fallback(newFallback As EncoderFallback)
-		If ActiveBasic.IsNothing(newFallback) Then
-			Throw New ArgumentNullException("newFallback")
-		End If
-		fallback = newFallback
-	End Sub
+		Convert(src, srcCount, dst, dstCount, flush, srcUsed, GetBytes, completed)
+		If srcUsed < srcCount Then
+			Throw New ArgumentException("src", "buffer is too small")
+		End If
+	End Function
+
+	/*!
+	@brief	変換すると何文字になるか数える
+	@param[in] src	入力
+	@param[in] srcCount 入力要素数
+	@param[in] flush	終了後に内部状態を初期化するとして計算するかどうか
+	@return	必要な文字数
+	*/
+	Function GetBytesCount(src As *WCHAR, srcCount As Long, flush As Boolean) As Long
+		If src = 0 Then
+			Throw New ArgumentNullException("src")
+		ElseIf srcCount < 0 Then
+			Throw New ArgumentOutOfRangeException("srcCount")
+		End If
+		GetBytesCountCore(src, srcCount, flush)
+	End Function
+
+	/*!
+	@brief	内部状態を初期状態に戻す
+	*/
+	Virtual Sub Reset()
+	End Sub
+
 Protected
 	/*!
-	@brief	実際に変換するメソッド
-	@param[in] chars	入力
-	@param[in] charCount 入力要素数
-	@param[out] bytes	出力
-	@param[in] byteCount 出力要素数
+	@brief	実際に変換する
+	@param[in] src	入力
+	@param[in] srcCount 入力要素数
+	@param[out] dst	出力
+	@param[in] dstCount 出力要素数
 	@param[in] flush	終了後に内部状態を初期化するかどうか
-	@param[out] bytesUsed	使用された入力の要素数
-	@param[out] charsUsed	出力の内、実際に書き込まれた要素数
+	@param[out] dstUsed	使用された入力の要素数
+	@param[out] srcUsed	出力の内、実際に書き込まれた要素数
 	@param[out] completed	入力の全ての文字が変換に使われたかどうか
 	*/
-	Abstract 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)
-
-Private
-	fallback As EncoderFallback
+	Abstract Sub ConvertCore(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long, flush As Boolean,
+		ByRef dstUsed As Long, ByRef srcUsed As Long, ByRef completed As Boolean)
+
+	/*!
+	@brief	変換すると何文字になるか数える
+	@param[in] src	入力
+	@param[in] srcCount 入力要素数
+	@param[in] flush	終了後に内部状態を初期化するとして計算するかどうか
+	@return	必要な文字数
+	*/
+	Abstract Function GetBytesCountCore(src As *WCHAR, srcCount As Long, flush As Boolean) As Long
 End Class
 
@@ -771,6 +536,136 @@
 End Enum
 
-Class EncoderFallback
+Namespace Detail
+
+/*!
+@brief WideCharToMultiByte/MultiByteToWideCharで変換を行うエンコーディング。
+DBCS/SBCS限定。UTF-8やUTF-7は非対応。
+*/
+Class WindowsCodePageEncoding
+	Inherits Encoding
+Public
+	Sub WindowsCodePageEncoding(codepage As DWord)
+		cp = codepage
+	End Sub
+
+	/*!
+	@brief	符号器を取得する。
+	*/
+	Override Function GetDecoder() As Decoder
+		GetDecoder = New WindowsCodePageDecoder(cp)
+	End Function
+
+	/*!
+	@brief	復号器を取得する。
+	*/
+	Override Function GetEncoder() As Encoder
+		GetEncoder = New WindowsCodePageEncoder(cp)
+	End Function
+
+	Override Function GetHashCode() As Long
+		GetHashCode = cp As Long
+	End Function
+
+	Override Function Equals(x As Object) As Boolean
+		If GetType().Equals(x.GetType()) Then
+			Dim xe = x As WindowsCodePageEncoding
+			Equals = cp = xe.cp
+		Else
+			Equals = False
+		End If
+	End Function
+
+	/*!
+	@brief	ある長さの文字列を符号化して得られるバイト列の最大の長さを返す。
+	*/
+	Override Function GetMaxByteCount(srcCount As Long) As Long
+		GetMaxByteCount = srcCount * 2
+	End Function
+
+	/*!
+	@brief	ある長さのバイト列を復号して得られる文字列の最大の長さを返す。
+	*/
+	Override Function GetMaxCharCount(srcCount As Long) As Long
+		GetMaxCharCount = srcCount
+	End Function
+
+Private
+	cp As DWord
 End Class
+
+Class WindowsCodePageEncoder
+	Inherits Encoder
+Public
+	Sub WindowsCodePageEncoder(codepage As DWord)
+		cp = codepage
+	End Sub
+
+	Override Sub Reset()
+		nextByte = 0
+	End Sub
+
+Protected
+	Override Sub ConvertCore(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long, flush As Boolean,
+		ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
+
+		Dim srcPos = 0 As Long
+		Dim dstPos = 0 As Long
+		If dstCount > 0 And nextByte <> 0 Then
+			dst[0] = nextByte
+			nextByte = 0
+			dstPos++
+		End If
+		While srcPos < srcCount And dstPos < srcCount
+			Dim buf[1] As CHAR
+			Dim len = WideCharToMultiByte(cp, WC_COMPOSITECHECK Or WC_DEFAULTCHAR, VarPtr(src[srcPos]), 1, buf, Len(buf), 0, 0)
+			If len = 0 Then
+				ActiveBasic.Windows.ThrowWithLastError()
+			End If
+			dst[dstPos] = buf[0] As Byte
+			If len = 2 Then
+				If dstCount = 1 Then
+					nextByte = buf[1] As Byte
+					Exit While
+				End If
+				dstPos++
+				dst[dstPos] = buf[1] As Byte
+				nextByte = 0
+			End If
+			srcPos++
+			dstPos++
+		Wend
+		srcUsed = srcPos
+		dstUsed = dstPos
+		completed = (srcPos = srcCount And dstPos = srcCount And nextByte = 0)
+	End Sub
+
+	Override Function GetBytesCountCore(src As *WCHAR, srcCount As Long, flush As Boolean) As Long
+	End Function
+
+Private
+	cp As DWord
+	nextByte As Byte
+End Class
+
+Class WindowsCodePageDecoder
+	Inherits Decoder
+Public
+	Sub WindowsCodePageDecoder(codepage As DWord)
+		cp = codepage
+	End Sub
+
+Protected
+	Override Sub ConvertCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long, flush As Boolean,
+		ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
+	End Sub
+
+	Override Function GetCharsCountCore(src As *Byte, srcCount As Long, flush As Boolean) As Long
+	End Function
+
+Private
+	cp As DWord
+End Class
+
+End Namespace
 
 End Namespace 'Text
