RXS_Convert()

RXS_Convert is a flexible subprocedure allowing you to perform many commonly required text and data conversions:

  • Convert to/from Base64 encoding
  • Convert to/from Base64Url encoding
  • Perform XML entity encoding/decoding to replace characters with the appropriate XML entities:
    • & to &
    • to "
    • ' to '
    • < to &lt;
    • > to &gt;
  • Encode or decode a URL’s querystring
  • Convert between CCSIDs (character sets)
  • Convert to uppercase or lowercase in a CCSID-aware manner - preferable to the common practice of using the %XLATE built-in function
  • General find & replace - you can specify your own characters/strings to perform replacements with. Essentially, this allows developers on IBM i OS 6.1 to access functionality similar to that of the %SCANRPL built-in function added in IBM i OS 7.1.

Subprocedure Prototype

D RXS_Convert...
D                 PR                  Extproc('RXS_Convert') Opdesc
D                                     Like(RXS_Var16Mv_t)
D                                     Rtnparm

The output of the specified conversion operation is returned.

D  pInput                             Like(RXS_Var16Mv_t) Const
D                                     Options(*Varsize:*Omit)

Field to hold the input of the selected conversion operation. You can pass a field smaller than 16M without any additional effort.

D  pDS                                Like(RXS_Var64K_t)
D                                     Options(*Varsize)

Holds settings which control how RXS_Convert operates. This parm can accomodate a number of possible data structures, listed below.

Valid Values:

  • RXS_ConvertCcsidDS_t
  • RXS_ConvertCaseDS_t
  • RXS_ConvertBase64DS_t
  • RXS_ConvertXMLEntitiesDS_t
  • RXS_ConvertUrlPercentDS_t
  • RXS_ConvertUserDefinedDS_t

Example Code

*--------------------------------------------------------------
* This example uses RXS_Convert() to encode data to Base64.
* Base64 is commonly used to transfer binary data such as images
* or cryptographic keys/hashes, but may be used on any data.
* Important to note is that no CCSID conversion is performed on
* the decoded data. If you are sending text, the receiver will
* most likely not expect the data to be in EBCDIC, so you may
* need to use RXS_Convert() to perform CCSID conversion prior
* to performing Base64 encoding.
*--------------------------------------------------------------
H DFTACTGRP(*NO) BNDDIR('RXSBND') ACTGRP(*CALLER)

 /copy QRPGLECPY,RXSCB

D gRawData        S                   Like(RXS_Var8Kv_t)
D gBase64         S                   Like(RXS_Var8Kv_t)

D gConvBase64DS   DS                  LikeDS(RXS_ConvertBase64DS_t)
 /free
  gRawData = 'hello world!';

  RXS_ResetDS( gConvBase64DS : RXS_DS_TYPE_CONVERTBASE64 );
  gConvBase64DS.EncodeDecode = RXS_ENCODE;
  gBase64 = RXS_Convert( gRawData : gConvBase64DS );

  // After encoding, gBase64 will contain:
  //  aGVsbG8gd29ybGQh

  *INLR = *ON;
 /end-free
*--------------------------------------------------------------
* This example uses RXS_Convert() to decode Base64 encoded data.
* Base64 is commonly used to transfer binary data such as images
* or cryptographic keys/hashes, but may be used on any data.
* Important to note is that no CCSID conversion is performed on
* the decoded data. If you are receiving ASCII data that was
* Base64 encoded, you may need to use RXS_Convert() to convert
* it to a non-ASCII CCSID.
*--------------------------------------------------------------
H DFTACTGRP(*NO) BNDDIR('RXSBND') ACTGRP(*CALLER)

 /copy QRPGLECPY,RXSCB

D gBase64         S                   Like(RXS_Var8Kv_t)
D gDecoded        S                   Like(RXS_Var8Kv_t)

D gConvBase64DS   DS                  LikeDS(RXS_ConvertBase64DS_t)
 /free
  gBase64 = 'aGVsbG8gd29ybGQh';

  RXS_ResetDS( gConvBase64DS : RXS_DS_TYPE_CONVERTBASE64 );
  gConvBase64DS.EncodeDecode = RXS_DECODE;
  gDecoded = RXS_Convert( gBase64 : gConvBase64DS );

  // After decoding, gDecoded will contain:
  //  hello world!

  *INLR = *ON;
 /end-free
