Module Marshal


module Marshal: sig  end
Marshaling of data structures.

このモジュールは、任意のデータ構造を、ファイルに書いたりパイプやネットワーク接続を通して送信したりできるバイト列にエンコードする関数を提供します。このバイト列は、後で読み込んで (別プロセスからでも) 、元のデータ構造に直すことが出来ます。バイト列のフォーマットは Objective Caml のバージョンが同じならば全てのマシンで互換性を持ちます。

注意: 現時点では marshaling は型が安全ではありません。marshal されたデータの値は伝達されますが型は伝達されません。このため読み直したデータが文脈によって想定されている型になっているかどうかチェックすることが出来ません。特に、Marshal.from_* 関数の結果の型は 'a ですが、これは問題を生じさせることがあります。Caml の返値は全ての 'a に対して型 'a になっているとは限りません。コンパイル時に決定出来ないなんらかの型になっています。プログラマは以下の文法を使って、返値の想定される型を明示的に与えてください。

marshal された値は人が読みやすい形式ではなく、バイト列には表示不可能な文字も使用されています。よって、Marshal.to_channelMarshal.from_channel に接続される入出力チャンネルは open_out_binopen_in_bin などを使用してバイナリモードでオープンされてなければなりません。テキストモードでオープンされたチャンネルでは、テキストチャンネルとバイナリチャンネルが異なる挙動を示すプラットフォーム (Windows など) でデコードエラーを起こす場合があります。


type extern_flags =
| No_sharing (*Don't preserve sharing*)
| Closures (*Send function closures*)
以下の Marshal.to_* 関数にわたすフラグです。

val to_channel : Pervasives.out_channel -> 'a -> extern_flags list -> unit
Marshal.to_channel chan v flags はチャンネル chanv を表すバイト列を書き出します。引数 flags は共有値や関数値に対する marshal の振る舞いを決定するフラグのリストです。空リストを指定しても構いません。

flagsMarshal.No_sharing を指定しない場合、値 v 中の循環や共有が検出されたらそれもバイト列に含めて保存します。これによって marshal が必ず終了すると保証されることに注意してください。ただし異なる Marshal.to_channel の呼び出しで出力された複数の値の間で共有されるデータは検出されません。 flagsMarshal.No_sharing を指定する場合、共有は無視されます。 v 中に共有構造がない場合 marshaling が速くなりますが、共有がある場合は遅くなった上に出力されるデータが大きくなってしまいます。さらに、v に循環がある場合は停止しません。

flagsMarshal.Closures が指定しない場合、v 中に関数値があると marshal は失敗します。「純粋」なデータ構造 (関数値もオブジェクトも含まない) だけなら、異なるプログラム間でも安全にやりとり出来ます。flagsMarshal.Closures が指定される場合、関数値はプログラムのコードの位置 (ポインタ) として出力されます。この場合 marshal の出力は、出力したプログラムと全く同じプログラム (コンパイルされた同じコード) からしか読み込み直せません (これは読み込みの時、ポインタの示す位置のコードの MD5 ダイジェストを利用してチェックされます) 。

val to_string : 'a -> extern_flags list -> string
Marshal.to_string v flagsv を表すバイト列を含む文字列を返します。引数 flags の意味は Marshal.to_channel と同じです。
val to_buffer : string -> int -> int -> 'a -> extern_flags list -> int
Marshal.to_buffer buff ofs len v flags は値 v を表す文字列を、文字列 buff の指定された位置に保存します。ofs 文字目から、最長 len 文字保存され、実際に書き込んだ文字数を返します。v のバイト列が len では収まらない場合、例外 Failure を発生します。
val from_channel : Pervasives.in_channel -> 'a
Marshal.from_channel chan はチャンネル chan から値を表すバイト列 (Marshal.to_* のどれかで構成された者) を読んで値を再構成しそれを返します。
val from_string : string -> int -> 'a
Marshal.from_string buff ofsMarshal.from_channel と同じように値を再構成します。ただしこちらはチャンネルではなく文字列 buffofs 文字目から読み込みます。
val header_size : int
marshal の出力する値を表すバイト列は固定長のヘッダ部と可変長のデータ部に分かれます (データ部の長さはヘッダ部に保存されています) 。Marshal.header_size はヘッダ部の長さです (単位文字数) 。Marshal.data_size buff ofs はデータ部の長さを返します (ただし文字列 buffofs 文字目からヘッダがきちんとある場合) 。Marshal.total_size buff ofs では全体のサイズが返されます。Marshal.data_sizeMarshal.total_sizebuff, ofs のヘッダがなかったり壊れていたりしたら例外 Failure を発生します。

文字列バッファに保存されたバイト列を読む手順は次のようになります。まず Marshal.header_size 文字をバッファに読み込み、次に Marshal.data_size を使って残りのバイト列の長さを把握し、十分な長さ読み込めたら、最後に Marshal.from_string で元の値に戻します。

val data_size : string -> int -> int
Marshal.header_size を見てください。
val total_size : string -> int -> int
Marshal.header_size を見てください。