"xdrlib" --- Codificar y decodificar datos XDR
**********************************************

**Código fuente:** Lib/xdrlib.py

======================================================================

El módulo "xdrlib" soporta el estándar de representación externa de
datos (*External Data Representation Standard*) como se describe en
**RFC 1014**, escrito por Sun Microsystems, Inc. en junio de 1987.
Soporta la mayoría de los tipos de datos descritos en el RFC.

El módulo "xdrlib" define dos clases, una para empaquetar variables en
la representación XDR, y otra para desempaquetar valores de la
representación XDR. También hay dos clases de excepciones.

class xdrlib.Packer

   "Packer" es la clase para empaquetar datos en la representación
   XDR. La clase "Packer" es instanciada sin argumentos.

class xdrlib.Unpacker(data)

   "Unpacker" es la clase complementaria que desempaqueta los valores
   de datos XDR de un búfer de cadena.  El búfer de entrada se
   proporciona como *data*.

Ver también:

  **RFC 1014** - XDR: estándar de representación externa de datos
     Este RFC definió la codificación de datos que era XDR en el
     momento en que este módulo fue escrito originalmente.
     Aparentemente ha quedado obsoleto, siendo reemplazado por **RFC
     1832**.

  **RFC 1832** - XDR: estándar de representación externa de datos
     El RFC más reciente que proporciona una definición revisada de
     XDR.


Instancias de la clase *Packer*
===============================

Las instancias de la clase "Packer" poseen los siguientes métodos:

Packer.get_buffer()

   Retorna el búfer del paquete actual como una cadena de caracteres.

Packer.reset()

   Restablece el búfer del paquete a la cadena de caracteres vacía.

En general, puedes empaquetar cualquiera de los tipos de datos XDR más
comunes, invocando el método "pack_tipo()" apropiado.  Cada método
toma un solo argumento, el valor a empaquetar.  Los siguientes métodos
simples de empaquetado de tipos de datos son soportados:
"pack_uint()", "pack_int()", "pack_enum()", "pack_bool()",
"pack_uhyper()", y "pack_hyper()".

Packer.pack_float(value)

   Empaqueta el número de punto flotante de precisión simple, *value*.

Packer.pack_double(value)

   Empaqueta el número de punto flotante de doble precisión, *value*.

Los siguientes métodos soportan el empaquetado de cadenas de
caracteres, bytes y datos opacos:

Packer.pack_fstring(n, s)

   Empaqueta una cadena de caracteres de longitud fija, *s*.  *n* es
   la longitud de la cadena de caracteres pero *no* es empaquetada en
   el búfer de datos.  La cadena de caracteres es rellenada con bytes
   nulos si es necesario, para garantizar que la longitud de los datos
   sea un múltiplo de 4 bytes.

Packer.pack_fopaque(n, data)

   Empaqueta un flujo de datos opaco de longitud fija, similar a
   "pack_fstring()".

Packer.pack_string(s)

   Empaqueta una cadena de caracteres de longitud variable, *s*.  En
   primer lugar, la longitud de la cadena de caracteres es empaquetada
   como un entero sin signo, luego los datos de la cadena de
   caracteres son empaquetados con "pack_fstring()".

Packer.pack_opaque(data)

   Empaqueta una cadena de caracteres de datos opacos de longitud
   variable, similar a "pack_string()".

Packer.pack_bytes(bytes)

   Empaqueta una secuencia de bytes de longitud variable, similar a
   "pack_string()".

Los siguientes métodos soportan el empaquetamiento de arreglos y
listas:

Packer.pack_list(list, pack_item)

   Empaqueta una *lista* de elementos homogéneos.  Este método es útil
   para listas con longitud indeterminada; en otras palabras, el
   tamaño no está disponible hasta que se haya recorrido toda la
   lista.  Para cada elemento de la lista, un entero sin signo "1" se
   empaqueta primero, seguido del valor de datos de la lista.
   *pack_item* es la función que se llama para empaquetar el elemento
   individual.  Al final de la lista, se empaqueta un entero sin signo
   "0".

   Por ejemplo, para empaquetar una lista de enteros, el código podría
   parecerse a esto:

      import xdrlib
      p = xdrlib.Packer()
      p.pack_list([1, 2, 3], p.pack_int)

Packer.pack_farray(n, array, pack_item)

   Empaqueta una lista (*arreglo*) de elementos homogéneos de longitud
   fija.  *n* es la longitud de la lista; *no* es empaquetada en el
   búfer, pero una excepción "ValueError" es lanzada si "len(array)"
   no es igual a *n*.  Al igual que en el método anterior, *pack_item*
   es la función usada para empaquetar cada elemento.

