Advanced MQeFields APIs

Three sets of advanced MQeFields APIs are provided for experienced programmers who want to put and get data in and out of the fields object more efficiently.

The three sets are described below:

MQeFieldsGetByArrayOfFd() and MQeFieldsPutByArrayOfFd()
These APIs enable an application programmer to put and get an array of fields into and out of an MQeFields object. Instead of doing individual MQeFieldsGet and MQeFieldsPut calls on each field, think of this API as batch processing. It calls into the WebSphere MQ Everyplace system library only once, as opposed to multiple times for the individual get and put calls. If used properly, this API improves the performance of the MQeFields API usage.
#include <hmq.h>
static MQECHAR const * FieldsType = "com.ibm.mqe.MQeFields";
static const MQECHAR textVal[]  = 
					"The Owl and the Pussy Cat went to sea.";
 
/* template for fields */
static  const MQEFIELD PFDS[] = {
        {MQE_TYPE_BYTE, 0, 7, "fooByte", 
				(MQEBYTE *)0, 0, (MQEBYTE *)0},   
        {MQE_TYPE_SHORT, 0, 8, "fooShort", 
				(MQEBYTE *)0, 0, (MQEBYTE *)0},   
        {MQE_TYPE_LONG, 0, 7, "fooLong", 
				(MQEBYTE *)0, 0, (MQEBYTE *)0},   
        {MQE_TYPE_ASCII, 0, 7, "fooText", 
				(MQEBYTE *)0, 0, (MQEBYTE *)0},  
        };
#define NFDS (sizeof(PFDS)/sizeof(PFDS[0]))
MQEHSESS   hSess;
MQEINT32   compcode;
MQEFIELD   Fds[NFDS];
MQEINT32   reason;
MQEHFIELDS hFlds;
MQEBYTE    byteVal;
MQEINT16   int16Val;
MQEINT32   int32Val;
MQEBYTE    datatype;
MQEINT32   rc;
MQEINT32   nFlds,i;
 
hSess = MQeInitialize("MyAppsName", 
								&compcode, &reason);
hFlds = MQeFieldsAlloc( hSess, FieldsType, 
								&compcode, &reason);
 
 
/* Put some fields in the fields 
	object using MQeFieldsPutByArrayOfFd() */
byteVal  = 0xAE;
int16Val = 0x9876;
int32Val = 0x12345678;
 
/* Copy template */
memcpy(Fds,PFDS,sizeof(Fds));
Fds[0].fd_data = &byteVal;
Fds[0].fd_datalen = 1;
Fds[1].fd_data = &int16Val;
Fds[1].fd_datalen = 1;
Fds[2].fd_data = &int32Val;
Fds[2].fd_datalen = 1;
Fds[3].fd_data = &textVal;[0];
Fds[3].fd_datalen = sizeof(textVal);
compcode = MQECC_OK, reason = 0;
MQeFieldsPutByArrayOfFd( hSess, hFlds, Fds, NFDS , 
									&compcode, &reason);
 
/* Copy template */
memcpy(Fds,PFDS,sizeof(Fds));
 
/* Get data lengths */
rc = MQeFieldsGetByArrayOfFd( hSess, hFlds, Fds, NFDS, 
										&compcode, &reason);
 
/* Get space for each field data */
for( i=0; i<rc; i++) {
  int len = Fds[i].fd_datalen*MQE_SIZEOF(Fds[i].fd_datatype);
  if (len > 0) {
    Fds[i].fd_data = (MQEBYTE *) malloc(len);
  }  
}
 
/* Get all the fields defined in field 
		descriptor array in one shot */
 
compcode = MQECC_OK, reason = 0;
MQeFieldsGetByArrayOfFd( hSess, hFlds, Fds, NFDS, 
									&compcode, &reason);

MQeFieldsGetByStruct() and MQeFieldsPutByStruct()
These APIs enable an application programmer to map a C data structure in the application program directly to a set of fields in the MQeFields object. By defining a fields structure descriptor for the C data structure, these two APIs automatically move the data between the C data structure and an MQeFields object.

The following code sample shows the use of these APIs:

#include <hmq.h>
   struct myData_st {
   MQEINT32 x;          /* simple variable */
   MQECHAR *name  ;     /* pointer to name buffer */
   MQEINT32 namelen;    /* length of name */
   MQEBYTE  buf[8];      /* fixed buffer in struct */
   MQEINT32 fieldlen;    
 
/* length of a field, buffer not in struct */
};
 
MQEINT32 field[10];      
/* buffer whose length is in a structure */
 
#ifndef MQE_OFFSETOF
#define MQE_OFFSETOF(_struct,_field) 
								(&((struct _struct *)0._field))
#endif 
 
/* A possible sample definition of 
		MQEFIELDDESC for myData_st  */
 
