Erlterm is a project mainly written in Common Lisp, based on the MIT license.
Converting between Erlang term and Common Lisp object
文字列を扱う場合、使用するCommon Lispの処理系がユニコード(UTF-32)に対応していないと文字化けが生じる可能性がある
DestributionHeader,ATOM_CACHE_REF及び圧縮形式には未対応
* (require :asdf)
* (require :asdf-install)
* (asdf-install:install "erlterm-0.0.1.tar.gz")
メインパッケージ
Erlang項のバイナリエンコーディングをCommon Lispのオブジェクトにデコードする。
binary-intput-stream: 入力元のバイナリストリーム packet: バイナリデータ本体の前に、受信するバイトの長さが付与されている場合は、そのサイズデータのバイト長を指定する。 サイズデータが付与されていない場合はnilを指定する。 (member nil 1 2 4) ※ 現バージョンでは、このサイズデータは単に読み捨てられている。 term: デコードされたCommon Lispオブジェクト
Common LispのオブジェクトをErlang項のバイナリフォーマットにエンコードする
term: エンコード対象となるオブジェクト binary-output-stream: バイナリデータ出力先のストリーム packet: バイナリデータ本体の前に、出力バイト数を付与する場合は、そのサイズデータに用いるバイト長を指定する。 サイズデータを付与しない場合はnilを指定する。 (member nil 1 2 4) minor-version: バイナリフォーマットのマイナーバージョン。 0 or 1。 1の場合は浮動小数点数のエンコーディングに、新しいフォーマットが使用される。
ポートを使った通信例:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Common Lisp側# リストの反転を行う
;;;; ファイル名: reverse.lisp
;;;;
;;;; 処理系: sbcl-1.0.40
;;;; ※ 標準入出力に対してバイナリ操作が行えるのは(おそらく)SBCLの拡張
(require :asdf)
(require :erlterm)
(defvar *in* *standard-input*)
(defvar *out* *standard-output*)
(handler-case
(loop
(let ((list (erlterm:decode-term *in* :packet 2))) ; リストを受け取る
(erlterm:encode-term (reverse list) *out* :packet 2) ; 反転して返す
(force-output *out*)))
(end-of-file ()
'done))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Erlang側(補助モジュール)# ポート関連の操作をラップ
%%%% ファイル名: port_rpc.erl
-module(port_rpc).
-export([open/1,close/1,call/2]).
open(Command) ->
open_port({spawn, Command}, [{packet, 2},binary]).
close(Port) ->
Port ! {self(), close}.
call(Port, Message) ->
Port ! {self(), {command, term_to_binary(Message)}},
receive
{Port, {data, Data}} -> binary_to_term(Data)
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Erlang側(shell)# Common Lispとの通信
> c(port_rpc). % コンパイル & ロード
> Port = port_rpc:open("sbcl --script reverse.lisp"). % ポートオープン
> port_rpc:call(Port, [first, {1, "middle", 3.2}, last]). % Common Lisp呼び出し
=> [last, {1, "middle", 3.2}, first] % => 反転されたリストが返る
> port_rpc:close(Port). % ポートクローズ