fhg
Volume 10, Number 27 -- September 15, 2010

Basing Pointer Variables in RPG: The Basics

Published: September 15, 2010

by Ted Holt

When I began pursuit of my computer science degree eons ago, the only programming experience I had was business programming. Jumping from System/34 RPG II to Pascal was a shock, but learning Pascal was one of the best things that ever happened to me professionally. Learning Pascal introduced me to programming constructs that I had not seen before, including pointer variables, the topic of this article. If you've not mastered pointers, continue reading. Do it for your own edification.

RPG has two types of pointer variables: basing pointers, and procedure pointers. Both types of pointers hold memory addresses. Both types of pointers provide a way to indirectly access something else. This article deals only with basing pointers.


Your Address, Please

Basing pointers are variables, but they don't store the types of data to which we are accustomed, such as names, addresses, account numbers, quantities, and currency amounts. Basing pointers store the memory addresses of data. They are indicated by an internal data type of asterisk (*) in position 40 of the definition specification. Here's a basing pointer named Address.

DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++++++
D Address         s               *

A basing pointer has a null value by default. That is, it doesn't point to any data at all.

So, if a basing pointer can store an address of data, but cannot store the data itself, where is the data to which the basing pointer points? The simple answer is that the data is somewhere else. That unknown "somewhere else" is represented by a based variable. Here is a basing pointer, PtrName, and a character variable, Name, to which the basing pointer points.

D PtrName         s               *
D Name            s             20a   based(PtrName)

The Name variable has no place of its own in memory, so it must share memory that has been allotted to something else. To do that, assign the address of another variable to the pointer. (There is another method--use the %alloc function or the ALLOC op code to allocate memory for the based variable--but that will buy us nothing for this discussion.)

To see how it works, consider this example.

D AddressOfTheSelectedVar...
D                 s               *
D TheSelectedVar...
D                 s             20a   based(AddressOfTheSelectedVar)
D*
D Name            s             20a
D Address         s             20a
D City            s             20a
D
 /free
     *inlr = *on;
     AddressOfTheSelectedVar = %addr(Name);
     TheSelectedVar = 'John Dilatory';
     AddressOfTheSelectedVar = %addr(Address);
     TheSelectedVar = 'P. O. Box 1';
     AddressOfTheSelectedVar = %addr(City);
     TheSelectedVar = 'Lost Angeles';
     return;

In addition to the basing pointer and based variable, there are three static variables: Name, Address, and City. This short routine assigns values to the three static variables, but it does so indirectly. The second assignment statement retrieves the memory address of Name and stores that memory address in the basing pointer AddressOfTheSelectedVar. Now Name and TheSelectedVar refer to the same 20 bytes of memory, which means that changing one changes the other.

After this code runs, Name, Address, and City contain the values John Dilatory, P. O. Box 1, and Lost Angeles, respectively.


Let's Be Practical

Let's consider a more practical example. Suppose we have a command named DOIT (do it).

CMD        PROMPT('Do it')
PARM       KWD(WHEN) TYPE(*TIME) MIN(1) MAX(6) +
             PROMPT('Time to do it')

Notice that DOIT has a list parameter, WHEN, which allows the user to specify from one to six times that "it" should be done.

DOIT WHEN(080000 123000 144500 180000)

The system formats the time values into a variable-length string. The first two bytes contain a binary number that tells how many values were keyed into the parameter. Following that are a series of one to six 6-byte character values. The system will send either eight, 14, 20, 26, 32, or 38 characters to the command-processing program.

While we're supposing, let's suppose that the command-processing program is written in RPG. How is the RPG program to interpret the list of time values? Before pointers, an RPG program would have to define the parameter with a length of at least 38 bytes.

Suppose the command is changed so that a maximum of 10 values can be keyed into the WHEN parameter. The length of the list parameter in the RPG program would have to be changed from at least 38 to 62.

