1. Introduction 
        Non-persistent CGI are "stateless".
        In other words, the browser connects to the server, makes a request
        (calls a CGI),
        receives the response, then disconnects from the server.
        On the next request from the same browser, there is no guarantee that the
        same program has maintaned the state (variables and record positioning)
        it was left with at the end of the previous request.
         In such a stateless situation, the developer has to implement some
        "tricks" to restore some variables on the next call to the CGI,
        such as 
        - using hidden input fields in the HTML forms
        
 - writing and retrieving cookies
  
        Sometimes, however, when designing complex transactions, these rather simple tricks
        may not be sufficient to fulfill state requirements
        and a programmer would be tempted to use "persistent" CGI instead.
        However, persistent
        CGI have their own problems.
         In those cases, better methods for storing and retrieving
        state information are required.
        
  
         
         2. User spaces 
        iSeries user spaces objects are ideal for this purpose: 
        - Each user space can hold up to 16 MB of information
        
 - System APIs are provided to create a user space, change its attributes
            (including making it automatically extendible, retrieve a pointer to it, etc.)
        
 - Once addressability to a user space (a pointer) has been established,
            one can map, using based variables, many types of data into it,
            including data structures
        
 - Saving and restoring user state information can be accomplished as follow:
            
            - at the start of the transaction, create a uniquely named user space,
            
 - use based variable(s) to map the user's data into the space,
            
 - send an HTTP response to the user, including a hidden field containing the user space name,
            
 - when the user makes a request using the form that contains the hidden user space name, use that
                name to retrieve a pointer to the user space, thus restoring addressability to the user space's contents
                using the same based variables that were used to store them.
            
  
          
        
         
        3. User space procedures 
        
         
        - Subprocedure "CrtUsrSpc" - Create an User Space
  
        It creates a randomly named, automatically extendible user space
        in a user-specified library.  The user space's contents are initialized
        to all x'00's.
        Parameters 
        - User space library (input)
            - If the library not found, CrtUsrSpc sets the user space name
                to blanks and MsgId to CPF9810
            
 - If the requestor does not have change authority to the library,
                CrtUsrSpc sets the user space name to blanks and MsgId to CPF2144 
  
         - Pointer to user space (output)
            - Set to null if the user space is not created
  
         - Message ID (output)
            - blank if no errors
            
 - else, message id of error
  
          
        Optional Parameters 
        - Public authority (input)
            - If not passed, it is set to *EXCLUDE
  
         - Text (input)
            - If not passed, it is set to 'Created by CGIDEV2' plus timestamp
  
         - Initial size (input)
            - If not passed, it is set to 12288
  
         - Extended attribute
            - If not passed, it is set to blanks
  
          
        Returns 
        Errors in system APIs 
         - If any of the called system APIs fails, a message is forced into
             the CGIDEBUG file.
        
  
        Example:
         
        
        
 * Input variables
D AnEntry         s             40    varying
 * User space
D UsrSpcName      s             10
D UsrSpcLib       c                   'CGIDEV2USP'
* Message ID for CrtUsrSpc
D MsgId           s              7
* State related variables (user space contents)
D State           ds                  based(StateP)
D  Count                        10i 0
D  Entries                    1000    varying
C                   eval      UsrSpcName= CrtUsrSpc(
C                               UsrSpcLib : StateP : MsgID)
         |   
         |   
        In this example, a user space is created in library CGIDEV2USP
        and its name is loaded into variable "UsrSpcName".
        
  
         
        - Subprocedure "RtvUsrSpcPtr" - Retrieve Pointer to User Space
  
        Parameters 
        - User space name (input)
        
 - User space library (input)
        
  
        Returns 
         - If successful
             - Pointer to the user space
  
          - Otherwise
        
  
        Errors in system APIs 
         - If any of the called system APIs fails, a message is forced into
             the CGIDEBUG file.
        
  
        Example:
         
        
        
C                   eval      StateP = RtvUsrSpcPtr(UsrSpcName:
C                             UsrSpcLib)
C                   if        StateP = *null
                    ... ...
C                   endif
         |   
         |   
        In this example, the contents of the user space
        are made accessible via data structure "State".
        
  
        To update the contents of the user space,
        one should just update the data structure "State":
        
        
        
C                   eval      AnEntry = ZhbGetVar('AnEntry')
C                   if        AnEntry <> ''
C                   eval      Count = Count + 1
C                   eval      Entries = Entries + '<br>' + AnEntry
C                   endif
         |   
         |   
        
  
         
        
         
        4. Sample program 
        CGI program  STATE demonstrates
        the use of user space to maintain program state information.
         In this programs, the user may enter, one at a time,
        several inputs. The inputs are saved in a user space.
        The user space contents are displayed to the user.
         
  |