XDR ルーチンを使用するときは、前もってメモリーを割り当てておかなければならない (または、必要なメモリーサイズを決定しておかなければならない) 場合があります。XDR 変換ルーチンで使用するメモリーの割り当てや割り当て解除が必要なときのために、xdr_sizeof() というルーチンが提供されています。xdr_sizeof() は、XDR フィルタルーチン (func()) がデータ (data()) の符号化や復号化で使用するバイト数を返します。xdr_sizeof() が返す値には、RPC ヘッダーやレコードマークは含まれていませんので、必要なメモリーサイズを正確に求めるには、それらのバイト数も加えなければなりません。エラーが起こった場合、xdr_sizeof() はゼロを返します。
xdr_sizeof(xdrproc_t func, void *data) |
xdr_sizeof() は、RPC 環境以外で XDR を使用するアプリケーションでメモリーを割り当てるとき、トランスポートプロトコルを選択するとき、下位レベルの RPC を使用してクライアント作成関数やサーバー作成関数を実行するときに特に便利です。
例 A-5 と 例 A-6で、xdr_sizeof()の 2 通りの使用方法を説明します。
#include <rpc/rpc.h> /* * この関数への入力引数は、CLIENT ハンドル、XDR 関数、XDR 変換を行う * データへのポインタです。XDR 変換を行うデータが、CLIENT ハンドルに * 結合しているトランスポートで送信可能な大きさの場合は TRUE、 * 大き過ぎて送信不可能な場合は FALSE を返します。 */ bool_t cansend(cl, xdrfunc, xdrdata) CLIENT *cl; xdrproc_t xdrfunc; void *xdrdata; { int fd; struct t_info tinfo; if (clnt_control(cl, CLGET_FD, &fd) == -1) { /* ハンドルの clnt_control() エラー */ return (FALSE); } if (t_getinfo(fd, &tinfo) == -1) { /* ハンドルの t_getinfo() エラー */ return (FALSE); } else { if (tinfo.servtype == T_CLTS) { /* * 現在使用しているのは非接続型トランスポートです。 * xdr_sizeof() を使用して、メモリー要求がこのトランスポートでは * 大き過ぎないか調べます。 */ switch(tinfo.tsdu) { case 0: /* TSDU の概念なし */ case -2: /* 通常データの送信不可能 */ return (FALSE); break; case -1: /* TSDU サイズの制限なし */ return (TRUE); break; default: if (tinfo.tsdu < xdr_sizeof(xdrfunc, xdrdata)) return (FALSE); else return (TRUE); } } else return (TRUE); } } |
例 A-6 は、xdr_sizeof() の使用例 2 になります。
#include <sys/statvfs.h> #include <sys/sysmacros.h> /* * この関数への入力引数は、ファイル名、XDR 関数、XDR 変換を行うデータへの * ポインタです。この関数は、ファイルが置かれているファイルシステムに、 * データを XDR 変換するのに必要な空間が残っていれば TRUE を返します。 * ファイルシステムに関して statvfs(2) で得られる情報はブロック数単位 * なので、xdr_sizeof() の戻り値もバイト数からディスクブロック数に * 変換しなければならないことに注意してください。 */ bool_t canwrite(file, xdrfunc, xdrdata) char *file; xdrproc_t xdrfunc; void *xdrdata; { struct statvfs s; if (statvfs(file, &s) == -1) { /* ハンドルの statvfs() エラー */ return (FALSE); } if (s.f_bavail >= btod(xdr_sizeof(xdrfunc, xdrdata))) return (TRUE); else return (FALSE); } |