きりかノート 3冊め

おあそびプログラミング

RubyCocoa 今週のコミット 2014-06-13 文字列のエンコーディング

Ruby 1.8と1.9以降のちがいについては、るびま25号の"Rubyist Magazine - Ruby M17N の設計と実装"に詳しい。すげー雑に書くと、

という感じ。CocoaのNSStringは後者と同様にエンコーディングを持ってる。

なので、RubyObjective-Cで文字列オブジェクトを変換するときには、それぞれのエンコーディングに読み替えて処理するようにしてやればよい。中間データとしては例によって(char *)になる。

RubyエンコーディングはEncodingクラスおよびそのインスタンスで表現され(内部的にはrb_encoding*とindexも使える)、NSStringではNSStringEncoding(CoreFoundationではCFStringEncoding)を使う。

それぞれ文字列の生成や、バイト列を取るときにエンコーディングを指定できるので、プログラム的には問題なさそう。

実装に当たって決めなきゃいけないことは、

あたり。

1つめは基本がんばるしかない。やってみないとわからないけど、IANA Character Setsの名前でマッチングさせて変換表を自動的に作れたりするとだいぶ楽になるかもしれない。

2つめはRubyではダミーエンコーディング、NSStringではCoreFoundationになるけどkCFStringEncodingInvalidIdとよくわからないデータで構成される文字列(?)を表現するエンコーディングがある(正しくはRubyのはそうではない)。Rubyにはバイナリとかバイト列用のダミーエンコーディングはあらかじめ定義はされていないので、rb_define_dummy_encoding()を使って自分で使うダミーエンコーディングを定義してやる必要がある。

3つめは次のどちらかかなあ。

  • 変換できそうな一般的なエンコーディング(たとえばUTF-8)に変換を試みる。できなければバイト列と同様に扱う。
  • バイト列として扱う。

今回の仮実装では前者とした。

で、これらをとりあえず実装してみたのがr2551になる。

恐ろしいことにこれでもけっこうちゃんと動いたりするわけだけど、もうちょっとマシにするためのタスクはこのくらい。

  • 変換をswitch/ifでなく、対応関係を登録したst_tableを使うようにする。Rubyはindexを、CocoaはCFStringEncodingを登録するようにするつもり。
    • ruby側からの変換表へのアクセス機能を提供。実行時に変換表を登録、削除、lookupできるように。
  • ダミーエンコーディングの定義をRubyCocoa初期化のときに行うように。
  • ダミーエンコーディングのStringをつくる関数を定義して、それを使うようにする。

だいぶゴールが近づいてきた感じがする。