[comp.sys.sun] xdr_char

paquette@cpsc.ucalgary.ca (Trevor Paquette) (03/09/89)

I am currently writing a program that must use the xdr routines for
reading and wrinting data. I have however come across a small drawback.
One of the machines that I am proting the code to (Iris 3020) does not
have xdr_char() in it's libraries. My question then is this:

How can I emulate xdr_char() with the other xdr routines?  I have tried
the following but it core dumps in me..

xdr_char(xdrs, ch)
XDR *xdrs;
char *ch;
{
 char t[2];
 int ret;

 if(xdrs -> x_op == XDR_ENCODE)
   {
    t[0] = *ch;
    t[1] = 0;
    ret = xdr_string(xdrs, t, 1);
   }
 else
   {
    ret = xdr_string(xdrs, t, 1);
    *ch = t[0];
   }
 return(ret);
}

               Trevor Paquette/GraphicsLand, Calgary, Alberta                 
 ..uunet!{ubc-cs,utai,alberta}!calgary!paquette          ICBM:51 03 N/114 05 W
 calgary!paquette@cs.ubc.ca      Luminous beings we are, not this crude matter

mike@cfdl.larc.nasa.gov (Mike Walker) (03/23/89)

Here is the actual xdr_char function from the SUNRPC 4.0 distribution:

/*
 * XDR a char
 */
bool_t
xdr_char(xdrs, cp)
	XDR *xdrs;
	char *cp;
{
	int i;

	i = (*cp);
	if (!xdr_int(xdrs, &i)) {
		return (FALSE);
	}
	*cp = i;
	return (TRUE);
}

The entire (source) of 4.0 is or soon will be available for ftp from
titan.rice.edu (and others no doubt.)

Mike
--
Mike Walker                         mike@cfdl.larc.nasa.gov
NASA Langley Research Center             [128.155.24.55]
Bldg. 1192D, Mailstop 159           Work: (804) 864-6804
Hampton, Virginia.  23665           Home: (804) 865-0325

viktor@cucumber.princeton.edu (Viktor Dukhovni) (03/30/89)

paquette@cpsc.ucalgary.ca (Trevor Paquette) writes:
>xdr_char(xdrs, ch)
>XDR *xdrs;
>char *ch;
>{
> char t[2];
> int ret;
>
> if(xdrs -> x_op == XDR_ENCODE)
>   {
>    t[0] = *ch;
>    t[1] = 0;
>    ret = xdr_string(xdrs, t, 1);
>   }
> else
>   {
>    ret = xdr_string(xdrs, t, 1);
>    *ch = t[0];
>   }
> return(ret);
>}

There are a couple of problems with this "replacement" for xdr_char:

1)  xdr_string,  like all xdr_rroutines,  expects a pointer to the object
being encoded/decoded.  So  xdr_string(xdrs,t,1)  is wrong!  You need a
char **.  Unfortunately the compiler won't let you take the address of an
array, arrays are *constant* pointers!

	If you want to use the above add
	char *p = t ;
	and call xdr_sting with
	xdr_string(xdrs,&p,...)

2) As well as encode and decode, xdrs->x_op could be XDR_FREE you should
probably pass that down to xdr_string() as you are doing, but it may be
better to leave poor ch alone when freeing args, particulary since p (You
have replaced t by &p) may not point anywhere useful!  So *ch = **p  may
get you a SIGSEGV.

3)  The iris may well have xdr_bytes(),  or xdr_opaque(),  either should
be able to give you better mileage than xdr_string, (No need to encode the
trailing null.  Also if you are already paying the penalty of passing
around integer length fields (=1 or 2) per character,  why not pass the
chars as ints!

	xdr_char(xdrs,p)
		XDR *xdrs ;
		u_char *p ; 	/* Lets not get messed up in sign murk */
	{
		int x = *p ;
		bool_t ret=xdr_int(xdrs,&x) ;
		if ( xdrs->x_op == XDR_DECODE )
			*p = x & 0377 ;  /* Don't need to be this anal */
		return ret ;
	}


Hope this helps.  It may be all be a late night dream,  but looks ok for
being typed on the fly.

	Viktor Dukhovni <viktor%fine@princeton.edu>