Packer.pack_array(list, pack_item)

   Empaqueta una *lista* de elementos homogéneos de longitud variable.
   Primero, la longitud de la lista es empaquetada como un entero sin
   signo, luego cada elemento es empaquetado como en el método
   "pack_farray()" de arriba.


Instancias de la clase *Unpacker*
=================================

La clase "Unpacker" ofrece los siguientes métodos:

Unpacker.reset(data)

   Restablece el búfer de cadena de caracteres a la *data*
   especificada.

Unpacker.get_position()

   Retorna la posición actual desempaquetada en el búfer de datos.

Unpacker.set_position(position)

   Establece la posición de desempaquetado del búfer de datos en la
   posición *position*. Debes tener cuidado al usar los métodos
   "get_position()" y "set_position()".

Unpacker.get_buffer()

   Retorna el búfer de datos actual desempaquetado como una cadena de
   caracteres.

Unpacker.done()

   Indica se ha completado el proceso de desempaquetado.  Lanza una
   excepción "Error" si no se han desempaquetado todos los datos.

Además, cada tipo de datos que puede ser empaquetados con un "Packer",
puede ser desempaquetado con un "Unpacker".  Los métodos de
desempaquetados son de la forma "unpack_tipo()", y no tienen
argumentos.  Estos retornan el objeto desempaquetado.

Unpacker.unpack_float()

   Desempaqueta un número de punto flotante de precisión simple.

Unpacker.unpack_double()

   Desempaqueta un número de punto flotante de doble precisión,
   similar a "unpack_float()".

Adicionalmente, los siguientes métodos desempaquetan cadenas de
caracteres, bytes y datos opacos:

Unpacker.unpack_fstring(n)

   Desempaqueta y retorna una cadena de caracteres de longitud fija.
   *n* es el número de caracteres esperados.  Se asume un relleno con
   bytes nulos hasta que la longitud de los datos sea un múltiplo de 4
   bytes.

Unpacker.unpack_fopaque(n)

   Desempaqueta y retorna un flujo de datos opaco de longitud fija,
   similar a "unpack_fstring()".

Unpacker.unpack_string()

   Desempaqueta y retorna una cadena de caracteres de longitud
   variable.  La longitud de la cadena de caracteres es desempaquetada
   primero como un entero sin signo, luego los datos de la cadena de
   caracteres son desempaquetados con el método "unpack_fstring()".

Unpacker.unpack_opaque()

   Desempaqueta y retorna un flujo de datos opaco de longitud
   variable, similar a "unpack_string()".

Unpacker.unpack_bytes()

   Desempaqueta y retorna una secuencia de bytes de longitud variable,
   similar a "unpack_string()".

Los siguientes métodos soportan el desempaquetado de arreglos y
listas:

Unpacker.unpack_list(unpack_item)

   Desempaqueta y retorna una lista de elementos homogéneos.  La lista
   se desempaqueta un elemento a la vez desempaquetando primero un
   indicador entero sin signo.  Si el flag es "1", el elemento se
   desempaqueta y se agrega a la lista.  Un flag de "0" indica el
   final de la lista.  *unpack_item* es la función a la que se invoca
   para desempaquetar los elementos.

Unpacker.unpack_farray(n, unpack_item)

   Desempaqueta y retorna (como una lista) un arreglo de elementos
   homogéneos de longitud fija.  *n* es el número de elementos de la
   lista que se esperan en el búfer. Como se mostró anteriormente,
   *unpack_item* es la función empleada para desempaquetar cada
   elemento.

Unpacker.unpack_array(unpack_item)

   Desempaqueta y retorna una *lista* de elementos homogéneos de
   longitud variable. En primer lugar, la longitud de la lista se
   desempaqueta como un entero sin signo, luego cada elemento se
   desempaqueta como en el método "unpack_farray()" de arriba.


Excepciones
===========

En este módulo, las excepciones se codifican como instancias de clase:

exception xdrlib.Error

   La clase de excepción base.  "Error" tiene un único atributo
   público, "msg", que contiene la descripción del error.

exception xdrlib.ConversionError

   Clase derivada de "Error".  No contiene variables de instancia
   adicionales.

A continuación se muestra un ejemplo de cómo detectarías una de estas
excepciones:

   import xdrlib
   p = xdrlib.Packer()
   try:
       p.pack_double(8.01)
   except xdrlib.ConversionError as instance:
       print('packing the double failed:', instance.msg)
