Ignore:
Timestamp:
Dec 28, 2008, 12:18:53 AM (15 years ago)
Author:
イグトランス (egtra)
Message:

TextWriter同様TextReaderでバッファリングし、StreamReaderはMultiByteToWideChar固定で仮実装。これで、マルチバイトモードでもStringReaderが使えるようにした。
(#235)

File:
1 edited

Legend:

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

    r662 r665  
    3838    End Function
    3939
    40     /*
    41     @date 2008/02/25
    42     @auther Egtra
    43     */
    44     Override Function Peek() As Long
    45         If charSize = charCur Then
    46             fillCharBuf()
    47             If charSize = charCur Then
    48                 Peek = -1
    49                 Exit Function
    50             End If
    51         End If
    52         Peek = charBuf[charCur]
    53     End Function
    54 
    55     /*
    56     @date 2008/02/25
    57     @auther Egtra
    58     */
    59     Override Function Read() As Long
    60         Read = Peek()
    61         If Read <> -1 Then
    62             charCur++
    63         End If
    64     End Function
    6540
    6641Protected
     
    7954
    8055    /*
    81     @date 2008/02/25
     56    @date 2008/12/27
    8257    @auther Egtra
    8358    */
    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)
     59    Override Function Underflow() As Boolean
     60        Dim wcBuf[4095] As WCHAR
     61        Dim mbBuf[4095] As SByte
     62        Dim mbLen = s.Read(mbBuf As *Byte, 0, Len(buf))
     63        If mbLen = 0 Then
     64            Underflow = False
    8865            Exit Function
    8966        End If
    90         ReadImpl = readFromBuffer(buffer, n)
    91         If ReadImpl = count Then 'バッファの中身で足りた場合
    92             Exit Function
     67        Dim pNext = mbBuf As PSTR
     68        Do
     69            Dim q = CharNextExA(cp, pNext, 0)
     70            If q = pNext Then
     71                Exit Do
     72            End If
     73            pNext = q As PSTR
     74        Loop
     75        If pNext <> mbBuf + mbLen Then
     76            leadByte = mbBuf[mbLen - 1]
    9377        End If
    94         fillCharBuf()
    95         ReadImpl += ReadImpl(VarPtr(buffer[n]), count - n)
     78        Dim wcLen = MultiByteToWideChar(cp, 0, mbBuf, (pNext - mbBuf) As Long, wcBuf, 4095)
     79        Dim s = New String(wcBuf, wcLen)
     80        Dim buf = Buffer
     81        buf.Append(s)
     82        Underflow = True
    9683    End Function
     84Private
    9785
    98 Private
    9986    /*
    10087    @date 2008/02/25
     
    10390    Sub init(str As Stream)
    10491        s = str
    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
    118     End Sub
    119 
    120     /**
    121     @brief バッファの中身から読み取る。
    122     @date 2008/02/25
    123     @auther Egtra
    124     文字数が足りなくても、元のストリームまで読みには行かない。
    125     */
    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
    130     End Function
    131 
    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             Dim completed As Boolean
    151             decoder.Convert(VarPtr(byteBuf[byteCur]), byteSize - byteCur,
    152                 VarPtr(charBuf[charSize]), charCapacity - charSize,
    153                 byteEof, charUsed, byteUsed, completed)
    154             charEof = byteEof And completed And byteCur = byteSize
    155             byteCur += byteUsed
    156             charSize += charUsed
    157         End If
     92        cp  = CP_ACP '暫定。
     93        leadByte = 0
    15894    End Sub
    15995
    16096    s As Stream
    161     encoding As Text.Encoding
    162     decoder As Text.Decoder
    163     charBuf As *WCHAR
    164     byteBuf As *Byte
    165     charCur As Long '読み取っていないデータの開始位置
    166     byteCur As Long
    167     charSize As Long 'Bufの内、有効なデータの数
    168     byteSize As Long
    169     charCapacity As Long '確保済み容量 = GC_mallocしたときの引数の値
    170     byteCapacity As Long
    171     charEof As Boolean 'Trueのとき、次にcur = sizeになるまでしかデータがことを示す
    172     byteEof As Boolean
    173     '常に0 <= cur <= size <= capacity
     97    cp As Word
     98    leadByte As Byte
    17499End Class
    175100
Note: See TracChangeset for help on using the changeset viewer.