チェンジセット 655

差分発生行の前後
無視リスト:
コミット日時:
2008/11/09 14:21:49 (2 ヶ月前)
コミッタ:
egtra
ログメッセージ:

#161完了。StreamReaderのUnicode対応。

ファイル:

凡例:

変更無し
追加
削除
更新
コピー
移動
  • 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