Handling variable-length and large data
Normally, you must define the size of each parameter in your Synergy server routines in the Synergy Method Catalog (SMC) so that xfServerPlus knows what to expect. (See Defining Your Synergy Methods for details on defining data in the SMC.) Sometimes, though, you may not know exactly what size the data will be, or you may know that it will vary in size, or your application may need to handle data that exceeds the usual size limits. If your application needs to support such cases, you may be able to use one of the following methods:
- Use a memory handle to pass a single, non-array parameter of variable length and/or larger than 64K. See Passing a single parameter as a memory handle, below.
- (Java and .NET clients only) Use a Synergy System.String class to pass a single parameter of variable length and/or larger than 64K. See Passing a System.String parameter.
- (Java and .NET clients only) Use a memory handle to pass a collection of structures, which can vary in the number of elements it contains, to an ArrayList on the client. See Returning a collection of structures.
- (Java and .NET clients only) Use a Synergy System.Collections.ArrayList class to pass an ArrayList of structures or other types of elements to the client or receive an ArrayList from the client. See Passing a System.Collections.ArrayList parameter.
- Use a memory handle on a Synergy client to pass an array larger than 64K. (All xfNetLink clients can handle arrays larger than 64K, but only the Synergy client requires a special technique to do so.) See Passing arrays larger than 64K.
Passing a single parameter as a memory handle
Use this method to pass a non-array parameter that is of variable length and/or larger than 64K (65,535 bytes) in size. This method is supported on all xfNetLink clients.
Your Synergy server routine must declare the argument that receives the data as a memory handle (i4; do not use int). xfServerPlus will place the data in a memory area and pass the memory handle allocated to that area to your Synergy server routine. (You must use the memory handle provided by xfServerPlus; do not attempt to allocate your own.) After the data has been returned to xfNetLink, xfServerPlus will free the memory area.
Note the following:
- If you are attributing your code, set the type property in the xfParameter attribute to SynType.handle. See type .
- If you are defining parameters in the MDU, specify a data type of handle. The length will default to 0.
- On a Java client, the parameter is handled as a String (or StringBuffer). See Appendix B: Data Type Mapping for xfNetLink Java for details.
- On a .NET client, it is handled as a string. See Appendix C: Data Type Mapping for xfNetLink .NET for details.
- On a Synergy client, the argument is handled as a memory handle. Consequently, you must use the RCB_xxx routines to make remote calls. You cannot use %RXSUBR. When setting the arguments in the routine call block with either RCB_SETARG or RCB_INSARG, use the D_TYPE_HANDLE define and pass as the data argument the memory handle where the data is stored on the client. Returned data will be placed back into the same memory area. For details on using the RCB_xxx routines, see Synergy Routine Call Block API.
- If you are using xfNetLink Synergy and the memory area allocated to the handle is resized within the Synergy routine on the server, it will be resized accordingly on the client upon returning from the routine. Trailing blanks will be trimmed, so the resized memory area on the client may be smaller than it was on the server.
Passing a System.String parameter
When using a Java or .NET client, you can use a Synergy System.String to pass a parameter that is of variable length and/or larger than 64K. This method is an alternative to using a memory handle, as described above. System.String can also be used as a function return value.
In the Synergy server routine, the parameter is declared as @System.String. For more information on using string data in Synergy DBL see Data types and System.String.
Note the following:
- If you are attributing your code, the data type will be obtained from your Synergy code.
- If you are defining parameters in the MDU, specify a data type of System.String. The length will default to 0.
- In your client code, instantiate a string. Refer to your Java or .NET documentation for more information.
Returning a collection of structures
When using a Java or .NET client, you can return a structure collection parameter to the client from Synergy. A structure collection is an array of structures with a variable number of elements. The structure collection can only be used to send data from Synergy to the client.
On the client side, the structure collection is handled as an ArrayList; on the xfServerPlus side, the data is placed in a memory area. When the call returns from xfServerPlus, the ArrayList will be filled with structures and will know its own size (number of elements).
The Synergy server routine must declare the argument that will return the structure collection as a memory handle (i4; do not use int). xfServerPlus will create an empty memory area and pass the memory handle allocated to that area to your Synergy server routine. (You must use the memory handle provided by xfServerPlus; do not attempt to allocate your own.) Your routine must resize the area and place the structures in it. After the data has been sent to xfNetLink, xfServerPlus will free the memory area.
Note the following:
- If you are attributing your code, in the xfParameter attribute, set the collectionType property to xfCollectType.structure and specify the structure name with the structure property.
- If you are defining parameters in the MDU, specify a data type of structure, select the structure by name, and then select the Structure collection check box. The Data passed field will automatically be set to Out.
For a .NET client, you can choose to have the ArrayList on the client created as a DataTable by selecting the DataTable check box in the MDU or setting the dataTable property of the xfParameter attribute to “true” if you are attributing your code. See Using DataTables for more information.
- On a Java client, instantiate an empty ArrayList (if there is any data in the list, it will be cleared) and pass it to the Synergy method that will return the structure collection. The ArrayList will be generic, so you must instantiate an ArrayList of structures. When the structure collection parameter is returned, use the ArrayList.size() method to get the size. Then you can enumerate through the ArrayList to access the structures or access them by position (index). Refer to your Java documentation for more information on ArrayLists.
- On a .NET client, instantiate an empty ArrayList (if there is any data in the list, it will be cleared) and pass it to the Synergy method that will return the structure collection. If you run gencs with the -w option, you will need to instantiate a List<T> instead of an ArrayList. When the structure collection parameter is returned, use the ArrayList.Count (or List<T>.Count) property to get the size. Then you can enumerate through the ArrayList to access the structures or access them by position (index). Refer to your .NET documentation for more information on ArrayLists.
If you have defined a structure collection parameter in the SMC for use with a Java or .NET client, and you want to also use a Synergy client with your server-side code, write your Synergy client code as though you were passing variable length data. That is, create a memory area on the client and pass the memory handle (as the parameter that is defined as a structure collection in the SMC) to xfServerPlus using the RCB_xxx routines. (See Passing a single parameter as a memory handle.) Do not alter the method definition in the SMC. When xfServerPlus receives the call from the Synergy client, it will not give a “parameter mismatch” error because it has been programmed to permit a mismatch when a Synergy client passes a memory handle to a parameter that is defined as a structure collection in the SMC.
Passing a System.Collections.ArrayList parameter
When using a Java or .NET client, you can use a Synergy System.Collections.ArrayList class to pass an ArrayList parameter either from Synergy to the client or from the client to Synergy. This method is an alternative to the one described in Returning a collection of structures. In addition to allowing data to be passed in either direction, the other advantage to this method is that the elements in the ArrayList are not limited to structures. You may also pass data defined as alpha, decimal, implied-decimal, integer, or System.String data types. The ArrayList may vary in the number of elements it contains.
In the Synergy server routine, declare the parameter as @System.Collections.ArrayList. See System.Collections.ArrayList for details.
If the ArrayList contains structures and is being sent from the client to the server, in your Synergy server routine use a FOREACH loop to extract data from the ArrayList and declare the loop counter variable as a boxed alpha. (See Synergex KnowledgeBase article 2224 for an example.)
Note the following:
- If you are attributing your code, set the collectionType property of the xfParameter attribute to the data type of the array elements. If the data type is structure, you must also specify the structure name with the structure property. See collectionType .
- If you are defining parameters in the MDU, in the Data type field, select the data type of the elements in the ArrayList. If the data type is structure, select the structure by name. Select the ArrayList check box and set Data passed to either In or Out. (In/Out is not supported.)
In xfNetLink .NET, if the ArrayList contains structures, you can choose to have it created as a DataTable on the client by selecting the DataTable check box in the MDU or setting the dataTable property to “true” if you are attributing your code. See Using DataTables for more information.
- For Java, instantiate an ArrayList (generic, of the specified type) in the client code. Mixed type ArrayLists are not supported.
- For .NET, in your client code, instantiate an ArrayList or, if you ran gencs with the -w option, a List<T>. Mixed type ArrayLists are not supported. Refer to your .NET documentation for more information on Lists and ArrayLists.
Passing arrays larger than 64K
You can pass an array parameter larger than 64K (65,535 bytes) as long as no element in the array exceeds 64K. The maximum size for an arrayed field in Synergy DBL is 256 MB. This feature is supported on all clients.
Your Synergy server routine should declare the argument that receives the array in the normal manner (that is, as an array argument of a particular data type).
Note the following:
- For a Java or .NET client, you do not need to do anything special on the client side to pass large arrays.
- For a Synergy client, the array must be placed in a memory handle, and you must use the RCB_xxx routines to make the remote call. You cannot use %RXSUBR. When setting the arguments in the routine call block with either RCB_SETARG or RCB_INSARG, you will use the D_TYPE_MEMARG define and pass as the data argument the memory handle where the array is stored on the client. Returned data will be placed back into the same memory area. For details on using the RCB_xxx routines, see Synergy Routine Call Block API.