高度な検索
Developer Connection
Member Login ログイン | ご入会 ADC連絡先

Technical Q&A QA1173
Text Encodings in VFS


Q: Mac OS X 用にファイルシステム(VFS)プラグインを書いています。テキストコードを正しく処理するにはどうすればよいでしょうか?

A: Mac OS X では、VFS API のファイル名は、定義上、正規分解による Unicode 文字で、UTF-8 を使ってエンコードされています。このことが、いくつかの興味深い問題を引き起こしています。

合成済み文字と分解された文字

この Q&A は、「合成済み Unicode 文字」および「分解された Unicode 文字」という用語を熟知していることを前提としています。これらの用語をよく知らない場合は、DTS Q&A 1235 Converting to Precomposed Unicode(合成済み Unicode への変換)に簡単な説明が掲載されています。

重要:
この Q&A で使われている「分解された」および「合成済み」という用語は、大まかにいうと、Unicode Normal Forms D および C にそれぞれ対応しています。しかし、ほとんどのボリューム形式は、これらの標準形の厳密な仕様に従っているわけではありません。たとえば HFS Plus は、Normal Form D の変形を使用しており、U+2000 から U+2FFF、U+F900 から U+FAFF、および U+2F800 から U+2FAFF は分解されません(古い Mac のテキストコードからの相互変換に関する問題を回避します)。お使いのボリューム形式にも同じような変形がある可能性があります。

ボリューム形式

ターゲットのボリューム形式が、合成済み Unicode と分解された Unicode のどちらを使用するかを定義します。たとえば、HFS Plus は分解された Unicode を使用し、UDF と SMB は合成済み Unicode を使用します。

残念ながら、いくつかのボリューム形式(たとえば、NFS)は承認された標準がありません。このことが、後述のように、さらにいくつかの課題を提示します。

注:
この Q&A では、ディスク上のボリュームおよびネットワークプロトコルのどちらを示す場合にも、ボリューム形式という用語を使用します。

名前を戻す

上位のレイヤへ名前を戻すときには(たとえば、VOP_READDIR エントリポイントから)、必ず分解された文字による名前を戻す必要があります。基盤のボリューム形式が合成済み文字の名前を使用する場合、システムに名前を戻す前に、合成済みの文字はすべて、それに相当する分解された文字に変換しておく必要があります。

名前の受け付け

ほとんどの場合、高レベルのソフトウェアは、分解された文字による名前をファイルシステムに渡します。ただしこれが保証されているわけではありません。合成済み文字による名前がファイルシステムに渡される状況がいくつかあります(その一部については後述します)。ファイルシステムに入ってきたときの状態に関係なく、基盤のボリューム形式に必要なエンコード体系に名前を変換しなければなりません。このため、基盤のボリューム形式が合成済み文字を要求する場合は、ディスクに書き込む前に、名前を合成済み文字の変形に変換しておく必要があります。同様に、ボリューム形式が分解された文字を要求する場合は、合成済み文字はすべて分解しなければなりません。

基盤のボリューム形式が標準を規定していない場合はどうすべきかという問題があります。ここではよい解決策がありません。アップルの NFS の実装のように、何の変更も加えずに、ユーザに選択してもらうための何らかのユーザインタフェース(AppleShare ログインダイアログの「文字セット」ポップアップのようなもの)を提供することはできます。いずれにしてもユーザエクスペリエンスは理想的なものにはならないでしょう。

実装

Unicode コンバータ は、合成済み Unicode 文字を分解された Unicode 文字に変換する仕組みを提供します。これについてより詳しくは、DTS Q&A 1235 Converting to Precomposed Unicode(合成済み Unicode への変換)を参照してください。ただし、Unicode コンバータは、VFS プラグインが入っているカーネル内から呼び出すことができません。このため、おそらく Unicode を合成および分解するコードを自分で実行する必要があります。このための基本が、Technote 1150 HFS Plus Volume Formatの中ので説明されています。

Apple Public Source License に同意すると、HFS Plus の実装でアップルが使用しているコードを参照することもできます。

重要:
"utfconv.h" の先頭にある __APPLE_API_UNSTABLE ガードは、これらの API をカーネルコードが直接呼び出した場合に、将来、バイナリ互換性の問題が生じる可能性があることを示します。

お使いのファイルシステムでこのソースを利用しない場合でも、目を通しておくことを強く推奨します。合成済みと分解された Unicode テキスト間の変換は処理が複雑ですので、アップルのこの実装が、問題の範囲を理解する上で役立ちます。

この問題についての詳細は、Unicode コンソーシアムのウェブサイト を参照してください。Unicode のための国際的なコンポーネント(Unicode の国際化を目的とした IBM のオープンソースコード)で提供される正規化された関数を調べるのもよいでしょう。

互換性

理論上、上記のテクニックは、アプリケーションにとっては互換性の問題につながる可能性があります。たとえば、アプリケーションが合成済み文字による名前の付いたファイルを作成した後、単純なバイナリ文字列比較を使ってそのファイルがあるかどうかディレクトリを反復して検索しても、ファイルは見つかりません。実際には、めったに起こらない問題です。基本ファイルシステムである HFS Plus は、この方法で動作するため、お使いのファイルシステムと互換性のないプログラムは、すべて HFS Plus とも互換性がありません。

アップルに組み込まれているファイルシステムのほとんどは、上記のテクニックを使用しています。大きな例外としては、NFS と UFS があります。特に NFS は、合成済み文字による名前のファイルを作成する Mac 以外のクライアントと共有できますが、Mac OS X の NFS クライアントは、それらをアプリケーションに戻す前に分解しません。ユーザがネイティブのコピープログラム(コマンドラインツールの cp など)を使って NFS ボリュームからお使いのボリュームにファイルをコピーした場合、コピープログラムは、名前を分解せずにファイルをコピーします。このためお使いのファイルシステムは、合成済み文字による名前でファイルを作成することが要求されます。上記のように、お使いのファイルシステムでは、これに対応するように準備しておく必要があります。


[2003 年 2 月 10 日]