The second xdr_sizeof() example follows.
Example A-6 xdr_sizeof Example #2
Number Filters
The XDR library provides primitives to translate between numbers and their corresponding external representations. Primitives cover the set of numbers in the types:
[signed, unsigned] * [short, int, long] |
Specifically, the eight primitives are:
bool_t xdr_char(xdrs, op) XDR *xdrs; char *cp; bool_t xdr_u_char(xdrs, ucp) XDR *xdrs; unsigned char *ucp; bool_t xdr_int(xdrs, ip) XDR *xdrs; int *ip; bool_t xdr_u_int(xdrs, up) XDR *xdrs; unsigned *up; bool_t xdr_long(xdrs, lip) XDR *xdrs; long *lip; bool_t xdr_u_long(xdrs, lup) XDR *xdrs; u_long *lup; bool_t xdr_short(xdrs, sip) XDR *xdrs; short *sip; bool_t xdr_u_short(xdrs, sup) XDR *xdrs; u_short *sup; |
The first parameter, xdrs, is an XDR stream handle. The second parameter is the address of the number that provides data to the stream or receives data from it. All routines return TRUE if they complete successfully, and FALSE otherwise.
Floating-Point Filters
The XDR library also provides primitive routines for C floating-point types.
bool_t xdr_float(xdrs, fp) XDR *xdrs; float *fp; bool_t xdr_double(xdrs, dp) XDR *xdrs; double *dp; |
The first parameter, xdrs, is an XDR stream handle. The second parameter is the address of the floating-point number that provides data to the stream or receives data from it. Both routines return TRUE if they complete successfully, and FALSE otherwise.
Note - Because the numbers are represented in IEEE floating point, routines might fail when decoding a valid IEEE representation into a machine-specific representation, or the reverse.
Enumeration Filters
The XDR library provides a primitive for generic enumerations. The primitive assumes that a C enum has the same representation inside the machine as a C integer. The Boolean type is an important instance of the enum. The external representation of a Boolean is always TRUE (1) or FALSE (0).
#define bool_t int #define FALSE 0 #define TRUE 1 #define enum_t int bool_t xdr_enum(xdrs, ep) XDR *xdrs; enum_t *ep; bool_t xdr_bool(xdrs, bp) XDR *xdrs; bool_t *bp; |
The second parameters ep and bp are addresses of the associated type that provides data to or receives data from the stream xdrs.
No-Data Routine
Occasionally, an XDR routine must be supplied to the RPC system, even when no data is passed or required. The library provides such a routine.
bool_t xdr_void(); /* always returns TRUE */ |
Constructed Data Type Filters
Constructed or compound data type primitives require more parameters and perform more complicated functions than the primitives discussed previously. This section includes primitives for strings, arrays, unions, and pointers to structures.
Constructed data type primitives can use memory management. In many cases, memory is allocated when deserializing data with XDR_DECODE. Therefore, the XDR package must provide a means to de-allocate memory. The XDR operation, XDR_FREE provides this means. To review, the three XDR directional operations are XDR_ENCODE, XDR_DECODE, and XDR_FREE.
Strings
In the C language, a string is defined as a sequence of bytes terminated by a null byte, which is not considered when calculating string length. However, when a string is passed or manipulated, a pointer to it is employed. Therefore, the XDR library defines a string to be a char *, and not a sequence of characters. The external representation of a string is drastically different from its internal representation.
Externally, strings are represented as sequences of ASCII characters. Internally, strings are represented with character pointers. Conversion between the two representations is accomplished with the routine xdr_string():
bool_t xdr_string(xdrs, sp, maxlength) XDR *xdrs; char **sp; u_int maxlength; |
The first parameter xdrs is the XDR stream handle. The second parameter sp is a pointer to a string (type char **). The third parameter maxlength specifies the maximum number of bytes allowed during encoding or decoding. Its value is usually specified by a protocol. For example, a protocol specification might say that a file name can be no longer than 255 characters. The routine returns FALSE if the number of characters exceeds maxlength, and TRUE if it doesn't.
The behavior of xdr_string() is similar to the behavior of other routines discussed in this section. For example, in the direction XDR_ENCODE, the parameter sp points to a string of a certain length. If the string does not exceed maxlength, the bytes are serialized.
The effect of deserializing a string is subtle. First the length of the incoming string is determined; it must not exceed maxlength. Next sp is dereferenced. If the value is NULL, a string of the appropriate length is allocated and *sp is set to this string. If the original value of *sp is nonnull, the XDR package assumes that a target area has been allocated that can hold strings no longer than maxlength. In either case, the string is decoded into the target area. The routine then appends a null character to the string.
In the XDR_FREE operation the string is obtained by dereferencing sp. If the string is not NULL, it is freed and *sp is set to NULL. In this operation xdr_string() ignores the maxlength parameter.
Note that you can use XDR on an empty string ("") but not on a NULL string.