ILE RPG UUID functions
A UUID is a unique identifier which has an extremely low collision rate. This article explains some real-world uses for UUIDs. Here is the Wikipedia entry.
The first procedure simply retrieves the UUID itself. A UUID is nothing more than 16 hex bytes. Many applications, however, expect to see the “human representation” of the bytes in a standard format. A wrapper procedure will convert the UUID from hex to readable format.
The only downside to the i5/OS UUID (as of V5R4, I do not have access to a 6.1 machine to test) is it is a DCE version 1 UUID. The latest version as of this writing is version 5 with SHA-1 hashing.
Getuuid() procedure
d getUUID pr 16a
p getUUID b
d getUUID pi 16a
// Implements DCE version 1 UUID
// Source link:
// http://publib.boulder.ibm.com/iseries/v5r1/ic2924/tstudio/tech_ref/mi/GENUUID.htm
// Template structure required for _GENUUID.
d UUID_template ds
d UUID_bytes_provided...
d 10u 0 inz(%size(uuid_template))
d UUID_bytes_available...
d 10u 0
d UUID_reserved 8a inz(*allx'00')
d UUID_UUID 16a
d GenUUID pr extproc('_GENUUID')
d UUID_Template * value
/free
reset uuid_template;
GenUUID(%addr(UUID_Template));
return UUID_UUID;
/end-free
p getUUID e
As mentioned above, many times it is more useful to get the UUID in a human readable format. With that in mind, here is a getUUIDString() procedure. It takes an optional parameter, a hex UUID (perhaps previous retrieved from getUUID). If a UUID is not passed, one will be retrieved automatically. The procedure also converts the text representation to lower case.
getUUIDString() procedure & helpers
d getUUIDString pr 36a
d inUUID 16a options(*nopass)
p getUUIDString b
d getUUIDString pi 36a
d inUUID 16a options(*nopass)
d workuuid s inz like(inuuid)
d uuid_string s 36a inz
// Convert hex to character API.
d cvthc pr extproc('cvthc')
d Result 65534a options(*varsize)
d Source 32767a options(*varsize)
d ResultSize 10i 0 value
// NLS convert case.
d convertcase pr extproc('QlgConvertCase')
d ctrlBlock const like(FRCB)
d inString 65535a const options(*varsize)
d outString 65535a options(*varsize)
d inLength 10i 0 const
d apiErrorDS 300a options(*varsize)
// Formatted request control block required by QlgConvertCase.
d FRCB ds qualified
d ReqType 10i 0 inz(1)
d CCSID 10i 0 inz(0)
d CvtTo 10i 0 inz(0)
d Reserved 10a inz(*allx'00')
// Helper constants for FRCB.
// Uses request 1 (CCSID format): assumes lower case, job CCSID.
// For more information about the control block, see:
// http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/apis/QLGCNVCS.htm
d CvtToUpper c 0
d CvtToLower c 1
// Error code structure.
d errc0100 ds
d errc01bytpro 10i 0 inz(%size(errc0100))
d errc01bytava 10i 0 inz
d errc01excid 7a inz
d errc01resaaa 1a inz(x'00')
d errc01excdta 250a inz
/free
if %parms() = 1;
workuuid = inuuid;
else;
workuuid = getuuid();
endif;
cvthc( uuid_string : workuuid : %len(workuuid)*2 );
frcb.cvtto = cvttolower;
reset errc0100;
convertcase( frcb : uuid_string : uuid_string :
%len(uuid_string) : errc0100 );
uuid_string = %subst(uuid_string:1:8) + '-' +
%subst(uuid_string:9:4) + '-' +
%subst(uuid_string:13:4) + '-' +
%subst(uuid_string:17:4) + '-' +
%subst(uuid_string:21:12);
return uuid_string;
/end-free
p getUUIDString e
A few things going on in getUUIDString. It uses IBM QlgConvertCase API to convert the text to lower case (it can also do upper case), no %xlate() functions here. This is the “correct” way to convert case to respect CCSID. Also uses the cvthc API to convert the hex values to text representation. Personally I have not needed the function in normal programming, but it is also used to generate a human readable MD5 hash. Converting hex to character just doesn’t come up often in business programming. Lastly, it shows proper use of the error code parameter. All too often, developers leave the “bytes provided” parameter uninitialized. This translates to x’404040′ or a very large number. Just as often, it will be set to zero, which prevents the error structure from being populated.
Code sample usage
// Copy in the procedures above.
// Generate UUID and alpha representation
h option(*srcstmt : *nodebugio) dftactgrp(*no) bnddir('QC2LE')
d getUUID pr 16a
d getUUIDString pr 36a
d inUUID 16a options(*nopass)
d myuuid s 16a inz
d myuuidstring s 36a inz
/free
myuuidstring = getuuidstring();
myuuid = getuuid();
myuuidstring = getuuidstring(myuuid);
*inlr = *on;
return;
/end-free