Newsletters Subscriptions Media Kit About Us Contact Search Home

Stuff
OS/400 Edition
Volume 2, Number 19 -- September 25, 2003

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:

  • lstdtaoff (offset to list data section). Add one to this value to get the first byte of the actual list entries returned by the API.

  • lstnbrent (number of list entries). This tells you how many entries are in the user space.

  • lstentsize (size of each entry). This value is the size of the data structure used for data returned for each list entry.

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:

  • qualified user space name (input, 20 bytes, character). The first 10 bytes contains the user space name; the last 10 bytes contains the user space library.

  • extended attribute (input, 10 bytes, character). Must be a valid *NAME or have blanks; a *file object, for example, would be PF, LF, DSPF, PRTF.

  • initial size (input, 4 bytes, binary). The initial size of the user space.

  • initial value (input, 1 byte, character). The initial value for all bytes in the user space.

  • public authority (input, 10 bytes, character). The authority given to users who don't have specific authority to the user space.

  • text description (input, 50 bytes, character). The description of the user space.

The first two optional parameters can be very useful, but I will skip the final three, as they are not needed in most circumstances:

  • replace (input, 10 bytes, character). Whether you want to replace a user space with the same name.

  • error code (input/output, variable size, character). A standard API error structure used to return error. information.

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 extended attribute and text description values can be blanks, unless you plan to create permanent user spaces in libraries other than QTEMP.

  • Any initial size will work (I've settled on 1,024), since user spaces automatically expand as needed to hold the data placed in them.

  • An initial value of X'00' (*LOVAL) gives the best performance, so why use anything else?

  • Any valid value for public authority that suits your business is appropriate. I've chosen *ALL, since I always create user spaces in QTEMP anyway.

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:

  • qualified user space name (input, 20 bytes, character). Exactly as used above.

  • starting position (input, 4 bytes, binary). The first position to return from the user space.

  • length of data (input, 4 bytes, binary). The number of bytes to return from the user space.

  • receiver variable (output, variable size, character). The actual data returned from the user space.

And there is one optional parameter:

  • error code (input/output, variable size, character). Exactly as used above.

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:

  • qualified user space name (input, 20 bytes, character). Exactly as used above.

  • error code (input/output, variable size, character). Exactly as used above.

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:

  1. Create a user space.
  2. Call the list API, specifying the newly created user space.
  3. Retrieve the user space header information.
  4. Create a loop to retrieve user space entries, which is executed once for each entry, beginning at the first position of the detail area of the user space and moving to each succeeding entry based on the length of the entries.
  5. After the loop is complete, delete the user space.

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


Sponsored By
LAKEVIEW TECHNOLOGY

Neuvo Central Argentino Railroad
Stays on Track with MIMIX

Nuevo Central Argentino (NCA) is a proud part of the railroading tradition. NCA transports more than six million tons of goods 24 hours a day, seven days a week.

NCA runs a mixed IBM eServer iSeries and xSeries environment with OS/400 and Microsoft Windows. It is imperative that the systems are always available; otherwise, trains stop and goods perish.

NCA set up two data centers for disaster recovery in different buildings. They choose MIMIX and MIMIX for Windows to replicate data and applications in near real-time, and to switch users between the systems simply and quickly.

NCA suffered critical system failures in both its iSeries and xSeries environments. The company estimates that had MIMIX not been in place, the failures would have resulted in three-day system outages. Instead, with MIMIX, there was no interruption and no user impact. NCA is confident that MIMIX has already paid for itself.

Get the full story at: http://www.mimix.com/profiles/index.asp#NCA.

Lakeview Technology
http://www.mimix.com


THIS ISSUE
SPONSORED BY:

Lakeview Technology
ASNA
WorksRight Software
Profound Logic Software


BACK ISSUES

TABLE OF
CONTENTS
Putting User Spaces in Your Toolbox

Service Programs with a Smile

Back to Basics: The Copy Screen Feature

OS/400 Alert: Security Is More Than Staying Current


Editors
Shannon O'Donnell
Kevin Vandever

Managing Editor
Shannon Pastore

Contributing Editors:
Howard Arner
Raymond Everhart
Joe Hertvik
Ted Holt
Marc Logemann
David Morris

Publisher and
Advertising Director:

Jenny Thomas

Advertising Sales Representative
Kim Reed

Contact the Editors
Do you have a gripe, inside dope or an opinion?
Email the editors:
editors@itjungle.com


Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.