(Author's Note: This week's article is an excerpt from my upcoming book RPG TNT: 101 Dynamite Tips and Techniques for RPG IV Programmers.)
RPG IV supports declaring variables based on the attributes of an already-declared variable. The LIKE keyword does this for field definitions. To accomplish the same thing for data structures, use the LIKEDS keyword:
D item 5A
D qtyord 5P 0
D price 7P 2
D myOrders DS LikeDS(ORDERS)
The data structure named ORDERS is a typical RPG-style data structure. The other data structure, MYORDERS, is based on the ORDERS data structure. When this technique is applied, the new data structure (MYORDERS in this example) implicitly becomes a qualified data structure and inherits all the subfields of the ORDERS data structure, but not their initial values; the INZ keyword is not carried over to the MYORDERS data structure.
Because the new data structure is automatically qualified, the subfields of MYORDERS can have the same names as those of the ORDERS data structure. In this example, the generated code for the MYORDERS data structure would be as follows:
D item 5A
D qtyord 5P 0
D price 7P 2
To inherit the initial values of the original data structure, specify INZ(*LIKEDS) in addition to the LIKEDS keyword on the new data structure:
D INZ(*LIKEDS)
If INZ(*LIKEDS) is specified, the resulting data structure would look like this:
D item 5A
D qtyord 5P 0
D price 7P 2
The original or based-on data structure (ORDERS in our example) can be any type of data structure. That structure is used as a template to create the new data structure. When a data structure is used only as a format for other data structures, it is referred to as a data structure template. The new data structure is always a qualified data structure that includes all of the subfields from the original data structure. No data is ever stored in the based-on data structure; instead, new data structures are created using the original data structure, and data is stored only in them. Any data structure may be used as a data structure template.
A true data structure template will not contain data or will be initialized to some predefined default values. Here's an example:
The QlgConvertCase API requires a data structure for one of its parameters. That data structure controls the type of conversion that is performed and the direction of the conversion (to or from a target CCSID).
Most of the time, the QlgConvertCase API is used to convert between uppercase and lowercase letters. The data structure name it uses is FRCB and would normally appear as follows:
D ReqType 10I 0 Inz(1)
D CCSID 10I 0 Inz(0)
D CvtTo 10I 0 Inz(0)
D Reserved 10A Inz(*ALLX'00')
The four subfields are already initialized, and the data structure is qualified and aligned on a 16-byte boundary (a requirement for this data structure). We don't use this data structure directly, but instead treat it as a data structure template and create our own FRCB data structure:
D myFRCB DS LikeDS(FRCB)
D Inz(*LIKEDS)
While the INZ(*LIKEDS) keyword is optional, it is needed so that the new MYFRCB data structure includes not only all four of the original subfields, but also their initial values, a critical element to having the API work correctly. Remember, the ALIGN keyword is automatically inherited by LIKEDS so specifying it again would be redundant.
Now we can modify the content of the MYFRCB data structure and use it to call QlgConvertCase:
C eval myFRCB.CvtTo = 1
// Convert to all lower case letters
C CallP QlgCvtCase(myFRCB : inData :
C outData : %len(inData) :
C myAPIErrorDS)
If an initial value in the data structure template isn't necessary, you can save some storage and also prevent other programmers from storing information directly into the data structure template by removing its storage allocation. To remove the storage allocation from a data structure (used as a data structure template, for example), specify the BASED keyword with a dummy parameter. Here's an example:
D ReqType 10I 0
D CCSID 10I 0
D CvtTo 10I 0
D Reserved 10A
The BASED keyword causes the storage allocation for the data structure to be controlled by the programmer. No storage is allocated for the data structure when BASED is specified.
RPG IV implicitly declares a pointer variable with the same name as that specified on the BASED keyword. So a field named NOTHING_PTR is implicitly declared as follows:
Be sure to use a field name that isn't used elsewhere.
Since no storage is allocated, you cannot store data in the FRCB data structure. But if you create a new data structure using FRCB as the template, you may store data in the new data structure. This is because the BASED keyword is not inherited by LIKEDS.
Use this technique to create data structures such as those that are passed as parameters to subprocedures or other programs. One developer can design procedure parameters that may include a data structure and then create the corresponding data structure template(s) to define the parameters. A second developer using that subprocedure can declare a copy of it using the LIKEDS keyword and specify the new data structure name in positions 7 to 21 of the Definition specifications.
Data structure templates are easy to use. Every data structure you've created in your career can be used as a data structure template. This technique provides a level of dereferencing that allows you to make updates/modifications much more easily.
Bob Cozzi is a programmer/consultant, writer/author, and software developer of the RPG xTools, a popular add-on subprocedure library for RPG IV. His book The Modern RPG Language has been the most widely used RPG programming book for nearly two decades. He, along with others, speaks at and runs the highly-popular RPG World conference for RPG programmers.
LATEST COMMENTS
MC Press Online