External Data Representation (XDR) Files
Normally, binary data is not portable between different mac
XDR (eXternal Data Representation, developed by Sun Microsystems, Inc.) is a scheme under which all bina
Opening XDR Files
To use the XDR format, you must specify the Xdr keyword when opening the file. For example:
OPENW, /Xdr, 1, 'data.dat'
Transferring Data To and From XDR Files
The primary differences in the way PV-WAVE I/O procedures work with XDR files, as opposed to other data files, are listed below:
The only I/O data transfer routines that can be used with a file opened for XDR are READU and WRITEU.
The length of strings is saved and restored along with the string. This means that you do not have to initialize a string of the correct length before reading a string from the XDR file. (This is necessary with normal binary I/O, and is described in Binary Transfer of String Variables.)
Reading binary XDR data into a PV-WAVE LONG variable in PV-WAVE 64-bit causes 8 bytes to be extracted from the XDR file. In order to read 4 byte values from a binary XDR file you must pass the READ routine a PV-WAVE INT32 variable.
For the sake of efficiency, byte data is transferred as a single unit. Therefore, byte variables must be initialized to a length that matches the data to be input. Otherwise, an error message is displayed. See the following example for more details.
Example—Reading Byte Data from an XDR File
For example, given the statements:
; 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'
the following statements:
; Define b as a byte scalar.
b = 0B
; Try to read the first byte only.
READU, 1, b
; Close the file.
CLOSE, 1
will result in the error:
%End of file encountered. Unit: 1.
File: data.dat
%Execution halted at $MAIN$ (READU).
Instead, it is necessary to read the entire byte array back in one operation using statements such as:
; Define b as a byte array.
b = BYTARR(10)
; Read the whole array back at once.
READU, 1, b
; Close the file.
CLOSE, 1
Example —Reading C-generated XDR Data with PV-WAVE
This example demonstrates how to write XDR data with a C program and read the subsequent file with PV-WAVE.
C Program Write
The following C program produces a file containing different types of data using XDR. The usual error checking is omitted for the sake of brevity.
#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);
}
Running this program creates the file data.dat containing the XDR data.
PV-WAVE Read
The following PV-WAVE statements can be used to read this file and print its contents to the screen:
; 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
Executing these PV-WAVE statements produces the output:
{ 1 2 3 4.00000 5.0000000(6.00000, 7.00000) Hello}
XDR Conventions for Programmers
PV-WAVE uses certain conventions for reading and writing XDR files. If you use XDR only to exchange data in and out of PV-WAVE, you don’t need to be concerned about these conventions because PV-WAVE takes care of it for you.
However, if you want to create PV-WAVE compatible XDR files from other languages, you need to know the actual XDR routines used by PV-WAVE for various data types. These routine names are summarized in XDR Routines Used by PV‑WAVE :
| Data Type | XDR Routine |
|---|---|
| BYTE | xdr_bytes( ) |
| INT | xdr_short( ) |
| INT32 | xdr_long( ) |
| LONG | xdr_long( ), if !XDR_LONG is set to 32xdr_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. | |
XDR Routines for Transferring Complex and String Data
The routines used for types complex and string are not primitive XDR routines. Their definitions are shown in the following C code:
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);
}