Ignore:
Timestamp:
Nov 9, 2008, 2:21:49 PM (15 years ago)
Author:
イグトランス (egtra)
Message:

#161完了。StreamReaderのUnicode対応。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/ablib/src/Classes/System/IO/StreamReader.ab

    r627 r655  
    4343    */
    4444    Override Function Peek() As Long
    45         If cur = last Then
    46             last = s.Read(buf As *Byte, 0, size)
    47             cur = 0
    48             If last = 0 Then
     45        If charSize = charCur Then
     46            fillCharBuf()
     47            If charSize = charCur Then
    4948                Peek = -1
    5049                Exit Function
    5150            End If
    5251        End If
    53         Peek = buf[cur]
     52        Peek = charBuf[charCur]
    5453    End Function
    5554
     
    6160        Read = Peek()
    6261        If Read <> -1 Then
    63             cur++
     62            charCur++
    6463        End If
    65     End Function
    66 
    67     /*
    68     @date 2008/02/26
    69     @auther Egtra
    70     */
    71     Override Function ReadToEnd() As String
    72         Dim sb = New Text.StringBuilder(65536)
    73         sb.Append(buf, cur, last - cur)
    74         Do
    75             Dim read = Read(buf, 0, size)
    76             sb.Append(buf, 0, read)
    77             If read < size Then
    78                 ReadToEnd = sb.ToString
    79                 Exit Function
    80             End If
    81         Loop
    8264    End Function
    8365
     
    9476        End If
    9577        s = Nothing
    96         size = 0
    97         cur = 0
    98         last = 0
    9978    End Sub
    10079
     
    10382    @auther Egtra
    10483    */
    105     Override Function ReadImpl(buffer As *Char, index As Long, count As Long) As Long
    106         Dim n = last - cur
    107         If count <= n Then
    108             ReadImpl = ReadFromBuffer(buffer, index, count)
     84    Override Function ReadImpl(buffer As *WCHAR, count As Long) As Long
     85        Dim n = charSize - charCur '現在のバッファに溜まっている文字数
     86        If count <= n And charEof <> False Then
     87            ReadImpl = readFromBuffer(buffer, count)
    10988            Exit Function
    11089        End If
    111         Dim p = VarPtr(buffer[index])
    112         ReadImpl = ReadFromBuffer(p, 0, n)
     90        ReadImpl = readFromBuffer(buffer, n)
    11391        If ReadImpl = count Then 'バッファの中身で足りた場合
    11492            Exit Function
    11593        End If
    116         p = VarPtr(p[n])
    117         count -= n
    118         If count > size Then
    119             n = (count \ size) * size 'sizeの倍数分だけは直接bufferへ読み込ませる
    120             Dim read = s.Read(p As *Byte, 0, n)
    121             If read = 0 Then 'EOF
    122                 Exit Function
    123             End If
    124             p = VarPtr(p[n])
    125             ReadImpl += n
    126             count -= n
    127         End If
    128         last = s.Read(buffer As *Byte, 0, size)
    129         cur = 0
    130         If last = 0 Then 'EOF
    131             Exit Function
    132         End If
    133         ReadImpl += ReadFromBuffer(p, 0, Math.Min(last, count))
     94        fillCharBuf()
     95        ReadImpl += ReadImpl(VarPtr(buffer[n]), count - n)
    13496    End Function
    13597
     
    141103    Sub init(str As Stream)
    142104        s = str
    143         size = 4096
    144         last = 0
    145         cur = 0
    146         buf = GC_malloc(size)
     105        '暫定。正式版ではUTF-8を標準とする。
     106        encoding = New Text.Detail.WindowsCodePageEncoding(CP_ACP)
     107        decoder = encoding.GetDecoder()
     108        charCapacity = 4096
     109        byteCapacity = 4096
     110        charBuf = GC_malloc(charCapacity * SizeOf(WCHAR))
     111        byteBuf = GC_malloc(byteCapacity)
     112        charCur = 0
     113        byteCur = 0
     114        charSize = 0
     115        byteSize = 0
     116        charEof = False
     117        byteEof = False
    147118    End Sub
    148119
     
    153124    文字数が足りなくても、元のストリームまで読みには行かない。
    154125    */
    155     Function ReadFromBuffer(p As *Char, index As Long, count As Long) As Long
    156         memcpy(VarPtr(p[index]), VarPtr(buf[cur]), count * SizeOf (Char))
    157         cur += count
    158         ReadFromBuffer = count
     126    Function readFromBuffer(p As *WCHAR, count As Long) As Long
     127        memcpy(p, VarPtr(charBuf[charCur]), count * SizeOf (WCHAR))
     128        charCur += count
     129        readFromBuffer = count
    159130    End Function
    160131
     132    /*!
     133    @brief byteBufを基にcharBufを埋める。charBufが空になったときに用いる。
     134    @date 2008/11/08
     135    @auther Egtra
     136    */
     137    Sub fillCharBuf()
     138        charCur = 0
     139        charSize = 0
     140        If charEof = False Then
     141            If byteCur = byteSize Then
     142                byteSize = s.Read(byteBuf, 0, byteCapacity)
     143                byteCur = 0
     144                If byteSize = 0 Then
     145                    byteEof = True
     146                End If
     147            End If
     148            Dim charUsed As Long
     149            Dim byteUsed As Long
     150            decoder.Convert(VarPtr(byteBuf[byteCur]), byteSize - byteCur,
     151                VarPtr(charBuf[charSize]), charCapacity - charSize,
     152                byteEof, charUsed, byteUsed, charEof)
     153            byteCur += byteUsed
     154            charSize += charUsed
     155        End If
     156    End Sub
     157
    161158    s As Stream
    162     size As Long
    163     cur As Long
    164     last As Long '中身の終わり
    165     buf As *SByte '暫定
     159    encoding As Text.Encoding
     160    decoder As Text.Decoder
     161    charBuf As *WCHAR
     162    byteBuf As *Byte
     163    charCur As Long '読み取っていないデータの開始位置
     164    byteCur As Long
     165    charSize As Long 'Bufの内、有効なデータの数
     166    byteSize As Long
     167    charCapacity As Long '確保済み容量 = GC_mallocしたときの引数の値
     168    byteCapacity As Long
     169    charEof As Boolean 'Trueのとき、次にcur = sizeになるまでしかデータがことを示す
     170    byteEof As Boolean
     171    '常に0 <= cur <= size <= capacity
    166172End Class
    167173
Note: See TracChangeset for help on using the changeset viewer.