/*
 * demo.x -- demonstrates and tests some jrpcgen features. It doesn't
 *           boil down to a useful example, it just checks a few things
 *           within code generation.
 *
 * To compile, use
 *   java -jar jrpcgen.jar -p tests.org.acplt.oncrpc.jrpcgen -nobackup demo.x
 */

typedef string STRING<>;
typedef STRING STRINGVECTOR<>;

/* Check that dependencies are followed when dumping constants */
const C_B = C_A;
const C_A = C_C;
const C_C = 42;

/** Check enumerations */
enum ENUMBAZ { E_BAZ = C_B };

enum ENUMFOO {
    FOO, BAR, BAZ_1 = C_B, BAZ_2, BAZ_3 = E_BAZ
};

const FIXEDBUFFERLENGTH = 64;

/**
 * Definition of a single-linked list.
 * 
 * <p>Each node takes an integer value
 * and holds a reference to the next node,
 * if present.
 */
struct LINKEDLIST {
    int foo;
    struct LINKEDLIST *next;
};

struct TREE {
	string key<>;
	string value<>;
	struct TREE *left;
	struct TREE *right;
};

union UNION switch ( bool okay ) {
    case TRUE:
        LINKEDLIST *list;
    default:
        void;
};

union ANSWER switch ( int value ) {
    case 40:
    case 41:
        int wrong;
    case 42:
        int the_answer;
    default:
        int check_hash;
};

struct SILLYSTRUCT {
    char fixedbuffer[512];
    char buffer<128>;
    opaque fixedbytes[FIXEDBUFFERLENGTH];
    opaque bytes<32>;
    short si1;
    unsigned short usi1;
    unsigned int ui1;
    unsigned ui2;
    hyper hyper1;
    hyper int hyper2;
    unsigned hyper uhyper1;
    unsigned hyper int uhyper2; 
    string nonsense<>;
};

struct SOMERESULT {
	int error;
	string typedesc<>;
	opaque data<>;
	SILLYSTRUCT arrayone<23>;
	SILLYSTRUCT arraytwo[24];
	STRING stringone;
	STRINGVECTOR stringarray;
};

/**
 * Indirections declare optional data. With primitives such as
 * 'int', the transport of 'null' - values as known for example
 * to database columns gets possible.
 */
struct INDIRECTIONS {
	char *optionalCharacter;
	int *optionalInteger;
	float *optionalFloat;
	double *optionalDouble;
	STRING *optionalString;
	ENUMFOO *optionalEnum;
	ANSWER *optionalUnion;
	SILLYSTRUCT *optionalStruct;
};

/**
 * Dynamic vectors with a maximum length equal to one
 * are another way to declare optional data. However,
 * they are mapped to Java arrays instead of Java objects
 * as with indirections. Therefore they get their place here. 
 */
struct OPTIONALDATA {
	char optionalCharacter<1>;
	int optionalInteger<1>;
	float optionalFloat<1>;
	double optionalDouble<1>;
	STRING optionalString<1>;
	ENUMFOO optionalEnum<1>;
	ANSWER optionalUnion<1>;
	SILLYSTRUCT optionalStruct<1>;
}; 

struct PREDEFINED_TYPES {
	PredefinedTypeA a;
	PredefinedTypeB b[2];
	PredefinedTypeC c<>;
};

/**
 * The demo program shall give some examples on
 * type and procedure definitions for ONC/RPC programs.
 *
 * <p>A lot of variants are possible.
 */
program DEMO {
    version FIRST_DEMO_VERSION {
    	/**
    	 * Usually there is no need to define
    	 * the null-procedure call, explicitely.
    	 */
        void NULL(void) = 0;
        
        /**
         * Let's echo the passed string!
         *
         * @param The string to be echoed. 
         * @return The passed string.
         */
        string echo(string) = 1;
        string concat(STRINGVECTOR) = 2;
        bool checkfoo(ENUMFOO) = 3;
        ENUMFOO foo(void) = 4;
        LINKEDLIST ll(LINKEDLIST) = 5;
        SOMERESULT readSomeResult(void) = 42;
    } = 1;
    version SECOND_DEMO_VERSION {
        void NULL(void) = 0;
        string cat(string, string) = 42;
        
        /**
         * Concatenates the passed strings.
         *
         * @param one The beginning of the string to build
         * @param two The second part of the string to build
         * @param three The last part of the string to build
         * @return The string resulting from the concatenation of
         * the passed three strings {@code one}, {@code two} and
         * {@code three}.
         */
        string cat3(string one, string two, string three) = 43;
        string checkfoo(ENUMFOO foo) = 3;
        LINKEDLIST llcat(LINKEDLIST l1, LINKEDLIST l2) = 55;
        void test(string a, ENUMFOO b, ENUMFOO c, int d) = 100;
    } = 2;
} = 0x20049678;

/* End of file demo.x */