*--------------------------------------------------------------
* This example uses RXS_Convert() to encode XML entites in
* character data. Note that because < and > would need to be
* encoded, you cannot use RXS_Convert() to encode a complete
* XML document. Each item being composed into an XML element
* would need to be individually encoded.
*--------------------------------------------------------------
H DFTACTGRP(*NO) BNDDIR('RXSBND') ACTGRP(*CALLER)

 /copy QRPGLECPY,RXSCB

D gData            S                  Like(RXS_Var8Kv_t)
D gEncoded         S                  Like(RXS_Var8Kv_t)

D gConvXMLEntDS    DS                 LikeDS(RXS_ConvertXMLEntitiesDS_t)
 /free
  gData = 'Bob & Mary';

  RXS_ResetDS( gConvXMLEntDS : RXS_DS_TYPE_CONVERTXMLENTITIES );
  gConvXMLEntDS.EncodeDecode = RXS_ENCODE;
  gEncoded = RXS_Convert( gData : gConvXMLEntDS );

  // After encoding, gEncoded will contain:
  //  Bob &amp; Mary

  *INLR = *ON;
 /end-free
*--------------------------------------------------------------
* This example uses RXS_Convert() to decode XML entites back
* to the corresponding character data. If you have an XML
* document with encoded characters, it is generally safe to use
* RXS_Convert() on the entire XML document. One exception to this
* is when the XML document contains a nested complete XML document
* which frequently occurs with .Net SOAP services. In that scenario,
* you need to first parse the inner XML document out, and then
* perform conversion. Failure to do this may result in an invalid
* XML document.
*--------------------------------------------------------------
H DFTACTGRP(*NO) BNDDIR('RXSBND') ACTGRP(*CALLER)

 /copy QRPGLECPY,RXSCB

D gXML             S                  Like(RXS_Var8Kv_t)
D gDecoded         S                  Like(RXS_Var8Kv_t)

D gConvXMLEntDS    DS                 LikeDS(RXS_ConvertXMLEntitiesDS_t)
 /free
  gXML = '<xml>Bob &amp; Mary</xml>';

  RXS_ResetDS( gConvXMLEntDS : RXS_DS_TYPE_CONVERTXMLENTITIES );
  gConvXMLEntDS.EncodeDecode = RXS_DECODE;
  gDecoded = RXS_Convert( gXML : gConvXMLEntDS );

  // After decoding, gDecoded will contain:
  //  <xml>Bob & Mary</xml>

  *INLR = *ON;
 /end-free
*--------------------------------------------------------------
* This example uses RXS_Convert() to URL-encode data
* (also known as 'percent encoding'). This is generally used
* when passing values in a querystring within a URL. Note that
* it is not possible to perform URL encoding on a complete URL
* as many of the characters that make up a URL would be
* erroneously converted. Instead, each value must be encoded
* and concatenated to the URL.
*--------------------------------------------------------------
H DFTACTGRP(*NO) BNDDIR('RXSBND') ACTGRP(*CALLER)

 /copy QRPGLECPY,RXSCB

D gUrl            S                   Like(RXS_Var1Kv_t)
D gRawData        S                   Like(RXS_Var8Kv_t)
D gEncoded        S                   Like(RXS_Var8Kv_t)

D gConvUrlDS      DS                  LikeDS(RXS_ConvertUrlPercentDS_t)
 /free
  gURL = 'http://www.example.com?key='

  gRawData = 'hello world!';

  RXS_ResetDS( gConvUrlDS : RXS_DS_TYPE_CONVERTURLPERCENT );
  gConvUrlDS.EncodeDecode = RXS_ENCODE;
  gEncoded = RXS_Convert( gRawData : gConvUrlDS );

  // After encoding, gEncoded will contain:
  //  hello%20world%21

  gURL += gEncoded;

  // gURL now contains:
  //  http://www.example.com?key=hello%20world%21

  *INLR = *ON;
 /end-free
