• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Guru Classic: A Bevy Of BIFs — Updates

    February 5, 2020 Jon Paris

    In my previous tip I returned to the “Bevy” series to tell you about the latest addition to the family: %ScanRpl. Shortly after completing that tip I realized that there have been a number of more recent BIFs such as %SubArr and some enhancements to existing BIFs like %Trimx that seem to have escaped people’s notice. In this tip I attempt to fill those omissions.

    %Trim: Specify Characters to Trim

    Let’s start with a BIF that hopefully you are all familiar with: %Trim. Before going any further I should point out that when I say %Trim, I am referring to the entire Trim family, i.e., %Trim, %TrimL, and %TrimR.

    What you might not realize though is that %Trim now offers an optional second parameter that allows you to specify exactly which character(s) you want to trim off. This can be really useful when processing data from CSV files or Web services where you encounter numeric values with leading asterisks and/or a currency symbol. For example $250.95 or ***125. The sample code below shows how this new option would allow you to “clean up” such values.

    Running it will result in the field target receiving the value 123.45 and having a length of six, at this point it is able to be processed by %Dec() for subsequent use in numeric calculations.

    dcl-s  charAmt2  char(20)  Inz('***$123.45');
    dcl-s  target         varchar(20);
    target = %Trim( charAmt2 : ' *$' );
    

    Note that in order to have blanks removed (trailing blanks in the example) I had to include a space in the string of characters to be removed. This would not have been needed if the intent was simply to use the resulting value with %Dec() since that BIF will automatically ignore leading and trailing spaces.

    %Addr: *Data Option

    This is one that I’m sure a lot of people missed, judging from the number of examples I see posted in online forums that do not make use of it.

    Introduced back in V5R4, the *Data option of the %Addr BIF returns the address of the data portion of a varying-length field, automatically bypassing the two (or four) byte count header portion. I make a lot of use of this capability in programs that build a string iteratively. For example, records to be written to CSV files, JSON, HTML and XML, etc. These sorts of strings are much more efficiently built in varying-length fields than in fixed length, but until this option was introduced it was necessary to manually add two (or four) to the address before passing it to an API. As a result you may encounter this kind of code.

    pParmData = %Addr(ParmData) + 2; 
    

    Using this new option allows you to code it this way:

    pParmData = %Addr(ParmData: *Data);
    

    Not only is this code simpler and more obvious to anyone who has to maintain the code in the future, but it is also much safer.

    Why so? Suppose that ParmData was originally 50,000 bytes long, but we subsequently need to increase the size to 100,000 bytes. At this point we have to hope that the programmer tasked with making this change is aware that a varying length field of 100,000 bytes requires a 4-byte header, not a 2-byte. As a result, simply changing the field length is not enough. They must also remember to change the “+ 2” to “+ 4” or the address created will be incorrect. Had the original programmer used the *Data option then this would never have become a problem since the compiler would have automatically calculated the correct address.

    Arrays, Anyone?

    Ever since I started coding in PHP, where arrays are a way of life, I realized that RPGers don’t use arrays as much as they should. But even among those who do make use of them, the %SubArr BIF seems to have slipped by unnoticed. Until the advent of the V7.4 release, RPG lacked the ability to use dynamic arrays in the sense that languages like PHP do. %SubArr however does allow us to surmount some of the problems that fixed length arrays can present.

    %SubArr allows you to specify that an operation, such as a SORTA, is to take place on only a portion of the array. So, for example, if while loading the array myArray we keep track of the number of active elements in the field count we can subsequently use that value with %SubArr like so:

    SORTA %SubArr( myArray : 1 : count );
    

    This allows us to sort only the active portion of the array. Not only is this faster, but it also avoids the need to have previously loaded all of the array elements with high (or low) values to “keep them out of the way” after the sort.

    %SubArr() can also be used to assign one portion of an array to another. Similar in some ways to the way in which the old MOVEA operation could be used. In the first example below, elements 5 to 9 of arrayZone are copied to elements 1 to 5 of arrayPack. In the second example the elements 1, 2 and 3 of arrayZone are copied into elements 2, 3 and 4 of arrayPack.

    dcl-s  arrayPack  packed(5)  dim(5);
    dcl-s  arrayZone  zoned(7:2)  dim(10);
    dcl-s  i  int(5);
    // Fill up arrayZone elements
    for i = 1 to %Elem(arrayZone);
       arrayZone(i) = i * 3.3333;
    EndFor;
    
    // Copy elements 5 - 9 of arrayZone to elements 1 - 5 of  arrayPack 
    arrayPack = %SubArr( arrayZone : 5  );
    
    // Copy elements 1, 2 & 3 of arrayZone into elements 2, 3 & 4 of arrayPack 
    
    
    %SubArr( arrayPack : 2 : 3 ) = arrayZone;    
    

    While On The Subject Of Arrays . . .

    It may have slipped past you that in V7.1 we finally got the ability to perform lookup operations on Data Structure arrays. We have had DS arrays since V5R2, but to in order to search them we had to resort to APIs such as bsearch().

    While bsearch still has a role for complex lookups, it is no longer needed for simple lookup operations. As of V7.1 we can perform lookups directly on DS arrays as in the example below. Notice that (*) is used as the array index to indicate that the entire array is to be searched:

    dcl-s  element  int(5); 
    dcl-s  product  char(7);  
    dcl-ds productInfo  Dim(999)  Qualified;  
       productCode Like(product); 
       description Varchar(60); 
       price       Packed(7:2); 
       cost        Packed(7:2); 
    end-ds; 
    
    product = 'A1234456';
    element = %LookUp( product : productInfo(*).productCode );
    

    That’s a whole lot easier to code. The only downside is that currently only the basic %LookUp BIF is supported, not other members of the “family” such as %LookUpGE.

    Jon Paris is one of the world’s foremost experts on programming on the IBM i platform. A frequent author, forum contributor, and speaker at User Groups and technical conferences around the world, he is also an IBM Champion and a partner at Partner400 and System i Developer. He hosts the RPG & DB2 Summit twice per year with partners Susan Gantner and Paul Tuohy.

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags: Tags: 400guruclassic, API, BIF, CSV, FHGC, Four Hundred Guru Classic, HTML, IBM i, JSON, V5R2, V5R4, XML

    Sponsored by
    VISUAL LANSA 16 WEBINAR

    Trying to balance stability and agility in your IBM i environment?

    Join this webinar and explore Visual LANSA 16 – our enhanced professional low-code platform designed to help organizations running on IBM i evolve seamlessly for what’s next.

    🎙️VISUAL LANSA 16 WEBINAR

    Break Monolithic IBM i Applications and Unlock New Value

    Explore modernization without rewriting. Decouple monolithic applications and extend their value through integration with modern services, web frameworks, and cloud technologies.

    🗓️ July 10, 2025

    ⏰ 9 AM – 10 AM CDT (4 PM to 5 PM CEST)

    See the webinar schedule in your time zone

    Register to join the webinar now

    What to Expect

    • Get to know Visual LANSA 16, its core features, latest enhancements, and use cases
    • Understand how you can transition to a MACH-aligned architecture to enable faster innovation
    • Discover native REST APIs, WebView2 support, cloud-ready Azure licensing, and more to help transform and scale your IBM i applications

    Read more about V16 here.

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Guru Classic: Looking For Stuff With iSphere Guru Classic: Find a View of a View of a View. . .

    Leave a Reply Cancel reply

TFH Volume: 30 Issue: 9

This Issue Sponsored By

  • RPG & DB2 Summit
  • RPG & DB2 Summit
  • RPG & DB2 Summit

Table of Contents

  • Guru Classic: Find a View of a View of a View. . .
  • Guru Classic: A Bevy Of BIFs — Updates
  • Guru Classic: Looking For Stuff With iSphere

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • From Stable To Scalable: Visual LANSA 16 Powers IBM i Growth – Launching July 8
  • VS Code Will Be The Heart Of The Modern IBM i Platform
  • The AS/400: A 37-Year-Old Dog That Loves To Learn New Tricks
  • Meet The Next Gen Of IBMers Helping To Build IBM i
  • Looks Like IBM Is Building A Linux-Like PASE For IBM i After All
  • Will Independent IBM i Clouds Survive PowerVS?
  • Now, IBM Is Jacking Up Hardware Maintenance Prices
  • IBM i PTF Guide, Volume 27, Number 24
  • Big Blue Raises IBM i License Transfer Fees, Other Prices
  • Keep The IBM i Youth Movement Going With More Training, Better Tools

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2025 IT Jungle