However, if you use pointers to process the list, the program does not have to be changed. Look at this:

****   *entry plist
D 
D DoItCPP         pr
D parmWhen                       1a
D DoItCPP         pi
D parmWhen                       1a

D ListPointer     s               *
D NbrOfListElems  s              5i 0 based(ListPointer)
D TimeInList      s              6a   based(ListPointer)

D NbrOfTimes      s              5i 0
D Ndx             s             10i 0
D TimeVar         s              6a

 /free
     *inlr = *on;

     // How many time values were passed in?
     ListPointer = %addr(parmWhen);
     NbrOfTimes  = NbrOfListElems;

     // Advance to the first time value.
     ListPointer += 2;

     // Loop to extract the time values.
     for Ndx = 1 to NbrOfTimes;
        TimeVar = TimeInList;

        // Here's the place do something with TimeVar.

        // Advance to the next time value in the list.
        ListPointer += %size(TimeInList);
     endfor;

     return;

The input parameter, parmWhen, is defined as a 1-byte character value. That's obviously incorrect, but it doesn't matter, because all we need is the address of the parameter.

In the calcs, extract the number of time values from the first 2 bytes of the parameter.

D ListPointer     s               *
D NbrOfListElems  s              5i 0 based(ListPointer)

D NbrOfTimes      s              5i 0

 /free
     ListPointer = %addr(parmWhen);
     NbrOfTimes  = NbrOfListElems;

Advance the pointer 2 bytes so that it points to the first 6-byte time value.

     ListPointer += 2;

Process the time values in the list.

     // Loop to extract the time values.
     for Ndx = 1 to NbrOfTimes;
        TimeVar = TimeInList;

        // Here's the place do something with TimeVar.

        // Advance to the next time value in the list.
        ListPointer += %size(TimeInList);
     endfor;

Each iteration loads the next time into TimeVar and advances the pointer 6 bytes so that it points to the next time value in the list. After the last iteration, ListPointer is pointing to the first byte in memory that follows the list, but that's OK as long as we don't use ListPointer while it has that value.

If someone changes the MAX parameter of the DOIT command, the system will send strings of other lengths, but since the length of parmWhen is not specified in the parameter definition, the RPG program will not need to be changed.


Broaden Your Horizons

If you don't know how to use basing pointers, you may as well learn. Basing pointers are not difficult to understand. They especially come in handy when dealing with the data returned from certain APIs. And they're fun.




                     Post this story to del.icio.us
               Post this story to Digg
    Post this story to Slashdot


Sponsored By
PROFOUND LOGIC SOFTWARE

DDS Conversion to Rich UI with IBM's RPG Open Access

RPG Open Access and Profound UI provides a great method for developing rich new interfaces for your applications. But many organizations have a large number of green-screen applications and need a modernization solution that leverages the existing business logic. So, what can be done to reduce the effort of creating web interfaces for these applications?

Profound UI provides the answer to this issue with its DDS Conversion Module. With this module, customers can reuse their existing DDS source members by converting them into native IBM i objects that support a robust browser interface. All of this is done using an automated process to generate the new web interfaces based on your existing DDS without any screen-scrapping or ties to the 5250, and existing RPG programs can drive these interfaces with little or no modifications. Join us Thursday, September 30th at 1:00 PM EST.

Attend the upcoming webinar, "DDS Conversion to Rich UI with IBM's RPG Open Access," to learn about:

      What the DDS Conversion process is and how it works with RPG OA.
      How this process compares to other methods for modernizing IBM i apps.
      Determining the right approach to modernization for your business.
      How the results compare to other methods with a live demonstration.

Click here to learn more and register for this event.


Senior Technical Editor: Ted Holt
Technical Editor: Joe Hertvik
Contributing Technical Editors: Erwin Earley, Brian Kelly, Michael Sansoterra
Publisher and Advertising Director: Jenny Thomas
Advertising Sales Representative: Kim Reed
Contact the Editors: To contact anyone on the IT Jungle Team
Go to our contacts page and send us a message.