*--------------------------------------------------------------
* This example uses RXS_Convert() to decode URL-encoded data
* (also known as 'percent encoded').
*--------------------------------------------------------------
H DFTACTGRP(*NO) BNDDIR('RXSBND') ACTGRP(*CALLER)

 /copy QRPGLECPY,RXSCB

D gEncoded        S                   Like(RXS_Var8Kv_t)
D gDecoded        S                   Like(RXS_Var8Kv_t)

D gConvUrlDS      DS                  LikeDS(RXS_ConvertUrlPercentDS_t)
 /free
  gEncoded = 'key%3Dhello%20world%21';

  RXS_ResetDS( gConvUrlDS : RXS_DS_TYPE_CONVERTURLPERCENT );
  gConvUrlDS.EncodeDecode = RXS_DECODE;
  gDecoded = RXS_Convert( gEncoded : gConvUrlDS );

  // After decoding, gDecoded will contain:
  //  key=hello world!

  *INLR = *ON;
 /end-free
*--------------------------------------------------------------
* This example uses RXS_Convert() to perform CCSID conversion to
* convert from ISO 8859-1 (CCSID 819) to EBCDIC (CCSID 37).
*--------------------------------------------------------------
H DFTACTGRP(*NO) BNDDIR('RXSBND') ACTGRP(*CALLER)

 /copy QRPGLECPY,RXSCB

D gData819        S                   Like(RXS_Var8Kv_t)
D gData37         S                   Like(RXS_Var8Kv_t)

D gConvCcsidDS    DS                  LikeDS(RXS_ConvertCcsidDS_t)
 /free
  gData819 = x'48656C6C6F20576F726C6421'; 
  RXS_ResetDS( gConvCcsidDS : RXS_DS_TYPE_CONVERTCCSID );
  gConvCcsidDS.From = RXS_CCSID_ISO88591;
  gConvCcsidDS.To = RXS_CCSID_EBCDIC;
  gData37 = RXS_Convert( gData819 : gConvCcsidDS );

  // After conversion, gData37 will contain:
  //  Hello World!

  *INLR = *ON;
 /end-free
*--------------------------------------------------------------
* This example uses RXS_Convert() to convert lowercase characters
*  in gData to uppercase. This conversion happens in a CCSID
*  aware manner. For example, ü will be converted to Ü. This
*  is recommended over the common practice of using the %Xlate
*  function with A-Z/a-z constants.
*--------------------------------------------------------------
H DFTACTGRP(*NO) BNDDIR('RXSBND') ACTGRP(*CALLER)

 /copy QRPGLECPY,RXSCB

D gData           S                   Like(RXS_Var8Kv_t)
D gUppercase      S                   Like(RXS_Var8Kv_t)

D gConvCaseDS     DS                  LikeDS(RXS_ConvertCaseDS_t)
 /free
  gData = 'Hello Günter';

  RXS_ResetDS( gConvCaseDS : RXS_DS_TYPE_CONVERTCASE );
  gConvCaseDS.UpperLower = RXS_UPPERCASE;
  gUppercase = RXS_Convert( gData : gConvCaseDS );

  // After conversion, gLowercase will now contain
  //  HELLO GÜNTER

  *INLR = *ON;
 /end-free
*--------------------------------------------------------------
* This example uses RXS_Convert() to convert uppercase characters
*  in gData to lowercase. This conversion happens in a CCSID
*  aware manner. For example, Ü will be converted to ü. This
*  is recommended over the common practice of using the %Xlate
*  function with A-Z/a-z constants.
*--------------------------------------------------------------
H DFTACTGRP(*NO) BNDDIR('RXSBND') ACTGRP(*CALLER)

 /copy QRPGLECPY,RXSCB

D gData           S                   Like(RXS_Var8Kv_t)
D gLowercase      S                   Like(RXS_Var8Kv_t)

D gConvCaseDS     DS                  LikeDS(RXS_ConvertCaseDS_t)
 /free
  gData = 'HELLO GÜNTER';

  RXS_ResetDS( gConvCaseDS : RXS_DS_TYPE_CONVERTCASE );
  gConvCaseDS.UpperLower = RXS_LOWERCASE;
  gLowercase = RXS_Convert( gData : gConvCaseDS );

  // After conversion, gLowercase will now contain
  //  hello günter

  *INLR = *ON;
 /end-free
