Namespace System Namespace IO Class TextReader Implements System.IDisposable 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 Virtual Function Peek() As Long If pos >= buf.Length Then If Not Underflow() Then Peek = -1 Exit Function End If End If Peek = buf[pos] End Function Virtual Function Read() As Long Read = Peek() pos++ End Function /* @date 2008/02/26 @auther Egtra */ Virtual Function Read(buffer As *Char, index As Long, count As Long) As Long If buffer = 0 Then Throw New ArgumentNullException("buffer") ElseIf index < 0 Then Throw New ArgumentOutOfRangeException("index") ElseIf count < 0 Then Throw New ArgumentOutOfRangeException("count") End If Read = ReadImpl(VarPtr(buffer[index]), count) End Function Static Function Synchronized(reader As TextReader) As TextReader Synchronized = New Detail.SynchronizedTextReader(reader) 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 Dim isLead = FALSE Do Dim ch = Read() If ch = -1 Then Exit Do If isLead = FALSE Then 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 #ifdef UNICODE Case &h85 'NEL Exit Do Case &h2028 'LS Exit Do Case &h2029 'PS Exit Do #endif End Select End If sb.Append(ch As Char) #ifndef UNICODE isLead = IsDBCSLeadByte(ch As Byte) #endif Loop ReadLine = sb.ToString() End Function /*! @brief 現在位置からストリームの終わりまで読み込む。 @date 2008/02/26 @auther Egtra */ Virtual Function ReadToEnd() As String buf.Remove(0, pos) While Underflow() Wend ReadToEnd = buf.ToString() End Function Protected Sub TextReader() buf = New Text.StringBuilder pos = 0 End Sub Virtual Sub Dispose(disposing As Boolean) End Sub /*! @brief バッファが足りなくなったときに呼ばれる。 @date 2008/12/27 @auther Egtra @retval True まだEOFに達していない場合 @retval False EOFに達した場合 */ Virtual Function Underflow() As Boolean Underflow = False End Function /*! @brief 内部バッファを返す @date 2008/12/27 @auther Egtra @return 内部バッファ */ Function Buffer() As Text.StringBuilder Buffer = buf End Function /*! @date 2008/02/26 @auther Egtra */ Function ReadImpl(buffer As *Char, count As Long) As Long Dim p = StrPtr(buf) While buf.Length - pos < count If Underflow() = False Then Exit While Wend ReadImpl = Math.Min(buf.Length - pos, count) ActiveBasic.Strings.ChrCopy(buffer, VarPtr(p[buf]), ReadImpl As SIZE_T) pos += ReadImpl End Function Private buf As Text.StringBuilder pos As Long 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 Read(buffer As *Char, index As Long, count As Long) As Long ' Using lock = cs.Lock() Read = base.Read(buffer, index, count) ' 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 Private cs As ActiveBasic.Windows.CriticalSection base As TextReader End Class End Namespace End Namespace End Namespace