The following example uses the IDL encoding service features described in the preceding topics. The example verifies that the results of a number of decoding operations are the same as the parameters used to create the corresponding encodings.
The interface definition for this example is as follows:
[uuid(20aac780-5398-11c9-b996-08002b13d56d), version(0)]
interface es_array
{
const long N = 5000;
typedef struct
{
byte b;
long l;
} s_t;
typedef struct
{
byte b;
long a[7];
} t_t;
void in_array_op1([in] handle_t h, [in] long arr[N]);
void out_array_op1([in] handle_t h, [out] long arr[N]);
void array_op2([in] handle_t h, [in,out] s_t big[N]);
void array_op3([in] handle_t h, [in,out] t_t big[N]);
}
The attribute configuration file for the example is as follows:
interface es_array
{
[encode] in_array_op1();
[decode] out_array_op1();
[encode, decode] array_op2();
[encode, decode] array_op3();
}
The test code for the example is as follows:
#include <dce/pthread_exc.h>
#include "rpcexc.h"
#include <stdio.h>
#include <stdlib.h>
#include <file.h>
#include <sys/file.h>
#include "es_array.h"
/*
* User state for incremental encode/decode
*/
typedef struct es_state_t {
idl_byte *malloced_addr;
int file_handle;
} es_state_t;
static es_state_t es_state;
#define OUT_BUFF_SIZE 2048
static idl_byte out_buff[OUT_BUFF_SIZE];
static idl_byte *out_data_addr;
static idl_ulong_int out_data_size;
/*
* User allocate routine for incremental encode
*/
void es_allocate(state, buf, size)
idl_void_p_t state;
idl_byte **buf;
idl_ulong_int *size;
{
idl_byte *malloced_addr;
es_state_t *p_es_state = (es_state_t *)state;
malloced_addr = (idl_byte *)malloc(*size);
p_es_state->malloced_addr = malloced_addr;
*buf = (idl_byte *)(((malloced_addr - (idl_byte *)0) + 7) & (~7));
*size = (*size - (*buf - malloced_addr)) & (~7);
}
/*
* User write routine for incremental encode
*/
void es_write(state, buf, size)
idl_void_p_t state;
idl_byte *buf;
idl_ulong_int size;
{
es_state_t *p_es_state = (es_state_t *)state;
write(p_es_state->file_handle, buf, size);
free(p_es_state->malloced_addr);
}
/*
* User read routine for incremental decode
*/
void es_read(state, buf, size)
idl_void_p_t state;
idl_byte **buf;
idl_ulong_int *size;
{
es_state_t *p_es_state = (es_state_t *)state;
read(p_es_state->file_handle, out_data_addr, out_data_size);
*buf = out_data_addr;
*size = out_data_size;
}
static ndr_long_int arr[N];
static ndr_long_int out_arr[N];
static s_t sarr[N];
static s_t ref_sarr[N];
static s_t out_sarr[N];
static t_t tarr[N];
static t_t ref_tarr[N];
static t_t out_tarr[N];
static ndr_long_int (*oarr)[M];
#define FIXED_BUFF_STORE (8*N+64)
static idl_byte fixed_buff_area[FIXED_BUFF_STORE];
/*
* Test Program
*/
main()
{
idl_es_handle_t es_h;
idl_byte *fixed_buff_start;
idl_ulong_int fixed_buff_size, encoding_size;
idl_byte *dyn_buff_start;
error_status_t status;
int i,j;
for (i = 0; i < N; i++)
{
arr[i] = random()%10000;
sarr[i].b = i & 0x7f;
sarr[i].l = random()%10000;
ref_sarr[i] = sarr[i];
tarr[i].b = i & 0x7f;
for (j = 0; j < 7; j++) tarr[i].a[j] = random()%10000;
ref_tarr[i] = tarr[i];
}
/*
*Incremental encode/decode
*/
/* Encode data using one operation */
es_state.file_handle = open("es_array_1.dat", \
O_CREAT|O_TRUNC|O_WRONLY,
0777);
if (es_state.file_handle < 0)
{
printf("Can't open es_array_1.dat\n");
exit(0);
}
idl_es_encode_incremental((idl_void_p_t)&es_state, es_allocate, \
es_write,
&es_h, &status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_encode_incremental\n", status);
exit(0);
}
in_array_op1(es_h, arr);
close(es_state.file_handle);
idl_es_handle_free(&es_h, &status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_handle_free\n", status);
exit(0);
}
/* Decode the data using another operation with the same signature */
out_data_addr = (idl_byte *)(((out_buff - (idl_byte *)0) + 7) & (~7));
out_data_size = (OUT_BUFF_SIZE - (out_data_addr - out_buff)) & (~7);
es_state.file_handle = open("es_array_1.dat", O_RDONLY, 0);
if (es_state.file_handle < 0)
{
printf("Can't open es_array_1.dat for reading\n");
exit(0);
}
idl_es_decode_incremental((idl_void_p_t)&es_state, es_read,
&es_h, &status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_decode_incremental\n", status);
exit(0);
}
out_array_op1(es_h, out_arr);
close(es_state.file_handle);
idl_es_handle_free(&es_h, &status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_handle_free\n", status);
exit(0);
}
/* Check the input and output are the same */
for (i = 0; i < N; i++)
{
if (out_arr[i] != arr[i])
{
printf("out_arr[%d] - found %d - expecting %d\n",
i, out_arr[i], arr[i]);
}
}
/*
* Fixed buffer encode/decode
*/
fixed_buff_start = (idl_byte *)(((fixed_buff_area - \
(idl_byte *)0) + 7)
& (~7));
fixed_buff_size = (FIXED_BUFF_STORE - \
(fixed_buff_start - fixed_buff_area))
& (~7);
idl_es_encode_fixed_buffer(fixed_buff_start, fixed_buff_size,
&encoding_size, &es_h, &status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_encode_fixed_buffer\n", status);
exit(0);
}
array_op2(es_h, sarr);
idl_es_handle_free(&es_h, &status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_handle_free\n", status);
exit(0);
}
idl_es_decode_buffer(fixed_buff_start, encoding_size, &es_h, &status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_decode_buffer\n", status);
exit(0);
}
array_op2(es_h, out_sarr);
idl_es_handle_free(&es_h, &status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_handle_free\n", status);
exit(0);
}
for (i = 0; i < N; i++)
{
if (out_sarr[i].b != ref_sarr[i].b)
{
printf("array_op2 - out_sarr[%d].b = %c\n", i, out_sarr[i].b);
}
if (out_sarr[i].l != ref_sarr[i].l)
{
printf("array_op2 - out_sarr[%d].l = %d\n", i, out_sarr[i].l);
}
}
/*
* Dynamic buffer encode - fixed buffer decode
*/
idl_es_encode_dyn_buffer(&dyn_buff_start, &encoding_size, &es_h, \
&status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_encode_dyn_buffer\n", status);
exit(0);
}
array_op3(es_h, tarr);
idl_es_handle_free(&es_h, &status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_handle_free\n", status);
exit(0);
}
idl_es_decode_buffer(dyn_buff_start, encoding_size, &es_h, &status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_decode_buffer\n", status);
exit(0);
}
array_op3(es_h, out_tarr);
rpc_ss_free (dyn_buff_start);
idl_es_handle_free(&es_h, &status);
if (status != error_status_ok)
{
printf("Error %08x from idl_es_handle_free\n", status);
exit(0);
}
for (i = 0; i < N; i++)
{
if (out_tarr[i].b != ref_tarr[i].b)
{
printf("array_op3 - out_tarr[%d].b = %c\n", i, out_tarr[i].b);
}
for (j=0; j<7; j++)
{
if (out_tarr[i].a[j] != ref_tarr[i].a[j])
{
printf("array_op3 - out_tarr[%d].a[%d] = %d\n",
i, j, out_tarr[i].a[j]);
}
}
}
printf("Test Complete\n");
}