ONC+ Developer's Guide

The XDR Language Specification

Notational Conventions

This specification uses a modified Backus-Naur Form notation for describing the XDR language. Here is a brief description of the notation:

  1. The characters |, (, ), [, ], and * are special.

  2. Terminal symbols are strings of any characters embedded in quotes (").

  3. Nonterminal symbols are strings of nonspecial italic characters.

  4. Alternative items are separated by a vertical bar (|).

  5. Optional items are enclosed in brackets.

  6. Items are grouped together by enclosing them in parentheses.

  7. A * following an item means 0 or more occurrences of the item.

    For example, consider the following pattern:

    "a " "very" (", " " very")* [" cold " "and"] " rainy " 
    				("day" | "night")

    An infinite number of strings match this pattern. A few of them are:

    a very rainy day
    a very, very rainy day
    a very cold and rainy day
    a very, very, very cold and rainy night

Lexical Notes

  1. Comments begin with /* and end with */.

  2. White space serves to separate items and is otherwise ignored.

  3. An identifier is a letter followed by an optional sequence of letters, digits, or underbars (_). The case of identifiers is not ignored.

  4. A constant is a sequence of one or more decimal digits, optionally preceded by a minus-sign (-).


    Example C-1 XDR Specification

    Syntax Information
    declaration:
    	type-specifier identifier
    	| type-specifier identifier "[" value "]"
    	| type-specifier identifier "<" [ value ] ">"
    	| "opaque" identifier "[" value "]"
    	| "opaque" identifier "<" [ value ] ">"
    	| "string" identifier "<" [ value ] ">"
    	| type-specifier "*" identifier
    	| "void"
    
    value:
    	constant
    	| identifier
    
    type-specifier:
    	 [ "unsigned" ] "int"
    	| [ "unsigned" ] "hyper"
    	| "float"
    	| "double"
    	| "quadruple"
    	| "bool"
    	| enum-type-spec
    	| struct-type-spec
    	| union-type-spec
    	| identifier
    
    enum-type-spec:
    	"enum" enum-body
    
    enum-body:
    	"{"
    	( identifier "=" value )
    	( "," identifier "=" value )*
    	"}"
    
    struct-type-spec:
    	"struct" struct-body
    
    struct-body:
    	"{"
    	( declaration ";" )
    	( declaration ";" )*
    	"}"
    
     union-type-spec:
    	"union" union-body
    
    union-body:
    	"switch" "(" declaration ")" "{"
    	( "case" value ":" declaration ";" )
    	( "case" value ":" declaration ";" )*
    	[ "default" ":" declaration ";" ]
    	"}"
    
    constant-def:
    	"const" identifier "=" constant ";"
    
    type-def:
    	"typedef" declaration ";"
    	| "enum" identifier enum-body ";"
    	| "struct" identifier struct-body ";"
    	| "union" identifier union-body ";"
    
    definition:
    	type-def
    	| constant-def
    
    specification:
    	definition *

Syntax Notes

The following are keywords and cannot be used as identifiers:

Table C-1 XDR Keywords

bool

const

enum

int

string

typedef

void

cas

default

float

opaque

struct

union

 

cha

double

hyper

quadruple

switch

unsigned

 

  1. Only unsigned constants may be used as size specifications for arrays. If an identifier is used, it must have been declared previously as an unsigned constant in a const definition.

  2. Constant and type identifiers within the scope of a specification are in the same name space and must be declared uniquely within this scope.

  3. Similarly, variable names must be unique within the scope of struct and union declarations. Nested struct and union declarations create new scopes.

  4. The discriminant of a union must be of a type that evaluates to an integer. That is, int, unsigned int, bool, an enum type, or any typedef that evaluates to one of these. Also, the case values must be legal discriminant values. Finally, a case value may not be specified more than once within the scope of a union declaration.

XDR Data Description

Here is a short XDR data description of a file data structure, which might be used to transfer files from one machine to another.


Example C-2 XDR File Data Structur

const MAXUSERNAME = 32;/* max length of a user name */
const MAXFILELEN = 65535;  /* max length of a file */
const MAXNAMELEN = 255;    /* max length of a file name */

/* Types of files: */
enum filekind {
 	TEXT = 0, /* ascii data */
 	DATA = 1, /* raw data */
 	EXEC = 2  /* executable */
 };

/* File information, per kind of file: */
union filetype switch (filekind kind) {
 	case TEXT:
 		void;                           /* no extra information */
 	case DATA:
 		string creator<MAXNAMELEN>;     /* data creator */
 	case EXEC:
 		string interpreter<MAXNAMELEN>; /*proginterptr*/
};

/* A complete file: */
struct file {
 	string filename<MAXNAMELEN>;        /* name of file */
 	filetype type;                      /* info about file */
 	string owner<MAXUSERNAME>;          /* owner of file */
 	opaque data<MAXFILELEN>;            /* file data */
};

Suppose now that there is a user named john who wants to store his LISP program sillyprog that contains just the data quit. His file would be encoded as follows:

Table C-2 XDR Data Description Example

Offset 

Hex Bytes 

ASCII 

Description 

00 00 00 09 

.... 

Length of filename = 9 

73 69 6c 6c 

sill 

Filename characters 

79 70 72 6f 

ypro 

... and more characters ... 

12 

67 00 00 00 

g... 

.. and 3 zero-bytes of fill 

16 

00 00 00 02 

.... 

Filekind is EXEC = 2 

20 

00 00 00 04 

.... 

Length of interpreter = 4 

24 

6c 69 73 70 

lisp 

Interpreter characters 

28 

00 00 00 04 

.... 

Length of owner = 4 

32  

6a 6f 68 6e 

john 

Owner characters 

36  

00 00 00 06 

.... 

Length of file data = 6 

40  

28 71 75 69 

(qu 

File data bytes ... 

44  

74 29 00 00 

t).. 

... and 2 zero-bytes of fill