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

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

Location:
trunk/Include/Classes/System
Files:
4 edited

Legend:

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

    r391 r426  
    7676
    7777        op = options As DWord
    78         If Not Environment.OSVersion.Platform = PlatformID.Win32NT Then
     78'       If (Environment.OSVersion.Platform As DWord) <> (PlatformID.Win32NT As DWord) Then 'ToDo: なぜかアクセス違反になる
    7979            op And= Not FILE_FLAG_OVERLAPPED
    80         End If
     80'       End If
    8181
    8282        This.handle=CreateFile(ToTCStr(path),ac,sh,ByVal NULL,mo,op,0)
     
    305305    End Sub
    306306
    307     Override Function Read( buffer As *Byte, offset As Long, count As Long) As Long
     307    Override Function Read(buffer As *Byte, offset As Long, count As Long) As Long
    308308        disposedCheck()
    309309        If buffer = 0 Then
    310 '           Throw ArgumentNullException("FileStream.Read: An argument is null value.", "buffer")
     310            Throw New ArgumentNullException("FileStream.Read: An argument is null value.", "buffer")
    311311        ElseIf Not This.CanRead() Then
    312 '           Throw NotSupportedException("FileStream.Read: This stream is not readable.")
     312            Throw New NotSupportedException("FileStream.Read: This stream is not readable.")
    313313        End If
    314314
     
    320320            overlapped.hEvent = CreateEvent(0, TRUE, FALSE, 0)
    321321            If overlapped.hEvent = 0 Then
    322 '               Throw OutOfMemoryException("FileStream.Read: Failed to create an event object.")
     322                Throw New OutOfMemoryException("FileStream.Read: Failed to create an event object.")
    323323            End If
    324324            Try
     
    327327                    Dim error = GetLastError()
    328328                    If error <> ERROR_IO_PENDING Then
    329 '                       Detail.ThrowWinIOException("FileStream.Read: Failed to read.", error)
     329                        Detail.ThrowWinIOException("FileStream.Read: Failed to read.", error)
    330330                    End If
    331331                End If
    332332                ret = GetOverlappedResult(This.handle, overlapped, readBytes, TRUE)
    333333                If ret = FALSE Then
    334 '                   Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.")
     334                    Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.")
    335335                End If
    336336                offset += Read
     
    341341            ret = ReadFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(readBytes),ByVal NULL)
    342342            If ret = FALSE Then
    343 '               Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.")
     343                Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.")
    344344            End If
    345345        End If
  • 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
  • trunk/Include/Classes/System/IO/TextReader.ab

    r420 r426  
    66
    77Public
    8     Virtual Sub TextReader()    :End Sub
    9     Virtual Sub ~TextReader()   :End Sub
     8'Protected
     9    Sub TextReader()
     10    End Sub
     11Public
     12    Virtual Sub ~TextReader()
     13        Dispose(False)
     14    End Sub
    1015
    11 /* Null*/
     16'   Static Null = StreamReader.Null As TextReader
    1217
    1318Public
    14     Virtual Sub Close()
    15         This.Dispose()
     19    Sub Close()
     20        Dispose(True)
    1621    End Sub
    17 /*  CreateObjRef*/
    18 /*  Dispose*/
    19 /*  Equals*/
    20 /*  GetHashCode*/
    21 /*  GetLifetimeService*/
    22 /*  GetType*/
    23 /*  InitializeLifetimeService*/
     22
     23    Sub Dispose()
     24        Dispose(True)
     25    End Sub
     26
     27    Abstract Sub Dispose(disposing As Boolean)
     28
    2429    Abstract Function Peek() As Long
    2530    Abstract Function Read() As Long
    26     Abstract Function Read(buffer As LPTSTR, index As Long, count As Long) As Long
    27     Abstract Function ReadBlock(buffer As LPTSTR, index As Long, count As Long) As Long
     31    Abstract Function Read(buffer As *StrChar, index As Long, count As Long) As Long
     32    Virtual Function ReadBlock(buffer As *StrChar, index As Long, count As Long) As Long
     33        ReadBlock = Read(buffer, index, count)
     34    End Function
    2835    Abstract Function ReadLine() As String
    2936    Abstract Function ReadToEnd() As String
    30 /*  ReferenceEquals*/
    31 /*  Synchronized*/
    32 /*  ToString*/
    33 /*  Dispose*/
    34 /*  Finalize*/
    35 /*  MemberwiseClone*/
    3637End Class
    3738
  • trunk/Include/Classes/System/String.ab

    r400 r426  
    117117
    118118        Const Function Operator + (y As PCSTR) As String
    119             Return Concat(y, lstrlenA(y))
     119            If y = 0 Then
     120                Return This
     121            Else
     122                Return Concat(y, lstrlenA(y))
     123            End If
    120124        End Function
    121125
    122126        Const Function Operator + (y As PCWSTR) As String
    123             Return Concat(y, lstrlenW(y))
     127            If y = 0 Then
     128                Return This
     129            Else
     130                Return Concat(y, lstrlenW(y))
     131            End If
    124132        End Function
    125133
    126134        Const Function Operator + (y As String) As String
    127             Return Concat(y.Chars, y.m_Length)
     135            If ActiveBasic.IsNothing(y) Then
     136                Return This
     137            Else
     138                Return Concat(y.Chars, y.m_Length)
     139            End If
    128140        End Function
    129141
     
    133145
    134146        Const Function Operator & (y As PCWSTR) As String
    135             Dim tempString = This + y
    136             Return tempString
     147            Return This + y
    137148        End Function
    138149
    139150        Const Function Operator & (y As String) As String
    140             Dim tempString = This + y
    141             Return tempString
     151            Return This + y
    142152        End Function
    143153
Note: See TracChangeset for help on using the changeset viewer.