Sponsored Links

iSeries DevCon2010:  Get 3 days of IBM i training and 365 DAYS OF VALUE, Nov 15-17, Las Vegas
looksoftware:  RPG OA & Beyond Webinar. Sept 28 & 29. Enter to win an Amazon Kindle™
COMMON:  Join us at the Fall 2010 Conference & Expo, Oct. 4 - 6, in San Antonio, Texas


 

IT Jungle Store Top Book Picks

Easy Steps to Internet Programming for AS/400, iSeries, and System i: List Price, $49.95
The iSeries Express Web Implementer's Guide: List Price, $49.95
The System i RPG & RPG IV Tutorial and Lab Exercises: List Price, $59.95
The System i Pocket RPG & RPG IV Guide: List Price, $69.95
The iSeries Pocket Database Guide: List Price, $59.00
The iSeries Pocket SQL Guide: List Price, $59.00
The iSeries Pocket Query Guide: List Price, $49.00
The iSeries Pocket WebFacing Primer: List Price, $39.00
Migrating to WebSphere Express for iSeries: List Price, $49.00
Getting Started With WebSphere Development Studio Client for iSeries: List Price, $89.00
Getting Started with WebSphere Express for iSeries: List Price, $49.00
Can the AS/400 Survive IBM?: List Price, $49.00
Chip Wars: List Price, $29.95


 
The Four Hundred
IBM Adds New SSD and Fat SFF Disk to Power Systems

Power7 Planning Beyond the Bells and Whistles

Companies Buy Lots of Disk Storage--At Cheap Prices--in Q2

As I See It: Introducing the New Quarterlife Crisis (with Cheese)

CIOs Are a Little More Optimistic About IT Hiring--But Not Much

Four Hundred Stuff
VAI Positions ERP Suite for Business Recovery

Vision Merges HA Products Into MIMIX Availability 7

Document Management Cuts Paper and Saves Money at Top Ranked City

Trilobyte Keeps the Original 5250 Emulator Alive

Oracle Adds DB2/400 Support to GoldenGate Data Integration Tool

Four Hundred Monitor
Four Hundred Monitor's
Full iSeries Events Calendar

System i PTF Guide
September 4, 2010: Volume 12, Number 36

August 28, 2010: Volume 12, Number 35

August 21, 2010: Volume 12, Number 34

August 14, 2010: Volume 12, Number 33

August 7, 2010: Volume 12, Number 32

July 31, 2010: Volume 12, Number 31

TPM at The Register
Ex-IBM heir apparent gets six months in the slammer

SGI readies first Project Mojo supers

HP eyes $1.46bn ArcSight security buy

IBM wheels and deals on servers

Oracle sneaks out Solaris 10 refresh

Dell launches Opteron 4100s into Boxes-o-Cloud

Appro sells another flash-happy HPC cluster

Netezza, Symantec jump on takeover rumors

HP punts MicroServer for SMBs

Cisco & Citrix marry on virty PCs

What does the Hurd mentality bring to Oracle?

Oracle rings up new Netra servers

THIS ISSUE SPONSORED BY:

WorksRight Software
Profound Logic Software
inFORM Decisions


Printer Friendly Version


TABLE OF CONTENTS
Get Thee to the Web, Part 2

Basing Pointer Variables in RPG: The Basics

Admin Alert: Getting Started with i/OS Security Auditing, Part 1

Four Hundred Guru

BACK ISSUES




 
Subscription Information:
You can unsubscribe, change your email address, or sign up for any of IT Jungle's free e-newsletters through our Web site at http://www.itjungle.com/sub/subscribe.html.

Copyright © 1996-2010 Guild Companies, Inc. All Rights Reserved.
Guild Companies, Inc., 50 Park Terrace East, Suite 8F, New York, NY 10034

Privacy Statement