例 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)(); /* プライベートエリアの解放 */
} *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;
データストリームに対する long 型数値の入出力には、x_getlong() と x_putlong() を使用します。この 2 つのルーチンは、数値のマシン固有表現から標準外部表現への変換を担当します。変換には、UNIX のプリミティブ htonl() と ntohl() を利用できます。上位レベルのXDR 対応ソフトウェアでは、符号付きと符号なしの long 型整数のビット数は同じで、非負の整数のビットパターンは符号なし整数のビットパターンと同じであるとみなします。入出力に成功すれば TRUE 、失敗すれば FALSE が返されます。
この 2 つのルーチンの引数は同じです。
bool_t xxxlong(xdrs, lp) XDR *xdrs; long *lp;
XDR ストリームを新規開発するときは、作成ルーチンを使用して、新たな操作ルーチンを持つ XDR 構造体を作成し、クライアントに提供しなければなりません。