Changeset 655 for trunk


Ignore:
Timestamp:
2008/11/09 14:21:49 (4 years ago)
Author:
egtra
Message:

#161完了。StreamReaderのUnicode対応。

Location:
trunk/ab5.0/ablib/src/Classes/System
Files:
5 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 
  • trunk/ab5.0/ablib/src/Classes/System/IO/StringReader.ab

    r497 r655  
    2323            Throw New ArgumentNullException("str") 
    2424        End If 
    25         s = str 
     25        Dim length = GetStr(str, s) 
     26        If length > LONG_MAX Then 
     27            Throw New ArgumentException("Must be Length <= LONG_MAX", "str") 
     28        End If 
     29        len = length As Long 
    2630        i = 0 
    2731    End Sub 
     
    3236    */ 
    3337    Override Function Peek() As Long 
    34         If i = s.Length Then 
     38        If i = len Then 
    3539            Peek = -1 
    3640        Else 
     
    4448    */ 
    4549    Override Function Read() As Long 
    46         If i = s.Length Then 
    47             Read = -1 
    48         Else 
    49             Read = s[i] 
    50             i++ 
    51         End If 
     50        Read = Peek() 
     51        i++ 
    5252    End Function 
    5353 
     
    5656    @auther Egtra 
    5757    */ 
     58/* 
    5859    Override Function ReadToEnd() As String 
    5960        ReadToEnd = s.Substring(i) 
    6061        i = s.Length 
    6162    End Function 
    62  
     63*/ 
    6364Protected 
    6465    /* 
     
    7576    @auther Egtra 
    7677    */ 
    77     Override Function ReadImpl(buffer As *Char, index As Long, count As Long) As Long 
    78         ReadImpl = Math.Min(count, s.Length - i) 
    79         ActiveBasic.Strings.ChrCopy(VarPtr(buffer[index]) As *Char, (StrPtr(s) + i * SizeOf (Char)) As *Char, ReadImpl As SIZE_T) 'ToDo: ポインタに対する+演算 
     78    Override Function ReadImpl(buffer As *WCHAR, count As Long) As Long 
     79        ReadImpl = Math.Min(count, len - i) 
     80        ActiveBasic.Strings.ChrCopy(buffer, VarPtr(s[i]), ReadImpl As SIZE_T) 'ToDo: ポインタに対する+演算 
    8081    End Function 
    8182 
    8283Private 
    83     s As String 
     84    s As *WCHAR 
     85    len As Long 
    8486    i As Long 
    8587End Class 
  • trunk/ab5.0/ablib/src/Classes/System/IO/TextReader.ab

    r497 r655  
    1 NameSpace System 
    2 NameSpace IO 
     1Namespace System 
     2Namespace IO 
    33 
    44Class TextReader 
    55    Implements System.IDisposable 
    6  
    7 Public 
    8 'Protected 
    9     Sub TextReader() 
    10     End Sub 
    116Public 
    127    Virtual Sub ~TextReader() 
     
    3126    @auther Egtra 
    3227    */ 
    33     Function Read(buffer As *Char, index As Long, count As Long) As Long 
     28    Function Read(buffer As *WCHAR, index As Long, count As Long) As Long 
    3429        If buffer = 0 Then 
     30            Throw New ArgumentNullException("buffer") 
    3531        ElseIf index < 0 Then 
     32            Throw New ArgumentOutOfRangeException("index") 
    3633        ElseIf count < 0 Then 
     34            Throw New ArgumentOutOfRangeException("count") 
    3735        End If 
    38         Read = ReadImpl(buffer, index, count) 
     36        Read = ReadImpl(VarPtr(buffer[index]), count) 
     37    End Function 
     38 
     39    Static Function Synchronized(reader As TextReader) As TextReader 
     40        Synchronized = New Detail.SynchronizedTextReader(reader) 
    3941    End Function 
    4042 
     
    4547    @retval 有効なStringインスタンス 読み取った1行 
    4648    */ 
    47     Virtual Function ReadLine() As String 
     49    Function ReadLine() As String 
    4850        If Peek() = -1 Then 
    4951            Exit Function 
    5052        End If 
    51         Dim sb = New Text.StringBuilder(256) 
     53        Dim sb = New Collections.Generic.List<WCHAR> 
    5254        Do 
    5355            Dim ch = Read() 
     
    6971                Case &h0D 'CR 
    7072                    Exit Do 
    71 '               Case &h85 'NEL 
    72 '                   Exit Do 
    73 '               Case &h2028 'LS 
    74 '                   Exit Do 
    75 '               Case &h2029 'PS 
    76 '                   Exit Do 
     73                Case &h85 'NEL 
     74                    Exit Do 
     75                Case &h2028 'LS 
     76                    Exit Do 
     77                Case &h2029 'PS 
     78                    Exit Do 
    7779            End Select 
    78             sb.Append(ch As Char) 'ToDo キャスト不要にすべきというチケットを書くこと 
     80            sb.Add(ch As WCHAR) 
    7981        Loop 
    80         ReadLine = sb.ToString 
     82        ReadLine = New String(sb As *WCHAR, sb.Count) 
    8183    End Function 
    8284    /* 
     
    9799    End Function 
    98100 
    99     Static Function Synchronized(reader As TextReader) As TextReader 
    100         Synchronized = New Detail.SynchronizedTextReader(reader) 
    101     End Function 
     101Protected 
     102    Sub TextReader() 
     103    End Sub 
    102104 
    103 Protected 
    104105    Virtual Sub Dispose(disposing As Boolean) 
    105106    End Sub 
     
    109110    @auther Egtra 
    110111    */ 
    111     Virtual Function ReadImpl(buffer As *Char, index As Long, count As Long) As Long 
     112    Virtual Function ReadImpl(buffer As *WCHAR, count As Long) As Long 
    112113        Dim i As Long 
    113         Dim p = VarPtr(buffer[index]) 
    114114        For i = 0 To ELM(count) 
    115115            Dim c = Read() 
    116116            If c = -1 Then 
    117                 ReadImpl = i - 1 
     117                ReadImpl = i 
    118118                Exit Function 
    119119            Else 
    120                 p[i] = c As Char 
     120                buffer[i] = c As Char 
    121121            End If 
    122122        Next 
    123         ReadImpl = i - 1 
     123        ReadImpl = i 
    124124    End Function 
    125125End Class 
     
    147147    End Function 
    148148 
    149     Override Function ReadLine() As String 
    150 '       Using lock = cs.Lock 
    151             ReadLine = base.ReadLine 
    152 '       End Using 
    153     End Function 
    154  
    155     Override Function ReadToEnd() As String 
    156 '       Using lock = cs.Lock 
    157             ReadToEnd = base.ReadToEnd 
    158 '       End Using 
    159     End Function 
    160  
    161149Protected 
    162150    Override Sub Dispose(disposing As Boolean) 
     
    171159    End Sub 
    172160 
    173     Override Function ReadImpl(buffer As *Char, index As Long, count As Long) As Long 
     161    Override Function ReadImpl(buffer As *WCHAR, count As Long) As Long 
    174162'       Using lock = cs.Lock 
    175             ReadImpl = base.ReadImpl(buffer, index, count) 
     163            ReadImpl = base.ReadImpl(buffer, count) 
    176164'       End Using 
    177165    End Function 
     
    183171End Namespace 
    184172 
    185 End NameSpace 
    186 End NameSpace 
     173End Namespace 
     174End Namespace 
  • trunk/ab5.0/ablib/src/Classes/System/Text/Encoding.ab

    r653 r655  
    353353        ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean) 
    354354 
    355         If src = 0 Then 
     355        If src = 0 And srcCount > 0 Then 
    356356            Throw New ArgumentNullException("src") 
    357357        ElseIf srcCount < 0 Then 
     
    452452        ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean) 
    453453 
    454         If src = 0 Then 
     454        If src = 0 And srcCount > 0 Then 
    455455            Throw New ArgumentNullException("src") 
    456456        ElseIf srcCount < 0 Then 
     
    641641 
    642642    Override Function GetBytesCountCore(src As *WCHAR, srcCount As Long, flush As Boolean) As Long 
     643        GetBytesCountCore = srcCount * 2 + 1 '暫定 
    643644    End Function 
    644645 
     
    658659    Override Sub ConvertCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long, flush As Boolean, 
    659660        ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean) 
     661 
     662        Dim srcPos = 0 As Long 
     663        Dim dstPos = 0 As Long 
     664        If dstCount > 0 And nextByte <> 0 Then 
     665            Dim buf[1] As CHAR 
     666            buf[0] = nextByte As CHAR 
     667            buf[1] = src[1] As CHAR 
     668            Dim len = MultiByteToWideChar(cp, 0, buf, Len(buf), VarPtr(dst[dstPos]), 10) 
     669            If len = 0 Then 
     670                ActiveBasic.Windows.ThrowWithLastError() 
     671            End If 
     672            srcPos++ 
     673            dstPos++ 
     674            nextByte = 0 
     675        End If 
     676        While srcPos < srcCount And dstPos < srcCount 
     677            Dim srcCharSize = 1 As Long 
     678            If IsDBCSLeadByteEx(cp, src[srcPos]) Then 
     679                srcCharSize = 2 
     680                If srcPos + 1 = srcCount Then 
     681                    nextByte = src[srcPos] 
     682                    Exit While 
     683                End If 
     684            End If 
     685            '将来的には行毎に変換しMB_USEGLYPHCHARSを使うようにしたい。 
     686            Dim len = MultiByteToWideChar(cp, 0, VarPtr(src[srcPos]) As *CHAR, srcCharSize, VarPtr(dst[dstPos]), 1) 
     687            If len = 0 Then 
     688                ActiveBasic.Windows.ThrowWithLastError() 
     689            End If 
     690            srcPos += srcCharSize 
     691            dstPos++ 
     692        Wend 
     693        srcUsed = srcPos 
     694        dstUsed = dstPos 
     695        completed = (srcPos = srcCount And dstPos = srcCount And nextByte = 0) 
    660696    End Sub 
    661697 
    662698    Override Function GetCharsCountCore(src As *Byte, srcCount As Long, flush As Boolean) As Long 
     699        GetCharsCountCore = srcCount + 1 '暫定 
    663700    End Function 
    664701 
    665702Private 
    666703    cp As DWord 
     704    nextByte As Byte 
    667705End Class 
    668706 
  • trunk/ab5.0/ablib/src/Classes/System/Xml/XmlDocument.ab

    r497 r655  
    9595    /*! 
    9696    @brief  指定したストリームからXML文書を読み込む。 
     97    @param  reader 読み込むリーダ。 
     98    */ 
     99    Virtual Sub Load( reader As System.IO.TextReader ) 
     100        This.RemoveAll() 
     101        ActiveBasic.Xml.Parser.Parse( reader.ReadToEnd(), This ) 
     102    End Sub 
     103 
     104    /*! 
     105    @brief  指定したストリームからXML文書を読み込む。 
    97106    @param  stream 読み込み先のストリーム。 
    98107    */ 
    99108    Virtual Sub Load( inStream As System.IO.Stream ) 
    100         Dim length = inStream.Length As DWord 
    101         Dim xmlBuffer = calloc( length + 1 ) As *Char 
    102         inStream.Read( xmlBuffer As *Byte, 0, length ) 
    103         inStream.Close() 
    104         Dim xmlString = New String( xmlBuffer ) 
    105         free( xmlBuffer ) 
    106  
    107         This.RemoveAll() 
    108         ActiveBasic.Xml.Parser.Parse( xmlString, This ) 
     109        Load( New System.IO.StreamReader( inStream ) ) 
    109110    End Sub 
    110111 
     
    114115    */ 
    115116    Virtual Sub Load( filename As String ) 
    116         Dim fileStream As System.IO.FileStream( filename, System.IO.FileMode.Open, System.IO.FileAccess.Read ) 
    117         Load( fileStream ) 
     117        Dim r = New System.IO.StreamReader( filename ) 
     118        Load( r ) 
     119        r.Dispose() 
    118120    End Sub 
    119121 
     
    123125    */ 
    124126    Virtual Sub Save( outStream As System.IO.Stream ) 
    125         Dim xmlStr = InnerXmlSupportedIndent( True ) 
    126         outStream.Write( xmlStr.StrPtr As *Byte, 0, xmlStr.Length * SizeOf( Char ) ) 
    127         outStream.Close() 
     127        Dim writer = New IO.StreamWriter( outStream ) 
     128        Save( writer ) 
     129        writer.Flush() 
    128130    End Sub 
    129131 
     
    133135    */ 
    134136    Virtual Sub Save( filename As String ) 
    135         Dim fileStream As System.IO.FileStream( filename, System.IO.FileMode.Create, System.IO.FileAccess.Write ) 
    136         Save( fileStream ) 
     137        Dim w = New IO.StreamWriter( filename ) 
     138        Save( w ) 
     139        w.Dispose() 
    137140    End Sub 
    138141 
     
    142145    */ 
    143146    Virtual Sub Save( writer As System.IO.TextWriter ) 
    144         writer.Write(InnerXmlSupportedIndent( True )) 
     147        writer.Write( InnerXmlSupportedIndent( True ) ) 
    145148    End Sub 
    146149End Class 
Note: See TracChangeset for help on using the changeset viewer.