/*
@file Include/Classes/System/IO/StreamWriter.ab
@brief StreamWriterの実装。
*/

Namespace System
Namespace IO

/*
@brief ストリームへの書き込みを行うTextWriterの派生。
@date 2008/03/09
@auther Egtra
*/
Class StreamWriter
	Inherits TextWriter
Public
	/*
	@date 2008/03/09
	@auther Egtra
	*/
	Sub StreamWriter(path As String)
		init(New FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None), Nothing)
	End Sub

	/*
	@date 2008/03/09
	@auther Egtra
	*/
	Sub StreamWriter(stream As Stream)
		init(stream, Nothing)
	End Sub

	/*
	@date 2009/02/16
	@auther Egtra
	*/
	Sub StreamWriter(stream As Stream, encoding As Text.Encoding)
		init(stream, encoding)
	End Sub

	/*
	@brief 基になるストリームを取得する
	@date 2008/09/02
	@auther NoWest
	*/
	Function BaseStream () As System.IO.Stream
		Return s
	End Function

	Override Sub Flush()
		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)
#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

Protected
	Override Sub Dispose(disposing As Boolean)
		If disposing Then
			Flush(True)
			s.Dispose()
		End If
	End Sub

Private
	Sub init(stream As Stream, e As Text.Encoding)
		s = stream
		buf = New Text.StringBuilder(4096)
		If ActiveBasic.IsNothing(e) Then
			'暫定。正式版ではUTF-8を標準とする。
			encoder = New Text.Detail.WindowsCodePageEncoder(CP_ACP)
		Else
			encoder = e.GetEncoder()
		End If
	End Sub

	encoder As Text.Encoder
	s As System.IO.Stream
End Class

End Namespace
End Namespace
