ONC+ 開発ガイド

XDR ルーチンで必要なメモリー

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 通りの使用方法を説明します。


例 A-5 xdr_sizeof() の使用例 1

#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 になります。


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