この節では、新たな XDR ストリームインスタンスの作成に必要な抽象データ型を示します。
例 A-13 の構造体は、XDR ストリームとのインタフェースを定義します。
enum xdr_op {XDR_ENCODE=0, XDR_DECODE=1, XDR_FREE=2}; typedef struct { enum xdr_op x_op; struct xdr_ops { bool_t (*x_getlong)(); /* ストリームから long 型データを入力 */ bool_t (*x_putlong)(); /* ストリームに long 型データを出力 */ bool_t (*x_getbytes)(); /* ストリームから複数バイトを入力 */ bool_t (*x_putbytes)(); /* ストリームに複数バイトを出力 */ u_int (*x_getpostn)(); /* ストリームのオフセットを返す */ bool_t (*x_setpostn)(); /* オフセットの再設定 */ caddr_t (*x_inline)(); /* バッファリングされたデータへのポインタ */ VOID (*x_destroy)(); /* プライベートエリアの解放 */ bool_t (*x_control)(); /* クライアント情報の検索、変更 */ bool_t (*x_getint32)(); /* ストリームから int を取得 */ bool_t (*x_putint32)(); /* ストリームに int を出力 */ } *x_ops; caddr_t x_public; /* ユーザーデータ */ caddr_t x_private; /* プライベートデータへのポインタa */ caddr_t x_base; /* 位置情報のためのプライベートデータ */ int x_handy; /* その他のプライベートワード */ } XDR; |
x_op フィールドは、現在ストリームに対して実行している処理内容を示します。このフィールドは XDR プリミティブにとっては重要なフィールドですが、ストリームの実現に対しては影響ありません。すなわち、ストリームは、この値に依存した方法で作成しないでください。x_private、x_base、x_handy の各フィールドは、特定のストリームを実現するためのプライベートデータです。x_public は XDR クライアントのためのフィールドでなので、XDR ストリームを実現するために使用したり、XDR プリミティブで使用したりできません。x_getpostn()、x_setpostn()、x_destroy() はストリームへのアクセス操作に使用するマクロです。x_inline() ルーチンには、XDR * と符号なし整数 (バイトカウント) の 2 つの引数を渡します。このルーチンからは、ストリームの内部バッファセグメントへのポインタが返されます。呼び出し側ではそのバッファセグメントを自由に使用できます。ストリーム側からみると、そのバッファセグメントに入っているデータは失われます。このルーチンは、要求されたサイズのバッファセグメントを返せない場合は NULL を返します。x_inline() ルーチンは、バッファを反復して使用するためのもので、このバッファの使用は移植可能ではありません。この機能の使用はお勧めできません。
ストリームに対するバイトシーケンスの単純な入出力には、x_getbytes() と x_putbytes() を使用します。入出力に成功すれば TRUE、失敗すれば FALSE が返されます。この 2 つのルーチンの引数は同じです。xxx を関数名に合わせて置き換えます。
bool_t xxxbytes(xdrs, buf, bytecount) XDR *xdrs; char *buf; u_int bytecount; |
x_getint32() と x_putint32() のオペレーションにより、データストリームから int 数値を受け取ったり、データストリームへ数値を出力したりできます。この 2 つのルーチンは、数値のマシン固有表現から標準外部表現への変換を担当します。変換には、UNIX のプリミティブ htonl() と ntohl() を利用できます。上位レベルの XDR 対応ソフトウェアでは、符号付きと符号なしの整数のビット数は同じで、負にならない整数のビットパターンは符号なしの整数のビットパターンと同じであるとみなします。入出力に成功すれば TRUE 、失敗すれば FALSE が返されます。
関数 x_getint() と x_putint() では、これらのオペレーションを使用します。この 2 つのルーチンの引数は同じです。
bool_t xxxint(xdrs, ip) XDR *xdrs; int32_t *ip; |
これらのオペレーションの long バージョン (x_getlong() と x_putlong()) でも、 x_getint32() と x_putint32() を呼び出します。この場合、プログラムがどのようなマシンで実行されていても、処理される量は必ず 4 バイトになります。
XDR ストリームを新規開発するときは、作成ルーチンを使用して、新たな操作ルーチンを持つ XDR 構造体を作成し、クライアントに提供しなければなりません。