\section{\module{xdrlib} ---
         XDR データのエンコードおよびデコード}

\declaremodule{standard}{xdrlib}
\modulesynopsis{外部データ表現 (XDR, External Data Representation) 
         データのエンコードおよびデコード。}

\index{XDR}
\index{External Data Representation}

\module{xdrlib} モジュールは外部データ表現標準 (External Data 
Representation Standard) のサポートを実現します。この標準は
1987 年に Sun Microsystems, Inc. によって書かれ、 \rfc{1014}
で定義されています。このモジュールでは RFC で記述されている
ほとんどのデータ型をサポートしています。

\module{xdrlib} モジュールでは 2 つのクラスが定義されています。
一つは変数を XDR 表現にパックするためのクラスで、もう一方は
XDR 表現からアンパックするためのものです。2 つの例外クラスが
同様にして定義されています。

\begin{classdesc}{Packer}{}
\class{Packer} はデータを XDR 表現にパックするためのクラスです。
\class{Packer} クラスのインスタンス生成は引数なしで行われます。
\end{classdesc}

\begin{classdesc}{Unpacker}{data}
\code{Unpacker} は Packer と対をなしていて、文字列バッファから
XDR をアンパックするためのクラスです。入力バッファ \var{data}
を引数に与えてインスタンスを生成します。
\end{classdesc}


\begin{seealso}
  \seerfc{1014}{XDR: External Data Representation Standard}{この
                RFC が、かつてこのモジュールが最初に書かれた当時に
                XDR 標準でであったデータのエンコード方法を定義していました。
                現在は \rfc{1832} に更新されているようです。}

  \seerfc{1832}{XDR: External Data Representation Standard}{こちらが
                新しい方のRFCで、XDR の改訂版が定義されています。}
\end{seealso}


\subsection{Packer オブジェクト \label{xdr-packer-objects}}

\class{Packer} インスタンスには以下のメソッドがあります:

\begin{methoddesc}[Packer]{get_buffer}{}
現在のパック処理用バッファを文字列で返します。
\end{methoddesc}

\begin{methoddesc}[Packer]{reset}{}
パック処理用バッファをリセットして、空文字にします。
\end{methoddesc}

一般的には、適切な \code{pack_\var{type}()} メソッドを使えば、
一般に用いられているほとんどの XDR データをパックすることができます。
各々のメソッドは一つの引数をとり、パックしたい値を与えます。
単純なデータ型をパックするメソッドとして、以下のメソッド:
\method{pack_uint()} 、\method{pack_int()} 、 \method{pack_enum()} 、
 \method{pack_bool()} 、\method{pack_uhyper()} そして
\method{pack_hyper()} がサポートされています。

\begin{methoddesc}[Packer]{pack_float}{value}
単精度 (single-precision) の浮動小数点数 \var{value} をパックします。
\end{methoddesc}

\begin{methoddesc}[Packer]{pack_double}{value}
倍精度 (double-precision) の浮動小数点数 \var{value} をパックします。
\end{methoddesc}

以下のメソッドは文字列、バイト列、不透明データ (opaque data) のパック
処理をサポートします:

\begin{methoddesc}[Packer]{pack_fstring}{n, s}
固定長の文字列、\var{s} をパックします。 \var{n} は文字列の長さ
ですが、この値自体はデータバッファにはパック \emph{されません} 。
4 バイトのアラインメントを保証するために、文字列は必要に応じて null 
バイト列でパディングされます。
\end{methoddesc}

\begin{methoddesc}[Packer]{pack_fopaque}{n, data}
\method{pack_fstring()} と同じく、固定長の不透明データストリームを
パックします。
\end{methoddesc}

\begin{methoddesc}[Packer]{pack_string}{s}
可変長の文字列 \var{s} をパックします。文字列の長さが最初に符号なし
整数でパックされ、続いて \method{pack_fstring()} を使って文字列データが
パックされます。
\end{methoddesc}

\begin{methoddesc}[Packer]{pack_opaque}{data}
\method{pack_string()} と同じく、可変長の不透明データ文字列をパックします。
\end{methoddesc}

\begin{methoddesc}[Packer]{pack_bytes}{bytes}
\method{pack_string()} と同じく、可変長のバイトストリームをパックします。
\end{methoddesc}

以下のメソッドはアレイやリストのパック処理をサポートします:

\begin{methoddesc}[Packer]{pack_list}{list, pack_item}
一様な項目からなる \var{list} をパックします。このメソッドは
サイズ不定、すなわち、全てのリスト内容を網羅するまでサイズが
分からないリストに対して有用です。リストのすべての項目に対し、
最初に符号無し整数 \code{1} がパックされ、続いてリスト中の
データがパックされます。\var{pack_item} は個々の項目をパック
するために呼び出される関数です。リストの末端に到達すると、
符号無し整数 \code{0} がパックされます。

例えば、整数のリストをパックするには、コードは以下のようになるはず
です:

\begin{verbatim}
import xdrlib
p = xdrlib.Packer()
p.pack_list([1, 2, 3], p.pack_int)
\end{verbatim}
\end{methoddesc}

\begin{methoddesc}[Packer]{pack_farray}{n, array, pack_item}
一様な項目からなる固定長のリスト (\var{array}) をパックします。
\var{n} はリストの長さです。この値はデータバッファにパック
\emph{されません} が、\code{len(\var{array})} が \var{n} と
等しくない場合、例外 \exception{ValueError} が送出されます。
上と同様に、\var{pack_item} は個々の要素をパック処理するための
関数です。
\end{methoddesc}

