module Marshal: sig end
このモジュールは、任意のデータ構造を、ファイルに書いたりパイプやネットワーク接続を通して送信したりできるバイト列にエンコードする関数を提供します。このバイト列は、後で読み込んで (別プロセスからでも) 、元のデータ構造に直すことが出来ます。バイト列のフォーマットは Objective Caml のバージョンが同じならば全てのマシンで互換性を持ちます。
注意: 現時点では marshaling は型が安全ではありません。marshal されたデータの値は伝達されますが型は伝達されません。このため読み直したデータが文脈によって想定されている型になっているかどうかチェックすることが出来ません。特に、Marshal.from_*
関数の結果の型は 'a
ですが、これは問題を生じさせることがあります。Caml の返値は全ての 'a
に対して型 'a
になっているとは限りません。コンパイル時に決定出来ないなんらかの型になっています。プログラマは以下の文法を使って、返値の想定される型を明示的に与えてください。
(Marshal.from_channel chan : type)
.
ファイル内のオブジェクトが与えられた型に属さない場合、動作時に何が起こるかわかりません。Marshal.to_channel
や Marshal.from_channel
に接続される入出力チャンネルは open_out_bin
や open_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
はチャンネル chan
に v
を表すバイト列を書き出します。引数 flags
は共有値や関数値に対する marshal の振る舞いを決定するフラグのリストです。空リストを指定しても構いません。
flags
に Marshal.No_sharing
を指定しない場合、値 v
中の循環や共有が検出されたらそれもバイト列に含めて保存します。これによって marshal が必ず終了すると保証されることに注意してください。ただし異なる Marshal.to_channel
の呼び出しで出力された複数の値の間で共有されるデータは検出されません。
flags
に Marshal.No_sharing
を指定する場合、共有は無視されます。
v
中に共有構造がない場合 marshaling が速くなりますが、共有がある場合は遅くなった上に出力されるデータが大きくなってしまいます。さらに、v
に循環がある場合は停止しません。
flags
に Marshal.Closures
が指定しない場合、v
中に関数値があると marshal は失敗します。「純粋」なデータ構造 (関数値もオブジェクトも含まない) だけなら、異なるプログラム間でも安全にやりとり出来ます。flags
に Marshal.Closures
が指定される場合、関数値はプログラムのコードの位置 (ポインタ) として出力されます。この場合 marshal の出力は、出力したプログラムと全く同じプログラム (コンパイルされた同じコード) からしか読み込み直せません (これは読み込みの時、ポインタの示す位置のコードの MD5 ダイジェストを利用してチェックされます) 。
val to_string : 'a -> extern_flags list -> string
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 ofs
は Marshal.from_channel
と同じように値を再構成します。ただしこちらはチャンネルではなく文字列 buff
の ofs
文字目から読み込みます。val header_size : int
Marshal.header_size
はヘッダ部の長さです (単位文字数) 。Marshal.data_size
buff ofs
はデータ部の長さを返します (ただし文字列 buff
の ofs
文字目からヘッダがきちんとある場合) 。Marshal.total_size
buff ofs
では全体のサイズが返されます。Marshal.data_size
も Marshal.total_size
も buff
, 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
を見てください。