NameSpace System
NameSpace IO

Class TextReader
	Implements System.IDisposable

Public
'Protected
	Sub TextReader()
	End Sub
Public
	Virtual Sub ~TextReader()
		Dispose(False)
	End Sub

'	Static Null = StreamReader.Null As TextReader

Public
	Sub Close()
		Dispose(True)
	End Sub

	Sub Dispose()
		Dispose(True)
	End Sub

	Abstract Function Peek() As Long
	Abstract Function Read() As Long
	/*
	@date 2008/02/26
	@auther Egtra
	*/
	Function Read(buffer As *Char, index As Long, count As Long) As Long
		If buffer = 0 Then
		ElseIf index < 0 Then
		ElseIf count < 0 Then
		End If
		Read = ReadImpl(buffer, index, count)
	End Function

	/*
	@date 2008/02/26
	@auther Egtra
	@retval Nothing EOFに達しているとき
	@retval 有効なStringインスタンス 読み取った1行
	*/
	Virtual Function ReadLine() As String
		If Peek() = -1 Then
			Exit Function
		End If
		Dim sb = New Text.StringBuilder(256)
		Do
			Dim ch = Read()
			If ch = &h0D Then
				If Peek() = &h0A Then
					Read() 'CR LFの場合
				End If
				Exit Do
			End If
			Select Case ch
				Case -1 'EOF
					Exit Do
				Case &h0A 'LF
					Exit Do
				Case &h0B 'VT
					Exit Do
				Case &h0C 'FF
					Exit Do
				Case &h0D 'CR
					Exit Do
'				Case &h85 'NEL
'					Exit Do
'				Case &h2028 'LS
'					Exit Do
'				Case &h2029 'PS
'					Exit Do
			End Select
			sb.Append(ch As Char) 'ToDo キャスト不要にすべきというチケットを書くこと
		Loop
		ReadLine = sb.ToString
	End Function
	/*
	@brief 現在位置からストリームの終わりまで読み込む。
	@date 2008/02/26
	@auther Egtra
	*/
	Virtual Function ReadToEnd() As String
		Dim sb = New Text.StringBuilder(8192)
		Do
			Dim ch = Read()
			If ch = -1 Then
				ReadToEnd = sb.ToString
				Exit Function
			End If
			sb.Append(ch As Char)
		Loop
	End Function

	Static Function Synchronized(reader As TextReader) As TextReader
		Synchronized = New Detail.SynchronizedTextReader(reader)
	End Function

Protected
	Virtual Sub Dispose(disposing As Boolean)
	End Sub

	/*
	@date 2008/02/26
	@auther Egtra
	*/
	Virtual Function ReadImpl(buffer As *Char, index As Long, count As Long) As Long
		Dim i As Long
		Dim p = VarPtr(buffer[index])
		For i = 0 To ELM(count)
			Dim c = Read()
			If c = -1 Then
				ReadImpl = i - 1
				Exit Function
			Else
				p[i] = c As Char
			End If
		Next
		ReadImpl = i - 1
	End Function
End Class

Namespace Detail

Class SynchronizedTextReader
	Inherits TextReader
Public
	Sub SynchronizedTextReader(reader As TextReader)
		cs = New ActiveBasic.Windows.CriticalSection
		base = reader
	End Sub

	Override Function Peek() As Long
'		Using lock = cs.Lock
			Peek = base.Peek
'		End Using
	End Function

	Override Function Read() As Long
'		Using lock = cs.Lock
			Read = base.Read
'		End Using
	End Function

	Override Function ReadLine() As String
'		Using lock = cs.Lock
			ReadLine = base.ReadLine
'		End Using
	End Function

	Override Function ReadToEnd() As String
'		Using lock = cs.Lock
			ReadToEnd = base.ReadToEnd
'		End Using
	End Function

Protected
	Override Sub Dispose(disposing As Boolean)
		Dim s = Nothing As Stream
		SetPointer(VarPtr(s) As *VoidPtr, InterlockedExchangePointer(ByVal VarPtr(base) As *VoidPtr, 0))
		If disposing Then
			If Not ActiveBasic.IsNothing(s) Then
				s.Dispose()
			End If
			cs.Dispose()
		End If
	End Sub

	Override Function ReadImpl(buffer As *Char, index As Long, count As Long) As Long
'		Using lock = cs.Lock
			ReadImpl = base.ReadImpl(buffer, index, count)
'		End Using
	End Function
Private
	cs As ActiveBasic.Windows.CriticalSection
	base As TextReader
End Class

End Namespace

End NameSpace
End NameSpace
