Client Sample
The sample included in the toolkit performs the same function as the APING client utility. It sends data to a server process that echoes the data back to the APING utility. The sample client has been compiled and placed into the CPICJAVA.JAR file. The source file (JPing.java) is installed in the IBMCS\SDK\JAVA\CPIC\SAMPLES subdirectory when the ECL for Java™ is installed.
The API is supplied as a Java package called COM.ibm.eNetwork.cpic. The first line of code in the following sample is required in order to access the classes supplied with the toolkit. The CPIC class is the main interface to the native CPI-C code. The CPIC class contains many constants defined in CPI-C, such as, the length of a conversation ID, along with methods that are passed through to the native CPI-C calls.
You need only declare one CPIC object per class. Java will load the dynamic link library (DLL) containing the native methods (CPICJAVA.DLL) when the CPIC object is instantiated.
The following sample describes the CPI-C pipeline; it does not replicate the information in the JPing.java source file.
/*---------------------------------------------------------------
* Pipeline transaction, client side.
*---------------------------------------------------------------*/
import COM.ibm.eNetwork.cpic.*;
public class Pipe extends Object {
public static void main(String args[]) {
// Make a CPIC object
CPIC cpic_obj = new CPIC();
Each type of parameter has its own class, and each of these classes has associated constants defined as class variables. For example, the CPICReturnCode class has the success return code, CM_OK, defined.
There are two major reasons for having a class for each type of parameter. Because Java passes all parameters by value, there is no way to return data in simple types, such as integer. If we pass an object as a parameter to a method, the method can set a variable in that object, thus returning data to the caller. Secondly, the use of objects encapsulates constants within the objects that understand those constants. This is a standard information-hiding technique.
// Return Code
CPICReturnCode cpic_return_code =
new CPICReturnCode(CPICReturnCode.CM_OK);
// Request to send received?
CPICControlInformationReceived rts_received =
new CPICControlInformationReceived(
CPICControlInformationReceived.CM_NO_CONTROL_INFO_RECEIVED);
The CPI-C send function expects a C-language buffer, that is, allocated space of no specific type. Unlike C, Java has no facility to allocate untyped memory. Other than primitives, everything in Java is an object. Whatever the program sends must be converted from its object type into a C-style array of bytes.
Java provides methods that facilitate these conversions. For example, Java can convert a string into a Java array of bytes. While an array of bytes is an object in Java, Java allows you to extract the data from an array of bytes with a native method.
// String to Send
String sendThis = "Test of the PipeLine Transaction";
// Length of String to send
CPICLength send_length = new CPICLength(sendThis.length());
// Convert String to send to a Java array of bytes
byte[] stringBytes = new byte[ send_length.intValue()];
sendThis.getBytes(0,send_length.intValue(),stringBytes,0);
Like buffer processing, the CPI-C native calls expect symbolic destination names to be C-strings, not Java Strings. The toolkit automatically converts them from Java strings to C-strings as necessary. In general, automatic conversion is possible when the toolkit expects a specific Java type.
The conversation ID is a Java array of bytes which is converted automatically by the toolkit to a C array consisting of a simple block of bytes.
// this hardcoded sym_dest_name must
// be 8 chars long & blank padded
String sym_dest_name = "PIPE ";
// Space to hold a conversation ID
// (which is just a bunch of bytes)
byte[] conversation_ID = new byte[CPIC.CM_CID_SIZE];
The program starts making CPI-C calls which are very similar to those used in C. However, the method calls are prefixed with the name of the CPI-C object, and the parameters are not prefixed by the pass-by-reference (&) symbol.
//
// Initialize CPI-C
//
cpic_obj.cminit( /* Initialize_Conversation */
conversation_ID, /* O: returned conversation ID */
sym_dest_name, /* I: symbolic destination name */
cpic_return_code); /* O: return code from this call */
//
// ALLOCATE
//
cpic_obj.cmallc( /* Allocate Conversation */
conversation_ID, /* I: conversation ID */
cpic_return_code); /* O: return code from this call */
//
// SEND
//
cpic_obj.cmsend( /* Send_Data */
conversation_ID, /* I: conversation ID */
stringBytes, /* I: send this buffer */
send_length, /* I: length to send */
rts_received, /* O: was RTS received? */
cpic_return_code); /* O: return code from this call */
//
// DEALLOCATE
//
cpic_obj.cmdeal( /* Deallocate */
conversation_ID, /* I: conversation ID */
cpic_return_code); /* O: return code from this call */
} // end main method
} // end the class