⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xdr.nts.ms

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 MS
📖 第 1 页 / 共 4 页
字号:
Let's continue with more constructed data types..NH 3\&Opaque Data.IX "XDR library" "opaque data".LPIn some protocols, handles are passed from a server to client.The client passes the handle back to the server at some later time.Handles are never inspected by clients;they are obtained and submitted.That is to say, handles are opaque.The.I xdr_opaque() .IX xdr_opaque() "" \fIxdr_opaque()\fPprimitive is used for describing fixed sized, opaque bytes..DS.ft CWbool_t xdr_opaque(xdrs, p, len)    XDR *xdrs;    char *p;    u_int len;.DEThe parameter.I p is the location of the bytes;.I lenis the number of bytes in the opaque object.By definition, the actual datacontained in the opaque object are not machine portable..NH 3\&Fixed Sized Arrays.IX "XDR library" "fixed sized arrays".LPThe XDR library provides a primitive,.I xdr_vector (),for fixed-length arrays..ie t .DS.el .DS L.ft CW#define NLEN 255    /* \fImachine names must be < 256 chars\fP */#define NGRPS 20    /* \fIuser belongs to exactly 20 groups\fP */.sp.5struct netuser {    char *nu_machinename;    int nu_uid;    int nu_gids[NGRPS];};.sp.5bool_txdr_netuser(xdrs, nup)    XDR *xdrs;    struct netuser *nup;{    int i;.sp.5    if (!xdr_string(xdrs, &nup->nu_machinename, NLEN))        return(FALSE);    if (!xdr_int(xdrs, &nup->nu_uid))        return(FALSE);    if (!xdr_vector(xdrs, nup->nu_gids, NGRPS, sizeof(int),         xdr_int)) {            return(FALSE);    }    return(TRUE);}.DE.NH 3\&Discriminated Unions.IX "XDR library" "discriminated unions".LPThe XDR library supports discriminated unions.A discriminated union is a C union and an.I enum_tvalue that selects an \*Qarm\*U of the union..DS.ft CWstruct xdr_discrim {    enum_t value;    bool_t (*proc)();};.sp.5bool_t xdr_union(xdrs, dscmp, unp, arms, defaultarm)    XDR *xdrs;    enum_t *dscmp;    char *unp;    struct xdr_discrim *arms;    bool_t (*defaultarm)();  /* \fImay equal NULL\fP */.DEFirst the routine translates the discriminant of the union located at .I *dscmp .The discriminant is always an.I enum_t .Next the union located at.I *unp is translated.The parameter.I armsis a pointer to an array of.I xdr_discrimstructures. Each structure contains an ordered pair of.I [value,proc] .If the union's discriminant is equal to the associated.I value ,then the.I procis called to translate the union.The end of the.I xdr_discrimstructure array is denoted by a routine of value.I NULL (0).  If the discriminant is not found in the.I armsarray, then the.I defaultarmprocedure is called if it is non-null;otherwise the routine returns.I FALSE ..LP.I "Example D:"Suppose the type of a union may be integer,character pointer (a string), or a.I gnumbers structure.Also, assume the union and its current typeare declared in a structure.The declaration is:.ie t .DS.el .DS L.ft CWenum utype { INTEGER=1, STRING=2, GNUMBERS=3 };.sp.5struct u_tag {    enum utype utype;   /* \fIthe union's discriminant\fP */    union {        int ival;        char *pval;        struct gnumbers gn;    } uval;};.DEThe following constructs and XDR procedure (de)serializethe discriminated union:.ie t .DS.el .DS L.ft CWstruct xdr_discrim u_tag_arms[4] = {    { INTEGER, xdr_int },    { GNUMBERS, xdr_gnumbers }    { STRING, xdr_wrap_string },    { __dontcare__, NULL }    /* \fIalways terminate arms with a NULL xdr_proc\fP */}.sp.5bool_txdr_u_tag(xdrs, utp)    XDR *xdrs;    struct u_tag *utp;{    return(xdr_union(xdrs, &utp->utype, &utp->uval,        u_tag_arms, NULL));}.DEThe routine.I xdr_gnumbers() was presented above in .I "The XDR Library"section..I xdr_wrap_string() was presented in example C.The default .I arm parameter to.I xdr_union() (the last parameter) is.I NULL in this example.  Therefore the value of the union's discriminantmay legally take on only values listed in the.I u_tag_arms array.  This example also demonstrates thatthe elements of the arm's array do not need to be sorted..LPIt is worth pointing out that the values of the discriminantmay be sparse, though in this example they are not.It is always goodpractice to assign explicitly integer values to each element of thediscriminant's type.This practice both documents the externalrepresentation of the discriminant and guarantees that differentC compilers emit identical discriminant values..LPExercise: Implement.I xdr_union() using the other primitives in this section..NH 3\&Pointers.IX "XDR library" "pointers".LPIn C it is often convenient to put pointersto another structure within a structure.The.I xdr_reference() .IX xdr_reference() "" \fIxdr_reference()\fPprimitive makes it easy to serialize, deserialize, and freethese referenced structures..DS.ft CWbool_t xdr_reference(xdrs, pp, size, proc)    XDR *xdrs;    char **pp;    u_int ssize;    bool_t (*proc)();.DE.LPParameter.I pp is the address ofthe pointer to the structure;parameter.I ssizeis the size in bytes of the structure (use the C function.I sizeof() to obtain this value); and.I procis the XDR routine that describes the structure.When decoding data, storage is allocated if.I *pp is.I NULL ..LPThere is no need for a primitive.I xdr_struct() to describe structures within structures,because pointers are always sufficient..LPExercise: Implement.I xdr_reference() using.I xdr_array ().Warning:.I xdr_reference() and.I xdr_array() are NOT interchangeable external representations of data..LP.I "Example E:"Suppose there is a structure containing a person's nameand a pointer to a.I gnumbers structure containing the person's gross assets and liabilities.The construct is:.DS.ft CWstruct pgn {    char *name;    struct gnumbers *gnp;};.DEThe corresponding XDR routine for this structure is:.DS.ft CWbool_txdr_pgn(xdrs, pp)    XDR *xdrs;    struct pgn *pp;{    if (xdr_string(xdrs, &pp->name, NLEN) &&      xdr_reference(xdrs, &pp->gnp,      sizeof(struct gnumbers), xdr_gnumbers))        return(TRUE);    return(FALSE);}.DE.IX "pointer semantics and XDR".I "Pointer Semantics and XDR" .LPIn many applications, C programmers attach double meaning to the values of a pointer.  Typically the value.I NULL (or zero) means data is not needed,yet some application-specific interpretation applies.In essence, the C programmer is encodinga discriminated union efficientlyby overloading the interpretation of the value of a pointer.For instance, in example E a.I NULL pointer value for.I gnpcould indicate thatthe person's assets and liabilities are unknown.That is, the pointer value encodes two things:whether or not the data is known;and if it is known, where it is located in memory.Linked lists are an extreme example of the useof application-specific pointer interpretation..LPThe primitive.I xdr_reference() .IX xdr_reference() "" \fIxdr_reference()\fPcannot and does not attach any specialmeaning to a null-value pointer during serialization.That is, passing an address of a pointer whose value is.I NULL to.I xdr_reference() when serialing data will most likely cause a memory fault and, on the UNIXsystem, a core dump..LP.I xdr_pointer() correctly handles .I NULL pointers.  For more information about its use, see the.I "Linked Lists"topics below..LP.I Exercise:After reading the section on.I "Linked Lists" ,return here and extend example E so thatit can correctly deal with .I NULL pointer values..LP.I Exercise:Using the.I xdr_union (),.I xdr_reference() and.I xdr_void() primitives, implement a generic pointer handling primitivethat implicitly deals with.I NULL pointers.  That is, implement.I xdr_pointer ()..NH 2\&Non-filter Primitives.IX "XDR" "non-filter primitives".LPXDR streams can be manipulated withthe primitives discussed in this section..DS.ft CWu_int xdr_getpos(xdrs)    XDR *xdrs;.sp.5bool_t xdr_setpos(xdrs, pos)    XDR *xdrs;    u_int pos;.sp.5xdr_destroy(xdrs)    XDR *xdrs;.DEThe routine.I xdr_getpos() .IX xdr_getpos() "" \fIxdr_getpos()\fPreturns an unsigned integerthat describes the current position in the data stream.Warning: In some XDR streams, the returned value of.I xdr_getpos() is meaningless;the routine returns a \-1 in this case(though \-1 should be a legitimate value)..LPThe routine.I xdr_setpos() .IX xdr_setpos() "" \fIxdr_setpos()\fPsets a stream position to.I pos .Warning: In some XDR streams, setting a position is impossible;in such cases,.I xdr_setpos() will return.I FALSE .This routine will also fail if the requested position is out-of-bounds.The definition of bounds varies from stream to stream..LPThe.I xdr_destroy() .IX xdr_destroy() "" \fIxdr_destroy()\fPprimitive destroys the XDR stream.Usage of the streamafter calling this routine is undefined..NH 2\&XDR Operation Directions.IX XDR "operation directions".IX "direction of XDR operations".LPAt times you may wish to optimize XDR routines by takingadvantage of the direction of the operation \(em.I XDR_ENCODE.I XDR_DECODEor.I XDR_FREEThe value.I xdrs->x_opalways contains the direction of the XDR operation.Programmers are not encouraged to take advantage of this information.Therefore, no example is presented here.  However, an example in the.I "Linked Lists"topic below, demonstrates the usefulness of the.I xdrs->x_opfield..NH 2\&XDR Stream Access.IX "XDR" "stream access".LPAn XDR stream is obtained by calling the appropriate creation routine.These creation routines take arguments that are tailored to thespecific properties of the stream..LPStreams currently exist for (de)serialization of data to or fromstandard I/O.I FILEstreams, TCP/IP connections and UNIX files, and memory..NH 3\&Standard I/O Streams.IX "XDR" "standard I/O streams".LPXDR streams can be interfaced to standard I/O using the.I xdrstdio_create() .IX xdrstdio_create() "" \fIxdrstdio_create()\fProutine as follows:.DS.ft CW#include <stdio.h>#include <rpc/rpc.h>    /* \fIxdr streams part of rpc\fP */.sp.5voidxdrstdio_create(xdrs, fp, x_op)    XDR *xdrs;    FILE *fp;    enum xdr_op x_op;.DEThe routine.I xdrstdio_create() initializes an XDR stream pointed to by.I xdrs .The XDR stream interfaces to the standard I/O library.Parameter.I fpis an open file, and.I x_opis an XDR direction..NH 3\&Memory Streams.IX "XDR" "memory streams".LPMemory streams allow the streaming of data into or out ofa specified area of memory:.DS.ft CW#include <rpc/rpc.h>.sp.5voidxdrmem_create(xdrs, addr, len, x_op)    XDR *xdrs;    char *addr;    u_int len;    enum xdr_op x_op;.DEThe routine.I xdrmem_create() .IX xdrmem_create() "" \fIxdrmem_create()\fPinitializes an XDR stream in local memory.The memory is pointed to by parameter.I addr ;parameter.I lenis the length in bytes of the memory.The parameters.I xdrsand.I x_opare identical to the corresponding parameters of.I xdrstdio_create ().Currently, the UDP/IP implementation of RPC uses.I xdrmem_create ().Complete call or result messages are built in memory before calling the.I sendto() system routine..NH 3\&Record (TCP/IP) Streams.IX "XDR" "record (TCP/IP) streams".LPA record stream is an XDR stream built on top ofa record marking standard that is built on top of theUNIX file or 4.2 BSD connection interface..DS.ft CW#include <rpc/rpc.h>    /* \fIxdr streams part of rpc\fP */.sp.5xdrrec_create(xdrs,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -