先日に引き続き、Erlang/OTP R13A の Unicode サポートについて調査していく。
リストとバイナリの混成
iodata() と同様のコンセプトの Unicode 対応版として、*chardata() というデータ型が導入される。
- chardata()
- UTF-8 でエンコードされたバイナリと、妥当な Unicode コードポイントからなるリストの混成
- latin1_chardata()
- latin1(iso-8859-1) でエンコードされたバイナリと、latin1 文字コードからなるリストの混成。iodata() と直接の互換性がある
- external_chardata()
- UTF-8 以外の Unicode 系エンコーディング(UTF-16/UTF-32)でエンコードされたバイナリと、妥当な Unicode コードポイントからなるリストの混成
このうち標準となるのが chardata() であり、Erlang/OTP 内部ではこの表現で統一するよう推奨されている。latin1_chardata() と external_chardata() は(少なくとも現時点では)後方互換性と外部システムとの連携のために用意されたものだと言える。実際 latin1_chardata() の定義におけるリストの制限は露骨に後方互換性を意識したものであることを示しているし、external_chardata() の定義はかなりテキトーだ(バイナリのエンコーディングに制限がないので、複数のエンコーディングが混在しても定義に適う。もちろんそれでは使い物にならないはずだが)。
unicode モジュール
*chardata() をフラットなリスト/バイナリに変換するための関数が unicode モジュールに用意される。詳細はマニュアルを参照。基本となるのは次の2つの関数である。
- characters_to_list(Data, InEncoding)
- Data を InEncoding でデコードして、Unicode コードポイントのリストに変換する
- characters_to_binary(Data, InEncoding, OutEncoding)
- Data を InEncoding でデコードして、OutEncoding でエンコードしたバイナリを返す
InEncoding に latin1 を指定した場合、Data は latin1_chardata() でなければならない。すなわちリスト内に含まれる整数は 255 以下に制限される。
例1:リストで表現された”日本語”という文字列を UTF-8 バイナリに変換
unicode:characters_to_binary([26085,26412,35486], utf8, utf8). %% -> <<230,151,165,230,156,172,232,170,158>>
例2:UTF-8 でエンコードされた”日本語”という文字列を UTF-16LE に変換
unicode:characters_to_binary( <<230,151,165,230,156,172,232,170,158>>, utf8, {utf16,little}). %% -> <<229,101,44,103,158,138>>
例3:”日本語”という文字列のリスト表現と UTF-16LE バイナリ表現を連結してフラットなリストに変換
unicode:characters_to_list( [[26085,26412,35486],<<229,101,44,103,158,138>>], {utf16,little}). %% -> [26085,26412,35486,26085,26412,35486]
続く。