/*!
@file	Classes/System/IO/Fallback.ab
@date	2007/12/09
*/

Namespace System
Namespace Text

/*!
@brief	復号時、復号できないバイト並びに遭遇したときの処理を提供する
@date	2007/12/09
@auther	Egtra
*/
Class DecoderFallback
Public
	/*!
	@brief	フォールバックを行う
	@param[in] bytesUnknown	復号中の文字列
	@param[in] len	bytesUnknownの要素数
	@param[in] index	問題の列の開始位置
	@param[out] bufLen	戻り値の要素数
	@return フォールバック文字列
	*/
	Abstract Function Fallback(bytesUnknown As *Byte, len As Long, index As Long, ByRef bufLen As Long) As *WCHAR

	/*!
	@brief	このDecoderFallbackの処理で生成される可能性のある最大の文字列の長さを返す。
	*/
	Abstract Function MaxCharCount() As Long

	/*!
	@brief	フォールバックとして、例外を投げるDecoderFallbackを返す。
	@bug	未実装
	*/
	Static Function ExceptionFallback() As DecoderFallback
	End Function

	/*!
	@brief	フォールバックとして、適当な文字に変換するDecoderFallbackを返す。
	*/
	Static Function ReplacementFallback() As DecoderFallback
		ReplacementFallback = replacementFallback
	End Function

Private
	Static replacementFallback = New DecoderReplacementFallback
End Class

/*!
@brief	復号時、復号できないバイト並びに遭遇したときの処理を提供する
@date	2007/12/09
@auther	Egtra
*/
Class DecoderReplacementFallback
	Inherits DecoderFallback
Public
	/*!
	@brief	既定のフォールバック文字列でDecoderReplacementFallbackを構築する。
	*/
	Sub DecoderReplacementFallback()
		str = VarPtr(default)
		len = 1
	End Sub

	/*!
	@brief	指定された文字列でDecoderReplacementFallbackを構築する。
	@param[in] replacement	代替文字列
	@param[in] length	replacementの長さ
	*/
	Sub DecoderReplacementFallback(replacement As *WCHAR, length As Long)
		If replacement = 0 Then
			Throw New ArgumentNullException("replacement")
		ElseIf length < 0 Then
			Throw New ArgumentOutOfRangeException("length")
		End If
		str = replacement
		len = length
	End Sub
#ifdef UNICODE
	/*!
	@brief	指定された文字列でDecoderReplacementFallbackを構築する。
	@param[in] replacement	代替文字列
	*/
	Sub DecoderReplacementFallback(replacement As String)
		If ActiveBasic.IsNothing(replacement) Then
			Throw New ArgumentNullException("replacement")
		End If
		With replacement
			str = .StrPtr
			len = .Length
		End With
	End Sub
#endif
	/*!
	@brief	フォールバックを行う。
	*/
	Override Function Fallback(bytesUnknown As *Byte, bytesLen As Long, index As Long, ByRef bufLen As Long) As *WCHAR
		bufLen = len
		Dim bufSize = len * SizeOf (WCHAR)
		Fallback = GC_malloc_atomic(bufSize)
		memcpy(Fallback, str, bufSize)
	End Function
	/*!
	@brief	このDecoderFallbackの処理で生成される可能性のある最大の文字列の長さを返す。
	*/
	Override Function MaxCharCount() As Long
		MaxCharCount = len
	End Function
	/*!
	@brief	代替文字列を返す
	@return	代替文字列へのポインタ
	
	長さはDefaultStringLengthで得られる
	*/
	Function DefaultStringArray() As *WCHAR
		DefaultStringArray = str
	End Function

	/*!
	@brief	代替文字列の長さを返す
	*/
	Function DefaultStringLength() As Long
		DefaultStringLength = len
	End Function

#ifdef UNICODE
	/*!
	@brief	代替文字列を返す
	@return	代替文字列
	*/
	Function DefaultString() As String
		DefaultString = New String(str, len)
	End Function
#endif

Private
	str As *WCHAR
	len As Long

	Static default = &h3f As WCHAR '? 疑問符
End Class

/*!
@brief	
@date	2007/12/27
@auther	Egtra
*/
Class DecoderExceptionFallback
	Inherits DecoderFallback
Public
	/*!
	@brief
	*/
	Sub DecoderExceptionFallback()
	End Sub

	/*!
	@brief	指定された文字列でDecoderReplacementFallbackを構築する。
	@param[in] replacement	代替文字列
	@param[in] length	replacementの長さ
	*/
	Sub DecoderReplacementFallback(replacement As *WCHAR, length As Long)
		If replacement = 0 Then
			Throw New ArgumentNullException("replacement")
		ElseIf length < 0 Then
			Throw New ArgumentOutOfRangeException("length")
		End If
	End Sub
#ifdef UNICODE
	/*!
	@brief	指定された文字列でDecoderReplacementFallbackを構築する。
	@param[in] replacement	代替文字列
	*/
	Sub DecoderReplacementFallback(replacement As String)
		If ActiveBasic.IsNothing(replacement) Then
			Throw New ArgumentNullException("replacement")
		End If
		With replacement
			str = .StrPtr
			len = .Length
		End With
	End Sub
#endif
	/*!
	@brief	フォールバックを行う。
	@exception DecoderFallbackException
	*/
	Override Function Fallback(bytesUnknown As *Byte, bytesLen As Long, index As Long, ByRef bufLen As Long) As *WCHAR
		'Throw New DecoderFallbackException
	End Function

	/*!
	@brief	このDecoderFallbackの処理で生成される可能性のある最大の文字列の長さを返す。
	@return	常に0
	*/
	Override Function MaxCharCount() As Long
		MaxCharCount = 0
	End Function
End Class

/*!
@brief	DecoderExceptionFallbackでフォールバックが起こった時に投げられる例外
@date	2007/12/27
@auther Egtra
*/
Class DecoderFallbackException
	Inherits ArgumentException
Public
	Sub DecoderFallbackException()

	End Sub

	Sub DecoderFallbackException(message As String)
	End Sub

	Sub DecoderFallbackException(message As String, innerException As Exception)
	End Sub

'bytesの大きさはどうしよう
	Sub DecoderFallbackException(message As String, bytesUnknown As *Byte, index As Long)
	End Sub


End Class

End Namespace 'Text
End Namespace 'System
