先の記事ではDelphi 2009での文字列処理の流れの基本を書きましたが、
RawByteStringについても誤解が多いみたいなのでここで書いておこうと思います。
○RawByteStringの想定利用方法
RawByteStringは、「コードページを変換しない特殊なAnsiString型」です。
もう一度言います。
「コードページを変換しない特殊なAnsiString型」です。
このうち、「コードページを変換しない」
というのが最も大事なところです。
特集のRawByteStringのところでも書きましたが、
AnsiStringはデフォルトのコードページになるため、
関数や手続きの引数、または関数の戻り値として使ってしまうと、
意図しないコードページ変換が行われてしまいます。
これを防ぐためにコードページを変換しないRawByteStringが必要になったのです。
つまり、RawByteStringが使用される局面は、
・関数、手続きの引数
・関数の戻り値
が基本です。
○世間の誤解・誤用・濫用の有様
ところが、世間的には上記のような理解はあまり得られていません。
あたかも、RawByteString=万能のAnsiString型とでも言うような誤解があります。
原因のひとつは、SetCodePageの存在です。
これはRawByteStringのコードページを変更するというルーチンですが、
こいつを利用することでどんなコードページにでも変換できる便利な型という誤解が生まれているんだと思います。
もともと、RawByteStringを変数として宣言したり、変数パラメーターとして渡すことは想定外の利用方法です。
このことについてはNickがDelphi Unicodeワールド パートII: RTLの新機能と、UnicodeをサポートするクラスというEDNの記事で触れています。
-引用(RawByteString)
RawByteString型の目的は、コードページによる変換を一切行わずに任意のコードページの文字列を渡せるようにすることです。これは、バイト単位での文字列検索のように、特定のエンコーディングにこだわらないルーチンに極めて便利です。一般的に、文字列のコードページに無関係に文字列を処理するルーチンのパラメータにはRawByteStringを使用すべき、ということになるでしょう。 RawByteString型のインスタンスを宣言すると、未定義の動作やデータの欠落を引き起こしかねないので、滅多に使うべきではないでしょう。
-引用(SetCodePage)
SetCodePageは、十分に注意した上で、控え目に使うべきです。もしそのコードページが既存の文字列データに実際に適合しない場合には(例えばConvertがFalseに設定された)、予測できない結果が生じます。また、もし文字列の既存データが変換され、その新しいコードページが元の文字を表現できない場合には、データの欠落が発生します。
本当に重要なことが、しれっと書いてありますねw
また、もう一つの原因が、RTMのヘルプにRawByteStringの記載がないことです。
EDNの記事自体は2008/09/16に公表されていますが、
読み落としているとRawByteStringの使い方に気づくのは難しいでしょう。
とりあえずRawByteStringが万能な型だという認識をしている人は、
今すぐ間違いだと再認識して下さい。
正しい使い方は引数または戻り値です。
それ以外で使うと大抵はまともな結果を得られない物だと思って下さい。
RawByteStringあくまで特殊なAnsiString型です。
どう間違っても万能ではありません。