Ignore:
Timestamp:
Jan 13, 2009, 2:01:38 AM (15 years ago)
Author:
イグトランス (egtra)
Message:

#231に関連して、エンコーディング周りを見直し、Encoder/Decoderをストリーム用に特化。
UTF8Encodingをコンパイル可能にし、ビルドに含めるようにした。ただし、実装が不完全なためテストは不可。
(#231)

Location:
trunk/ab5.0/ablib/src/Classes/System/IO
Files:
4 edited

Legend:

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

    r666 r676  
    11'Classes/System/IO/StreamReader.ab
     2
     3'ToDo: コンソールで入力待ちになる問題への対処
    24
    35Namespace System
     
    3840    End Function
    3941
    40 
    4142Protected
    4243    /*
     
    5859    */
    5960    Override Function Underflow() As Boolean
    60         Dim wcBuf[4095] As WCHAR
    61         Dim mbBuf[4095] As SByte
    62         Dim pNext = mbBuf As PSTR
    63         Dim mbBufSize = Len(buf)
    64         If leadByte <> 0 Then
    65             pNext[0] = leadByte
    66             leadByte = 0
    67             pNext++
    68             mbBufSize--
    69         End If
    70         Dim mbLen = s.Read(pNext As *Byte, 0, mbBufSize)
    71         If mbLen = 0 Then
    72             Underflow = False
    73             Exit Function
    74         End If
    75         Do
    76             Dim q = CharNextExA(cp, pNext, 0)
    77             If q = pNext Then
    78                 Exit Do
    79             End If
    80             pNext = q As PSTR
    81         Loop
    82         If pNext <> mbBuf + mbLen Then
    83             leadByte = mbBuf[mbLen - 1]
    84         End If
    85         Dim wcLen = MultiByteToWideChar(cp, 0, mbBuf, (pNext - mbBuf) As Long, wcBuf, 4095)
    86         Dim s = New String(wcBuf, wcLen)
    8761        Dim buf = Buffer
     62        Dim tmp = New Collections.Generic.List<WCHAR>
     63        Underflow = decoder.Decode(tmp, s)
     64        'ToDo: 非UNICODEのとき、
     65        ' サロゲートペアや結合文字列 (Combining Character Sequence)の途中でバッファが途切れている場合に対応する
     66        Dim s = New String(tmp.Data, tmp.Count)
    8867        buf.Append(s)
    89         Underflow = True
    9068    End Function
    9169Private
     
    9775    Sub init(str As Stream)
    9876        s = str
    99         cp  = CP_ACP '暫定。
    100         leadByte = 0
     77        decoder = New Text.Detail.WindowsCodePageDecoder(CP_ACP)
    10178    End Sub
    10279
    10380    s As Stream
    104     cp As Word
    105     leadByte As Byte
     81    decoder As Text.Decoder
    10682End Class
    10783
  • trunk/ab5.0/ablib/src/Classes/System/IO/StreamWriter.ab

    r653 r676  
    4141
    4242    Override Sub Flush()
    43         Dim buf = Buffer()
    44         Dim pws As PCWSTR
    45         Dim size = GetWCStr(buf.ToString(), pws)
    46         Dim pwsEnd = VarPtr(pws[size])
    47         Dim charConverted As Long
    48         Dim byteBuf[4095] As Byte
    49         Dim byteSize As Long
    50         Dim completed As Boolean
    51         Do
    52             Dim converted As Long
    53             encoder.Convert(pws, size, byteBuf, Len(byteBuf), False, charConverted, byteSize, completed)
    54             s.Write(byteBuf, 0, byteSize)
    55             pws = VarPtr(pws[charConverted])
    56             size -= charConverted
    57         Loop Until pws = pwsEnd
    58         buf.Length = 0
     43        Flush(False)
     44    End Sub
     45
     46    Sub Flush(last As Boolean)
     47#ifdef UNICODE
     48        encoder.Encode(StrPtr(buf), buf.Length As SIZE_T, s, last)
     49        buf.Remove(0, buf.Length As SIZE_T)
     50#else
     51        Dim p = StrPtr(buf)
     52        Dim i = 0 As SIZE_T
     53        Dim mbLen = 0 As SIZE_T
     54        While i <= buf.Length
     55            mbLen = i
     56            'ヌル文字で終わっていないので、CharNextは使えない
     57            If IsDBCSLeadByte(p[i]) Then
     58                i += 2
     59            Else
     60                i += 1
     61            End If
     62        Wend
     63        Dim wcBuf As PCWSTR
     64        Dim wcLen = GetStr(p, mbLen, wcBuf)
     65        encoder.Encode(wcBuf, wcLen, s, last)
     66        buf.Remove(0, mbLen)
     67        If last Then
     68            If buf.Length <> 0 Then
     69                s.WriteByte(Asc("?"))
     70                buf.Length = 0 
     71            End If
     72        End If
     73#endif
    5974    End Sub
    6075
     
    6277    Override Sub Dispose(disposing As Boolean)
    6378        If disposing Then
    64             Flush()
    65             flushLast()
     79            Flush(True)
    6680            s.Dispose()
    6781        End If
     
    7387        buf = New Text.StringBuilder(4096)
    7488        '暫定。正式版ではUTF-8を標準とする。
    75         encoding = New Text.Detail.WindowsCodePageEncoding(CP_ACP)
    76         encoder = encoding.GetEncoder()
     89        encoder = New Text.Detail.WindowsCodePageEncoder(CP_ACP)
    7790    End Sub
    7891
    79     Sub flushLast()
    80         Dim charConverted As Long
    81         Dim byteBuf[63] As Byte
    82         Dim byteSize As Long
    83         Dim completed As Boolean
    84         Do
    85             encoder.Convert(0, 0, byteBuf, Len(byteBuf), False, charConverted, byteSize, completed)
    86             s.Write(byteBuf, 0, byteSize)
    87         Loop Until completed
    88     End Sub
    89 
    90     encoding As Text.Encoding
    9192    encoder As Text.Encoder
    9293    s As System.IO.Stream
  • trunk/ab5.0/ablib/src/Classes/System/IO/StringReader.ab

    r665 r676  
    1616    @date 2008/02/26
    1717    @auther Egtra
    18     @param str 読み取るとなる文字列。
     18    @param str 読み取るとなる文字列。
    1919    @exception ArgumentNullException strがNothingのとき。
    2020    */
     
    2323            Throw New ArgumentNullException("str")
    2424        End If
    25         Buffer.Append(str)
    26     End Sub
    27 
    28 
    29 Protected
    30     /*
    31     @date 2008/02/26
    32     @auther Egtra
    33     */
    34     Override Sub Dispose(disposing As Boolean)
     25        Dim b = Buffer
     26        b.Append(str)
    3527    End Sub
    3628End Class
  • trunk/ab5.0/ablib/src/Classes/System/IO/TextReader.ab

    r668 r676  
    2222    Virtual Function Peek() As Long
    2323        If pos >= buf.Length Then
     24            buf.Length = 0
     25            pos = 0
    2426            If Not Underflow() Then
    2527                Peek = -1
     
    114116        Wend
    115117        ReadToEnd = buf.ToString()
     118        buf.Length = 0
     119        pos = 0
    116120    End Function
    117121
     
    141145    @auther Egtra
    142146    @return 内部バッファ
     147    内部バッファの既存の要素は、一切の変更をしないこと。また、空であるという仮定を置かないこと。
    143148    */
    144149    Function Buffer() As Text.StringBuilder
     
    151156    */
    152157    Function ReadImpl(buffer As *Char, count As Long) As Long
     158        'ToDo 適当なところでバッファの読み取り済みの部分を除去する処理を入れる(現在Peekのみ)。
    153159        Dim p = StrPtr(buf)
    154160        While buf.Length - pos < count
     
    156162        Wend
    157163        ReadImpl = Math.Min(buf.Length - pos, count)
    158         ActiveBasic.Strings.ChrCopy(buffer, VarPtr(p[pos]), ReadImpl As SIZE_T)
     164        ActiveBasic.Strings.ChrCopy(buffer, VarPtr(p[pos]) As *Char, ReadImpl As SIZE_T)
    159165        pos += ReadImpl
    160166    End Function
Note: See TracChangeset for help on using the changeset viewer.