Switch to Italian
Giovanni's logo Write HTML to a stream file
(Dynastatic pages)
this means Version 2
power search
blue line
1. Subprocedures WrtHtmlToStmf() and AppHtmlToStmf
There may be cases, where a page created from a CGI (dynamic page)
  • is frequently accessed
  • requires some relevant processing, thus providing a rather long response time
  • and its contents may change at unpredictable times
Examples of such cases could be:
  • our page about "our subscribers per country"
  • many other statistics pages
One interesting way to serve such requests is to have some dynamic processes generating static pages:
  • user response is much faster
  • computer load much lower

  • the generation of a static page may be triggered by an event or scheduled at a regular time interval
Implementing such a process is quite easy: you have to write a batch program similar to a CGI and gear it to some event or schedule.

Here is how you may write such a program:

  1. Develop the external HTML as usual for a CGI program, but
    1. do not insert the initial http header
      Content-type: text/html
      (you are going to build a static page)
  2. Develop the program as if it were a CGI program using our CGISRVPGM2 service program (you may use our command to create an initial sample CGI source)
    1. avoid reading and parsing the input string
      (drop our cgidev2/crtcgisrc generated statement
      /copy .../qrpglesrc,prolog1/2/3
    2. instead of sending the html buffer to the client with the instruction
      callp     wrtsection('*fini')
      save it as an IFS stream file using the subrocedure WrtHtmlToStmf():
      D  Stmf           s            512    varying
      D                                     inz('/web/dynapage1.html')
      D  CCSID          s             10i 0 inz(819)
      D  rc             s             10i 0
       * If "CCSID" parameter omitted, the CCSID is assigned by the
       * system (the CCSID of the job is used).
      C                   if        CCSID > 0
      C                   eval      rc = WrtHtmlToStmf(Stmf:CCSID)
      C                   else
      C                   eval      rc = WrtHtmlToStmf(Stmf)
      C                   endif
    1. The filename portion in the "stream file" variable supports a maximum length of 245 bytes.
    2. Create the program with actgrp(*new).
    3. Subprocedure WrtHtmlToStmf() clears the output buffer before returning to the user program. This is done to allow the user program to create more than one stream file without overlaying previous output data.
    4. CCSID 1208 should be used for UTF-8 Unicode.
      For other CCSID's see this page.
    5. Should you need instead to append the html buffer to an existing stream file, you must use subprocedure AppHtmlToStmf():
      D  Stmf           s            512    varying
      D                                     inz('/web/dynapage1.html')
      D  rc             s             10i 0
      C                   eval      rc = AppHtmlToStmf(Stmf)

Example of a dynamic/static page:

  • Please browse the source of our example program. It would generate a page containing some random integers. To run this program:
    1. addlible cgidev2
    2. enter command
      CGIDEV2/RANDOMNBRS STMF('/cgidev/randomnbrs.htm') CODEPAGE(819)
  • Check out the generated static page.

Error codes.
If subprocedure wrtHtmlToStmf does not complete normally, it returns a non-zero error code (in field "rc"). Error codes are documented in an IBM Infocenter separate page.

Size limit
As you know, the addressability limit of an IBM i program is 16 megabyte. That size accounts also for the buffer containing the output "page" generated from a (CGI) program. As a consequence, the output "page" size is must be somehow lower than 16 MB and attempts to load more data than allowed into the output buffer result to program exceptions. This is why we have added a new procedure, named WrtSectionToStmf that allows you to generate large stream files (no size limit) from your (CGI) program.

blue line

2. Subprocedure WrtSectionToStmf()
Use this procedure to generate, from your CGIDEV2 output buffer, a large stream file (more than 16 MB).
In your program, instead of using procedure Wrtsection() to add contents to the output buffer, you use procedure WrtsectionToStmf which - after adding contents to the buffer - writes the buffer to a stream file and clears the buffer, thus overcoming buffer size restrictions.
To close the stream file for good, you must send a *FINI section via WrtsectionToStmf().

This procedure has four parameters:

  1. Section names - a string of blank separated names for the sections you want to output (the same as in procedure Wrtsection() )
  2. Stream file path and name - this must be specified only in the first WrtsectionToStmf(), in order to create the stream file (if the stream file already exists, it is deleted)
  3. Data type - also this can be specified only in the first WrtsectionToStmf() and can be either
    • *TEXT (which means that data must be converted to the stream file CCSID), OR
    • *BIN (which means that no data conversion should take place.
    If omitted, *TEXT is assumed.
  4. Stream file CCSID - The CCSID of the receiving stream file. If omitted, CCSID 819 (US ASCII) is assumed. It can be specified only in the first WrtsectionToStmf().

Look at the following sample code that creates stream file '/tmp/test.html':

 /copy CGIDEV2/qrpglesrc,hspecs
 /copy CGIDEV2/qrpglesrc,hspecsbnd
FUTIFILE   IF   e           K DISK    extfile('MYLIB/UTIFILE')
 /copy CGIDEV2/qrpglesrc,prototypeb
 /copy CGIDEV2/qrpglesrc,usec
 /copy CGIDEV2/qrpglesrc,variables3
D stmf            s           1024    varying
D                                     inz('/tmp/test.html')
D extHtml         s           2000    inz('/mylib/html/test.txt')
D IfsMultIndicators...
D                 ds
D  NoErrors                       n
D  NameTooLong                    n
D  NotAccessible                  n
D  NoFilesUsable                  n
D  DupSections                    n
D  FileIsEmpty                    n


      wrtSectionToStmf('top':stmf:'*TEXT':819);  //Create  the stmf, write the first section 'top'

      read utircd;
      dow not %eof;
          wrtSectionToStmf('row');      //write a repeated section
          read utircd;
      wrtSectionToStmf('end *fini');    //write the last section and close the stream file