*--------------------------------------------------------------
* This example uses RXS_Convert() to replace instances of
* specified characters or bytes with the provided replacements.
* This was originally introduced to provide customers on IBM i
* 6.1 with something similar to the %ScanRpl built-in function
* which was only available on IBM i 7.1 or higher. Generally
* if you are on IBM i 7.1 or higher, you can just use %ScanRpl.
* The only advantage offered by using RXS_Convert() is that
* up to 50 replacements may be specified, but each From and To
* are limited to 32 bytes.
*--------------------------------------------------------------
H DFTACTGRP(*NO) BNDDIR('RXSBND') ACTGRP(*CALLER)

 /copy QRPGLECPY,RXSCB

D gInput          S                   Like(RXS_Var8Kv_t)
D gOutput         S                   Like(RXS_Var8Kv_t)

D gConvUsrDfnDS   DS                  LikeDS(RXS_ConvertUserDefinedDS_t)
 /free
  gInput = 'This is a sample message';

  RXS_ResetDS( gConvUsrDfnDS : RXS_DS_TYPE_CONVERTUSERDEFINED );
  gConvUsrDfnDS.From(1) = 'sample';
  gConvUsrDfnDS.To(1) = 'cool';
  gConvUsrDfnDS.From(2) = 'message';
  gConvUsrDfnDS.To(2) = 'message!';
  gOutput = RXS_Convert( gInput : gConvUsrDfnDS );

  // gOutput now contains:
  //  This is a cool message!

  *INLR = *ON;
 /end-free

Data Structures

D RXS_ConvertBase64DS_t...
D                 DS                  Qualified Template Inz
 
D   ReturnedErrorInfo...
D                                     LikeDS(RXS_ReturnedErrorInfoDS_t) Inz
 
D   DataStructureType...
D                                5I 0 Inz(RXS_DS_TYPE_CONVERTBASE64)

Internal use only

D   OnErrorMessageType...
D                                5I 0
 
D   EncodeDecode                  N

Set to RXS_ENCODE or RXS_DECODE.

Valid Values:

  • RXS_ENCODE
  • RXS_DECODE

Default Value: RXS_DECODE

D   InputPointer...
D                                 *

Internal use only

D   InputLength                 10I 0

Internal use only

D   OutputPointer...
D                                 *

Internal use only

D   OutputLength                10I 0

Internal use only

D   Reserved                  2048A

Internal use only

D RXS_ConvertBase64DS_t...
D                 DS                  Qualified Template Inz
 
D   ReturnedErrorInfo...
D                                     LikeDS(RXS_ReturnedErrorInfoDS_t) Inz
 
D   DataStructureType...
D                                5I 0 Inz(RXS_DS_TYPE_CONVERTBASE64)

Internal use only

D   OnErrorMessageType...
D                                5I 0
 
D   EncodeDecode                  N

Set to RXS_ENCODE or RXS_DECODE.

Valid Values:

  • RXS_ENCODE
  • RXS_DECODE

Default Value: RXS_DECODE

D   PadEncodedOutput...           N   Inz(RXS_NO)

Set to RXS_YES or RXS_NO.

Valid Values:

  • RXS_YES
  • RXS_NO

Default Value: RXS_NO

D   InputPointer...
D                                 *

Internal use only

D   InputLength                 10I 0

Internal use only

D   OutputPointer...
D                                 *

Internal use only

D   OutputLength                10I 0

Internal use only

D RXS_ConvertCaseDS_t...
D                 DS                  Qualified Template Inz
 
D   ReturnedErrorInfo...
D                                     LikeDS(RXS_ReturnedErrorInfoDS_t) Inz
 
D   DataStructureType...
D                                5I 0 Inz(RXS_DS_TYPE_CONVERTCASE)
 
D   OnErrorMessageType...
D                                5I 0
 
D   Ccsid                       10I 0

The CCSID of the input string. Defaults to the CCSID of the current job.

