'Classes/System/IO/StreamReader.ab Namespace System Namespace IO /* @brief ストリームから読み取りを行うTextReaderの実装。 @date 2008/02/25 @auther Egtra */ Class StreamReader Inherits TextReader Public /* @date 2008/02/25 @auther Egtra */ Sub StreamReader(path As String) init(New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) End Sub /* @date 2008/02/25 @auther Egtra */ Sub StreamReader(stream As Stream) init(stream) End Sub /* @date 2008/02/25 @auther Egtra */ Override Function Peek() As Long If cur = last Then last = s.Read(buf, 0, size) cur = 0 If last = 0 Then Peek = -1 Exit Function End If End If Peek = buf[cur] End Function /* @date 2008/02/25 @auther Egtra */ Override Function Read() As Long Read = Peek() If Read <> -1 Then cur++ End If End Function /* @date 2008/02/26 @auther Egtra */ Override Function ReadToEnd() As String Dim sb = New Text.StringBuilder(65536) sb.Append(buf, cur, last - cur) Do Dim read = Read(buf, 0, size) sb.Append(buf, 0, read) If read < size Then ReadToEnd = sb.ToString Exit Function End If Loop End Function Protected /* @date 2008/02/25 @auther Egtra */ Override Sub Dispose(disposing As Boolean) If disposing Then If Not ActiveBasic.IsNothing(s) Then s.Dispose(True) End If End If s = Nothing size = 0 cur = 0 last = 0 End Sub /* @date 2008/02/25 @auther Egtra */ Override Function ReadImpl(buffer As *StrChar, index As Long, count As Long) As Long Dim n = last - cur If count <= n Then ReadImpl = ReadFromBuffer(buffer, index, count) Exit Function End If Dim p = VarPtr(buffer[index]) ReadImpl = ReadFromBuffer(p, 0, n) If ReadImpl = count Then 'バッファの中身で足りた場合 Exit Function End If p = VarPtr(p[n]) count -= n If count > size Then n = (count \ size) * size 'sizeの倍数分だけは直接bufferへ読み込ませる Dim read = s.Read(p, 0, n) If read = 0 Then 'EOF Exit Function End If p = VarPtr(p[n]) ReadImpl += n count -= n End If last = s.Read(buffer, 0, size) cur = 0 If last = 0 Then 'EOF Exit Function End If ReadImpl += ReadFromBuffer(p, 0, Math.Min(last, count)) End Function Private /* @date 2008/02/25 @auther Egtra */ Sub init(str As Stream) s = str size = 4096 last = 0 cur = 0 buf = GC_malloc(size) End Sub /** @brief バッファの中身から読み取る。 @date 2008/02/25 @auther Egtra 文字数が足りなくても、元のストリームまで読みには行かない。 */ Function ReadFromBuffer(p As *StrChar, index As Long, count As Long) As Long memcpy(VarPtr(p[index]), VarPtr(buf[cur]), count * SizeOf (StrChar)) cur += count ReadFromBuffer = count End Function s As Stream size As Long cur As Long last As Long '中身の終わり buf As *SByte '暫定 End Class End Namespace End Namespace