|
|||||||
|
|
![]() |
|
|
Putting User Spaces in Your Toolbox by Bruce Guetzkow [The code for this article is available for download.] One of the more powerful tools for iSeries programmers is the user space. Many IBM list APIs use a user space to hold the results of these API calls. A user space is similar to a data area, except that it can be much larger (up to 16 Mb, as opposed to only 2 Kb). It also expands in size automatically as more data is added to it, while data areas are fixed in length. User spaces can be accessed only by using APIs. This article explains the basic APIs needed to access user spaces, and presents procedures and a service program to simplify their use even further. General Concepts When IBM list APIs place data in a user space they do so by using standardized data structures. The first 576 bytes of the user space is the user space header. The header contains information about the data returned to the user space. The following is a complete layout of the header area:
*==========================================
* User Space Header Data Structure.
*==========================================
d usrspchdrds ds inz qualified
d userarea 64a
d genhdrsize 9b 0
d strrlslvl 4a
d fmtname 8a
d apiused 10a
d crtdattim 13a
d infosts 1a
d usrspcsize 9b 0
d inpparmoff 9b 0
d inpparmsiz 9b 0
d hdrsctoff 9b 0
d hdrsctsize 9b 0
d lstdtaoff 9b 0
d lstdtasize 9b 0
d lstnbrent 9b 0
d lstentsize 9b 0
d ccsid 9b 0
d country 2a
d language 3a
d sstlstind 1a
d rsv001 42a
d apientpnt 256a
d rsv002 128a
*
d usrspchdrlgth s 9b 0 inz(%size(usrspchdrds))
Three values are of particular importance:
The rest of the user space contains the list entries. The size of each entry varies according to the list API used and the amount and type of information requested. All of the user space APIs use the standard API error data structure:
*=============================================
* API Error Data Structure.
*=============================================
d apierrds ds inz qualified
d bytesprov 9b 0 inz(%size(apierrds.msgdata))
d bytesaval 9b 0
d msgid 7a
d filler 1a
d msgdata 100a
I have configured all of the procedures to return the error message ID and message text in the first 107 bytes of the return value. Your application program can then test the message ID for a successful call (blanks). If the message ID is not blank, it can be passed to an error-handling routine, along with the message text, for error processing. The following procedures have simplified the API calls as much as possible. The version presented uses default values that are appropriate to my own work environment. If you find these defaults are not right for your situation, you can easily customize them as needed. Create User Space Before you can use any of the list APIs, you must first create a user space to place the results in. This is done with the QUSCRTUS (Create User Space) API. The API has six required parameters and another five optional parameters. First, the required parameters:
The first two optional parameters can be very useful, but I will skip the final three, as they are not needed in most circumstances:
The #crtusrspc procedure simplifies these parameters considerably by having only two 10-byte character parameters for the user space name and library. All other API parameters can use default values:
The procedure's return value is the API error data structure message ID and message text fields, which can be interrogated to determine the success of the procedure call. Retrieve User Space After the list API has completed, it's time to retrieve the data from the user space. The QUSRTVUS (Retrieve User Space) API has four required parameters:
And there is one optional parameter:
For the #rtvusrspc procedure we again use separate parameters for the user space name and library. The remaining parameters are for the starting position and the data length. The return value is the API error data structure message ID and the message text, plus the receiver value. The receiver value can be any length, as long as it is at least as long as the data being returned. I have chosen a length of 2,000 bytes, as this is generally longer than the data returned for a single list entry. To simplify the procedure I have tailored the API call to always return a single list entry at a time, although the API can return multiple entries if desired. By placing this restriction on the procedure, the API call may not perform optimally, but I believe it is more flexible this way. Delete User Space Use the QUSDLTUS (Delete User Space) API to delete the user space. This is the easiest of the user space APIs to use and has just two required parameters:
As with the #crtusrspc procedure, only two parameters are needed (user space name and library) and the return value is the API error data structure fields. Using the Procedures Click here to download the complete service module code. Once you have created the user space module and service program, calling list APIs is a fairly routine process:
As each entry is retrieved, you can perform any pertinent processing such as loading entries into a subfile, printing entries on a report, or whatever the situation dictates. Here is a sample of how to use the procedures with an IBM list API:
*===============================================================
d/copy qcpysrc,usrspchdds
*===============================================================
* Miscellaneous Fields.
*===============================================================
d nbrent s 9b 0 inz
d strpos s 9b 0 inz(1)
d usrspcnam s 10a inz('DFTUSRSPCN')
d usrspclib s 10a inz('QTEMP ')
*
d rtnds01 ds inz qualified
d msgid 7a
d msgdata 100a
*
d rtnds02 ds inz qualified
d msgid 7a
d msgdata 100a
d rcvvar 2000a
*===============================================================
* Procedure Prototypes
*===============================================================
d/copy qcpysrc,usrspapipr
*===============================================================
/free
// Create User Space
rtnds01 = #crtusrspc(usrspcnam:
usrspclib);
if rtnds01.msgid <> *blanks;
// Error Handling
endif;
// Load User Space (Call List API)
callp LISTAPI(parm1:
parm2:
parm3)
// Retrieve User Space Header
rtnds02 = #rtvusrspc(usrspcnam:
usrspclib:
strpos:
usrspchdrlgth);
if rtnds02.msgid <> *blanks;
// Error Handling
endif;
// Move Receiver Variable to User Space Data Structure
usrspchdrds = rtnds02.rcvvar;
// Set New Position-to field
reset strpos;
strpos = strpos + usrspchdrds.lstdtaoff;
// Retrieve User Space Detail Entries
for nbrent = 1
to usrspchdrds.lstnbrent;
rtnds02 = #rtvusrspc(usrspcnam:
usrspclib:
strpos:
usrspchdrds.lstentsize);
if rtnds02.msgid <> *blanks;
leave;
endif;
LISTAPIds = rtnds02.rcvvar;
// Process List Entry As Desired
// Set New Position-to field
strpos = strpos + usrspchdrds.lstentsize;
endfor;
// Delete User Space
rtnds01 = #dltusrspc(usrspcnam:
usrspclib);
/end-free
Using a Valuable New Tool Now that you have the basics available in a ready-to-use service program, you can tackle any IBM list API with relative ease. In a future article I will add procedures to the service program for the remaining user space APIs and demonstrate another method for retrieving information from a user space that is not tied specifically to list APIs, so it is more generic. Bruce Guetzkow has programmed on the AS/400 and iSeries since 1990, in manufacturing, distribution and other industries. He is currently the IS director at United Credit Service in Elkhorn, Wisconsin. E-mail: bruceg@unitedcreditservice.com
|
Editors
Contact the Editors |
| Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved. |