D   UpperLower                    N

Set to RXS_UPPERCASE or RXS_LOWERCASE.

Valid Values:

  • RXS_UPPERCASE
  • RXS_LOWERCASE

Default Value: RXS_UPPERCASE

D   InputPointer...
D                                 *

Internal use only

D   InputLength                 10I 0

Internal use only

D   OutputPointer...
D                                 *

Internal use only

D   OutputLength                10I 0

Internal use only

D   Reserved                  2050A

Internal use only

D RXS_ConvertCcsidDS_t...
D                 DS                  Qualified Template Inz
 
D   ReturnedErrorInfo...
D                                     LikeDS(RXS_ReturnedErrorInfoDS_t) Inz
 
D   DataStructureType...
D                                5I 0 Inz(RXS_DS_TYPE_CONVERTCCSID)

Internal use only

D   OnErrorMessageType...
D                                5I 0
 
D   From                        10I 0

CCSID to convert the input data from.

D   To                          10I 0

CCSID to convert the input data to.

D   InputPointer...
D                                 *

Internal use only

D   InputLength                 10I 0

Internal use only

D   OutputPointer...
D                                 *

Internal use only

D   OutputLength                10I 0

Internal use only

D   Reserved                  2048A

Internal use only

D RXS_ConvertUrlPercentDS_t...
D                 DS                  Qualified Template Inz
 
D   ReturnedErrorInfo...
D                                     LikeDS(RXS_ReturnedErrorInfoDS_t) Inz
 
D   DataStructureType...
D                                5I 0 Inz(RXS_DS_TYPE_CONVERTURLPERCENT)

Internal use only

D   OnErrorMessageType...
D                                5I 0
 
D   EncodeDecode                  N

Set to RXS_ENCODE or RXS_DECODE.

Valid Values:

  • RXS_ENCODE
  • RXS_DECODE

Default Value: RXS_DECODE

D   AsciiEbcdic                   N

Determines whether the returned encoded hexadecimal values are returned as ASCII bytes (RXS_ASCII) or converted to EBCDIC (RXS_EBCDIC).

Valid Values:

  • RXS_ASCII
  • RXS_EBCDIC

Default Value: RXS_ASCII

D   InputPointer...
D                                 *

Internal use only

D   InputLength                 10I 0

Internal use only

D   OutputPointer...
D                                 *

Internal use only

D   OutputLength                10I 0

Internal use only

D   Reserved                  2050A

Internal use only

D RXS_ConvertUserDefinedDS_t...
D                 DS                  Qualified Template Inz
 
D   ReturnedErrorInfo...
D                                     LikeDS(RXS_ReturnedErrorInfoDS_t) Inz
 
D   DataStructureType...
D                                5I 0 Inz(RXS_DS_TYPE_CONVERTUSERDEFINED)

Internal use only

D   OnErrorMessageType...
D                                5I 0
 
D   From                        32A   Varying Dim(50)
 
D   To                          32A   Varying Dim(50)
 
D   InputPointer...
D                                 *

Internal use only

D   InputLength                 10I 0

Internal use only

D   OutputPointer...
D                                 *

Internal use only

D   OutputLength                10I 0

Internal use only

D   Reserved                  2048A

Internal use only

D RXS_ConvertXMLEntitiesDS_t...
D                 DS                  Qualified Template Inz
 
D   ReturnedErrorInfo...
D                                     LikeDS(RXS_ReturnedErrorInfoDS_t) Inz
 
D   DataStructureType...
D                                5I 0 Inz(RXS_DS_TYPE_CONVERTXMLENTITIES)

Internal use only

D   OnErrorMessageType...
D                                5I 0
 
D   EncodeDecode                  N

Set to RXS_ENCODE or RXS_DECODE.

Valid Values:

  • RXS_ENCODE
  • RXS_DECODE

Default Value: RXS_DECODE

D   InputPointer...
D                                 *

Internal use only

D   InputLength                 10I 0

Internal use only

D   OutputPointer...
D                                 *

Internal use only

D   OutputLength                10I 0

Internal use only

D   Reserved                  2049A

Internal use only