\begin{methoddesc}[Packer]{pack_array}{list, pack_item}
一様の項目からなる可変長の \var{list} をパックします。
まず、リストの長さが符号無し整数でパックされ、つづいて各
要素が上の \method{pack_farray()} と同じやり方でパックされます。
\end{methoddesc}


\subsection{Unpacker オブジェクト \label{xdr-unpacker-objects}}

\class{Unpacker} クラスは以下のメソッドを提供します:

\begin{methoddesc}[Unpacker]{reset}{data}
文字列バッファを \var{data} でリセットします。
\end{methoddesc}

\begin{methoddesc}[Unpacker]{get_position}{}
データバッファ中の現在のアンパック処理位置を返します。
\end{methoddesc}

\begin{methoddesc}[Unpacker]{set_position}{position}
データバッファ中のアンパック処理位置を \var{position} に設定します。
\method{get_position()} および \method{set_position()} は注意して
使わなければなりません。
\end{methoddesc}

\begin{methoddesc}[Unpacker]{get_buffer}{}
現在のアンパック処理用データバッファを文字列で返します。
\end{methoddesc}

\begin{methoddesc}[Unpacker]{done}{}
アンパック処理を終了させます。全てのデータがまだアンパックされて
いなければ、例外 \exception{Error} が送出されます。
\end{methoddesc}

上のメソッドに加えて、\class{Packer} でパック処理できるデータ型はいずれも
\class{Unpacker} でアンパック処理できます。アンパック処理メソッドは
\code{unpack_\var{type}()} の形式をとり、引数をとりません。
これらのメソッドはアンパックされたデータオブジェクトを返します。

\begin{methoddesc}[Unpacker]{unpack_float}{}
単精度の浮動小数点数をアンパックします。
\end{methoddesc}

\begin{methoddesc}[Unpacker]{unpack_double}{}
\method{unpack_float()} と同様に、倍精度の浮動小数点数をアンパックします。
\end{methoddesc}

上のメソッドに加えて、文字列、バイト列、不透明データをアンパックする
以下のメソッドが提供されています:

\begin{methoddesc}[Unpacker]{unpack_fstring}{n}
固定長の文字列をアンパックして返します。\var{n} は予想される文字列の
長さです。4 バイトのアラインメントを保証するために null バイトによる
パディングが行われているものと仮定して処理を行います。
\end{methoddesc}

\begin{methoddesc}[Unpacker]{unpack_fopaque}{n}
\method{unpack_fstring()} と同様に、固定長の不透明データストリームを
アンパックして返します。
\end{methoddesc}

\begin{methoddesc}[Unpacker]{unpack_string}{}
可変長の文字列をアンパックして返します。最初に文字列の長さが符号無し
整数としてアンパックされ、次に \method{unpack_fstring()} を使って
文字列データがアンパックされます。
\end{methoddesc}

\begin{methoddesc}[Unpacker]{unpack_opaque}{}
\method{unpack_string()} と同様に、可変長の不透明データ文字列をアンパック
して返します。
\end{methoddesc}

\begin{methoddesc}[Unpacker]{unpack_bytes}{}
\method{unpack_string()} と同様に、可変長のバイトストリームをアンパック
して返します。
\end{methoddesc}

以下メソッドはアレイおよびリストのアンパック処理をサポートします。

\begin{methoddesc}[Unpacker]{unpack_list}{unpack_item}
一様な項目からなるリストをアンパック処理してかえします。リストは
一度に 1 要素づつアンパック処理されます、まず符号無し整数によるフラグ
がアンパックされます。もしフラグが \code{1} なら、要素はアンパックされ、
返り値のリストに追加されます。フラグが \code{0} であれば、リストの終端
を示します。 \var{unpack_item} は個々の項目をアンパック処理するために
呼び出される関数です。
\end{methoddesc}

\begin{methoddesc}[Unpacker]{unpack_farray}{n, unpack_item}
一様な項目からなる固定長のアレイをアンパックして（リストとして）返します。
\var{n} はバッファ内に存在すると期待されるリストの要素数です。
上と同様に、 \var{unpack_item} は各要素をアンパックするために使われる
関数です。
\end{methoddesc}

\begin{methoddesc}[Unpacker]{unpack_array}{unpack_item}
一様な項目からなる可変長の \var{list} をアンパックして返します。
まず、リストの長さが符号無し整数としてアンパックされ、続いて各要素が
上の \method{unpack_farray()} のようにしてアンパック処理されます。
\end{methoddesc}


\subsection{例外 \label{xdr-exceptions}}

このモジュールでの例外はクラスインスタンスとしてコード
されています:

\begin{excdesc}{Error}
ベースとなる例外クラスです。\exception{Error} public なデータメンバ
として \member{msg} を持ち、エラーの詳細が収められています。
\end{excdesc}

\begin{excdesc}{ConversionError}
\exception{Error} から導出されたクラスです。インスタンス変数は塚されて
いません。
\end{excdesc}

これらの例外を補足する方法を以下の例に示します:

\begin{verbatim}
import xdrlib
p = xdrlib.Packer()
try:
    p.pack_double(8.01)
except xdrlib.ConversionError, instance:
    print 'packing the double failed:', instance.msg
\end{verbatim}



