Microsoft.VisualBasic.Strings.StrConv の第2引数である、VbStrConv 列挙体の定義は

 [Flags]
 public enum VbStrConv
 {
     None = 0x0,
     Uppercase = 0x1,
     Lowercase = 0x2,
     ProperCase = 0x3,
     Wide = 0x4,
     Narrow = 0x8,
     Katakana = 0x10,
     Hiragana = 0x20,
     SimplifiedChinese = 0x100,
     TraditionalChinese = 0x200,
     LinguisticCasing = 0x400,
 }

になっています。

ここに、FromUnicode, Unicode を追加して、VbStrConvEx 列挙体を作成します。

 [Flags]
 public enum VbStrConvEx
 {
     UpperCase = 0x01,
     LowerCase = 0x02,
     ProperCase = 0x03,
     Wide = 0x04,
     Narrow = 0x08,
     Katakana = 0x10,
     Hiragana = 0x20,
     Unicode = 0x40,
     FromUnicode = 0x80,
     SimplifiedChinese = 0x100,
     TraditionalChinese = 0x200,
     LinguisticCasing = 0x400,
 }

実際の変換は、StrConv メソッドを使います。

文字が シフトJIS に変換できるかどうかは一文字ずつでよいのですが、Wide 変換は、「プ」→「プ」になる等、単純に一文字ずつというわけにはいきません。

文字列をブロック単位で処理することになります。

 private static Encoding encShiftJis = Encoding.GetEncoding("Shift_JIS");
 
 public static VBString StrConvEx(VBString value, VbStrConvEx Conversion)
 {
     if ((object)value == null) return string.Empty;
     if (value.LengthB == 0) return string.Empty;
 
     // vbUnicode は先に変換する
 
     if ((Conversion & VbStrConvEx.Unicode) == VbStrConvEx.Unicode)
     {
         value = encShiftJis.GetString(value.ToByteArray());
         Conversion = Conversion & ~VbStrConvEx.Unicode;
     }
 
     // vbFromUnicode は後で変換するので、フラグとして保存する
     bool fromUnicode = (Conversion & VbStrConvEx.FromUnicode) == VbStrConvEx.FromUnicode;
     Conversion = Conversion & ~VbStrConvEx.FromUnicode;
 
     // シフト JIS に変換可能な部分は変換
     // それ以外の文字は無変換とする
 
     VbStrConv newConversion = (VbStrConv)Conversion;
 
     StringBuilder resultBuffer = new StringBuilder();
     StringBuilder shiftJisBuffer = new StringBuilder();
     string stringValue = value.ToString();
     bool state = false;
 
     foreach (char c in stringValue)
     {
         bool currentState = c.IsShiftJis();
 
         // 前の文字と違う場合
         if (currentState != state)
         {
             // シフトJIS 文字の変換を行う
             if (shiftJisBuffer.Length > 0)
             {
                 resultBuffer.Append(VBStrConv(shiftJisBuffer.ToString(), newConversion));
                 shiftJisBuffer.Length = 0;
             }
             state = currentState;
         }
 
         if (currentState)
             // シフトJIS なら変換用バッファに積む
             shiftJisBuffer.Append(c);
         else
             // その他の文字は無変換
             resultBuffer.Append(c);
     }
 
     // 最後のバッファを変換
     if (shiftJisBuffer.Length > 0)
     {
         resultBuffer.Append(VBStrConv(shiftJisBuffer.ToString(), newConversion));
     }
 
     // シフト JIS に変換
     if (fromUnicode)
         return encShiftJis.GetBytes(resultBuffer.ToString());
     else
         return resultBuffer.ToString();
 }
  
 // Microsoft.VisualBasic.Strings.StrConv を呼び出す
 private static string VBStrConv(string value, VbStrConv Conversion)
 {
     return Microsoft.VisualBasic.Strings.StrConv(value, Conversion);
 }

StrConv のソースを見ると、LCMapStringA を呼び出しているので、LCMapStringW を呼び出すと良い感じですが、実装が面倒そうなので、暇ができたら実装したいと思います。




トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   最終更新のRSS
Last-modified: 2013-09-08 (日) 04:18:33 (1389d)