note | XDR is not as efficient as pure binary I/O because it does involve the overhead of converting between the network and hardware binary representations. Nevertheless, it is still much more efficient than ASCII I/O because conversion to and from ASCII characters is much more involved than converting between binary representations. |
OPENW, /Xdr, 1, 'data.dat'
note | OPENW and OPENU normally open files for both input and output. However, XDR files can only be open in one direction at a time. Thus, using these procedures with the Xdr keyword results in a file open for output only, and the only I/O data transfer routines that can be used is WRITEU. OPENR works in the usual way. |
; Open a file for XDR output.
OPENW, /Xdr, 1, 'data.dat'
; Write a 10-element byte array.
WRITEU, 1, BINDGEN(10)
; Close the file ...
CLOSE, 1
; . . . and re-open it for input.
OPENR, /Xdr, 1, 'data.dat'
; Define b as a byte scalar.
b = 0B
; Try to read the first byte only.
READU, 1, b
; Close the file.
CLOSE, 1
%End of file encountered. Unit: 1.
File: data.dat
%Execution halted at $MAIN$ (READU).
; Define b as a byte array.
b = BYTARR(10)
; Read the whole array back at once.
READU, 1, b
; Close the file.
CLOSE, 1
note | This restriction (in other words, the necessity of transferring byte data as a single unit) does not apply to the other data types. |
#include <stdio.h>
#include <rpc/rpc.h>
/* For more information about xdr_wave_complex( ) and xdr_wave_string( ), refer to following section.*/
[xdr_wave_complex() and xdr_wave_string() included here]
main()
{
static struct { /* output data */
unsigned char c;
short s;
long l;
float f;
double d;
struct complex { float r, i } cmp;
char *str;
} data = {1, 2, 3, 4, 5.0, { 6.0, 7.0}, "Hello" };
/* Length of a character */
u_int c_len = sizeof (unsigned char);
/* Address of byte field */
char *c_data = (char *) &data.c;
/* stdio stream pointer */
FILE *outfile;
/* XDR handle */
XDR xdrs;
/* Open stdio stream and XDR handle */
outfile = fopen("data.dat", "w");
xdrstdio_create(&xdrs, outfile, XDR_ENCODE);
/* Output the data */
(void) xdr_bytes(&xdrs, &c_data, &c_len, c_len);
(void) xdr_short(&xdrs, (char *) &data.s);
(void) xdr_long(&xdrs, (char *) &data.l);
(void) xdr_float(&xdrs, (char *) &data.f);
(void) xdr_double(&xdrs, (char *) &data.d);
(void) xdr_wave_complex(&xdrs, (char *) &data.cmp);
(void) xdr_wave_string(&xdrs, &data.str);
/* Close XDR handle and stdio stream */
xdr_destroy(&xdrs);
(void) fclose(outfile);
}
; Create structure containing correct types.
data = {s, c:0B, s:0, l:0L, f:0.0, d:0.0D, $
cmp:COMPLEX(0), str:' '}
; Open the file for input.
OPENR, /Xdr, 1, 'data.dat'
; Read the data.
READU, 1, data
; Close the file.
CLOSE, 1
; Show the results.
PRINT, data
{ 1 2 3 4.00000 5.0000000
(6.00000, 7.00000) Hello}
Data Type | XDR Routine |
BYTE | xdr_bytes( ) |
INT | xdr_short( ) |
INT32 | xdr_long( ) |
LONG | xdr_long( ), if !XDR_LONG is set to 32 xdr_hyper( ) or xdr_longlong( ), if !XDR_LONG is set to 64 |
FLOAT | xdr_float( ) |
DOUBLE | xdr_double( ) |
COMPLEX | xdr_wave_complex( ) * |
STRING | xdr_wave_string( ) * |
The asterisk (*) indicates compound routines. |
note | For further details about XDR, consult the XDR documentation for your machine. If you are a Sun workstation user, consult the Network Programming manual. |
bool_t xdr_wave_complex(xdrs, p)
XDR *xdrs;
struct complex { float r, i } *p;
{
return(xdr_float(xdrs, (char *) &p->r)&&
xdr_float(xdrs, (char *) &p->i));
}
bool_t xdr_wave_string(xdrs, p)
XDR *xdrs;
char **p;
{
int input = (xdrs->x_op == XDR_DECODE);
short length;
/* If writing, obtain the length */
if (!input) length = strlen(*p);
/* Transfer the string length */
if (!xdr_short(xdrs, (char *) &length)) return(FALSE);
/* If reading, obtain room for the string */
if (input)
{
*p = malloc((unsigned) (length + 1));
*p[length] = '\0';/* Null termination */
}
/* If nonzero, return string length */
return (length ? xdr_string(xdrs, p, length) : TRUE);
}