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);
}
|