Changeset 673 for branch


Ignore:
Timestamp:
2009/01/05 01:40:11 (3 years ago)
Author:
egtra
Message:

Encoder/Decoderを排除した実装(UTF8Encodingは修正していません)。

Location:
branch/egtra-stream-without-en_dec/Classes/System
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branch/egtra-stream-without-en_dec/Classes/System/IO/StreamReader.ab

    r666 r673  
    5858    */ 
    5959    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 
     60        Dim nextRead As *Byte 
     61        Dim readSize = s.Read(mbBuf + bufSize, 0, bufCapacity - bufSize) 
     62        If readSize = 0 Then 
     63            If bufSize <> 0 Then 
     64#ifdef UNCODE 
     65                Buffer.Append(&hfffd As WCHAR) 
     66#else 
     67                Buffer.Append("?") 
     68#endif 
     69            End If 
    7270            Underflow = False 
    7371            Exit Function 
    7472        End If 
     73        Dim mbLen = bufSize + readSize 
     74        '文字全体が揃っている部分を抽出する。 
     75        Dim pNext = mbBuf 
    7576        Do 
    76             Dim q = CharNextExA(cp, pNext, 0) 
     77            Dim q = e.NextChar(pNext, ((mbBuf + mbLen) - pNext) As Long) 
    7778            If q = pNext Then 
    7879                Exit Do 
    7980            End If 
    80             pNext = q As PSTR 
     81            pNext = q 
    8182        Loop 
    82         If pNext <> mbBuf + mbLen Then 
    83             leadByte = mbBuf[mbLen - 1] 
     83        '文字全体が揃っている部分を変換しTextReaderのバッファに送る。 
     84        Dim wcBufCapacity = e.GetMaxCharCount(mbLen) 
     85        Dim wcBuf = GC_malloc_atomic(wcBufCapacity * SizeOf (WCHAR)) As *WCHAR 
     86        Dim wcLen = e.GetChars(mbBuf, (pNext - mbBuf) As Long, wcBuf, wcBufCapacity) 
     87        Dim appendStr As PCTSTR 
     88        Dim appendLen = GetStr(wcBuf, wcLen As SIZE_T, appendStr) 
     89        Dim readerBuffer = Buffer 
     90        readerBuffer.Append(appendStr, 0, appendLen) 
     91        'マルチバイトの揃っていない部分を手前に連れてくる。 
     92        bufSize = ((mbBuf + mbLen) - pNext) As Long 
     93        If bufSize <> 0 Then 
     94            memmove(mbBuf, mbBuf + mbLen, bufSize) 
    8495        End If 
    85         Dim wcLen = MultiByteToWideChar(cp, 0, mbBuf, (pNext - mbBuf) As Long, wcBuf, 4095) 
    86         Dim s = New String(wcBuf, wcLen) 
    87         Dim buf = Buffer 
    88         buf.Append(s) 
    8996        Underflow = True 
    9097    End Function 
     
    97104    Sub init(str As Stream) 
    98105        s = str 
    99         cp  = CP_ACP '暫定。 
    100         leadByte = 0 
     106        e = New Text.Detail.WindowsCodePageEncoding(CP_ACP) '暫定。 
     107        bufCapacity = 8192 
     108        mbBuf = GC_malloc_atomic(bufCapacity) As *Byte 
     109        bufSize = 0 
    101110    End Sub 
    102111 
    103112    s As Stream 
    104     cp As Word 
    105     leadByte As Byte 
     113    e As Text.Encoding 
     114    mbBuf As *Byte 
     115    bufSize As Long 
     116    bufCapacity As Long 
    106117End Class 
    107118 
  • branch/egtra-stream-without-en_dec/Classes/System/IO/StreamWriter.ab

    r653 r673  
    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        softFlush() 
     44        s.Flush() 
     45    End Sub 
     46 
     47    Override Sub WriteLine() 
     48        Super.WriteLine() 
     49        softFlush() 
    5950    End Sub 
    6051 
     
    6354        If disposing Then 
    6455            Flush() 
    65             flushLast() 
    6656            s.Dispose() 
    6757        End If 
     
    7363        buf = New Text.StringBuilder(4096) 
    7464        '暫定。正式版ではUTF-8を標準とする。 
    75         encoding = New Text.Detail.WindowsCodePageEncoding(CP_ACP) 
    76         encoder = encoding.GetEncoder() 
     65        e = New Text.Detail.WindowsCodePageEncoding(CP_ACP) 
    7766    End Sub 
    7867 
    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 
     68    Sub softFlush() 
     69        Dim buf = Buffer() 
     70        Dim pws As PCWSTR 
     71        Dim wcSize = GetWCStr(buf.ToString(), pws) 
     72        Dim mbMaxSize = e.GetMaxByteCount(wcSize) 
     73        Dim mbBuf = GC_malloc_atomic(mbMaxSize) As *Byte 
     74        Dim mbBufSize = e.GetBytes(pws, wcSize, mbBuf, mbMaxSize) 
     75        s.Write(mbBuf, 0, mbBufSize) 
    8876    End Sub 
    8977 
    90     encoding As Text.Encoding 
    91     encoder As Text.Encoder 
     78    e As Text.Encoding 
    9279    s As System.IO.Stream 
    9380End Class 
  • branch/egtra-stream-without-en_dec/Classes/System/IO/TextWriter.ab

    r665 r673  
    8686    End Sub 
    8787 
    88     Sub WriteLine() 
     88    Virtual Sub WriteLine() 
    8989        Write(Environment.NewLine) 
    9090    End Sub 
  • branch/egtra-stream-without-en_dec/Classes/System/Text/Encoding.ab

    r655 r673  
    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    /*! 
    216     @brief  符号器を取得する。 
    217     */ 
    218     Abstract Function GetDecoder() As Decoder 
    219  
    220     /*! 
    221     @brief  復号器を取得する。 
    222     */ 
    223     Abstract Function GetEncoder() As Encoder 
    224  
    225     /*! 
    226206    @brief  ある長さの文字列を符号化して得られるバイト列の最大の長さを返す。 
    227207    */ 
     
    242222 
    243223    /*! 
    244     @brief  GetPreambleの配列の要素数 
     224    @brief  GetPreambleの配列の要素数 
    245225    */ 
    246226    Virtual Function GetPreambleLength() As Long 
     
    248228    End Function 
    249229 
     230    /*! 
     231    @brief 与えられたバイト文字列から2文字目の開始地点を探す。 
     232    @param[in] s (マルチバイト)文字列 
     233    @param[in] count sの要素数 
     234    @return 2文字目の開始位置。2文字が存在しない場合、sを返す。 
     235    */ 
     236    Function NextChar(s As *Byte, count As Long) As *Byte 
     237        If count = 0 Then 
     238            NextChar = s 
     239        ElseIf s = 0 Then 
     240            Throw New ArgumentNullException("s") 
     241        ElseIf count < 0 Then 
     242            Throw New ArgumentException("count") 
     243        Else 
     244            NextChar = NextCharCore(s, count) 
     245        End If 
     246    End Function 
     247Protected 
     248    /*! 
     249    @brief NextCharの処理を行う。 
     250    @param[in] s (マルチバイト)文字列 
     251    @param[in] count sの要素数 
     252    @return 2文字目の開始位置。2文字が存在しない場合、sを返す。 
     253    */ 
     254    Abstract Function NextCharCore(s As *Byte, count As Long) As *Byte 
     255 
     256Public 
    250257'   Abstract Function BodyName() As String 
    251258'   Abstract Function HeaderName() As String 
     
    331338End Class 
    332339 
    333 /*! 
    334 @brief  復号を行うクラス 
    335 @date   2007/12/19 
    336 @auther Egtra 
    337 */ 
    338 Class Decoder 
    339 Public 
    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) 
    365     End Sub 
    366  
    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 
    529 End Class 
    530  
    531340Enum NormalizationForm 
    532341    FormC 
     
    549358    End Sub 
    550359 
    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  
    565360    Override Function GetHashCode() As Long 
    566361        GetHashCode = cp As Long 
     
    590385    End Function 
    591386 
     387Protected 
     388    Override Function GetBytesCountCore(src As *WCHAR, srcCount As Long) As Long 
     389        GetBytesCountCore = WideCharToMultiByte(cp, 0, src, srcCount, 0, 0, 0, 0) 
     390        If srcCount <> 0 And GetBytesCountCore = 0 Then 
     391            ActiveBasic.Windows.ThrowWithLastError() 
     392        End If 
     393    End Function 
     394 
     395    Override Function GetBytesCore(src As *WCHAR, srcCount As Long, dst As *Byte, dstCount As Long) As Long 
     396        GetBytesCore = WideCharToMultiByte(cp, 0, src, srcCount, dst As PCSTR, dstCount, 0, 0) 
     397        If srcCount <> 0 And GetBytesCore = 0 Then 
     398            ActiveBasic.Windows.ThrowWithLastError() 
     399        End If 
     400    End Function 
     401 
     402    Override Function GetCharsCountCore(src As *Byte, srcCount As Long) As Long 
     403        GetCharsCountCore = MultiByteToWideChar(cp, 0, src As PCSTR, srcCount, 0, 0) 
     404        If srcCount <> 0 And GetCharsCountCore = 0 Then 
     405            ActiveBasic.Windows.ThrowWithLastError() 
     406        End If 
     407    End Function 
     408 
     409    Override Function GetCharsCore(src As *Byte, srcCount As Long, dst As *WCHAR, dstCount As Long) As Long 
     410        GetCharsCore = MultiByteToWideChar(cp, 0, src As PCSTR, srcCount, dst, dstCount) 
     411        If srcCount <> 0 And GetCharsCore = 0 Then 
     412            ActiveBasic.Windows.ThrowWithLastError() 
     413        End If 
     414    End Function 
     415 
     416    Override Function NextCharCore(s As *Byte, count As Long) As *Byte 
     417        NextCharCore = CharNextExA(cp As Word, s As PCSTR, 0) As *Byte 
     418    End Function 
     419 
    592420Private 
    593421    cp As DWord 
    594422End Class 
    595423 
    596 Class WindowsCodePageEncoder 
    597     Inherits Encoder 
    598 Public 
    599     Sub WindowsCodePageEncoder(codepage As DWord) 
    600         cp = codepage 
    601     End Sub 
    602  
    603     Override Sub Reset() 
    604         nextByte = 0 
    605     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 
    645  
    646 Private 
    647     cp As DWord 
    648     nextByte As Byte 
    649 End Class 
    650  
    651 Class WindowsCodePageDecoder 
    652     Inherits Decoder 
    653 Public 
    654     Sub WindowsCodePageDecoder(codepage As DWord) 
    655         cp = codepage 
    656     End Sub 
    657  
    658 Protected 
    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 
    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) 
    696     End Sub 
    697  
    698     Override Function GetCharsCountCore(src As *Byte, srcCount As Long, flush As Boolean) As Long 
    699         GetCharsCountCore = srcCount + 1 '暫定 
    700     End Function 
    701  
    702 Private 
    703     cp As DWord 
    704     nextByte As Byte 
    705 End Class 
    706  
    707424End Namespace 
    708425 
Note: See TracChangeset for help on using the changeset viewer.