The

The **.idl** declarations are as follows:

/*

* Transmit_as example: Here we turn a large sparse array into

* a small conformant array for transmission. The server is able

* to reconstitute the
sparse array.

*/

const long int S_ARRAY_SIZE = 32;

typedef struct{

unsigned32 value;

unsigned32
subscript;

} a_element;

typedef struct{

unsigned32 size;

[size_is(size)] a_element array[];

}compact_array_t;

typedef [transmit_as(compact_array_t)] unsigned32 sparse_array_t[S_ARRAY_SIZE];

void ship_array(

[in] handle_t handle,

[in] sparse_array_t *array,

[out] error_status_t *status

);

All the callback routines are placed in a single module that is linked with both client and server (in this case, for the **test** interface). As an alternative, the appropriate callbacks could
be declared separately within the client and server modules:

/*

* test_xmit.c:

*

* The routines required to implement a [transmit_as] type.

*/

#include "test.h"

/* The to_xmit routine must allocate all space for the transmitted

* type. In general, the stubs have no way to determine how to allocate

*
space for the transmitted type. Here, for example, the to_xmit

* routine determines the size of a conformant array.

*/

void
sparse_array_t_to_xmit(sparse_array_t *s_array,

compact_array_t **c_array

)

{

unsigned32 i,j;

unsigned32 csize;

/* Count up the number of nonzero elements in the sparse array */

for (i = 0, csize = 0; i < S_ARRAY_SIZE; i++)

{

if ((*s_array)[i] != 0)

{

csize++;

}

}

/*
Allocate a structure to hold the compact array */

*c_array = (compact_array_t *)calloc(csize*2 + 1, sizeof(unsigned32));

((compact_array_t)**c_array).size = csize;

/* Fill in the compact array from the nonzero elements */

for (i = 0, j = 0; i < S_ARRAY_SIZE;
i++)

{

if ((*s_array)[i] != 0)

{

((compact_array_t)**c_array).array[j].value = (*s_array)[i];

((compact_array_t)**c_array).array[j++].subscript = i;

}

}

}

/*

* The from_xmit routine may not have to
allocate any space for the

* presented type. The presented type is always of a definite size

* (conformant, varying, etc. types are not permitted), so the stub

* provides an instance of the top level of the presented type. In

* this case, for example, s_array points to an instance of a sparse

* array. If the
presented type contains any pointers, the from_xmit

* routine needs to allocate space for the referents and the free_inst

* routine needs to free them.

*/

void sparse_array_t_from_xmit(compact_array_t *c_array,

sparse_array_t *s_array)

{

unsigned32 i,j;

for (i = 0; i < ((compact_array_t) * c_array).size; i++)

{

j = ((compact_array_t)*c_array).array[i].subscript;

(*s_array)[j] = ((compact_array_t)*c_array).array[i].value;

}

}

/* This routine is called to free anything allocated by the

* to_xmit routine.

*/

void sparse_array_t_free_xmit(compact_array_t *c_array)

{

free(c_array);

}

/* This routine is called to free anything allocated by the

* from_xmit routine. Since from_xmit doesn't allocate anything

* this is a null routine.

*/

void sparse_array_t_free_inst(sparse_array_t *s_array)

{

}

The client code to exercise the sparse array transmitted type is as follows:

sparse_array_t test_array;

/* Create a sparse array with only three nonzero members */

memset(test_array,0,sizeof(unsigned32)*S_ARRAY_SIZE);

test_array[0] = 2;

test_array[20] = 4;

test_array[31] = 8;

/*

* When compressed, this array requires 7 32-bit
integers, as opposed

* 32 32-bit integers for the uncompressed array. If you don't care

* about reconstructing the sparse array on the server side, you can

* get even more efficiency.

*/

ship_array(binding_h, &test_array, &status);

The server manager code is as follows:

void ship_array(

handle_t binding_h,

sparse_array_t *array,

error_status_t *status

)

{

int i;

/*

* Print the elements of the sparse array.

*/

for (i = 0; i < S_ARRAY_SIZE; i++)

{

printf("%i0, (*array)[i]);

}

*status = error_status_ok;

}

Note that the **free_inst** routine will not be needed if the transmitted type does not contain pointers. However, the routine is called by the stub automatically in any case, so at least a
null routine must be provided. As an exercise, you might add **printf( )**s to each callback to see when it is called. You could also add code to show the format of the transmitted array
before it is reconstructed by the **from_xmit** routine. Finally, you can create an even more efficient compression by not attempting to reconstruct the original array on the server side.