Ignore:
Timestamp:
Feb 26, 2008, 3:33:49 AM (16 years ago)
Author:
イグトランス (egtra)
Message:

StreamReaderの実装開始。
Stringの+演算子で右辺がNullのときに起こるアクセス違反を回避。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Include/Classes/System/IO/StreamReader.ab

    r420 r426  
    22Namespace IO
    33
     4Class StreamReader
     5    Inherits TextReader
     6Public
     7    Sub StreamReader(path As String)
     8        init(New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
     9    End Sub
    410
    5 Class StreamReader
    6     Inherits System.IO.TextReader
    7     ' TODO: 実装
     11    Sub StreamReader(stream As Stream)
     12        init(stream)
     13    End Sub
     14
     15    Override Sub Dispose(disposing As Boolean)
     16        s.Dispose(disposing)
     17        size = 0
     18        cur = 0
     19        last = 0
     20    End Sub
     21
     22    Override Function Peek() As Long
     23        If cur = last Then
     24            last = s.Read(buf, 0, size)
     25            cur = 0
     26            If last = 0 Then
     27                Peek = -1
     28                Exit Function
     29            End If
     30        End If
     31        Peek = buf[cur]
     32    End Function
     33
     34    Override Function Read() As Long
     35        Read = Peek()
     36        cur++
     37    End Function
     38
     39    Override Function Read(buffer As *StrChar, index As Long, count As Long) As Long
     40        If buffer = 0 Then
     41        ElseIf index < 0 Then
     42        ElseIf count < 0 Then
     43        End If
     44
     45        Dim n = last - cur
     46        If count <= n Then
     47            Read = ReadFromBuffer(buffer, index, count)
     48            Exit Function
     49        End If
     50        Dim p = VarPtr(buffer[index])
     51        Read = ReadFromBuffer(p, 0, n)
     52        If Read = count Then 'バッファの中身で足りた場合
     53            Exit Function
     54        End If
     55        p = VarPtr(p[n])
     56        count -= n
     57        If count > size Then
     58            n = (count \ size) * size 'sizeの倍数分だけは直接bufferへ読み込ませる
     59            Dim read = s.Read(p, 0, n)
     60            If read = 0 Then 'EOF
     61                Exit Function
     62            End If
     63            p = VarPtr(p[n])
     64            Read += n
     65            count -= n
     66        End If
     67        last = s.Read(buffer, 0, size)
     68        cur = 0
     69        If last = 0 Then 'EOF
     70            Exit Function
     71        End If
     72        Read += ReadFromBuffer(p, 0, Math.Min(last, count))
     73    End Function
     74
     75    Override Function ReadLine() As String
     76        Dim sb = New Text.StringBuilder(256)
     77        Do
     78            Dim ch = Read()
     79            If ch = &h0D Then
     80                If Peek() = &h0A Then
     81                    Read() 'CR LFの場合
     82                End If
     83                Exit Do
     84            End If
     85            Select Case ch
     86                Case -1 'EOF
     87                    Exit Do
     88                Case &h0A 'LF
     89                    Exit Do
     90                Case &h0B 'VT
     91                    Exit Do
     92                Case &h0C 'FF
     93                    Exit Do
     94                Case &h0D 'CR
     95                    Exit Do
     96'               Case &h85 'NEL
     97'                   Exit Do
     98'               Case &h2028 'LS
     99'                   Exit Do
     100'               Case &h2029 'PS
     101'                   Exit Do
     102            End Select
     103            sb.Append(ch As StrChar) 'ToDo キャスト不要にすべきというチケットを書くこと
     104        Loop
     105        ReadLine = sb.ToString
     106    End Function
     107
     108    Override Function ReadToEnd() As String
     109    End Function
     110
     111Private
     112    Sub init(str As Stream)
     113        s = str
     114        size = 4096
     115        last = 0
     116        cur = 0
     117        buf = GC_malloc(size)
     118    End Sub
     119
     120    /**
     121    @brief バッファの中身から読み取る。
     122    文字数が足りなくても、元のストリームまで読みには行かない。
     123    */
     124    Function ReadFromBuffer(p As *StrChar, index As Long, count As Long) As Long
     125        memcpy(VarPtr(p[index]), VarPtr(buf[cur]), count * SizeOf (StrChar))
     126        cur += count
     127        ReadFromBuffer = count
     128    End Function
     129
     130    s As Stream
     131    size As Long
     132    cur As Long
     133    last As Long '中身の終わり
     134    buf As *Byte '暫定
    8135End Class
    9 
    10136
    11137End Namespace
Note: See TracChangeset for help on using the changeset viewer.