6.2.5 Example: Sending a Synchronous Message with TPNOCHANGE Set

The following listing shows how the TPNOCHANGE communication flag is used to enforce strong buffer type checking by indicating that the reply message must be returned in the same type of buffer that was originally allocated. This example refers to a service routine called REPORT. (The REPORT service is also shown in Example: Sending a Synchronous Message with TPNOTRAN Set.)

In this example, the client receives the reply in a VIEW typed buffer called rview1 and prints the elements in printf() statements. The strong type check flag, TPNOCHANGE, forces the reply to be returned in a buffer of type VIEW and of subtype rview1.

A possible reason for this check is to guard against errors that may occur in the REPORT service subroutine, resulting in the use of a reply buffer of an incorrect type. Another reason is to prevent changes that are not made consistently across all areas of dependency. For example, another programmer may have changed the REPORT service to standardize all replies in another VIEW format without modifying the client process to reflect the change.

Listing Sending a Synchronous Message with TPNOCHANGE Set

#include <stdio.h>
#include "atmi.h"
#include "rview1.h"

main(argc, argv)
int argc;
char * argv[];

{
char *rbuf;                    /* report buffer */
struct rview1 *rrbuf;         /* report reply buffer */
long rlen, rrlen;            /* buffer lengths of send and reply 
                                buffers for report */
if (tpinit((TPINIT *) tpinfo) == -1)
fprintf(stderr, "%s: failed to join application\n", argv[0]);

if (rbuf = tpalloc("STRING", NULL, 0) == NULL) { /* allocate space for report 
*/
    tpterm();
    exit(1);
}
                            /* allocate space for return buffer */
if (rrbuf = (struct rview1 *)tpalloc("VIEW", "rview1", sizeof(struct 
rview1)) \ == NULL{
    tpfree(rbuf);
    tpterm();
    exit(1);
}
(void)strcpy(rbuf, "REPORT=accrcv DBNAME=accounts FORMAT=rview1");
rlen = strlen(rbuf)+1;        /* length of request */
                              /* get report in rview1 struct */
if (tpcall("REPORT", rbuf, rlen, (char **)&rrbuf, &rrlen, TPNOCHANGE) == -1) 
{
    fprintf(stderr, "accounts receivable report failed in service call\n");
    if (tperrno == TPEOTYPE)
        fprintf(stderr, "report returned has wrong view type\n");
    tpfree(rbuf);
    tpfree(rrbuf);
    tpterm();
    exit(1);
}
(void)printf("Total accounts receivable %6d\n", rrbuf->total);
(void)printf("Largest three outstanding %-20s %6d\n", rrbuf->name1, 
rrbuf->amt1);
(void)printf("%-20s %6d\n", rrbuf->name2, rrbuf->amt2);
(void)printf("%-20s %6d\n", rrbuf->name3, rrbuf->amt3);
tpfree(rbuf);
tpfree(rrbuf);
tpterm();
}