static MQEFIELDDESC myDataStruct_fd[] = {
             {"x", 1, MQE_TYPE_INT, 0, 
							MQE_OFFSETOF(myData_st,x), 1},
             {"name", 4, MQE_TYPE_ASCII, 
							MQSTRUCT_LEN|MQSTRUCT_DATA, 
              MQE_OFFSETOF(myData_st,name), 
							MQE_OFFSETOF(myData_st,namelen)},
             {"buf",  3, MQE_TYPE_BYTE, 0, 
							MQE_OFFSETOF(myData_st,buf), 8},
             {"field",5, MQE_TYPE_INT, 
							MQSTRUCT_LEN|MQSTRUCT_NODATA, 
              		0, MQE_OFFSETOF(myData_st,fieldlen) }
};
 
static  MQECHAR * textVal  = 
				"The Owl and the Pussy Cat went to sea.";
static  MQECHAR   textBuf[] = { 0xAB, 0xCD, 0x12, 0x44 };
MQEHSESS   hSess;
MQEINT32   compcode;
MQEINT32   reason;
MQEHFIELDS hFlds;
struct myData_st myData;
MQEINT32  int32Val;
MQEINT32  rc;
 
for (rc=0; rc<sizeof(field)/sizeof(field[0]); 
				rc++) field[rc]=rc;
 
hSess   = MQeInitialize("MyAppsName", 
									&compcode, &reason);
hFlds   = MQeFieldsAlloc( hSess, 
									MQE_OBJECT_TYPE_MQE_FIELDS, 
                         &compcode, 
									&reason);
 
/* Put some fields into the fields object. */
int32Val = 0xABABBABA;
rc = MQeFieldsPut( hSess, hFlds, "x", 
							MQE_TYPE_INT, 
							&int32Val, 1, 
                  	&compcode, 
							&reason); 
 
rc = MQeFieldsPut( hSess, hFlds, 
							"name", MQE_TYPE_ASCII, 
							textVal, strlen(textVal), 
                  	&compcode, 
							&reason); 
 
rc = MQeFieldsPut( hSess, 
							hFlds, 
							"buf", 
							MQE_TYPE_BYTE, 
							textBuf, 
                   sizeof(textBuf)/sizeof(textBuf[0]), 
                  	&compcode, 
							&reason); 
 
rc = MQeFieldsPut( hSess, hFlds, "field", 
							MQE_TYPE_INT, &field, 
                   sizeof(field)/sizeof(field[0]), 
                  	&compcode, &reason); 
 
/* Retrieve all the fields out at once 
	and populate the user data structure. */
rc = MQeFieldsGetByStruct( hSess, hFlds, 
						&myData, myDataStruct_fd, 
                 sizeof(myDataStruct_fd)/sizeof(myDataStruct_fd[0]), 
                 &compcode, &reason);
 
printf("x = 0x%x, name = \"%s\", 
			buf[0..3]=0x%08x-%08x\n", 
        myData.x, myData.name, 
			&myData.buf[0], 
       	&myData.buf[4]);
 
/* Output of printf() should look something like this */
/* "x = 0xABABBABA, name = 
			"The Owl and the Pussy Cat went to sea.", 
         buf[0..3]=0xABCD1244-ABCD1248" */
 

MQeFieldsRead() and MQeFieldsWrite()
These APIs enable an application to stream data in and out of a field in an MQeFields object, so that data can be written a chunk at a time into a field or read a chunk at a time from a field. This enables the application to use a small intermediate transfer buffer to move large chunks of data.
#include <hmq.h>
 
static MQECHAR const * FieldsType = "com.ibm.mqe.MQeFields";
MQEHSESS   hSess;
MQEHFIELDS hFlds;
MQEINT32   compcode;
MQEINT32   reason;
MQEINT32   i, nread;
MQECHAR    buf[64];
MQEINT32   rc;
 
hSess   = MQeInitialize("MyAppsName", 
									&compcode, &reason);
hFlds   = MQeFieldsAlloc( hSess, FieldsType, 
									&compcode, &reason);
 
/* Allocate a 128 byte buffer field */
rc = MQeFieldsPut( hSess, hFlds, "y" , 	
							MQE_TYPE_BYTE, NULL , 128, 
							&compcode, &reason); 
 
/* Fill the buffer with values 0-127 */
for (i=0; i<128; i++) {
   char c=i;
   MQeFieldsWrite( hSess, hFlds, "y" , i, 
							&c, 1, 
                  	&compcode, 
							&reason); 
}
 
/* Read 64 byte out into an output buf, nread = 64 */
nread  = MQeFieldsRead( hSess, hFlds, "y", 
									MQE_TYPE_BYTE, buf, 
									0, 64, NULL, 
                       	&compcode, 
									&reason);


© IBM Corporation 2002. All Rights Reserved