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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/ablib/src/Classes/System/Text/Encoding.ab

    r655 r676  
    3939    @brief  符号化して得られる文字列の長さを計算する。
    4040    @param[in] src  対象文字列
    41     @param[in] srcCount srcの長さ
    42     @return 符号化して得られる文字列の長さ
     41    @param[in] srcCount srcの長さ(要素数単位)
     42    @return 符号化して得られる文字列の長さ(要素数単位)
    4343    @date   2007/12/08
    4444    */
     
    5555    @brief  符号化して得られる文字列の長さを計算する。
    5656    @param[in] src  対象文字列
    57     @return 符号化して得られる文字列の長さ
     57    @return 符号化して得られる文字列の長さ(要素数単位)
    5858    @date   2007/12/08
    5959    */
     
    6666#endif
    6767
    68 Private
     68Protected
    6969    /*!
    7070    @brief  GetBytesCountの実装を行う。
    7171    @param[in] src  対象文字列
    72     @param[in] srcCount srcの長さ
    73     @return 符号化して得られる文字列の長さ
    74     @date   2007/12/08
    75     */
    76     Function GetBytesCountCore(src As *WCHAR, srcCount As Long) As Long
    77         Dim enc = GetEncoder()
    78         GetBytesCountCore = enc.GetBytesCount(src, srcCount, True)
    79     End Function
     72    @param[in] srcCount srcの長さ(要素数単位)
     73    @return 符号化して得られる文字列の長さ(要素数単位)
     74    @date   2007/12/08
     75    */
     76    Abstract Function GetBytesCountCore(src As *WCHAR, srcCount As Long) As Long
    8077Public
    8178    /*!
    8279    @brief  符号化する。
    8380    @param[in] src  入力
    84     @param[in] srcCount srcの長さ
     81    @param[in] srcCount srcの長さ(要素数単位)
    8582    @param[out] dst 出力
    86     @param[in] dstCount dstのバッファの大きさ
    87     @return dstに書き込まれたバイト
     83    @param[in] dstCount dstのバッファの大きさ(要素数単位)
     84    @return dstに書き込まれた要素
    8885    @date   2007/12/08
    8986    */
     
    10299    End Function
    103100
    104 Private
     101Protected
    105102    /*!
    106103    @brief  GetBytesの処理を行う。
    107104    @param[in] src  入力
    108     @param[in] srcCount srcの長さ
     105    @param[in] srcCount srcの長さ(要素数単位)
    109106    @param[out] dst 出力
    110     @param[in] dstCount dstのバッファの大きさ
    111     @return dstに書き込まれたバイト
     107    @param[in] dstCount dstのバッファの大きさ(要素数単位)
     108    @return dstに書き込まれた要素
    112109    @exception ArgumentException    バッファの大きさが足りない
    113110    @date   2007/12/08
    114111    */
    115     Function GetBytesCore(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long) As Long
    116         GetBytesCore = GetEncoder().GetBytes(src, srcCount, dst, dstCount, True)
    117     End Function
     112    Abstract Function GetBytesCore(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long) As Long
    118113Public
    119114    /*!
    120115    @brief  復号して得られる文字列の長さを計算する。
    121116    @param[in] src  対象文字列
    122     @param[in] srcCount srcの長さ
    123     @return 復号して得られる文字列の長さ
     117    @param[in] srcCount srcの長さ(要素数単位)
     118    @return 復号して得られる文字列の長さ(要素数単位)
    124119    @date   2007/12/08
    125120    */
     
    133128    End Function
    134129
    135 Private
     130Protected
    136131    /*!
    137132    @brief  GetCharsCountの処理を行う。
    138133    @param[in] src  対象文字列
    139     @param[in] srcCount srcの長さ
    140     @return 符号化して得られる文字列の長さ
    141     @date   2007/12/08
    142     */
    143     Function GetCharsCountCore(src As *Byte, srcCount As Long) As Long
    144         Dim dec = GetDecoder()
    145         GetCharsCountCore = dec.GetCharsCount(src, srcCount, True)
    146     End Function
     134    @param[in] srcCount srcの長さ(要素数単位)
     135    @return 符号化して得られる文字列の長さ(要素数単位)
     136    @date   2007/12/08
     137    */
     138    Abstract Function GetCharsCountCore(src As *Byte, srcCount As Long) As Long
    147139Public
    148140    /*!
    149141    @brief  復号する。
    150142    @param[in] src  入力
    151     @param[in] srcCount srcの長さ
     143    @param[in] srcCount srcの長さ(要素数単位)
    152144    @param[out] dst 出力
    153     @param[in] dstCount srcのバッファの大きさ
    154     @return dstに書き込まれたバイト
     145    @param[in] dstCount srcのバッファの大きさ(要素数単位)
     146    @return dstに書き込まれた要素
    155147    @date   2007/12/08
    156148    */
     
    169161    End Function
    170162
    171 Private
     163Protected
    172164    /*!
    173165    @brief  GetCharsの処理を行う。
    174166    @param[in] src  入力
    175     @param[in] srcCount srcの長さ
     167    @param[in] srcCount srcの長さ(要素数単位)
    176168    @param[out] dst 出力
    177     @param[in] dstCount dstのバッファの大きさ
    178     @return dstに書き込まれたバイト
     169    @param[in] dstCount dstのバッファの大きさ(要素数単位)
     170    @return dstに書き込まれた要素
    179171    @exception ArgumentException    バッファの大きさが足りない
    180172    @date   2007/12/08
    181173    */
    182     Function GetCharsCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long) As Long
    183         GetCharsCore = GetDecoder().GetChars(src, srcCount, dst, dstCount, True)
    184     End Function
     174    Abstract Function GetCharsCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long) As Long
    185175Public
    186176#ifdef UNICODE
     
    188178    @brief  復号し、Stringで結果を返す。
    189179    @param[in] src  入力
    190     @param[in] srcCount srcの長さ
     180    @param[in] srcCount srcの長さ(要素数単位)
    191181    @return 変換結果の文字列
    192182    @date   2007/12/08
     
    214204Public
    215205    /*!
     206    @brief  復号器を取得する。
     207    */
     208    Abstract Function GetDecoder() As Decoder
     209
     210    /*!
    216211    @brief  符号器を取得する。
    217     */
    218     Abstract Function GetDecoder() As Decoder
    219 
    220     /*!
    221     @brief  復号器を取得する。
    222212    */
    223213    Abstract Function GetEncoder() As Encoder
     
    242232
    243233    /*!
    244     @brief  GetPreambleの配列の要素数
     234    @brief  GetPreambleの配列の要素数
    245235    */
    246236    Virtual Function GetPreambleLength() As Long
     
    248238    End Function
    249239
     240Public
    250241'   Abstract Function BodyName() As String
    251242'   Abstract Function HeaderName() As String
     
    333324/*!
    334325@brief  復号を行うクラス
    335 @date   2007/12/19
     326@date   2009/01/12
    336327@auther Egtra
     328内部処理用
    337329*/
    338330Class Decoder
    339331Public
    340     /*!
    341     @brief  変換する
    342     @param[in] src  入力
    343     @param[in] srcCount 入力要素数
    344     @param[out] dst 出力
    345     @param[in] dstCount 出力要素数
    346     @param[in] flush    終了後に内部状態を初期化するかどうか
    347     @param[out] srcUsed 使用された入力の要素数
    348     @param[out] dstUsed 出力の内、実際に書き込まれた要素数
    349     @param[out] completed   入力の全ての文字が変換に使われたかどうか
    350     */
    351     Sub Convert(src As *Byte, srcCount As Long,
    352         dst As *WCHAR, dstCount As Long, flush As Boolean,
    353         ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
    354 
    355         If src = 0 And srcCount > 0 Then
    356             Throw New ArgumentNullException("src")
    357         ElseIf srcCount < 0 Then
    358             Throw New ArgumentOutOfRangeException("srcCount")
    359         ElseIf dst = 0 Then
    360             Throw New ArgumentNullException("dst")
    361         ElseIf dstCount < 0 Then
    362             Throw New ArgumentOutOfRangeException("dstCount")
    363         End If
    364         ConvertCore(src, srcCount, dst, dstCount, flush, srcUsed, dstUsed, completed)
     332    Function Decode(dst As Collections.Generic.List<WCHAR>, st As IO.Stream) As Boolean
     333        Decode = DecodeImpl(dst, st)
     334    End Function
     335
     336Protected
     337    Abstract Function DecodeImpl(dst As Collections.Generic.List<WCHAR>, s As IO.Stream) As Boolean
     338End Class
     339
     340/*!
     341@brief  符号化を行うクラス
     342@date   2009/01/12
     343@auther Egtra
     344内部処理用
     345*/
     346Class Encoder
     347Public
     348    Sub Encode(src As *WCHAR, size As SIZE_T, s As IO.Stream, last As Boolean)
     349        EncodeImpl(src, size, s, last)
    365350    End Sub
    366351
    367     /*!
    368     @brief  変換する
    369     @param[in] src  入力
    370     @param[in] srcCount 入力要素数
    371     @param[out] dst 出力
    372     @param[in] dstCount 出力要素数
    373     @param[in] flush    終了後に内部状態を初期化するかどうか
    374     @return 出力の内、実際に書き込まれた要素数
    375     */
    376     Function GetChars(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long, flush As Boolean) As Long
    377         Dim srcUsed As Long
    378         Dim completed As Boolean
    379         Convert(src, srcCount, dst, dstCount, flush, srcUsed, GetChars, completed)
    380         If srcUsed < srcCount Then
    381             Throw New ArgumentException("src", "buffer is too small")
    382         End If
    383     End Function
    384 
    385     /*!
    386     @brief  変換すると何文字になるか数える
    387     @param[in] src  入力
    388     @param[in] srcCount 入力要素数
    389     @param[in] flush    終了後に内部状態を初期化するとして計算するかどうか
    390     @return 必要な文字数
    391     */
    392     Function GetCharsCount(src As *Byte, srcCount As Long, flush As Boolean) As Long
    393         If src = 0 Then
    394             Throw New ArgumentNullException("src")
    395         ElseIf srcCount < 0 Then
    396             Throw New ArgumentOutOfRangeException("srcCount")
    397         End If
    398         GetCharsCountCore(src, srcCount, flush)
    399     End Function
    400 
    401     /*!
    402     @brief  内部状態を初期状態に戻す
    403     */
    404     Virtual Sub Reset()
    405     End Sub
    406 
    407 Protected
    408     /*!
    409     @brief  実際に変換する
    410     @param[in] src  入力
    411     @param[in] srcCount 入力要素数
    412     @param[out] dst 出力
    413     @param[in] dstCount 出力要素数
    414     @param[in] flush    終了後に内部状態を初期化するかどうか
    415     @param[out] dstUsed 使用された入力の要素数
    416     @param[out] srcUsed 出力の内、実際に書き込まれた要素数
    417     @param[out] completed   入力の全ての文字が変換に使われたかどうか
    418     */
    419     Abstract Sub ConvertCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long, flush As Boolean,
    420         ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
    421 
    422     /*!
    423     @brief  変換すると何文字になるか数える
    424     @param[in] src  入力
    425     @param[in] srcCount 入力要素数
    426     @param[in] flush    終了後に内部状態を初期化するとして計算するかどうか
    427     @return 必要な文字数
    428     */
    429     Abstract Function GetCharsCountCore(src As *Byte, srcCount As Long, flush As Boolean) As Long
    430 End Class
    431 
    432 /*!
    433 @brief  符号化を行うクラス
    434 @date   2007/12/19
    435 @auther Egtra
    436 */
    437 Class Encoder
    438 Public
    439     /*!
    440     @brief  変換する
    441     @param[in] src  入力
    442     @param[in] srcCount 入力要素数
    443     @param[out] dst 出力
    444     @param[in] dstCount 出力要素数
    445     @param[in] flush    終了後に内部状態を初期化するかどうか
    446     @param[out] srcUsed 使用された入力の要素数
    447     @param[out] dstUsed 出力の内、実際に書き込まれた要素数
    448     @param[out] completed   入力の全ての文字が変換に使われたかどうか
    449     */
    450     Sub Convert(src As *WCHAR, srcCount As Long,
    451         dst As *Byte, dstCount As Long, flush As Boolean,
    452         ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
    453 
    454         If src = 0 And srcCount > 0 Then
    455             Throw New ArgumentNullException("src")
    456         ElseIf srcCount < 0 Then
    457             Throw New ArgumentOutOfRangeException("srcCount")
    458         ElseIf dst = 0 Then
    459             Throw New ArgumentNullException("dst")
    460         ElseIf dstCount < 0 Then
    461             Throw New ArgumentOutOfRangeException("dstCount")
    462         End If
    463         ConvertCore(src, srcCount, dst, dstCount, flush, srcUsed, dstUsed, completed)
    464     End Sub
    465 
    466     /*!
    467     @brief  変換する
    468     @param[in] src  入力
    469     @param[in] srcCount 入力要素数
    470     @param[out] dst 出力
    471     @param[in] dstCount 出力要素数
    472     @param[in] flush    終了後に内部状態を初期化するかどうか
    473     @return 出力の内、実際に書き込まれた要素数
    474     */
    475     Function GetBytes(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long, flush As Boolean) As Long
    476         Dim srcUsed As Long
    477         Dim completed As Boolean
    478         Convert(src, srcCount, dst, dstCount, flush, srcUsed, GetBytes, completed)
    479         If srcUsed < srcCount Then
    480             Throw New ArgumentException("src", "buffer is too small")
    481         End If
    482     End Function
    483 
    484     /*!
    485     @brief  変換すると何文字になるか数える
    486     @param[in] src  入力
    487     @param[in] srcCount 入力要素数
    488     @param[in] flush    終了後に内部状態を初期化するとして計算するかどうか
    489     @return 必要な文字数
    490     */
    491     Function GetBytesCount(src As *WCHAR, srcCount As Long, flush As Boolean) As Long
    492         If src = 0 Then
    493             Throw New ArgumentNullException("src")
    494         ElseIf srcCount < 0 Then
    495             Throw New ArgumentOutOfRangeException("srcCount")
    496         End If
    497         GetBytesCountCore(src, srcCount, flush)
    498     End Function
    499 
    500     /*!
    501     @brief  内部状態を初期状態に戻す
    502     */
    503     Virtual Sub Reset()
    504     End Sub
    505 
    506 Protected
    507     /*!
    508     @brief  実際に変換する
    509     @param[in] src  入力
    510     @param[in] srcCount 入力要素数
    511     @param[out] dst 出力
    512     @param[in] dstCount 出力要素数
    513     @param[in] flush    終了後に内部状態を初期化するかどうか
    514     @param[out] dstUsed 使用された入力の要素数
    515     @param[out] srcUsed 出力の内、実際に書き込まれた要素数
    516     @param[out] completed   入力の全ての文字が変換に使われたかどうか
    517     */
    518     Abstract Sub ConvertCore(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long, flush As Boolean,
    519         ByRef dstUsed As Long, ByRef srcUsed As Long, ByRef completed As Boolean)
    520 
    521     /*!
    522     @brief  変換すると何文字になるか数える
    523     @param[in] src  入力
    524     @param[in] srcCount 入力要素数
    525     @param[in] flush    終了後に内部状態を初期化するとして計算するかどうか
    526     @return 必要な文字数
    527     */
    528     Abstract Function GetBytesCountCore(src As *WCHAR, srcCount As Long, flush As Boolean) As Long
     352Protected
     353    Abstract Sub EncodeImpl(src As *WCHAR, size As SIZE_T, s As IO.Stream, last As Boolean)
    529354End Class
    530355
     
    549374    End Sub
    550375
    551     /*!
    552     @brief  符号器を取得する。
    553     */
    554     Override Function GetDecoder() As Decoder
    555         GetDecoder = New WindowsCodePageDecoder(cp)
    556     End Function
    557 
    558     /*!
    559     @brief  復号器を取得する。
    560     */
    561     Override Function GetEncoder() As Encoder
    562         GetEncoder = New WindowsCodePageEncoder(cp)
    563     End Function
    564 
    565376    Override Function GetHashCode() As Long
    566377        GetHashCode = cp As Long
     
    576387    End Function
    577388
     389    Override Function GetDecoder() As Decoder
     390        GetDecoder = New WindowsCodePageDecoder(cp)
     391    End Function
     392
     393    Override Function GetEncoder() As Encoder
     394        GetEncoder = New WindowsCodePageEncoder(cp)
     395    End Function
     396
    578397    /*!
    579398    @brief  ある長さの文字列を符号化して得られるバイト列の最大の長さを返す。
     
    588407    Override Function GetMaxCharCount(srcCount As Long) As Long
    589408        GetMaxCharCount = srcCount
     409    End Function
     410
     411Protected
     412    Override Function GetBytesCountCore(src As *WCHAR, srcCount As Long) As Long
     413        GetBytesCountCore = WideCharToMultiByte(cp, 0, src, srcCount, 0, 0, 0, 0)
     414        If srcCount <> 0 And GetBytesCountCore = 0 Then
     415            ActiveBasic.Windows.ThrowWithLastError()
     416        End If
     417    End Function
     418
     419    Override Function GetBytesCore(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long) As Long
     420        GetBytesCore = WideCharToMultiByte(cp, 0, src, srcCount, dst As PCSTR, dstCount, 0, 0)
     421        If srcCount <> 0 And GetBytesCore = 0 Then
     422            ActiveBasic.Windows.ThrowWithLastError()
     423        End If
     424    End Function
     425
     426    Override Function GetCharsCountCore(src As *Byte, srcCount As Long) As Long
     427        GetCharsCountCore = MultiByteToWideChar(cp, 0, src As PCSTR, srcCount, 0, 0)
     428        If srcCount <> 0 And GetCharsCountCore = 0 Then
     429            ActiveBasic.Windows.ThrowWithLastError()
     430        End If
     431    End Function
     432
     433    Override Function GetCharsCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long) As Long
     434        GetCharsCore = MultiByteToWideChar(cp, 0, src As PCSTR, srcCount, dst, dstCount)
     435        If srcCount <> 0 And GetCharsCore = 0 Then
     436            ActiveBasic.Windows.ThrowWithLastError()
     437        End If
    590438    End Function
    591439
     
    594442End Class
    595443
     444/*!
     445@brief  WideCharToMultiByteで復号化を行うクラス
     446@date   2009/01/12
     447@auther Egtra
     448内部処理用
     449*/
    596450Class WindowsCodePageEncoder
    597451    Inherits Encoder
     
    601455    End Sub
    602456
    603     Override Sub Reset()
    604         nextByte = 0
     457Protected
     458    Override Sub EncodeImpl(src As *WCHAR, size As SIZE_T, s As IO.Stream, last As Boolean)
     459        ' サロゲートペアや結合文字列 (Combining Character Sequence)の途中でバッファが途切れている場合に対応する
     460        ' ToDo: エラー処理
     461        Dim mbLen = WideCharToMultiByte(cp, 0, src, size, 0, 0, 0, 0)
     462        Dim mbBuf = GC_malloc_atomic(mbLen)
     463        WideCharToMultiByte(cp, 0, src, size, mbBuf, mbLen, 0, 0)
     464        s.Write(mbBuf, 0, mbLen)
    605465    End Sub
    606 
    607 Protected
    608     Override Sub ConvertCore(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long, flush As Boolean,
    609         ByRef srcUsed As Long, ByRef dstUsed As Long, ByRef completed As Boolean)
    610 
    611         Dim srcPos = 0 As Long
    612         Dim dstPos = 0 As Long
    613         If dstCount > 0 And nextByte <> 0 Then
    614             dst[0] = nextByte
    615             nextByte = 0
    616             dstPos++
    617         End If
    618         While srcPos < srcCount And dstPos < srcCount
    619             Dim buf[1] As CHAR
    620             Dim len = WideCharToMultiByte(cp, WC_COMPOSITECHECK Or WC_DEFAULTCHAR, VarPtr(src[srcPos]), 1, buf, Len(buf), 0, 0)
    621             If len = 0 Then
    622                 ActiveBasic.Windows.ThrowWithLastError()
    623             End If
    624             dst[dstPos] = buf[0] As Byte
    625             If len = 2 Then
    626                 If dstCount = 1 Then
    627                     nextByte = buf[1] As Byte
    628                     Exit While
    629                 End If
    630                 dstPos++
    631                 dst[dstPos] = buf[1] As Byte
    632                 nextByte = 0
    633             End If
    634             srcPos++
    635             dstPos++
    636         Wend
    637         srcUsed = srcPos
    638         dstUsed = dstPos
    639         completed = (srcPos = srcCount And dstPos = srcCount And nextByte = 0)
    640     End Sub
    641 
    642     Override Function GetBytesCountCore(src As *WCHAR, srcCount As Long, flush As Boolean) As Long
    643         GetBytesCountCore = srcCount * 2 + 1 '暫定
    644     End Function
    645466
    646467Private
    647468    cp As DWord
    648     nextByte As Byte
    649469End Class
    650470
     471/*!
     472@brief  MultiByteToWideCharで復号化を行うクラス
     473@date   2009/01/12
     474@auther Egtra
     475内部処理用
     476*/
    651477Class WindowsCodePageDecoder
    652478    Inherits Decoder
     
    657483
    658484Protected
    659     Override Sub ConvertCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long, flush As Boolean,
    660         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
     485    Override Function DecodeImpl(dst As Collections.Generic.List<WCHAR>, s As IO.Stream) As Boolean
     486        Dim i As Long
     487        For i = 0 To DefalultDecodingBufferSize - 1 'ELM
     488            Dim len As Long
    665489            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()
     490            Dim t = s.ReadByte()
     491            If t = -1 Then
     492                DecodeImpl = False
     493                Exit Function
    671494            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
     495            buf[0] = t As CHAR
     496            If IsDBCSLeadByteEx(cp, buf[0]) Then
     497                t = s.ReadByte()
     498                If t = -1 Then
     499                    dst.Add(&hfffd As WCHAR)
     500                    DecodeImpl = False
     501                    Exit For
    683502                End If
     503                buf[1] = t As CHAR
     504                len = 2
     505            Else
     506                len = 1
    684507            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()
     508            Dim wc As WCHAR
     509            If MultiByteToWideChar(cp, 0, buf, len, VarPtr(wc), 1) = 0 Then
     510                dst.Add(&hFFFD As WCHAR)
     511            Else
     512                dst.Add(wc)
    689513            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)
    696     End Sub
    697 
    698     Override Function GetCharsCountCore(src As *Byte, srcCount As Long, flush As Boolean) As Long
    699         GetCharsCountCore = srcCount + 1 '暫定
     514        Next
     515        DecodeImpl = True
    700516    End Function
    701517
    702518Private
    703519    cp As DWord
    704     nextByte As Byte
    705520End Class
     521
     522Const DefalultDecodingBufferSize = 16384
    706523
    707524End Namespace
Note: See TracChangeset for help on using the changeset viewer.