Sirius Software, Inc.
Contents
 

 

Sirius Home
 
Sirius Product News
April, 2010

Recent product releases:

Sirius Mods Version 7.7 March, 2010
SirAud Version 1.05 December, 2009
Sirius Mods Version 7.6 November, 2009
Sirius Mods Version 7.5 April, 2009
Sirius Mods Version 7.4 February, 2009
Sirius Mods Version 7.3 October, 2008
Sirius Mods Version 7.2 February 2008
Fast/Unload Version 4.4 September, 2007
Older product releases

Sirius Mods Version 7.7

Version 7.7 of the Sirius Mods was released in March, 2010. Please refer to the Notes for Sirius Mods Version 7.7 for more detailed information.

Supported Model 204 Versions

Sirius Mods version 7.7 supports Model 204 versions V6R1, V6R3, V7R1, and V7R2.

All or Multiple Products

Documentation

In addition to the incorporation of new features for Sirius Mods version 7.7, the Janus Network Security Reference Manual has been reorganized and edited to improve its readability and to clarify the role of client certificates.

The User Language ADDCA utility

The JANUS ADDCA command adds a “trusted” certifying authority's certificate (encrypted public key) to a Janus SSL server or client port. The User Language ADDCA utility, new in version 7.7 of the Sirius Mods, does the work of a series of ADDCA commands to let you add any number of the CA certificates that Sirius has already obtained and saved in the UL/SPF SIRIUS file.

Although a server port is not likely to need to use the JANUS ADDCA command more than once, a client port may want to use it to add multiple certificates. As a convenience especially for a CLSOCK port connecting to an SSL server, Sirius pre-loads a set of standard certifying authorities' certificates to the SIRIUS procedure file (as of UL/SPF 7.3).

Janus Sockets SSL client ports must add the certificate(s) of the CA that signed the certificate of the SSL server or servers to which the client will connect. (Janus does not allow a port to specify exceptions, that is, signed certificates that a port accepts without having the signing CA's certificate.)

The SIRIUS file certificates can be loaded to a port by the JANUS ADDCA command or by the ADDCA utility. Adding this set of certificates equips the client port in much the same way that internet browsers are equipped with multiple CA certificates.

The certificates are procedures whose names have the prefix “CA_” so they are easy to scan using a DISPLAY PROCEDURE command or by browsing the procedures in SirPro. Sirius will periodically review the certificates loaded to SIRIUS, eliminate any that have expired, and load new ones when they are made available by various well-accepted CAs.

The User Language ADDCA utility lets you add some or all of these certificates at once to an SSL port. The utility is invoked at the command level via INCLUDE:

IN SIRIUS INCLUDE ADDCA portname certificate User Language ADDCA utility syntax

Where each parameter is positional and required:

portname
The defined JANUS SSL port to which the certificate is to be added. The name can include wildcards.

Non-SSL ports may not have trusted CA certificates added to them.

certificate
The name of the procedure that contains the base64 encoded CA certificate.

This parameter may contain wildcards. To load all certificates in the SIRIUS file whose names begin with “CA_AOL”, you can use: CA_AOL*

This ADDCA utility invocation loads (at least) the CA_ThawtePremiumServerCA certificates, for example:

IN FILE SIRIUS INCLUDE ADDCA WEBBY CA_T*

The utility internally runs a series of ADDCA commands like the following to load to WEBBY each certificate in file SIRIUS that matches the specified pattern:

JANUS ADDCA WEBBY SIRIUS CA_ThawtePremiumServerCA
JANUS ADDCA WEBBY SIRIUS CA_ThawteServerCA
JANUS ADDCA WEBBY SIRIUS CA_ThawteTimestampingCA
JANUS ADDCA WEBBY SIRIUS CA_ThawteSGCCA

Note: The CA certificates are stored as procedures with mixed-case names, which makes them much easier to scan visually, but a little more difficult to manipulate.

For instance, if the above INCLUDE command is used, all the intended certificates are loaded, because the “CA_T” in uppercase matches the case of the corresponding characters in the certificate names. But if you want a more precise search and the name to be matched by the pattern includes mixed-case characters, the INCLUDE command must be performed with lower case enabled.

SSL certificate renegotiation

As of Sirius Mods version 7.7, after the initial “handshake” between a Janus SSL server and a client to establish their secure connection, the server will start an SSL renegotiation (that is, a new handshake) that requests a digital certificate from the client if the following are both true:

  • The server program requests information from a client certificate (via $web_cert_levels, $web_cert_info, the Socket class's CertInfo and CertLevels methods, or the XmlDoc class ClientCertificate method).
  • The server port definition does not specify a SSLCLCERT or SSLCLCERTR parameter (so it does not cause a client certificate to be requested in the initial handshake).

This new ability to renegotiate allows a port to require a client certificate for some content, but not for other content.

In this renegotiation, the server requests a certificate, but does not insist that the client present one. It is the responsibility of the server application to take appropriate action if no client certificate is presented. Specifying that action depends on how the $function or method that causes the renegotiation indicates that no certificate is returned.

Note: A client certificate will only ever be requested once for an SSL session. If the initial server-client handshake requested a certificate because the port definition included SSLCLCERT or SSLCLCERTR, a subsequent $web_cert_info (for example) will not request a certificate again.

Similarly, if a $web_cert_levels call (for example) caused a renegotiation by requesting a client certificate, a subsequent $web_cert_info will not cause another request for a client certificate, whether or not a client certificate was returned for the initial renegotiation. This is because:

  • There is no reason a client would not return a certificate on an initial renegotiation, but return a certificate on a later renegotiation.
  • There is no reason a client would return a certificate on an intial renegotiation, then return a different client certificate on a subsequent SSL renegotiation.

Fast/Reload

The following are new or changed features in Fast/Reload:

  • NEWfgid option on LAI statement

    The NEWfgid option on the LAI statement means that fieldgroup IDs from the TAPEI input file are not copied to fieldgroups created in the target file, but rather that fieldgroup IDs are recreated such that within each target record the ID numbers begin with 1 and are incremented by 1 for each subsequent fieldgroup.

    Fieldgroups are a new feature as of Model 204 V7R2.

Janus SOAP ULI

New Unicode intrinsic methods: UnicodeToUpper and UnicodeToLower

The UnicodeToUpper and UnicodeToLower functions return the Unicode alphabetic characters in the method object string as all-uppercase or all-lowercase characters, respectively. Non-alphabetic characters are returned as is, and the input string undergoes no other change.

Character references are returned for characters that do not translate to an EBCDIC character. The default substitute for non-displayable characters in your environment, say a question mark (?), is returned for characters that translate to an EBCDIC character that is not displayable.

These methods produce a one-character for one-character translation, which will fail to correctly handle unusual characters whose uppercase versions have two-characters, for example.

%outUni = unicode:UnicodeToUpper %outUni = unicode:UnicodeToLower UnicodeToUpper and UnicodeToLower syntax

New StringTokenizer method: SkipTokens

This method moves the current token and tokenizing position forward in the tokenizer string the number of tokens specified in the method argument. Skipping one token is equivalent to executing the NextToken method; skipping three tokens is equivalent to executing NextToken three times consecutively.

If a token is found after advancing the designated number of tokens, the tokenizing position in the string is moved after the found token, and the CurrentToken method will return the found token. If the end of the tokenizer string occurs before the specified number of tokens, the request is cancelled.

%tok:SkipTokens(num) SkipTokens syntax

The value of num must be greater than 0 and less than the number of tokens remaining in the tokenizer string.

For a new StringTokenizer instance, issuing NextToken, SkipTokens, or FindToken is required before CurrentToken may be issued without error.

New parameter (Skip) for StringTokenizer NextToken method

The NextToken Skip parameter specifies the number of tokens to skip before returning the next token. This optional, name required parameter gives the NextToken method the flexibility to advance more than a single token at a time.

The new syntax of NextToken is:

%string = %tok:NextToken([Skip=num])

The value of num must be greater than 0, and it must be be less than the number of tokens remaining in the tokenizer string.

New arguments for Record class ToXmlDoc method

The ToXmlDoc method in the Record class has the following new arguments:

CodepageTable=False|True
This Boolean argument, which defaults to False, specifies whether to use the base codepage translation table when creating the XmlDoc.
AllowNull=False|True
This Boolean argument, which defaults to False, is copied to the AllowNull property of the XmlDoc created by ToXmlDoc. The XmlDoc's AllowNull property, in turn, determines whether field values which contain the X'00' character are stored in the XmlDoc with base64 encoding - they are base64 encoded if AllowNull = False.

Janus SOAP Xml API

AddTopElement method

%newElementNode = %xmlDoc:AddTopElement(elementName, [URI])

This method adds a new Element node as the new top-level element of the XmlDoc that is the object method, making all of the former children of the XmlDoc Root node into children of the new element.

The elementName argument, a Unicode string, is the name to be given to the new element; it is required.

The URI argument is optional and defaults to the null string.

  • If elementName contains a prefix, then URI specifies the URI associated with that prefix for the element, so it must be a non-null string which is a valid URI.
  • If elementName does not contain a prefix, then URI must be omitted or must be the null string. This rule means that this URI argument is more restrictive than the URI argument of the AddElement method.

When you need to change the structure of an XML document and that need can be accomplished with AddTopElement, it is a more efficient approach than using AddSubtree. For example, if you wanted to make a copy of an XML document adding “SOAP wrappers” to it, you could use the following:

%doc2 = %doc:DeepCopy %doc2:AddTopElement('soap:Body', - 'http://schemas.xmlsoap.org/soap/envelope/') %doc2:AddTopElement('soap:Envelope', - 'http://schemas.xmlsoap.org/soap/envelope/')

Notes:

  • The order of the AddTopElement invocations is the reverse of the final order of the elements, that is, the second invocation creates the first element in the final document.
  • If you have no need to preserve the original XmlDoc, then in the above example, both AddTopElement invocations can use %doc as the object method, and the DeepCopy can be omitted.
  • In the above example, there will be a redundant namespace declaration on the soap:Body element; this is unavoidable.

ReplaceUnicode deserialization option

The ReplaceUnicode option for deserialization methods (for example, LoadXml) specifies that Unicode characters are to be converted using the replacements specified for your site by UNICODE updating commands that use the Rep subcommand (for example, UNICODE Table Standard Rep U=2122 '(TM)').

The replacement is performed on all names, element and attribute values, comments, and PI “values” in the document, after any entity and character references have been converted to characters.

For example, assume the following command is in CCAIN:

UNICODE Table Standard Rep U=2122 '(tm)'

Given the above command, the following fragment:

%u Unicode Initial('<a>') %u = %u:UnicodeWith('2122':X:Utf16ToUnicode) %u = %u:UnicodeWith('</a>':U) %d:LoadXml(%u, 'ReplaceUnicode') %d:Print

results in:

<a>(tm)</a>

In the preceeding example, the stream of input characters to LoadXml contains the Unicode character U+2122. Since the ReplaceUnicode option applies to both the stream of input characters and to the character value of character references, the following fragment (assuming the same CCAIN line as above):

%d:LoadXml('<a>&amp;#x2122;</a>' 'ReplaceUnicode')

also results in:

<a>(tm)</a>

In this case, U+2122 does not occur in the input character stream, but it is the value of the character reference.

AddNamespace allowed on top level element with children

The AddNamespace method is now allowed to add namespace declarations to the top level element, even if the top level element already has element children.

Length limit of XML names changed to 127

The length limit of XML names has been changed from 100 to 127. For example, the prefix part must be shorter than 128 characters, and the local name part must be shorter than 128 characters, for the “name” argument of the AddElement method.

Also, the Janus SOAP Reference Manual “XML syntax” section has been corrected. It previously stated that the maximum length of an XML name is 650 characters, which was not correct.

NewFromRecord, LoadFromRecord, and AddToRecord methods

The NewFromRecord and LoadFromRecord methods have been implemented, which perform the same operation (copying the contents of a record to an XmlDoc) as does the Record class' ToXmlDoc method.

The AddToRecord method has been implemented, which copies the fields and fieldgroups contained in an XmlDoc (such as that created by LoadFromRecord, NewFromRecord, or ToXmlDoc), storing into in the current record. In the version 7.7 Sirius Mods, this method requires version V7R2 of Model 204.

Return to top of page

SirAud Version 1.05

SirAud Version 1.05 was released in December, 2009.

Supported Model 204 Versions

SirAud Version 1.05 supports Model 204 versions V6R1, V6R3, V7R1, and V7R2.

Return to top of page

Sirius Mods Version 7.6

Version 7.6 of the Sirius Mods was released in November, 2009. Please refer to the Notes for Sirius Mods Version 7.6 for more detailed information.

New SirMon statistics

These statistics are added for version 7.6. They are retrievable or viewable with $SYSTAT or SirMon:

JSCREENS
Counts the number of times Janus Web Server incremented the SCREENS statistic. Since these increments may occur outside of request context, they will not necessarily have corresponding Since-Last statistics. Janus Web Server will only increment SCREENS for connections that were closed with Status Code 200 (OK).
JWEBERRS
Counts the number of times that Janus Web Server returned a 4xx status code. Note that these instances will not be counted in the SCREENS statistic, but it is useful to know that, for example, many 404 or 401 errors are occurring.
SFTRSTRT
Counts the number of times a soft user restart has occurred.
HRDRSTRT
Counts the number of times a hard user restart has occurred.

Janus SOAP ULI

XHTML entities for converting to Unicode

In addition to using hexadecimal character references, you can now use XHTML entities to represent Unicode characters when converting from EBCDIC to Unicode. Just like character references, XHTML entities are converted by the U constant method, or by the CharacterDecode=True argument on the EbcdicToUnicode and EbcdicToAscii methods.

For example, the following declaration initializes a Unicode %variable to the “non-breaking-space” character:

%nbsp Is Unicode Initial('&nbsp;':U)

You can find the list of XHTML entities on the Internet at the following URL: http://www.w3.org/TR/xhtml1/dtds.html#h-A2

Except for the five predefined entities (ampersand, apostrophe, greater than, less than, and double quotation mark), the XHTML entities are still not acceptable to the Janus SOAP XML document deserializing methods.

Print/Audit/Trace statements character-encode Unicode values

The Print, Audit, and Trace statements have been changed so that when displaying Unicode data, any Unicode character not translatable to EBCDIC is displayed using the character encoding (“&#xhhhh;”) of the character, and any ampersand character is displayed using the string “&amp;”. For example, the following fragment using the new UnicodeWith method:

%u Unicode %u = 'Trademark (&trade;)':U:UnicodeWith(' & ') %u = %u:UnicodeWith('Euro (&euro;)':U) Print %u

Results in:

Trademark (&#x2122;) &amp; Euro (&#x20AC;)

Note: in the case of ampersand, this represents an upwards incompatibility.

Extended Codepages on UNICODE command

There are three new codepages that can be used in the UNICODE command:

1047EXT
Same as 1047, except that there are mappings between EBCDIC and Unicode for the 27 "extended" characters in the Microsoft 1252 enhanced version of ISO-8859-1.
0037EXT
Same as 0037, except that there are mappings between EBCDIC and Unicode for the 27 "extended" characters in the Microsoft 1252 enhanced version of ISO-8859-1.
0285EXT
Same as 0285, except that there are mappings between EBCDIC and Unicode for the 27 "extended" characters in the Microsoft 1252 enhanced version of ISO-8859-1.

To see the extended characters mapped by these codepages, issue, for example, the following command:

UNICODE Difference Codepages 0037 And 0037EXT

In addition to providing the extended mappings between Unicode and EBCDIC, using any of 1047EXT, 0037EXT, or 00285EXT as the base codepage affects translations involving “ASCII”, as described in the following section.

ASCII translations with xxxEXT codepages

With “non-xxxEXT” codepages, Unicode characters correspond to “ASCII” characters with the same numeric value of the codepoint, for example, Unicode U+86 (the “Start Of Selected Area” control character) corresponds to the same ASCII control character at codepoint X'86'.

The Microsoft 1252 encodings redefine the mappings between “ASCII” and Unicode for the extended characters, as follows:

ASCIIUnicodeDescription
X'80'U+20ACEuro
X'82'U+201ASingle comma quotation mark
X'83'U+0192Small letter script f
X'84'U+201EDouble comma quotation mark
X'85'U+2026Horizontal ellipsis
X'86'U+2020Dagger
X'87'U+2021Double dagger
X'88'U+02C6Modifier letter circumflex
X'89'U+2030Per mille sign
X'8A'U+0160Capital letter S with caron
X'8B'U+2039Single left-pointing angle quote
X'8C'U+0152Capital ligature OE
X'8E'U+017DCapital letter Z with caron
X'91'U+2018Left single quotation mark
X'92'U+2019Right single quotation mark
X'93'U+201CLeft double quotation mark
X'94'U+201DRight double quotation mark
X'95'U+2022Bullet
X'96'U+2013En dash
X'97'U+2014Em dash
X'98'U+02DCSmall tilde
X'99'U+2122Trademark sign
X'9A'U+0161Small letter s with caron
X'9B'U+203ASingle right-pointing angle quote
X'9C'U+0153Small ligature oe
X'9E'U+017ESmall letter z with caron
X'9F'U+0178Capital letter Y with diaeresis

To keep the implicit translations between Unicode and “ASCII” invertible when any of 1047EXT, 0037EXT, or 00285EXT is the base codepage, the Unicode character with the same numerical value as any of the above ASCII codepoints is not translatable to ASCII. For example, U+9F would not be translatable to ASCII.

Using any of 1047EXT, 0037EXT, or 00285EXT as the base codepage affects translations involving “ASCII”, please refer to the Notes for Sirius Mods Version 7.6 for more detailed information.

Migrating to codepage 1047EXT, 0037EXT, or 00285EXT

If you find that some of your XML document processing is unsuccessful because it contains some of the Unicode characters shown above as part of the Windows 1252 encodings, you may benefit by switching your base codepage, for example, from 0037 to 0037EXT. The principal effect of switching will be to allow the set of 27 Unicode characters, 26 of which were previously untranslatable to EBCDIC. Because one of these mappings (U+85) was translatable to EBCDIC (X'15'), you may see the following subtle differences using these codepages, compared to using their “non-EXT” counterparts (without any further modifications using the UNICODE command):

  • The EbcdicToAscii function, when an input character is X'15', results in an untranslatable character exception, rather then producing the X'85' ASCII Next Line control character. (Note that the mapping between EBCDIC X'15' and U+0085 is unchanged.)
  • The AsciiToEbcdic function, when an input character is X'85', results in the X'21' EBCDIC character, rather than the X'15' character.
  • If you are deserializing an ASCII XML document with the encoding="ISO-8859-1" declaration, and that document contains the ASCII X'85' character, then the X'85' is treated as the horizontal ellipsis character, rather than the “next line” control character.

Unicode enhancement methods

Enhancement methods for Unicode type string objects are now allowed. Although the User Language Unicode type was introduced in Sirius Mods version 7.3, enhancement methods for Unicode objects have not been allowed until this release.

For example, prior to Sirius Mods version 7.6, a local function like the following was invalid:

local function (unicode):foobar is float ... end function

Similarly, a function like the following inside a class was invalid:

class util public function (unicode):foobar is float ... end class

This restriction is now removed, and you can define an enhancement method like the following:

begin local function (unicode):unicodeReverse is unicode %result is unicode %i is float for %i from %this:unicodeLength to 1 by -1 %result = - %result:unicodeWith(%this:unicodeChar(%i)) end for return %result end function %u is unicode %u = 'Bye-bye, Miss American &pi;':u printText {~} = "{%u}", {~} = "{%u:unicodeReverse}" end

This request produces the following result:

%u = "Bye-bye, Miss American &#x03C0;" %u:unicodeReverse = "&#x03C0; naciremA ssiM ,eyb-eyB"

Changes to Auto New and Allow Auto

If you append Auto New to an object variable declaration for a user-defined class object, you are not required to later provide a statement that explicitly instantiates the object. Specifying Auto New is valid only if the class definition includes Allow Auto.

As of version 7.6 of the Sirius Mods, the Auto New functionality is allowed for extension classes — as long as all the base classes are defined as Allow Auto.

In addition, a related enhancement is added to Allow Auto. Prior to this release, a class defined with Allow Auto was not allowed to contain a constructor. As of version 7.6 of the Sirius Mods, Allow Auto is allowed in a class that has a constructor. However, for an object variable declared with Auto New in such a class, an automatic instantiation of the object will not call any of the constructors in the class, even if the class has defined an explicit constructor with the name New.

Method-variable assignment restriction is dropped

As of Sirius Mods version 7.6, you may assign an overridable method to a method variable. Prior to this version, such an assignment was not allowed.

Intrinsic classes

New Float method: FloatToString

This function converts a floating point number to a string with a specific length and number of decimal places.

%str = number:FloatToString([Length=len,] [Dp=num])
New Float method: Round

This function returns a floating point number that is the method object number rounded to a specified number of decimal places.

%num = number:Round(dp)

Negative numbers are rounded down to the nearest integer; positive numbers are rounded up.

New String method: Insert

This function inserts an argument string inside the method object string, starting before the specified position in the method object string.

%outStr = string:Insert(%insrtString, %before)

The value of %before must be between 1 and the number of characters in the method object string plus one. An invalid position produces a request cancellation.

New Unicode method: UnicodeWith

This function returns the Unicode string that is the concatenation of the method object Unicode string and its Unicode string argument.

%outUni = unicode:UnicodeWith(unistring)

For example, the following is a simple UnicodeWith call:

Begin %u is unicode Initial('This is an at sign: ') Print %u:unicodeWith('&#x40;':U) End

The result is:

This is an at sign: @

Collection classes

New system class: UnicodeNamedArrayList

The UnicodeNamedArrayList class is nearly identical to the NamedArraylist class. The main difference is that instead of EBCDIC subscript names for items as in the NamedArraylist class, the name subscripts in a UnicodeNamedArrayList object are Unicode values. UnicodeNamedArrayList items are stored by item name in Unicode order, whereas NamedArraylist items are stored by item name in EBCDIC order.

Note: The names of UnicodeNamedArraylists are limited to 127 characters (versus 255 bytes for NamedArrayLists).

Audit subroutine

This subroutine displays the contents of a UnicodeNamedArrayList in a readable form, useful for debugging, for example. Audit is identical to the Print method, except the result is sent to the Model 204 audit trail (like the User Language Audit statement).

[%rc =] %unamrayl:Audit([method,] -. [NumWidth=itemnumlen], - [Separator=separator], - [NameWidth=itemnamelen], - [Start=firstitem], - [MaxItems=maxitems]), - [Label=label] )
Copy function

This function makes a “shallow” copy of the UnicodeNamedArrayList method object %unamrayl. If %unamrayl contains objects, they are not copied. If %unamrayl is Null, a Null is returned.

%cop = %unamrayl:Copy
Count property

This ReadOnly property returns the number of items in the UnicodeNamedArrayList method object.

%num = %unamrayl:Count
DeepCopy function

This function makes a “deep copy” of the UnicodeNamedArrayList method object, %unamrayl. If %unamrayl contains objects, they are copied. If %unamrayl is Null, a Null is returned.

%dcop = %unamrayl:DeepCopy
Default property

This ReadWrite property indicates the value to be returned if a requested item name is not in the UnicodeNamedArrayList and the UseDefault property is set to True.

%val = %unamrayl:Default %unamrayl:Default = %val
Item property

This ReadWrite property returns or sets the value of the item that has the specified subscript name in the UnicodeNamedArrayList.

%item = %unamrayl:Item(name) %unamrayl:Item(name) = %item
ItemByNumber property

This ReadWrite property returns or sets the UnicodeNamedArrayList item that has the specified item number. Item number is ordinal, so ItemByNumber(3), for example, identifies the third item in the ordered-by-name UnicodeNamedArrayList.

%item = %unamrayl:ItemByNumber(number) %unamrayl:ItemByNumber(number) = %item
Maximum function

This function returns the subscript name of the UnicodeNamedArrayList item that has the maximum value after the application of a specified function to each item. The function that gets applied to each UnicodeNamedArrayList item, which you identify in the argument to Maximum, must be a method that operates on the item type and returns a User Language intrinsic datatype (Float, String, Longstring, or Unicode) value.

name = %unamrayl:Maximum(function)
Minimum function

This function returns the name (subscript) of the UnicodeNamedArrayList item that has the minimum value after the application of a specified function to each item. The function that gets applied to each UnicodeNamedArrayList item, which you identify in the argument to Minimum, must be a method that operates on the item type and returns a User Language intrinsic datatype (Float, String, Longstring, or Unicode) value.

name = %unamrayl:Minimum(function)
NameByNumber property

This ReadOnly property returns the subscript name of the item that has the specified item number (position) in the UnicodeNamedArrayList.

name = %unamrayl:NameByNumber(number)
New constructor

This method returns a new instance of a UnicodeNamedArrayList

%unamrayl = New
Number property

This ReadOnly property returns the item number (ordinal) of the item that has the specified subscript name in the UnicodeNamedArrayList.

%num = %unamrayl:Number(name)
Print subroutine

This method displays the contents of a UnicodeNamedArrayList on the user's standard output device, typically a terminal. The list item values, displayed in order by their subscript names, are preceded by their item number and item name, both of which by default are followed by a colon (:) and a blank.

[%rc =] %unamrayl:Print([method,] - [NumWidth=itemnumlen], - [Separator=separator], - [NameWidth=itemnamelen], - [Start=firstitem], - [MaxItems=maxitems]), - [Label=label] )
RemoveItem function

This callable function removes from the UnicodeNamedArrayList the item that has the specified subscript name.

[%num =] %unamrayl:RemoveItem(name)
Trace subroutine

This subroutine displays the contents of a UnicodeNamedArrayList in a readable form, useful for debugging, for example. Trace is identical to the Print method, except the result is sent to the selected Trace stream (like the User Language Trace statement).

[%rc =] %unamrayl:Trace([method,] - [NumWidth=itemnumlen], - [Separator=separator], - [NameWidth=itemnamelen], - [Start=firstitem], - [MaxItems=maxitems]), - [Label=label] )
UseDefault property

This ReadWrite property indicates whether an attempted retrieval of an item that is not on the UnicodeNamedArrayList should return the Default method value.

UseDefault will return, or may be assigned, only the values True or False. Its initial value is False.

%bool = %unamrayl:UseDefault %unamrayl:UseDefault = %bool
Print method for collection classes

In versions of the Sirius Mods prior to 7.6, the standard way to view the entire contents of a collection is to loop through the list items and display each one using a User Language Print statement (or Audit or Trace). For a NamedArrayList, for example, you use a method for the item subscript name and a method for the item content:

%nal is namedArraylist of float ... %nal = new %nal('Chicago') = 22 %nal('New York') = -999 %nal('Los Angeles') = 3.1415926 %nal('Philadelphia') = 1099 for %i from 1 to %nal:count. print %nal:nameByNumber(%i) and %nal:itemByNumber(%i) end for

This is the result:

Chicago 22 Los Angeles 3.1415926 New York -999 Philadelphia 1099

As of version 7.6 of the Sirius Mods, the Print method for any collection does the work of the loop in the preceding example, and more. Supplied for debugging purposes, Print (or the essentially identical Audit or Trace method) would produce the following output using the example collection above (that is: %nal:print):

1: Chicago: 22 2: Los Angeles: 3.1415926 3: New York: -999 4: Philadelphia: 1099

Notice that Print outputs all the collection items (or, optionally, a range of items), and it also includes:

  • The ordinal, or position, number for each item
  • A separator string after the item position number and also after the item name (if a named collection)

Print also has optional parameters that let you specify:

  • The lengths for the item name and number
  • A label string to precede each output line
  • The number of items to display

The Print method applies a ToString method (by default) to each item value (and always to each item name), to produce its result. Applying Print to a collection whose item types are not system classes will work only if the user class contains a ToString method.

The general syntax of Print (Audit or Trace) for a collection is:

%coll:Print (<method>, <numWidth>, <nameWidth>, - <separator>, <start>, <maxItems>, <label>)

All parameters are optional and all except have required names (which match the names used in the syntax above). The parameters are described briefly below and in greater detail in the Janus SOAP Reference Manual.

<method>
The method applied to collection items to produce the printed output. The method must take no parameters and produce an intrinsic (Float, String, Fixed, Unicode) value. It may be a system or user-written method, a class Variable or Property, a local method, or a method variable. The default is the ToString method.
<numWidth>
The number of bytes for the item number in the output. If 0, the default, the item number is not printed.
<namewidth>
The number of bytes for the item name (ignored if an ArrayList). If -1, the default, the entire name is fit exactly. If 0, the item name is not printed.
<separator>
A string that follows the item number and that repeats after the item name. The default is a colon. A blank follows each instance of separator.
<start>
The number of the collection item from which to start the output display. By default, the display begins from item one.
<maxItems>
The maximum number of collection items to print. By default, all items are displayed.
<label>
A string, null by default, marking the beginning of each item's line of output.
Searching methods for the collection classes

As of Sirius Mods version 7.6, a variety of methods are common to all the collection classes for the purpose of searching a collection for the item(s) that satisfy one or more specified conditions.

The searching methods (all functions, listed below) have the same, or nearly the same syntax. They take two parameters:

  • An object that specifies the search conditions (a SelectionCriterion object, added in Sirius Mods 7.6).
  • A parameter (Start) that specifies where in the collection to begin the search. One method, SubsetNew, does not accept this parameter.

The searching methods are:

FindNextItem
Searching "forward" in the collection, finds the next item that matches a criterion, and returns that item.
FindPreviousItem
Searching "backward" in the collection, finds the next item that matches a criterion, and returns that item.
FindNextItemNumber
Searching "forward," finds the next item that matches a criterion, and returns that item number.
FindPreviousItemNumber
Searching "backward," finds the next item that matches a criterion, and returns that item number.
SubsetNew
Returns a new collection that contains all the items in the input collection that match the criterion.

The FindNextItem and FindPreviousItem methods also throw an ItemNotFound exception if no item matches the SelectionCriterion.

A SelectionCriterion object, which might consist of multiple components, describes a single selection criterion. For example, the GE method in that class uses two parameters to form a ("greater than or equal to") comparison criterion to apply to the collection items. So, for SelectionCriterion object %sel, which selects items whose absolute value is less than or equal to 1000, you might have:

%sel = ge(absolute, 1000)

A simple search, starting from the eighth item in the %payoff arrayList, might be:

%item = %payoff:findNextItem(%sel, start=7)

The parameters of the SelectionCriterion GE method above provide the operands for the comparison operator GE. In this case, absolute, is an intrinsic Float method which is applied to an item value. In general, this must be a function that operates on the type of the items in the collection, and it may be a local method or method variable or a class member (variable, property).

The value that results from applying the Absolute method above is compared to the second GE parameter, 1000. This 1000 may be any User Language intrinsic expression, such as a string or numeric literal.

In the fragment that follows, the function in the SelectionCriterion is a local method, and the searching method, FindPreviousItemNumber, searches backward starting with the tenth item in the collection to find the item number of the first item that satisfies the criterion:

%flt is arraylist of float %sel is object selectionCriterion for float local function (float):myMod is float return %this:mod(7) end function %sel = LT(myMod, 1) %num = %flt:findPreviousItemNumber(%sel, start=11)

The local method myMod above, which calls the Mod intrinsic Float method, is necessary in this case because the SelectionCriterion function parameter may not itself specify a parameter. The function parameter is a method value, not a User Language expression.

The preceding example also shows a SelectionCriterion object declaration, which must suit the item type to which the criterion will be applied, as described in Declaring a SelectionCriterion object variable.

In the following example, the function parameter is the very useful identity function, This, which returns the value of the item to which it is applied. The searching method SubsetNew returns a collection of all the items in the collection that satisfy either of the criteria (< 0, > 999) that comprise the OR criterion:

%sel = OR(LT(this, 0), GT(this, 999)) %arraylist = %flt:findPreviousItemNumber(%sel, start=11)

Usage notes:

  • The main benefit of these searching methods is is the ease of coding provided by their simplicity and flexibility. However, the Find and Subset operations on collections of objects will necessarily be considerably more expensive than the comparable operations on $lists or Stringlists. For example, a level of indirection between object references and objects makes the processing much more complicated than that for StringLists. However, because the cost of locates or subsets is likely to be a small fraction of the cost of most applications, switching to objects for these applications offers the benefits of cleaner code without a major expense.
  • The FindNextItem and FindPreviousItem methods throw an ItemNotFound exception if no item matches the SelectionCriterion, but the FindNextItemNumber and FindPreviousItemNumber methods do not throw an exception in that case. The following are suggested guidelines for using these methods:
    • For simply checking if an item in a collection matches a SelectionCriterion, use FindNextItemNumber or FindPreviousItemNumber.
    • For looping over a collection, use FindNextItemNumber or FindPreviousItemNumber with an If test.
    • For extracting a single item that you are very sure must be in the collection, use FindNextItem or FindPreviousItem. If you are wrong about the presence of the item, the exception is thrown and the error is caught.
    • For conditionally extracting a single item from a collection, use FindNextItem or FindPreviousItem with a Try/Catch clause.
New defaults for collection maxima, minima, and sorting

The special identity function, This, is now the default function parameter value for the collection Minimum and Maximum methods and for the SortOrder Ascending and Descending methods. In addition, for the SortOrder argument in the sorting methods, Ascending (which implies Ascending(this)) is now the default.

For example, instead of explicitly specifying This in the printText statement in this request:

b %l is arraylist of float %l = list(7, 4, -3, 11, 5) printText {~} = {%l:maximum(this)} end

You can now use:

printText {~} = {%l:maximum}

Similarly, for a sort, instead of %l:sort(descending(this), you can now simply specify:

%l:sort(descending)

Furthermore, because Ascending is now the default argument, explicitly specifying ascending(this) in the following request is now optional:

b %l is arraylist of float %l = list(7, 4, -3, 11, 5) %l:sort(ascending(this)) end

Instead, you can now simply specify:

%l:sort

File classes

Enhancements to Recordset and SortedRecordSet instantiation
Inheritance support for Recordset and SortedRecordSet objects

Sirius Mods version 7.6 supports Find To and Sort To statements whose target is an object of an extension class of either a RecordSet or a SortedRecordSet. That is, a sequence of statements like the following will now succeed:

class truckWrecks extends recordset in file trucks ... end class ... %trex is object truckWrecks ... fd to %trex ...
Targets of Find To, Sort To, Text To may execute a constructor

In Sirius Mods version 7.6, a Find To or Sort To statement that constructs a recordSet object may execute a separate constructor method for the target variable before finding records for the target. For example, a statement like the following, which creates the already-declared recordSet %trex, is now valid:

fd to %trex = new(, LoopLockStrength=exclusive) end find

In the statement above, Find To first creates a new RecordSet instance (with the specified For loop lockstrength) and assigns it to the target object variable, %trex. Then Find To populates %trex with the found records.

Note: If the Find statement in the previous example is changed to this:

fdwol to %trex = new(, LoopLockStrength=exclusive)

The locking in the %trex recordSet is ultimately governed by the Find statement, so the resulting lockstrength here is None in agreement with Find Without Locks.

Similarly, the target of a Text To statement may now execute a constructor before populating the target list. For example, the following is is now valid:

%mylist is object stringlist text to %mylist = new ... end text

Previously, you would have to issue one more statement:

%mylist is object stringlist %mylist = new text to %mylist ... end text
Targets of Find To, Sort To, Text To may be a class variable or property

The Find To, Sort To, and Text To statements in Sirius Mods 7.6 all allow their target to be a class variable or even a class property. Before this version, none of these were allowed, except Text To allowed the target to be a class variable.

Note: The property support allows the target of a Find To to be a collection member. For example, the following fragment outlines a statement sequence that would validly instantiate the RecordSet object that is the item named for %value in the %wrek NamedArrayList:

%wrek is namedArraylist of object recordset in file foobar ... fd to %wrek(%value) foo = %value ... end find
New constructor for SortedRecordset and RecordsetCursor objects

Prior to this release, the SortedRecordset and RecordsetCursor classes had no constructor methods. Such objects could only be created with factory methods or their equivalents. Sirius Mods version 7.6 introduces simple New constructors for both classes:

  • A SortedRecordSet New constructor has no parameters and simply instantiates an empty instance of its class. For example: %srs is object sortedRecordset in sordid ... %srs = new

    Although such a new instance is not of significant value, the New constructor is useful to enable the creation of an extension class of the SortedRecordSet class, which the existing SortedRecordSet constructor factory methods cannot do. See, for example, this use of New in a Construct statement in an extension class:

    class sordidSet extends sortedRecordset in sordid inherit ... constructor new construct %(sortedRecordset in sordid):new ... end constructor ... end class
  • Since a RecordsetCursor references a Recordset or SortedRecordSet object and may have a LoopLockStrength, the RecordSetCursor New constructor is of this form: %(recordSetCursor):New(<recset> [,loopLockStrength=<lls>])

    Where:

    A required RecordSet or SortedRecordSet object.
    A LockStrength enumeration setting the minimum lock strength for a record in a For Record At loop on a RecordSetCursor object.

    Note: It is an error to specify this argument if is a SortedRecordSet object.

    If is empty, the RecordSetCursor New constructor returns a RecordSetCursor object with the state Empty, which is also new in Sirius Mods version 7.6.

    Note: This is different from the RecordSet and SortedRecordSet Cursor methods, which construct a RecordSetCursor object. Those Cursor methods still return a null if is empty.

    As is the case for the SortedRecordSet New constructor described earlier, the RecordSetCursor New constructor enables the creation of an extension class of the RecordSetCursor class, which the existing RecordSetCursor-object factory constructor cannot do.

New cursor state: Empty.

A RecordSetCursor cursor is in any of multiple positions, or cursor states, as it navigates a record set. Sirius Mods version 7.6 adds the Empty state to the set of possible cursor states. A cursor is in the Empty cursor state if it points to an empty record set.

The availability of the Empty state allows the New constructor to avoid returning a null if it is applied to a record set that has no records. And this becomes important if you are constructing an extension of the RecordSetCursor or SortedRecordSet class.

Exception classes

New exception class: ItemNotFound

An ItemNotFound exception indicates that a collection object search located no collection items that satisfy the selection criterion specified in the collection method that invoked the search. There are several searching methods, but only those that return a single found item produce an ItemNotFound exception.

This exception class has no properties. It is simply a notification that a valid search found no items that met the selection criterion.

The class's only method is the New constructor, which you would typically use with a User Language Throw statement to produce an ItemNotFound exception:

throw %(itemNotFound):new

When working with the collection searching methods, remember that an exception is thrown only if there is a catcher for the exception. For example, if you expect one or no matches from your search, you might specify a block like the following:

try %terminationInfo = - %terminationList:findNextItem (eq(custId, %custid) ... process the termination info catch itemNotFound end try

On the other hand, if you always expect a match, you might want a program crash to result if you are wrong about the match, so you could leave out a Try/Catch.

The Try/Catch approach is slightly more efficient than a test for a zero result. Try generates no quads other than the branch around the catch block if the search succeeds. And in fact, you could put a Try around a loop and use the ItemNotFound exception to exit the loop:

%i = 0 try repeat forever %i = %colla:findNextItemNumber(<criterion>), start=%i) %obj = %colla(%i) ... process the object end repeat catch itemNotFound end try
New constructor

This callable constructor generates an instance of an ItemNotFound exception. The New method format follows:

[%itemnf =] [%(ItemNotFound):]New ItemNotFound constructor syntax
New exception class: RecordLockingConflict

The RecordLockingConflict exception class catches record locking conflict errors thrown by file object operations, that is from methods in the file classes (Record, RecordSet, SortedRecordSet, RecordSetCursor). An exception is thrown only if there is a Catcher for the exception.

There is no distinction between a Find conflict and a record locking conflict. For example, you can use the following:

try fd to %foo ... end find catch recordLockingConflict ... end try

And you can also use:

try %rec = new(%recnum, exclusive) for record %rec ... end for catch recordLockingConflict ... end try

You can even catch record locking conflicts caused by LoopLockStrength promotions during a loop:

%rec = new(%recnum, none, loopLockStrength=share) ... try for record %rec ... end for catch recordLockingConflict ... end try

The members of the RecordLockingConflict class are described below. Except for the constructor, New, all class members are read-only properties:

UserNumber
The numeric value of the user number (unique per session) of the user that has the conflict.
UserID
A longstring that is the Model 204 userid (login name) of the user that has the conflict.
Filename
A longstring that is the name of the file in which the last record locking conflict occurred.
RecordNumber
The numeric value of the Model 204 internal record number of the record that has the conflict.
New
The constructor for the class, New lets you set values for each member of the class. Its optional named parameters are the properties of the class: %rlc = New ([UserNumber = %userNumber,] - [UserID = %userid,] - [Filename = %filename,] ) - [RecordNumber = %recordNumber])

The default values of the parameters are the null string or 0, as appropriate.

New exception class: XmlParseError

The XmlParseError exception class catches parsing errors (including syntax, translation, and encoding errors) thrown by the deserialization methods: LoadXml, WebReceive, and the ParseXml. method of the HttpResponse class.

The members of the class are described below. Except for the constructor, New, all class members are read-only properties:

Reason
An enumeration of type XmlParseErrorReason. The possible values are:
 
  • SyntaxError

    A violation of the syntax of an XML document.

  • InvalidUTF8Encoding

    The input UTF8 stream is invalid.

  • InvalidUTF16Encoding

    The input UTF16 stream is invalid.

  • UntranslatableUnicode

    The Unicode input contains a character that is not translatable to EBCDIC. This exception can be avoided using the AllowUntranslatable option of the deserialization method.

  • UntranslatableEBCDIC

    The EBCDIC input contains a character that is not translatable to Unicode.

  • UntranslatableISOn

    The ISO-8859-n input contains a character that is not translatable to Unicode.

  • InvalidUnicodeCharacter

    The Unicode input contains an invalid character.

CharacterPosition
The position within the input character stream at or before which the error was detected.
Description
A message that explains the error.
InputHexValue
A hexadecimal string that shows the incorrect input for all reasons except SyntaxError.
New
The constructor for the class, New lets you set values for each member of the class. %ex = New ( Reason = reasonEnum, - [CharacterPosition = num,] - [Description = string,] ) - [InputHexValue = string] )

The Reason argument is required; all other arguments are optional, with default values of the null string or 0 as appropriate.

New utility class: SelectionCriterion

Objects in the SelectionCriterion class are used primarily as input to the collection class searching methods. The searching methods take a SelectionCriterion object as a parameter which provides an item selection specification for the search.

The following description is an introduction to the SelectionCriterion class and its methods. For more detailed information, please refer to the Notes for Sirius Mods Version 7.6 and the Janus SOAP Reference Manual.

A selection specification, or criterion, is a relational expression (or more than one) that tests whether a collection item is to be included in the result set. The SelectionCriterion methods are named for the operation they provide: EQ (equal to), NE (not equal to), LT (less than), LE (less than or equal to), GT (greater than), GE (greater than or equal to). The AND, OR, and NOT methods let you combine comparison operations in a single criterion. The TRUE and FALSE methods respectively match all or no items.

Most SelectionCriterion objects use two parameters to construct a single criterion for selecting a collection item; some use two or more SelectionCriterion objects to construct a single criterion.

As an example specification, the selection criterion %sel in the following statement, instantiated by the LT constructor method, matches a number whose square root is less than 10:

%sel = lt(squareRoot, 10)

Where the left- and right-hand elements of the comparison operation are, respectively, the LT parameter values:

  • squareRoot is the intrinsic Float method which is applied to each item value before the comparison is made.
  • 10 might be any expression of any User Language intrinsic type.

This %sel criterion might be used as follows to locate the next ArrayList item after item 3 whose square root is less than 10:

%itemnum = %balance:findNextItemNumber(%sel, start=3).

The requirements for the SelectionCriterion parameter exemplified by the SquareRoot method above are:

  • It must be a method or method variable defined to operate on the type of the items in the collection being searched.
  • It must return an intrinsic (number, string, unicode) value.

Additional notes:

  • Comparison values are evaluated at SelectionCriterion construction time, not when the search method is evaluated. That is, the following sequence selects items with income greater than or equal to 50000, not 100000: %income = 50000 %sel = ge(income, %income) %income = 100000 %foo2 = %foo:subsetNew(%sel).
  • SelectionCriterion have a size limit: the SelectionCriterion, including the values for EQ, NE, LT, LE, GE, and GT comparisons must take less than 252 bytes.

    ANDs and ORs take 4 bytes, and comparison selectors have 12 bytes of overhead plus the length of the value rounded to a 4-byte multiple. So, for example, an And condition with seven 20-byte values would take 4+7*(20+12), or 228, bytes.

    You can work around a criterion that exceeds 252 bytes by encapsulating some or all of the conditions in a local method, since a local enhancement method can be the method parameter for a comparison SelectionCriterion.

Declaring a SelectionCriterion object variable

The SelectionCriterion class operates on specific objects, so a variable of the SelectionCriterion class must be qualified with the object to which it applies: For example:

%sel1 is selectionCriterion for object myClass %sel2 is selectionCriterion for object xmlNode %sel3 is selectionCriterion for longstring

The declaration for %sel in the example in the preceding section might be:

%sel is selectionCriterion for float

In general, the syntax for declaring a SelectionCriterion object variable is:

<objvar> Is Object SelectionCriterion For <itemtype>

Where:

The name of the SelectionCriterion object variable.
The datatype of the items in the collection to be searched.
Specifying a SelectionCriterion's parameters

As stated earlier, most of the SelectionCriterion methods accept two parameters, the first a “method value” and the second an intrinsic value. Regarding the first, just as a User Language “numeric” argument can be a numeric literal or a variable or even an expression that results in a number, a method value argument can be a method literal or a method variable or an expression that results in a method.

More specifically, a method value is a value assigned to a method variable. And for a SelectionCriterion, the method variable's implicit declaration is:

Is Function (<itemtype>):<methname> Is <intrinType> Where:
<itemtype>
The class of the items in the collection to be sorted.
<methname>
A method name, but merely a placeholder in an actual declaration. Any method (system or user), class Variable or Property, local method, or method variable that fits the declaration can be used in the SelectionCriterion.
<intrinType>
A User Language intrinsic class type returned by the function.

The method value argument must conform to the following rules:

  • It must return an intrinsic value.
  • It cannot have any parameters other than the method object.
The EQ, NE, GE, GT, LE, and LT constructors

These shared methods each create a new SelectionCriterion object that is a relational expression used to select items from a collection. Each of these constructors provides a different comparison operator. The EQ method, for example, constructs an equality expression that selects a collection item if the expression is true for that item. The other methods construct, respectively, not-equal-to, greater-than-or-equal-to, greater-than, less-than-or-equal-to, or less-than expressions.

The collection searching method that makes use of a selection criterion specifies:

  • Whether to return the first item or item number or all items that satisfy the selection criterion.
  • Where in the collection to begin searching.

The first of the two parameters in a selection criterion specifies a function that is applied to a collection item. The function result is the “left-side” operand in the criterion's expression. The second selection criterion parameter is a string or numeric that is the “right-side” operand in the expression. EQ(name, 'Ortiz') specifies the expression name='Ortiz'.

The function parameter of one of these constructors might simply be an identity function that returns the item value. Or, for example, it might be a function that returns the value of a class member for an item that is an object. This function must be a method that operates on the item type and returns a User Language intrinsic datatype (Float, String, Longstring, or Unicode) value.

%selc = [%(selectionCriterion for itemtype):] - EQ(function, value) EQ Syntax (same for NE, GE, GT, LE, and LT)

Notes:

  • The function parameter is a method value, not a User Language expression, and you may not specify a function that itself has an argument. The SelectionCriterion syntax does not provide for specifying a parameter for the function parameter. If necessary, the workaround for this restriction is to define a local method that accepts an argument, then use that method as the function parameter.
  • The function may be This, an identity method that is valid for User Language intrinsic method objects only. The This method returns the value of the item to which it is applied.
The OR and AND constructors

These shared methods each create a new SelectionCriterion object that is an expression used to select the items in a collection. Each constructor uses a different logical operator to form an expression that combines one or more SelectionCriterion objects.

An OR criterion returns true for a collection item if any of the component SelectionCriterion expressions are true for the item; otherwise it returns false. An AND criterion returns true if all of the component SelectionCriterion expressions are true for the item; otherwise it returns false.

%selc = [%(selectionCriterion for itemtype):] - OR(criterion1 [, criterion2] ... [, criterionN]) OR Syntax (same for AND)

All OR and AND SelectionCriterion conditions are short-circuiting conditions. That is, if any of the conditions in an OR return True, the subsequent conditions are not evaluated and the OR returns True. Similarly, if any of the conditions in an AND return False, the subsequent conditions are not evaluated, and the AND returns a False.

Therefore, it is wise to put the most likely conditions first in an OR, and it is wise to put the least likely first in an AND. For a mix of conditions where some are simply variable references and others require method evaluation, it probably is best to put the variable references first, as these are probably much cheaper to evaluate.

The NOT constructor

This shared method creates a new SelectionCriterion object that is a logical negation of its SelectionCriterion parameter. A NOT criterion returns true for a collection item if NOT's component SelectionCriterion expression is false for the item; otherwise it returns true.

%selc = [%(selectionCriterion for itemtype):] - NOT(criterion) NOT Syntax

The NOT constructor is never necessary, and anything you can do with the NOT can be done (probably more clearly) otherwise. For example, the following two criteria are identical:

%sel = not(gt(this(90)) %sel = le(this(90))

And the following two criteria are identical:

%sel = not(or(lt(this,70), ge(this,95))) %sel = and(ge(this,70), lt(this,95))

And these criteria are identical:

%sel = not(true) %sel = false

Internally, NOTs are always converted to the inverse of the parameter criterion.

The TRUE and FALSE constructors

These shared methods take no parameters and create a new SelectionCriterion object. A TRUE criterion returns true for any collection item; A FALSE criterion returns false for any collection item.

TRUE and FALSE thus provide the equivalent of an empty SelectionCriterion, and they substitute for a New constructor in the SelectionCiterion class.

%selc = [%(selectionCriterion for itemtype):]TRUE %selc = [%(selectionCriterion for itemtype):]FALSE TRUE and FALSE Syntax

Notes:

  • TRUE and FALSE exist to simplify dynamic SelectionCriterion applications. If you are dynamically generating a SelectionCriterion, under some conditions you may want the criterion to select all objects or to select no objects.

    In addition, if you are building a SelectionCriterion by using OR in conditions, it might be useful to start out with a FALSE SelectionCriterion:

    %sel = FALSE if <somecondition1> then %sel = OR(%sel, EQ(foo, 'A')) end if if <somecondition2> then %sel = OR(%sel, EQ(foo, 'B')) end if if <somecondition3> then %sel = OR(%sel, EQ(foo, 'C')) end if

    Similarly, if building a SelectionCriterion by using AND in conditions, it might be useful to start out with a TRUE SelectionCriterion.

  • These SelectionCriterion methods are constructors and as such can be called with no method object, with an explicit class name, or with an object variable, even if that object is null: %selc1 = TRUE %selc2 = %(selectionCriterion for float):FALSE %selc3 = %selc3:TRUE
  • The following statements are equivalent: %sel = and(ge(this, 22), true) %sel = ge(this, 22)

Janus SOAP Xml API

XmlDocs now maintained in Unicode

As of Sirius Mods version 7.6, XmlDocs contain Unicode rather than EBCDIC; this is true for all string values, names, prefixes, and URIs. As a consequence, most of the arguments and results of the Xml API methods that formerly were strings are now Unicode strings.

This change will allow you to store Unicode in an XmlDoc, thus achieving the W3C XML Recommendation (in which characters are Unicode), but without needing to change your existing Xml API applications. This is because automatic conversions are done between EBCDIC and Unicode in Janus SOAP.

For example, you can still code:

%d:AddElement('name', 'value')

The EBCDIC character strings above are automatically converted from EBCDIC to Unicode. Similarly, you can code:

%str = %n:Value

If the variable %str above is declared as type String or Longstring, then the Unicode result of the Value method is automatically converted from Unicode to EBCDIC when it is stored in %str.

This feature did require some changes to existing Janus SOAP Xml API methods. Those changed methods are included in the following sections, even where the change is only of an argument or result to Unicode.

New methods

AllowNull XmlDoc property

A new XmlDoc property, AllowNull, is now available. This Boolean property, which defaults to False, may be set to True, which allows the XmlDoc to contain null characters (U+0000) in node values.

Once this property has been set to True, null characters are allowed for deserialization into the XmlDoc. For example:

<a>Element contains null: &#0;</a>

Null characters are also allowed for “direct setting” of a node's value. For example:

%nod:AddElement('a', 'Element contains null:' With $X2C('00'))

When nodes have been added to an XmlDoc that has AllowNull=True, a “subtree copy” operation (that is, either AddSubtree or InsertSubtreeBefore) is not allowed using it as the source (argument 1) if the target (method object) of the operation is an XmlDoc with AllowNull=False.

Notes:

  • All Unicode characters except null can always be stored in an XmlDoc, so when AllowNull is set to True, all Unicode characters can be stored. Hence, the use of the InvalidChar=Allow is obsolete and the AllowNull=True setting should be used to indicate null characters are allowed.
  • Deserialization of Unicode characters that do not translate to EBCDIC is not allowed unless the AllowUntranslatable deserialization option is used.
  • When providing EBCDIC characters to be stored in an XmlDoc, those EBCDIC characters must be translatable to Unicode. If you have EBCDIC strings which may not be translatable, you must handle those before passing them to an XmlDoc update operation. For example, you may be able to use the Untranslatable argument of the EbcdicToUnicode function.
  • A null character in an XmlDoc is serialized as &#x0;.
AppendValue method in XmlNode class

A new XmlNode subroutine, AppendValue, appends to the value of a node in an XmlDoc.

xmlNode:AppendValue(stringlistOrUnicodeString) AppendValue syntax

Where:

  • The method object is an XmlNode other than the Root node. If it is an Element node, it may have at most one child, and any such child must be a Text node.
  • The method argument is either a Unicode string or a Stringlist object:
    • If a Unicode string, the value of the node is set to its current value followed by the Unicode string.
    • If a Stringlist object, the value of the node is set to its current value, followed by the Stringlist items converted from EBCDIC to Unicode, with Unicode linefeed characters between the Stringlist items.

For example, the following fragment appends a Unicode string and then a StringList to an Element value:

%n = %x:AddElement('a', 'begin value') %n:AppendValue('_some more_') Text To %sl and more and that's all End Text %n:AppendValue(%sl) %n:Print

The result is:

<a>begin value_some more_and more&#xA;and that's all</a>
NoEmptyElement property of element XmlNodes

The new XmlNode property, NoEmptyElement, may be specified for any Element node. If set for an Element that contains no children, the Element is serialized with a separate start tag and end tag, rather than with a single empty element tag. For example, <address></address> versus <address/>.

This formatting option can be useful if you are using the Janus SOAP ULI to generate XHTML. Tests show that some browsers work correctly for certain childless elements only if they have an empty element tag, and for other childless elements they work correctly only if there are separate start and end tags. (Therefore, you cannot obtain a “blanket” suppression of empty element tags via using the NoEmptyElt option of the serialization methods.)

The NoEmptyElement property accepts and returns a Boolean value. Setting it to True suppresses an empty element tag. The default is False.

Changes to existing methods

AllowUntranslatable deserialization option

A new option, AllowUntranslatable, is now available for the LoadXml and WebReceive methods, as well as for the ParseXml method of the HttpResponse class. When this option is specified, all valid Unicode strings are allowed in the XML document. When this option is not specified, Unicode strings that are not translatable to EBCDIC are not allowed.

How you use this option depends upon the application's handling of the XmlDoc into which you are deserializing. The basic rule is to use AllowUntranslatable only if the application checks for translatability when accessing parts of the XmlDoc that may have untranslatable Unicode content.

  • AllowUntranslatable not specified

    In this case, any access to the deserialized content is performed without any Unicode to EBCDIC translation errors. This approach detects (and throws an XmlParseError exception with reason UntranslatableUnicode) for any untranslatable Unicode in the serialized input XML document.

    That is to say, given the following fragment:

    %doc:WebReceive ... %val Longstring %val = %doc:Value(%xpath)

    The assignment to the EBCDIC string %val cannot fail due to a Unicode translation problem: if there is any untranslatable Unicode (including, of course, strings in the XML document which your application never accesses), the WebReceive operation fails.

  • AllowUntranslatable specified

    In this case, all Unicode characters in the serialized input XML document are allowed and stored in the XmlDoc. However, if the application later accesses content that is not translatable to EBCDIC, and the access performs an implicit Unicode-to-EBCDIC translation, the request will be cancelled.

    The code below shows a way to get the benefit of specifying AllowUntranslatable while limiting the risk of request cancellation. In the example, it is believed that only the element comments might contain untranslatable Unicode among all the data accessed from the XML document:

    %resp:ParseXml(%doc, 'AllowUntranslatable') ... %uVal Unicode %val Longstring %uVal = %node:Value('comments') Try %val = %uVal:UnicodeToEbcdic Catch CharacterTranslationException %val = %uVal:UnicodeToEbcdic(CharacterEncode=True) Print 'Untranslatable Unicode, character encoded:' - And %val End Try
Note: Unicode values, untranslatable or not, are always allowed when they are added to an XmlDoc using one of the methods which “directly store” into an XmlDoc. For example, the following fragment adds an Element node with a value which is the Unicode trademark sign: %node:AddElement('notation', '&#x2122;':U)
CharacterEncodeAll option of Print, Audit, and Trace

A new option, CharacterEncodeAll, is available for the Print, Audit, and Trace methods. This option uses character encoding in all contexts to display Unicode characters that do not translate to EBCDIC.

With or without this option, non-translatable Unicode characters in Attribute or Element values are displayed as character references. For example:

%doc:AddElement('top', '&#x2122;':U) %doc:Print

The result of this fragment is:

<top>&#x2122;</top>

However, with default serialization options, when an untranslatable Unicode character occurs in a context other than element or attribute value (that is, a name, comment, or PI), character encoding is not used. For example, the following statements result in a request cancellation:

%doc:AddElement('&amp;#x2122;':U) %doc:Print

The Print method fails, attempting to translate the element name, the U+2122 character, to EBCDIC. This request cancellation can be overcome using CharacterEncodeAll:

%doc:AddElement('&amp;#x2122;':U) %doc:Print(, 'CharacterEncodeAll')

The result of the above fragment is:

<&#x2122;/>

Note: The result of a Print with CharacterEncodeAll can be misleading. Request cancellation is avoided, but it produces multiple EBCDIC characters where only a single Unicode character is stored.

The XmlDoc, %doc, above is not a legal XML document, because the ampersand (&) is not a legal name character. Similarly, for an untranslatable Unicode character added to a document with AddComment or AddPI: printing with CharacterEncodeAll produces a stream of characters that informs about a single character reference but, if deserialized, would result in multiple stored characters. The standard XML syntax does not recognize character references as such in names, Comments, and PIs.

InvalidChar property removed

The InvalidChar property of the XmlDoc class is no longer supported. Requests containing InvalidChar will fail under Sirius Mods version 7.6. If you are using InvalidChar in source code to allow null characters, you can use the AllowNull property instead.

InvalidCharacterPosition shared XmlDoc function

The InvalidCharacterPosition method is enhanced as follows:

  • It now accepts an optional, name-required argument: AllowNull. AllowNull takes a Boolean value. If AllowNull is True, an input null character is not considered invalid.
  • It now validates either an EBCDIC or Unicode string. Formerly, only an EBCDIC argument was allowed.

    InvalidCharacterPosition returns zero if its argument string is:

    • Unicode, and all characters are legal in an XML document (that is, it does not contain any null characters).
    • EBCDIC, and all characters are translatable to Unicode characters other than the null character.

    Otherwise, it returns the character position of the first character that does not meet these criteria.

IsValidString shared XmlDoc function

The IsValidString method now accepts either an EBCDIC or Unicode string. Formerly, only an EBCDIC argument was allowed. IsValidString now returns True if its argument string is:

  • Unicode, and all characters are legal in an XML document (that is, it does not contain any null characters).
  • EBCDIC, and all characters are translatable to Unicode characters other than the null character.
Otherwise, it returns False.

Note: IsValidString is deprecated, in favor of the InvalidCharacterPosition function.

Janus TCP/IP Base

The following features are new or changed in Janus TCP/IP Base.

New forms of JANUS LOADXT

There are two new forms of the JANUS LOADXT command:

JANUS LOADXT xtabName UNICODE JANUS LOADXT xtabName DEFAULT

JANUS LOADXT xtabName UNICODE
This creates a Janus translation table which can be referenced, for example, in the XTAB parameter of the JANUS DEFINE or JANUS WEB command.

The name of the table is given in the third word of the command, shown as xtabName above.

The translations defined in the table are the same as the translations between ASCII and EBCDIC defined in the current Unicode table, except that, since there is no concept of “untranslatable” in the use of the Janus translation tables, the following translations are used:

  • ASCII to EBCDIC

    Untranslatable ASCII code points are translated to EBCDIC X'FF'.

  • EBCDIC to ASCII

    Untranslatable EBCDIC code points are translated to ASCII X'3A' (the ASCII colon character - “:”).

The translations defined between ASCII and EBCDIC are the translations used by the AsciiToEBCDIC and EBCDICToAscii methods.

JANUS LOADXT xtabName DEFAULT
This command will set the translation tables for the designated xtabName to the default (i.e., in the absence of any LOADXT commands) Janus tables.

This can be used as an “undo” command; for example, if you had issued:

JANUS LOADXT STANDARD UNICODE

Then the following command will revert the STANDARD xtab to its default:

JANUS LOADXT STANDARD DEFAULT

Janus Sockets

The following features are new or changed in Janus Sockets:

SMTP Helper

New parameters for AddPart method

The new Disposition and Description parameter options are added to the SMTP Helper AddPart method. These name required parameters are strings that provide content-disposition and content-description headers for attachments added with AddPart.

AddPart adds a content-disposition header or a content-description header to an e-mail attachment only if you specify, respectively, a Disposition or a Description value.

Backwards incompatibilities

Janus SOAP ULI

ToXmlDoc default changed to AttributeNames=True

The default value of the AttributeNames argument of the ToXmlDoc method in the Record class has been changed.

Formerly, the default was False; the default now is True. The reason for this change is that the AttributeNames=True format is more well suited to operations on the XmlDoc, particularly a record copying operation.

RecordSet LockStrength inconsistencies

Two similar fixed problems may introduce backwards incompatibilities:

  • Formerly, if a FD or FDWOL statement found no records, the target recordset LockStrength would be incorrectly set to None (when they should have been set according to their Find statement types to, respectively, Share and None). This made it possible for a user to do an FD followed by an AddRecordset, and the resultant recordset might be locked None or Share depending on whether the FD found any records.

    As of Sirius Mods version 7.6, the LockStrength of the target recordSet of a FD statement that finds no records is always set to Share.

  • The AddRecordsetNew, RemoveRecordsetNew, and AndRecordsetNew methods are supposed to set the LockStrength and LoopLockStrength of the their output RecordSet objects to be the same as that of their method objects. But in fact these methods always produced unlocked recordsets.

    As of Sirius Mods version 7.6, these methods now correctly set these output RecordSet locking strengths to be the same as that of the method objects.

Print/Audit/Trace statements encode Unicode ampersands

The Print, Audit, and Trace statements now encode Unicode data for display. In the case of the ampersand, this can change the result. For example, in version 7.5 of the Sirius Mods, the following fragment:

%u Unicode Initial('Jack & Jill') Print %u

produced the following result:

Jack & Jill

In version 7.6, however, it produces the following result:

Jack &amp; Jill

Janus SOAP Xml API

The following backwards compatibility issues have been introduced in the Janus SOAP Xml API.
Serialization of attributes always bracketed by quotes

In version 7.5 of Janus SOAP, some attempt is made to use the apostrophe (') to bracket the serialization of an attribute if it contains a quote ("). In version 7.6, attributes are always bracketed by quotes.

For example, consider the following fragment:

Begin %d:AddElement('a'):AddAttribute('b', '"Wow"') %d:Print

This produces the following result with version 7.5:

<a b='"Wow"'/>

However, starting with version 7.6, it produces the following result:

<a b="&quot;Wow&quot;"/>
InvalidChar XmlDoc property now obsolete

In versions 7.3 and 7.5 of Janus SOAP, although you are allowed to set and retrieve the InvalidChar property of an XmlDoc object, this property is ignored and has no effect. In versions 7.2 and older of Janus SOAP, this property allowed certain EBCDIC characters (nulls, for example) to be stored in an XmlDoc which otherwise were not allowed.

Starting with version 7.6 of Janus SOAP, all Unicode characters may be stored in an XmlDoc, except for the null character (U+0000), which is prohibited by the XML Recommendation.

Therefore, the InvalidChar property would be extremely misleading, so it has now been removed from Janus SOAP. If you had been using InvalidChar=Allow to allow null characters in an XmlDoc, this purpose can be achieved via AllowNull=True.

Also note that when providing EBCDIC characters to be stored in an XmlDoc, those EBCDIC characters must be translatable to Unicode. If you have EBCDIC strings which may not be translatable, you must handle those before passing them to an XmlDoc update operation; for example, you may be able to use the Untranslatable argument of the EbcdicToUnicode function.

Change to structure of LoadParameterInfo document

Now the LoadParameterInfo method builds an XmlDoc such that:

  • The name of each Model 204 parameter is used as the value of the 'name' attribute of a 'parameter' element in the XmlDoc; formerly, the name of that element was the name of the parameter.
  • The description of each Model 204 parameter is provided as the value of the 'description' element child of a 'parameter' element in the XmlDoc; formerly, the description was provided as the value of a text child of the element whose name was the name of the parameter.

Return to top of page

Sirius Mods Version 7.5

Version 7.5 of the Sirius Mods was released in April, 2009. This release obsoletes the limited distribution Version 7.4 and corresponds to General Availability of Model 204 V7R1. Please refer to the Notes for Sirius Mods Version 7.5 for more detailed information.

Supported Model 204 Versions

Sirius Mods 7.5 supports only Model 204 versions V6R1 and V7R1. The commercial release of Model 204 V7R1 is supported only by Sirius Mods 7.5 and later.

New Model 204 parameters

Two new parameters that affect Janus SOAP ULI “garbage collection” are added.

GCSTATS

Setting this User parameter reports garbage collection statistics in a message to the audit trail, to the terminal, or to both. The statistics include the number of objects discarded by the garbage collection process and the amount of time taken.

AUTOGCN

The Janus SOAP ULI performs garbage collection automatically at user logout: that is, at logout it removes user-created objects that were not discarded by the user or by the Janus SOAP ULI during and after each request. This garbage collection process can also be invoked explicitly (by %(object):GarbageCollect), and it may be time consuming. The AUTOGCN User parameter lets you invoke garbage collection automatically during a user session whenever normal post-request cleanup “leaves behind” a number of objects that meets or exceeds the AUTOGCN value.

For more information about garbage collection, please refer to the Janus SOAP Reference Manual.

Janus SOAP ULI

The following sections describe changes in the Janus SOAP ULI in this release.

New exception class: MaxDaemExceeded

The MaxDaemExceeded exception class indicates that the Daemon class constructor was invoked, but the calling thread is at its limit of daemon threads. The maximum number of daemons allowed per master thread is set by the MAXDAEM system parameter, whose default value is 1.

Unicode intrinsic methods

Many new intrinsic methods have been added, as described in the following subsections. Many of the examples use the PrintText statement, which was introduced in Sirius Mods version 7.2 and is described in the Janus SOAP Reference Manual.

UnicodeChar function

This function returns the string value of the single character at a specified position in the method object Unicode string.

%outUni = unicode:UnicodeChar(position)

UnicodeLeft function

This function returns the left-most characters of the method object string, possibly padding it on the right.

%outUni = unicode:unicodeLeft(length, [Pad=char])
UnicodeLength function

This function returns the number of characters in the method object string.

%len = unicode:unicodeLength
UnicodePositionIn and UnicodePositionOf functions

These functions return the numeric position of the first occurrence of one character string inside another (character case respected). The difference between the two methods is that for UnicodePositionIn, the method object string is located in the first argument string, whereas for UnicodePositionOf, the first argument string is located in the method object string. Which method is more convenient to use will be application dependent.

%pos = needle:unicodePositionIn(haystack, [Start=spos]) %pos = haystack:unicodePositionOf(needle, [Start=spos]) :figcap.UnicodePositionIn and UnicodePositionOf syntax

The starting position must be a positive number. A zero or negative number results in request cancellation. If the starting position is greater than the length of the haystack plus one minus the length of the needle, a zero will always be returned since there aren't enough characters in the haystack to satisfy the search.

The UnicodePositionOf and UnicodePositionIn methods do exactly the same thing. The only difference between them is that in UnicodePositionOf, the haystack is the method object and the needle is the first argument. In UnicodePositionIn, the method object and first argument are reversed. Which method is preferable will depend on the application, and, in many cases, it will be quite arbitrary which one is used.

The UnicodePositionOf and UnicodePositionIn methods are analogous to the String intrinsic PositionIn and PositionOf methods.

UnicodeRight function

This function returns a specified number of the right-most characters of the method object string, possibly padding them on the left.

%outUni = unicode:unicodeRight(length, [Pad=char])
UnicodeSubstring function

This function returns a specific number of characters starting at a specific position in the method object Unicode string, possibly padding it on the right.

%outUni = unicode:unicodeSubstring(start, length, [Pad=char])

Intrinsic conversion methods

Two new pairs of intrinsic conversion methods are added.

FloatToBinary and BinaryToFloat

The FloatToBinary function in the Float intrinsic class converts a numeric value to the binary string equivalent of its floating point representation. Since all Float types are processed in Model 204 as Float Len 8, FloatToBinary always returns an 8-byte string.

%str = number:FloatToBinary

The BinaryToFloat function in the String intrinsic class converts a binary representation of a floating point number to that number. The method object can be a string of length 4, 8, or 16.

%num = string:BinaryToFloat

IntegerToHex and HexToInteger

These methods convert between hex strings and integers.

IntegerToHex

IntegerToHex converts an integer to its hexadecimal string representation.

The method's arguments are the requested hex-byte output size, and an optional, boolean, named-parameter: Signed

%str = number:IntegerToHex(num, [Signed=bool])

HexToInteger

HexToInteger returns the integer value of a hex encoded string. It has a single, optional, boolean named-parameter: Signed.

%num = string:hexToInteger([Signed=bool])

New EbcdicToUnicode parameter: Untranslatable

The EbcdicToUnicode method now takes the Untranslatable named argument, which lets you specify how to handle EBCDIC input characters that are not translatable to Unicode.

The Untranslatable argument is optional; if it is omitted and an EBCDIC character is encountered that is not translatable to Unicode, a CharacterTranslationException exception is thrown.

Otherwise, the value of the Untranslatable argument can be the null string or can be a single Unicode character.

  • If it is the null string, any untranslatable EBCDIC characters are removed from the input string. The EbcdicRemoveNonUnicode method which formerly achieved this purpose has now been removed.
  • If it is a single Unicode character, any untranslatable EBCDIC characters are replaced with that Unicode character. The EbcdicTranslateNonUnicode method which formerly achieved this purpose has now been removed.
Removing the two methods introduces a backwards compatibility issue.

Janus SOAP Xml API

The following sections describe changes in the Janus SOAP Xml API.

Support 1.1 as XML version

The value of an XmlDoc's Version property may now be set to '1.1':

%doc:Version = '1.1'

Also, 1.1 is accepted in the XML declaration in a deserialization operation:

%doc:LoadXml('<?xml version="1.1"?><docFoo/>')

The ClientCertificate method

This new shared method is a constructor that produces an XmlDoc object that contains detailed information from a client certificate received by a Janus web server, server socket, or Telnet server. The XmlDoc that is returned includes details about the client and about the certificate's signer.

The ClientCertificate method provides much of the functionality of functions in Janus Web Server ($Web_Cert_Info and $Web_Cert_Levels) and Janus Sockets ($Sock_Cert_Info and $Sock_Cert_Levels).

The ClientCertificate syntax is:

%doc = [%(XmlDoc):]ClientCertificate ( - [AttributeNames=bool,] - [AttributeValues=bool] )

The AttributeNames and AttributeValues arguments indicate how to display certificate detail names and values within their XML document elements: as the element name, or as the value of a “name” or “value” attribute. For example, for the certificate detail named “locality”:

  • Element-name format is: <locality>Cambridge</locality>
  • Attribute format is: <info name="locality" value="Cambridge"/>

The default value for both is False, which produces element-name format.

The XmlDoc object produced by the ClientCertificate method is Null if:

  • The method is invoked in a scenario where there is no client certificate.
  • The method is invoked when you are not logged in on a Janus server port.
  • The Janus port is not defined to use SSL.
  • The client did not provide a certificate.

The information returned by this method is most useful in the server port's JANUS DEFINE NEWSESCMD processing. The information method can be used anywhere: no information in the client certificate is considered “secure.”

CrPreserve deserialization option

The following option is available for all deserialization methods:

CrPreserve
All whitespace characters in Element content are preserved, including carriage return. Unlike all other deserialization options, a carriage return in Element content does not undergo the normalization specified in the XML standard.

CrPreserve is mutually exclusive with all other Wsp* options, and with the LinefeedNoTrailingTabs option.

Janus Web Server

The following features are new or changed in Janus Web Server:

TextUtf8 option on $Web_*_Content functions

A new option has been added to the $Web_File_Content, $Web_Input_Content, and $Web_Output_Content functions. The name of this option is TextUtf8 and it is mutually exclusive with the Text and Binary options.

The TextUtf8 option causes $Web_Input_Content to first convert each two-byte UTF-8 sequence to the corresponding ASCII character, which is then translated to EBCDIC using the translation table in effect for the Janus Web Server connection.

For example:

%string = $Web_Input_Content('TextUtf8')

Return to top of page

Sirius Mods Version 7.4

Version 7.4 of the Sirius Mods was released in February, 2009. This was an interim release only available to the Beta testers of Model 204 V7R1. It is no longer available and its features will be documented as part of the Sirius Mods Version 7.5.

Return to top of page

Sirius Mods Version 7.3

Version 7.3 of the Sirius Mods was released in October, 2008. Please refer to the Notes for Sirius Mods Version 7.3 for more detailed information.

Supported Model 204 Versions

Sirius Mods version 7.3 supports only Model 204 V6R1.

Documentation

  • The Sirius Mods Command and Parameter Reference Manual is now available; it describes all Model 204 commands and parameters and Model 204 Editor commands which are implemented as part of the Sirius Mods.
  • The Janus Network Security Reference Manual and the HTML pages of the SSL certificate management application are copyedited as well as updated to include information about client certificates and intermediate server certificates.
  • The FloatNamedArray class that has been available since the earliest releases of the Janus SOAP ULI is now documented in the Janus SOAP Reference Manual.

All or Multiple Products

Several Janus SOAP classes available to all

A number of Janus SOAP classes are now available to any Sirius Mods version 7.3 customer. The following classes are not restricted to those with a Janus SOAP license:

  • String, Float, and Unicode intrinsic
  • StringList
  • CharacterMap
  • StringTokenizer

New Model 204 parameters

Two new parameters that affect Model 204 retrieve key processing are added.

RETRVBUF

This User 0 parameter specifies the size of the buffer for the 3270 terminal PF key that retrieves previously input command lines. The larger the retrieve buffer, the more commands you can save for retrieval.

The minimum and default setting of RETRVBUF is 288 bytes, and its maximum is 32767. The parameter setting is always rounded down to the nearest 8-byte multiple, so the largest buffer allowed is actually 32760 bytes.

RETRVOPT

This user parameter is a bitmask parameter that controls some characteristics of the Model 204 retrieve key.

The RETRVOPT bits are:

X'01'
The PF key that is 1 higher than the RETRVKEY setting is mapped to a forward retrieval operation, which returns the command in the retrieve buffer that follows the one that is currently displayed. For example, if this X'01' bit is set, and RETRVKEY is set to 6, PF7 will be a forward retrieve key.
X'02'
The forward and backward retrieve keys will not wrap. With this bit set, if you retrieve all the commands stored in the retrieve buffer, your next retrieval is a blank (instead of wrapping to the beginning of the retrieval ring, as was the behavior prior to the availability of the RETRVOPT parameter).
X'04'
Do not add to the retrieve buffer any text typed in response to a screen-full prompt. For example, if you issue a VIEW, then type C or K to stop the output, the C or K is added to the retrieve buffer — unless RETRVOPT X'04' is set. RETRVOPT X'04' also prevents N, NP, or NEW commands (which clear the screen) from being added to the retrieve buffer.
X'10'
If the X'01' bit is also set, RETRVOPT X'10' maps the forward retrieve key to the PF key that is 12 greater than the current retrieve key (setting of RETRVKEY). This will be the shifted version of the current retrieve key if that current key is less than PF13, and it will be the non-shifted version if that key is greater than PF12.

For example, if RETRVOPT is set to X'17' and RETRVKEY is 12, the forward retrieve key is PF24. And if RETRVOPT is set to X'17' and RETRVKEY is 21 (Shift+PF9), the forward retrieve key is PF9.

New bit settings for the FUNCOPTS system parameter

Two new FUNCOPTS bit settings allow a site to ease or eliminate the restrictions on who can use the $PRIORTY function to change another user's priority:

  • The X'40' bit means that any user can issue the $PRIORTY function.
  • The X'20' bit means that a procedure invoked via the NEWSESCMD facility can use $PRIORTY function.
If neither of these bits is set, then only a System Manager or System Administrator can use the $PRIORTY function.

New default for the SCRNSTBL user parameter

The default value of SCRNSTBL is increased from 4096 to 6144.

Enhancement to Sirius regex

The following feature is added to the Sirius regular expression support (the regex methods in the StringList and String intrinsic class, and the $RegexMatch and $RegexReplace $functions). The regex support is summarized in the “Regex Processing” chapters in the Janus SOAP Reference Manual and the Sirius Functions Reference Manual.

  • Support is added for the \b and \B multi-character escape sequences. They operate as they do under the Perl language.

Janus SOAP ULI

The following sections describe changes in the Janus SOAP ULI in this release.

New system classes

Three “smaller,” unrelated, system classes have been added. These are all documented in the Janus SOAP Reference Manual.

RandomNumberGenerator class

As its name suggests, the RandomNumberGenerator class is designed to generate random numbers. It is patterned after the Sirius functions $Random and $Random_Seed, described in the Sirius Functions Reference Manual.

The methods in the class include a New constructor to instantiate an object, a Value method for printing as well as constraining the random number value range, and an UpdateSeed method to reset the value of an object.

As an example, the methods in this request create a reproducible sequence of ten numbers between 0 and 99:

b %rand is object randomNumberGenerator %i is float %rand = new(seed='abcd') for %i from 1 to 10 printtext {~} = {%rand:value(0, 99)} end for end
CharacterMap class

A CharacterMap class object contains a mapping of characters to characters. Each character in an In string (the “input table”) is associated with, or mapped to, an individual character from an Out string (the “output table”). The output table may be supplemented with instances of a pad character to ensure a one-to-one mapping with the input table characters.

CharacterMap includes a constructor, copy methods, and an update method for modifying the map. Most of these methods are shown in the following example, which features the Translate method for longstrings (Translate function). In the example, a new CharacterMap is the argument for the Translate method; then that map is copied and modified, and the modified map is used in a second Translate call:

begin %map is object characterMap %map2 is object characterMap %ls is longstring %map = new(in='x-', out='!c') %ls = 'xu--exx' printtext {~} = '{%ls:translate(%map)}' %map2 = %map:copy %map2:update(in='x',out='s') printtext {~} = '{%ls:translate(%map2)}' end

The result is:

%ls:translate(%map) = '!ucce!!' %ls:translate(%map2) = 'success'
The UserStatistics class

Intended for performance work, the UserStatistics class is designed to replace $STAT and similar tools that return the values for selected Model 204 User statistics.

The UserStatistics constructor takes a snapshot of the user stat block at the time the constructor is invoked. You then use the UserStatistics methods to extract the statistical data from the instantiated object.

The object holds two types of user statistics: Login and Request.

  • Login statistics (also called “Final”) are those that keep data per user since the user's most recent login. The statistics available to the Model 204 $STAT function, as well as the OBJSWAP statistic for Janus SOAP objects, are valid.
  • Request statistics are a combination of:
    • Statistics that keep the current high-water marks for some work tables per user. Model 204 documentation includes these with “since last” statistics.
    • Since last statistics, which keep data per user comprising only the user's most recent work unit (like compilation or evaluation); they are not accumulated.

Login and Request statistics are not mutually exclusive. Both Login and Request data are kept for some activities, so many statistics appear in lists of both types and are valid in all methods that are restricted to one type or the other.

The Model 204 System Manager's Guide and the SirMon User's Guide are good sources of information about the available statistics, although not all statistics shown in the SirMon User's Guide are included in a UserStatistics object. Where they occasionally differ in spelling the name of a statistic, the Model 204 System Manager's Guide is more likely to have the spelling required by the UserStatistics methods.

You can also view all the individual statistics contained in a UserStatistics object by applying the ToString method to it, as follows:

%statobject:ToString(Zeros=true)

The longstring output from this ToString method invocation displays all the Login statistics followed by all the Request statistics.

Note: The ToString method shown above can be applied implicitly: simply print or audit an object variable, and the ToString method is automatically applied to the object. Print %statobject is equivalent to Print %statobject:ToString.

The following is a simple example that shows how much CPU a request uses and how many DKRDs it did:

b %statStart is object userStatistics %statEnd is object userStatistics %statStart = new %statEnd = new printText CPU: {%statEnd:difference(%statStart, 'CPU')} printText DKRDs: {%statEnd:difference(%statStart, 'DKRD')} end

Specifying a statistic that is not a User statistic, or that is not the type of statistic (Login or Request) that a method calls for, triggers an UnknownStatistic exception.

The StringTokenizer class

The StringTokenizer class is used to divide an input string (method object) into substrings (tokens). The tokens are separated by either of two types of delimiters:

  • Delimiters that are not tokens themselves (analogs of whitespace and quotation-mark characters in the English language)
  • Delimiters that are also tokens themselves (token-characters, that may be of interest or significance, like a character escape, for example)

A token is thus a sequence of consecutive characters that are not delimiters, or it is a single token-delimiter character. The delimiters are user definable, are specified per StringTokenizer object at creation time, and can be modified thereafter.

StringTokenizer operations maintain two positions within the method object string:

  • The location of the most recent token's first character (the “current token position”)
  • The location from which to begin parsing for the next token (the “tokenizing position”)
You can also explicitly modify these positions individually.

To navigate the simplest path through the given string, you “walk” forward (left to right) from the beginning of the string using token-sized steps (that is, from whole token to next whole token to next whole token, and so on). The following is a simple example of this in which three tokens are separated by blank, non-token delimiters:

%tok = new %tok:string = 'a tokenization example' %tok:nextToken %tok:nextToken %tok:nextToken

Each of the NextToken method calls above returns a token: respectively, “a”, “tokenization”, and “example”.

The StringTokenizer class also has methods that let you take character-sized steps forward in the string, as well as methods that let you modify the position markers and thereby select tokens or sub-tokens in the order you require. You can also locate specified tokens, and you can return substrings that are the characters in the entire string that precede a position or that follow a position.

The StringTokenizer class methods include:

AtEnd function

This method returns a Boolean value that indicates whether the present tokenizing position is immediately after the last token. The value is True if the position at after the last token; otherwise it is False.

CurrentQuoted function

This method returns a Boolean value that indicates whether the current token is a quoted token. A quoted token contains all the characters between a pair of identical quotation characters.

The CurrentQuoted value is True if the current token is quoted; otherwise it is False.

CurrentToken function

This method returns the string value of the current token. The current token is typically the most recent token returned by the NextToken or FindToken function. n CurrentToken is invalid and cancels the request until one of these calls has been made. You can also update the current token by explicitly setting the CurrentTokenPosition value.

CurrentTokenPosition property

This readWrite property returns or sets the position of the first character in the current token.

If you change the current token (by invoking NextToken or FindToken), CurrentTokenPosition is updated with a new value. If you explicitly set CurrentTokenPosition, the current token value is adjusted accordingly.

FindToken function

This callable method returns a Boolean value that indicates whether it finds a specified token. The value is True if the token is found; otherwise it is False. The search starts from the tokenizing position, the value of which is returned by NextPosition.

If the token is found, the position in the string is advanced past the found token, and CurrentToken will return the found token. Otherwise, AtEnd is set to True, and CurrentToken is set to the last token at the end of the string.

The delimiters that are involved in determining the tokens are set initially by the New method that instantiates the StringTokenizer object. The delimiters can be modified by the Spaces, Quotes, and and TokenChars methods.

New constructor

This method returns a new instance of a StringTokenizer object. It has three optional arguments that let you specify the delimiter characters that determine the tokens in the string that is being tokenized.

NextChar function

This method returns the value of the character that is at the tokenizing position, and it advances the tokenizing position past that character to the next character. The tokenizing position is the value returned by the NextPosition property.

NextPosition property

This readWrite property returns or sets the tokenizing position, the position of the character from which the parsing of the next token begins. Unless you explicitly set it otherwise, the tokenizing position is the position that follows the (last) character in the value returned by the most recent call of NextToken, FindToken or NextChar.

NextToken function

This method returns the string value of the next token forward in the current tokenizer string. The next token parsing begins from the tokenizing position, which is the value returned by NextPosition.

When the next token is determined, NextToken advances the tokenizing position to the position following that token, then returns the token value.

The delimiters that are involved in determining the tokens are set initially by the New method that instantiates the StringTokenizer object. The delimiters can be modified by the Spaces, Quotes, and TokenChars methods.

NotAtEnd function

This method returns a Boolean value that indicates whether or not the present tokenizing position is after the last token in the tokenizer string. The value is True if the position is not after the last token; otherwise it is False. The tokenizing position is given by NextPosition.

PeekChar function

This method returns the value of the character that is at the tokenizing position. The tokenizing position is the value returned by NextPosition. After returning the character value, PeekChar does not advance the tokenizing position, which remains what it was when PeekChar was called.

PeekToken function

This method returns the string value of the next token forward in the current tokenizer string. The next token parsing begins from the tokenizing position, which is the value returned by NextPosition. When the next token is determined, PeekToken does not advance the tokenizing position, which remains what it was when PeekToken was called.

The delimiters that are involved in determining the tokens are set initially by the New method that instantiates the StringTokenizer object. The delimiters can be modified by the Spaces, Quotes, and TokenChars methods.

Quotes property

This readWrite property returns or sets the characters that are recognized as quotation characters. The text between each disjoint pair of identical quotation characters (a “quoted region”) is treated as a single token, and any delimiter characters (Quote, Space, or TokenChar) within a quoted region are treated as non-delimiters.

RemoveQuotes property

This readWrite property returns or sets the Boolean value that indicates whether to remove the quote characters from the returned values of quoted tokens. The default value for a new tokenizer is True.

RestOfString function

This method returns the current non-tokenized substring of the tokenizer string. This substring starts from the position after the next token, and it includes the remaining characters going forward to the end of the string.

Spaces property

This readWrite property returns or sets the characters that are recognized as “whitespace”characters, that is, as characters that separate tokens. Such a character is also called a “non-token delimiter,” because it is a delimiter that is not itself a token.

You can specify “token delimiters,” which are delimiters that are also tokens, using the TokenChars method or the New constructor TokenChars parameter.

One or multiple consecutive whitespace characters mark the end or beginning of a token, except when these spaces are part of a quoted region. In that case, the spaces become non-delimiters.

StartOfString function

This method returns the substring of the tokenizer string that precedes the first character of the current token.

String property

This readWrite property returns or sets the string to be tokenized.

StringLength function

This method returns the length of the current tokenizing string. This string is the value of the String method.

SubString function

This function returns a substring that is a specified length and starts at a specific position in the tokenizing string. The substring may be padded on the right.

TokenChars property

This readWrite property returns or sets the characters that are recognized as token-delimiter characters, that is, as single-character delimiters that are also tokens themselves. As a delimiter, a token-delimiter character is a non-included boundary at the end or beginning of a token, unless the character is part of a quoted region (in which case it is treated as a non-delimiter character).

TokensToLower property

This readWrite property returns or sets the Boolean value that indicates whether to convert returned, non-quoted, tokens to all-lowercase characters. The default value for a new tokenizer is False.

TokensToUpper property

This readWrite property returns or sets the Boolean value that indicates whether to convert returned, non-quoted, tokens to all-uppercase characters. The default value for a new tokenizer is False.

New system exception class: UnknownStatistic

The UnknownStatistic exception class describes an exception associated with finding a string identifier that is not a valid or not an appropriate Model 204 statistic name.

To produce an UnknownStatistic exception, you typically use a User Language Throw statement with an UnknownStatistic constructor (New). For example, the following statement throws an UnknownStatistic exception for the value ABCD:

throw %(unknownStatistic):new(Name='abcd')

In addition to the New constructor that creates an object instance, the class includes a Name property that returns the invalid statistic name.

Constant methods

Constant methods are methods that belong to system classes but are unique because they are evaluated at compilation time. These methods require constant inputs and may have no parameters, but they have no run-time overhead.

For example, the following Constant method sets %x to a string with hex value x'0678':

%x = '0678':x

The hex conversion is done at compilation time. The method in this example (named X) is a compile-time-only equivalent of the String intrinsic class HexToString method.

As other intrinsic methods, the term “method object” is used for the constant value to which a Constant method is applied, even though the value is not really an object.

Unlike other intrinsic methods, Constant methods may be invoked only against constants. A variable as method object is not allowed:

%x = %y:x

Also, a statement like %x = 1234:x is not allowed, because a Constant method requires the constant to have the correct datatype (in this case, String). Once a Constant method is evaluated, the expression compilation is replaced by the constant result of the evaluation, and all intermediate work quads/variables are deleted. Thus, '0d25':x is basically a hex constant.

The X function and the Unicode U constant function are the only Constant methods as of Sirius Mods version 7.3.

%out = string:X

Float intrinsic methods

Multiple new methods are added, as described in the following subsections. Many of the examples use the PrintText statement, which was introduced in Sirius Mods version 7.2 and is described in the Janus SOAP Reference Manual.

Absolute function

This function returns a number that is the absolute value of the method object.

%value = number:absolute
AntiLog function

This function returns a number that is the natural anti-logarithm (or exponential) of the method object value. The result is the natural logarithmic base (e) raised to the power of the method object value. AntiLogE is a synonym for AntiLog. The AntiLog function is an object-oriented version of the $EXP function, which is described in the Sirius Functions Reference Manual.

%value = number:antiLog
AntiLog10 function

This function returns a number that is the base-10 anti-logarithm (or 10's exponent) of the method object value. The result is (10), the base-10 logarithmic base, raised to the power of the method object value. The AntiLog10 function is an object-oriented version of the $EXP10 function, which is described in the Sirius Functions Reference Manual.

%value = number:antiLog10
AntiLog2 function

This function returns a number that is the base-2 anti-logarithm (or 2's exponent) of the method object value. The result is (2), the base-2 logarithmic base, raised to the power of the method object value. The AntiLog2 function is an object-oriented version of the $EXP2 function, which is described in the Sirius Functions Reference Manual.

%value = number:antiLog2
Div function

This function returns the integer part of the result of dividing the method object by the method argument. The numbers to be divided are first rounded to the nearest integer, including zero. Any remainder from the division is ignored.

%quo = number:Div(num)
IntegerToBinary function

This function converts an integer to its binary string representation. Only integers that convert to a string no longer than four characters are allowed.

%str = number:IntegerToBinary(num, [Signed=bool])
IsPrime function

This function returns a boolean value that indicates whether the method object value, rounded to an integer, is prime.

%bool = number:IsPrime
Log function

This function returns a number that is the natural logarithm (the logarithm base-e) of the method object value. LogE is a synonym for Log. The Log function is an object-oriented version of the $Log function, which is described in the Sirius Functions Reference Manual.

%value = number:log If number is not greater than zero, the request is cancelled.
Log10 function

This function returns a number that is the logarithm base-10 of the method object value. The Log10 function is an object-oriented version of the $Log10 function, which is described in the Sirius Functions Reference Manual.

%value = number:log10

If number is not greater than zero, the request is cancelled.

Log2 function

This function returns a number that is the logarithm base-2 of the method object value. The Log2 function is an object-oriented version of the $Log2 function, which is described in the Sirius Functions Reference Manual.

%value = number:log2

If number is not greater than zero, the request is cancelled.

Modulus function

This function returns the remainder from the division of the method object by the method argument. The numbers to be divided are first rounded to an integer, including zero, so the remainder is always an integer or zero. Mod is a synonym for Modulus.

%mod = number:Mod[ulus](num)
NextPrime function

This function returns the next prime number after the method object value.

%value = number:NextPrime

The method object value is initially rounded to the nearest integer before the next prime is determined.

PreviousPrime function

This function returns the prime number that immediately precedes the method object value.

%value = number:PreviousPrime

The method object value is initially rounded to the nearest integer before the preceding prime is determined.

ToFloatPower function

This function returns a number that is the method object value raised to the float power specified by the method argument.

The ToFloatPower function is an object-oriented version of the $RXPR function, which is described in the Sirius Functions Reference Manual.

%value = number:toFloatPower(exponent) ToFloatPower uses good-fit techniques that sometimes produce slightly different results from ToIntegerPower with the same inputs. For example:

3:toFloatPower(6) = 728.999999999999 3:toIntegerPower(6) = 729 10:toFloatPower(7) = 9999999.99999997 10:toIntegerPower(7) = 10000000

Consequently, you should generally use ToIntegerPower unless you are working with Float powers.

ToIntegerPower function

This function returns a number that is the method object value raised to the power specified by the method argument. The argument value is initially rounded to the nearest integral value. ToPower is a synonym for ToIntegerPower. The ToIntegerPower function is an object-oriented version of the $RXPI function, which is described in the Sirius Functions Reference Manual.

%value = number:toIntegerPower(exponent)

If number is 0 and exponent is less than or equal to 0, the request is cancelled.

String intrinsic methods

Multiple new methods are added, as described in the following subsections. Many of the examples use the PrintText statement, which was introduced in Sirius Mods version 7.2 and is described in the Janus SOAP Reference Manual.

BinaryToInteger function

This function treats a string as if it were binary and converts it to an integer. The string may contain no more than four characters.

%num = string:BinaryToInteger([Signed=bool])
Center function

The Center function is introduced. For a given input string and suitable specified length, this function returns a string of the requested length that has the original string embedded in the center. If the requested length is larger than the length of the input string, pad characters are added to the input string to produce the returned string. If the requested length is shorter, the input string's front and end are cropped to produce the returned string. Centre is a synonym for the Center function.

%out = string:Center(length, [Pad=char,] [OffsetLeft=bool]) Note: This method is much like the $Center function except in cases where an uneven number of characters is to be padded or cropped. $Center puts the extra character on the right when padding and on the left when cropping. The Center method by default puts the extra character on the right in both cases, and it provides an optional parameter if you want to use the left side instead for the extra character.
Char function

The Char function returns one byte of the method object string, at the position requested by its argument.

outStr = string:Char(position)

If the position exceeds the length of method object string, the request is cancelled; otherwise, Char is the same as the Substring function with the given position argument and with the length argument set to 1.

IsOneOf function

This function returns a Boolean value that indicates whether the method object string is matched by one of the strings in an input list of strings. The input list of strings is concatenated in a single delimited longstring argument to the method. A returned value of True signals a successful match.

%bool = stringoneof:(stringSet)
MD5digest function

Available to Janus SOAP or Janus Network Security users, this function returns the 16-byte (always) binary string that is the MD5 digest (hash) of the method object string.

MD5 (Message-Digest algorithm 5) is a well-known cryptographic hashing function which is used in the Janus Network Security product for digital signatures. A complete explanation of MD5 hashing can be found at Wikipedia http://en.wikipedia.org/wiki/MD5.

%outStr = string:MD5digest

The 16-byte MD5 hash of a string is typically expressed as a 32-digit hex value. In the following example, the output string from the MD5digest method is converted to hex using the stringToHex intrinsic method:

printText {'this is a test':md5digest:stringtohex}
RC4encrypt function

This function returns a binary string that is the method object string encrypted or decrypted with the specified RC4 encryption key. The length of the returned string is the same as that of the object string. RC4 is the default stream cipher (algorithm) used in Janus Network Security, and it may be used by customers who license Janus Network Security or Janus SOAP. RC4decrypt is a synonym for RC4encrypt; you can use the RC4decrypt synonym to “document” that you are decrypting rather than encrypting in a call.

RC4 is a two-way, or symmetric, cipher, so encrypting a string with a key and then encrypting the result of that encryption with the same key produces the original string. That is, the following assertion should always hold:

assert %string:rc4encrypt(%key):rc4decrypt(%key) eq %string
Replace and Remove functions

The Replace method replaces one or multiple occurrences of a substring of an input string (the method object) with a substitute string, and it returns the modified version of the input string. The Remove method removes one or multiple occurrences of a specified substring from an input string, and it returns the modified version of the input string.

%out = string:Replace(substring, replacement, [Count=num]) %out = string:Remove(substring, [Count=num])
Reverse function

The Reverse function returns the characters in the method object string in right-to-left order.

outStr = string:Reverse
SHAdigest function

Available to Janus SOAP or Janus Network Security users, this function returns the 20-byte (always) binary string that is the SHA digest of the method object string. SHA (Secure Hash Algorithm) is a set of cryptographic hashing functions. SHAdigest provides SHA-1, the most commonly used function as descibed in http://en.wikipedia.org/wiki/SHA_hash_functions.

%outStr = string:SHAdigest The 20-byte SHA hash of a string is typically expressed as a 40-digit hex value.
ToUpper and ToLower functions

The ToUpper and ToLower functions return the alphabetic characters in the method object string as all-uppercase or all-lowercase characters, respectively. Non-alphabetic characters are returned as is, and the input string undergoes no other change.

outStr = string:ToUpper outStr = string:ToLower
Translate function

The Translate method for longstrings is a method that is roughly equivalent to $lstr_translate. The Translate method takes a CharacterMap object as input. A CharacterMap object maps In (“input table”) characters to Out (“output table”) characters.

%outStr = string:translate(charMap)

In the following request, a's are translated to B's, and c's are translated to d's, as dictated by the character mapping in %map:

Begin %map is object characterMap %ls is longstring %map = new(in='ac',out='Bd') %ls = 'aaaccc' printtext {~} = '{%ls:translate(%map)}' End

The result is:

%ls:translate(%map) = 'BBBddd'
Unspace function

This function removes the whitespace characters from the method object string and it returns the resulting string. Options are available to:

  • Define which character or characters are to be interpreted as whitespace
  • Remove leading whitespace, trailing whitespace, both or neither
  • Collapse to a single whitespace character any sequences of non-leading, non-trailing whitespace

%outStr = string:Unspace( [Spaces=chars], - [Leading=bool], - [Trailing=bool], - [Compress=bool] )

Collections of Collections

New with this release, Collections may be members of Collections. The members of a collection of any type (ArrayList, NamedArrayList, FloatNamedArrayList) may themselves be collections of any single type.

To declare a collection of a collection, you name the container collection, then as its type you fully identify the member collections. For example:

%value is NamedArrayList of NamedArrayList of longstring

As this declaration suggests, the collection members must all be the same type of collection and item datatype.

Collections of collections are otherwise not different from other collections, although referencing them is more complicated. To operate on an item in a member collection, you might need to identify which item it is in its array, as well as which item the array is in the containing array.

For example, to update the items in %scores, an Arraylist of Float, you might use:

for %i from 1 to %scores:count %scores(%i) = %scores(%i) + 10 end for

To perform a similar operation for the items in %AllScores, an Arraylist of Arraylist of Float, you require an additional loop:

for %i from 1 to %AllScores:count for %j from 1 to %AllScores:item(%i):count %AllScores(%i)(%j) = %AllScores(%i)(%j) + 10 end for end for

And for collection %x, a NamedArrayList of NamedArrayList of Float, you might specify the following to print the value of the bar item of the namedArraylist whose item name in %x is foo:

print %x('foo')('bar')

If you use the syntax of the New function that explicitly indicates the class for a collection of collections, both the collection and item datatypes must be specified just as on the collection variable declaration:

%nal is collection namedArrayList of arraylist of longstring %nal = %(namedArrayList of arraylist of longstring):new

Daemon class UserStatistics method

This method returns the Model 204 User statistics for the thread associated with the daemon object. It is useful for metering a daemon or for determining table usage by a compilation done on the daemon thread. The daemon cannot be running asynchronously when this method is invoked. The method takes no arguments and returns a UserStatistics object.

%ustat = %daem:UserStatistics

Record class ToXmlDoc method

This method returns in a Janus SOAP XmlDoc object the fields and values of the method Record object. The method has options that let you:

  • Display field names in uppercase or lowercase
  • Output the field names as XML element names or as values of a name attribute of the field XML element
  • Output the field values as XML attributes or as XML text of the field XML element

The default is to display the field names as uppercase XML element names, with field values as XML text; for example: COMM.

%doc = %rec:ToXmlDoc([AttributeValues=bool,] - [AttributeNames=bool,] - [NamestoLower=bool,] - [AllowUnreversible=bool])

Usage Notes

  • If a field value contains non-displayable characters, the ToXmlDoc output data is automatically base64 encoded, and an attribute called encoding is added to the field's XML element with a value of base64.
  • The ToXmlDoc method will add BLOB values to the output XmlDoc, no matter how large they are. A BLOB field will have a reserved attribute added to the field element if more bytes were reserved in the BLOB than are in the actual value.
  • The ToXmlDoc method insists that the record object be locked at least in share mode, therefore it gets no locks while it operates.

    No locks are required for a sorted record or in single-user mode.

Examples

The display of field data below is produced by the following request

OPENC FILE CCASYS b %r is object record in file ccasys %r = new(1) %r:toXmlDoc:print %r:toXmlDoc(namesToLower=true):print %r:toXmlDoc(attributeValues=true):print %r:toXmlDoc(attributeValues=true, attributeNames=true, - namestoLower=true):print end

The following are sample results:

<Record file="CCASYS" number="1"> <APSURTYP>SDEF</APSURTYP> <APSUNM>SUBSYSMGMT</APSUNM> <APSUBUND>COMM</APSUBUND> <APSUERRC>ERROR</APSUERRC> <APSUEXIT>EXIT</APSUEXIT> <Record file="CCASYS" number="1"> <apsurtyp>SDEF</apsurtyp> <apsunm>SUBSYSMGMT</apsunm> <apsubund>COMM</apsubund> <apsuerrc>ERROR</apsuerrc> <apsuexit>EXIT</apsuexit> <Record file="CCASYS" number="1"> <APSURTYP value="SDEF"/> <APSUNM value="SUBSYSMGMT"/> <APSUBUND value="COMM"/> <APSUERRC value="ERROR"/> <APSUEXIT value="EXIT"/> <Record file="CCASYS" number="1"> <field name="apsurtyp" value="SDEF"/> <field name="apsunm" value="SUBSYSMGMT"/> <field name="apsubund" value="COMM"/> <field name="apsuerrc" value="ERROR"/> <field name="apsuexit" value="EXIT"/>

Changed default for SCRNSTBL user parameter

The default value of the SCRNSTBL user parameter is changed from 4096 to 6144. SCRNSTBL specifies the maximum amount of STBL space available to an application that uses a Screen object.

Implicit ToString calls for printing enumeration values

Prior to this release, the ToString method was the only way to return a string representation of the value of a Janus SOAP ULI enumeration. As of Sirius Mods 7.3, however, you no longer need to explicitly specify ToString to print the value of a system or user-defined enumeration. You can now simply print (or audit) the value of an enumeration, as shown in the following example:

b enumeration color public value red value white value blue value green end public end enumeration %x is boolean initial(true) %z is enumeration color initial(blue) %daem is object daemon %daem = new print %x with ' ' %z printText {~} = {%x}, {~} = {%z} print %daem:haveDaemon printText {~} = {%daem:haveDaemon} end

The Print and PrintText statements above produce these results:

True blue %x = True, %z = blue True %daem:haveDaemon = True

In addition, the implicit ToString feature extends beyond enumerations: upon any attempt to print or audit any object value, Janus SOAP ULI will try to apply a ToString method to the object. If the object is an enumeration (as shown above) or is an instance of a class that has a ToString method (say, a user-defined class) a ToString is implicitly applied and the result is a successful print or audit of the object value.

For example, the user-defined class in the following request includes a ToString method:

b class mumble public variable a is float variable b is float constructor new(%a is float nameRequired, %b is float) function tostring is longstring end public constructor new(%a is float nameRequired, %b is float) %this:a = %a %this:b = %b end constructor function tostring is longstring return 'a=' with %a with ', b=' with %b end function end class %x is object mumble %x = new(a=11, b=22) printText {~} = {%x} end When this request is run it produces the following output:

%x = a=11, b=22

If the object you try to print or audit directly is not an enumeration or is an instance of a class (system or user) for which no ToString method is written, you receive a compilation error. For example, if %sl is a StringList object, no user ToString method exists, and your request contains a Print %sl statement, you get a message like the following:

*** 1 MSIR.0733: Member TOSTRING not found in class STRINGLIST print %sl (FILE = JALWORK, PROCEDURE = FOO, LINE = 28) *** M204.1042: COMPILATION ERRORS

Janus SOAP Xml API

The following sections describe changes in the Janus SOAP Xml API in this release.

ASCII subset of Unicode

A pervasive change to XML processing in Janus SOAP is related to support of the full 8-bit ASCII (ISO-8859-1) character set, that is, all Unicode code points with a value less than U+0256 (see Unicode). The changes to XML processing for full 8-bit ASCII character set support are described in this section. Some of these changes can cause compatibility issues, please refer to the Notes for Sirius Mods Version 7.3 for more detailed information.

XPathOrder property removed

Previously, the XPathOrder property was available (with a default value of Unicode) to allow EBCDIC ordered string comparisons in XPath. This has now been removed, and it is a compatibility issue.

InvalidChar property deprecated; null and untranslatable characters not allowed

Previously, setting the InvalidChar property of an XmlDoc to Allow let you store any EBCDIC character in the value of an Attribute or Text node (using any “storing” method, such as Value or AddElement). This toleration of any character did not apply to deserialization.

Version 1.1 of the XML standard has a different approach than XML 1.0 regarding valid characters. For deserialization, it allows a character reference to any character, in particular including control characters (for example, &#x01;) — except not for the null character (x'00').

Therefore, in view of this loosening of the validity standard, the InvalidChar property has no effect in version 7.3 of the Sirius Mods, and it is now deprecated. That is, Sirius recommends that InvalidChar not be used, and at some future date it may be removed from the Janus SOAP XML API.

In all cases in version 7.3, Janus SOAP deserialization allows references to all non-null characters, except those Unicode/ASCII characters that do not translate to an EBCDIC character. (With the default Unicode-to-EBCDIC table, the only characters that do not translate to an EBCDIC character were also disallowed — as “control characters” — in previous versions of Janus SOAP.)

Any “storing” method in version 7.3 allows the storing of any non-null EBCDIC character that translates to Unicode.

Note: This change in character validity is a compatibility issue. Previously, if the InvalidChar property is set to Allow, you were able to store any EBCDIC character, including the null character and including a character that does not translate to Unicode.

Reference used to serialize control characters

Since the design of XML is to be human-readable, the serialization of all control characters (for example, U+0008, the Backspace character) now uses a character reference (in this example, &#x8;).

This is a compatibility issue. Previously, when a control character (other than tab, carriage return, or linefeed) occurs in an XmlDoc (which could only happen if it were added using a “store” method while the XmlDoc InvalidChar property is set to Allow), it is serialized “directly”, using the octet containing the control character.

Corrected translations

When translating between EBCDIC and ASCII/Unicode, the Janus SOAP XML API now correctly does the following:

  • Translates to and from EBCDIC for the ASCII/Unicode code points X'85' and X'A0' through and including X'FF'.
  • Identifies the other code points in the range X'80' through and including X'9F' as not being translatable to EBCDIC.

Previously, all translations in this ASCII range (X'80' – X'FF') except X'A2' were incorrect (Unicode U+0080 - U+00FF: 8 bit ASCII mentions some of the types of characters in this range). For translation from EBCDIC, many code points now translate to a character in the range X'85' – X'FF'; previously these EBCDIC code points did not translate to an ASCII/Unicode character.

Note that the above comments about translations apply for most of the codepages, with no additional customization. Both the codepage to use and any additional customization can be specified during Model 204 initialization with the UNICODE command (see UNICODE command).

AllowXmlElement to deserialize "xml.." element names

When this XmlDoc property is set to True, you can deserialize an XML document into the XmlDoc even if the document contains elements whose names use the reserved character sequence xml (in any case) as the start of the element name.

Elements whose name begins with “xml” were restricted due to the following excerpt from the XML standard:

Names beginning with the string "xml", or any string which would match (('X'|'x') ('M'|'m') ('L'|'l')), are reserved for standardization in this or future versions of this specification.

Therefore you should use care with element names: using an element name such as XML makes you vulnerable to a change in the standards that would leave your document incompatible with them.

Note: This property does not allow the AddElement method to add an element with a name that starts with “xml”. However, it is easy to use the LoadXml method to accomplish this:

%doc:AllowXmlElement = True %node:LoadXml('<XML/>')

ToXpathString and ToXpathStringList methods

Two new methods are added to the XmlDoc and XmlNode classes: ToXpathString and ToXpathStringList.

ToXpathStringList is simply a synonym for the existing XpathNodeID method.

ToXpathString performs the same function as XpathNodeid (returns an absolute XPath expression), but instead of returning a StringList like ToXPathStringList, it returns a string. If the Stringlist returned from ToXpathStringList would contain multiple items, the string returned from ToXpathString in the same context would contain blank-delimited substrings.

The ToXpathString syntax, where %str is a string or longstring variable and nr is an XmlDoc or XmlNode object, is:

%str = nr:ToXpathString([selection_XPath]) Note: The impetus for creating the ToXpathString method is to allow SirFact, Janus Debugger, and Sirius Debugger users to extract XPath information when needed. The XPathNodeID method does not work in those environments because of its object (StringList) output.

OmitNullElement in serialization methods

The new OmitNullElement option of the Xml serialization methods (Print, Serial, WebSend, Xml) has the following restrictions and effect:

  • The OmitNullElement option may not be specified if ExclCanonical is specified.
  • When OmitNullElement is specified, an Element node that has no children and no Attributes is not serialized, unless it is the top level Element in the subtree being serialized.
  • Whether or not the serialization of an Element would contain Namespace declarations in its start tag has no effect on the suppression of the serialization of the Element.
  • OmitNullElement is not “transitive”; that is to say, if a (parent) Element node has no Attributes, and has only Element children (and it has one or more) and all of its children are Attribute-free and child-free, then that parent Element is serialized, even though its content in the serialization is empty.
  • If, in the previous case, an Element is serialized with empty content, it is serialized with a start tag and an end tag (and, if the serialization method inserts them, a line separator).

For example, given the following User Language fragment:

%d Object XmlDoc Auto New %l Object Stringlist Auto New Text To %l <top> <middle> <empty/> <p:empty2 xmlns:p="uri:stuff"/> </middle> </top> End Text %d:LoadXml(%l) Print 'Entire XmlDoc:' %d:Print(, 'OmitNullElement') Print 'Empty Element as top of subtree:' %d:Print('*/*/*', 'OmitNullElement')

The resulting output is:

Entire XmlDoc: <top> <middle> </middle> </top> Empty Element as top of subtree: <empty/>

Unicode

Traditional representation of characters has relied on 8-bit character codes, but an 8-bit character code only allows representation of at most 256 characters. With the need to represent many special-purpose characters and characters of many languages, 8-bit character sets have become strained to represent all necessary characters.

This has led to the use of multiple 8-bit code sets: in EBCDIC, using multiple code pages, and in ASCII, a variety of ISO-8859-x character sets. It has also led to the use of escape sequences where it is absolutely necessary (for example, with Kanji characters) to use more than 8 bits to represent a single character.

The Unicode standard (or ISO-10646) establishes a new character encoding scheme, and various representations for character codes, to allow for over 1 million characters. The first Unicode standard was published in 1990 (Unicode 1.0) and has evolved since then. The list of Unicode versions is available on the Internet at: http://www.unicode.org/versions/enumeratedversions.html

A useful table of Unicode characters for Unicode Version 5.1 can be found at: http://unicode.org/Public/5.1.0/ucd/UnicodeData.txt

Unicode is becoming ubiquitous; it is used as the encoding scheme on most non-mainframe applications, and over time, more and more Model 204 applications will need to accept Unicode data. Unicode also provides an important reference point. For example, you can discuss the square bracket character codes, U+005B and U+005D, without concern about the code page being used.

Version 7.3 of the Sirius Mods introduces support for Unicode, consisting of:

  • A UNICODE command to allow:
    • Customization, during Model 204 initialization, of Unicode tables (which specify translations between EBCDIC and Unicode/ASCII) and of replacement of Unicode characters.
    • Display of these customizations.
  • A new intrinsic data type: Unicode A string of type Unicode can contain any of the characters in Unicode's Basic Multilingual Plane, consisting of the code points U+0000 through and including U+FFFD, which cover most languages and characters.
  • A set of functions that operate on Unicode strings, return Unicode results, or are based on the Unicode tables.
  • Automatic conversion between Unicode strings and other User Language intrinsic types (String, Longstring, Float, Fixed).
  • An exception class for cases in which a conversion fails, for example when an attempt is made to translate a character from one code set to another that does not have a corresponding character.
  • Use of the Unicode tables to control XmlDoc serialization and deserialization, as well as XPath processing.

Using the UNICODE command for some common problems

Before the complete discussion of Unicode and its support in version 7.3 of the Sirius Mods, some applications of the UNICODE command are presented. For the full syntax of the UNICODE command, see UNICODE command.

A number of incorrect translations involving XML in earlier versions of the Sirius Mods have been corrected in version 7.3. These changes are intended to improve the quality of data that is handled by the Janus SOAP processing of XML documents, but there are some cases in which the changes can cause problems for customer applications. A discussion of some common problems and possible workarounds follows.

Invertible translations

An invertible translation occurs when a code point in one code set translates to a code point in another code set, and the translation of that other code point is the original code point. It is strongly desirable that all translations being used are invertible. This helps enforce data quality, simplicity of application programming, understandability of the Unicode translation tables, and consistent “round-tripping” of XML documents. All translations in the supported codepages are invertible.

Note: Standardizing on a single code page and correcting all User Language code to use that code page will ensure invertible translations and is the long term direction that Sirius recommends. However, because the correct translation of “special characters” has only recently become important, it is quite possible that a variety of translation issues have crept into User Language applications. The following discussions of workarounds show how non-invertible translations can be used to temporarily bypass common translation issues. It is important that you recognize these as temporary workarounds and that the d best long term solution is to achieve fully invertible translations using a standard codepage.

In the UNICODE command, an invertible translation, or a two-way translation or mapping, is specified with the Map form of the UNICODE updating command. (Note, however, that specifying a Map subcommand can cause an existing mapping to become uninvertible; see Vertical bar vs. broken bar.)

When a translation is uninvertible, unusual results can occur, and there can be cases of this in ealier versions of Janus SOAP. For example, if you employ the dual square bracket workaround described below and your base codepage is 1047, then the following request fragment shows how a character value can change merely by being serialized and then deserialized:

%d Object XmlDoc Auto New %s Longstring * Value is "secondary" left square bracket: %d:AddElement('x', 'BA':X) Print 'Before round trip, hex value:' And %d:Value:StringToHex %s = %d:Serial %d = New %d:LoadXml(%s) Print 'After round trip, hex value:' And %d:Value:StringToHex The result of the above fragment is:

Before round trip, hex value: BA After round trip, hex value: AD
Consistent XPath predicate errors — wrong codepage?

If you are receiving MSIR messages indicating “error processing XPath expression,” especially if that message is preceded by a message indicating “Invalid name character,” you may be using a different set of EBCDIC square brackets than those used by default in XML processing in version 7.3 of Janus SOAP.

Probably the best way to determine this is to run the following ad hoc request:

Begin Print $C2X('[]') End The result should be either BABB or ADBD.

  • If the result is BABB, then your terminal is probably using codepage 0037 (or, in the United Kingdom, codepage 0285). You can change the Sirius Mods Unicode processing to use that codepage by inserting the appropriate following command as part of Model 204 initialization:

    UNICODE Table Standard Base Codepage 0037

    or, in the UK:

    UNICODE Table Standard Base Codepage 0285

    If this resolves your XPath problems, all applications are likely to be consistently using square brackets from codepage 0037 or 0285. If there are still some XPath errors, then the applications may be inconsistent, with some using the 0037/0285 brackets, and some using the 1047 brackets.

  • If the result is ADBD, then your terminal is probably using codepage 1047, the same as the Sirius Mods Unicode default. This is probably a good indication that your applications may be inconsistent, with some using the 0037/0285 brackets, and some using the 1047 brackets.
XPath predicate errors even after setting proper codepage

If either of the following is true, you may benefit from temporarily using both common sets of square brackets in the Unicode tables:

  • You have determined the proper codepage to use as described above, and you are still getting the XPath errors indicative of codepage mismatch.
  • You have a mixture of codepages used by User Language programmers.

In the longer term, you should attempt to standardize the codepages used by User Language programmers and correct the square brackets in User Language applications so that you can remove this workaround.

If your base codepage is 1047

If your base codepage is 1047, you can use the following commands to add the alternate square brackets:

* Support codepage 0037 square brackets when 1047 is base * codepage - used until setting consistent square brackets: UNICODE Table Standard Trans E=BA To U=005B UNICODE Table Standard Trans E=BB To U=005D * Since codepage 1047 usually maps E=BA/BB to U=DD/A8, make * those Unicode points invalid, rather than have yet more * uninvertible translations: UNICODE Table Standard Trans U=00DD Invalid UNICODE Table Standard Trans U=00A8 Invalid
If your base codepage is 0037

If your base codepage is 0037, you can use the following commands to add the alternate square brackets:

* Support codepage 1047 square brackets when 0037 is base * codepage - used until setting consistent square brackets: UNICODE Table Standard Trans E=AD To U=005B UNICODE Table Standard Trans E=BD To U=005D * Since codepage 0037 usually maps E=AD/BD to U=DD/A8, make * those Unicode points invalid, rather than have yet more * uninvertible translations: UNICODE Table Standard Trans U=00DD Invalid UNICODE Table Standard Trans U=00A8 Invalid
If your base codepage is 0285

It is somewhat unusual to have mixed codepages among User Language programmers when the base codepage is 0285, but since the square bracket mappings for 0285 are the same as 0037, you can use the same approach as shown above for 0037. For the sake of consistency, you should change “0037” in the comment to “0285”.

Vertical bar vs. broken bar

The common translations for the vertical bar character (|) and for the broken bar character (¦) are shown in the following excerpt of the output of the UNICODE Display Codepage xxxx command (where xxxx is any of the common codepages: 1047, 0037, or 0285):

* .. Map E=4F Is U=007C Vertical bar * .. Map E=6A Is U=00A6 Broken bar

For these common codepages, the above translations are used in version 7.3 of Janus SOAP for XML processing. However, in earlier versions the translations are not correct:

  • EBCDIC vertical bar (X'4F') is correctly translated to ASCII X'7C'.
  • ASCII vertical bar (X'7C') is incorrectly translated to EBCDIC X'6A', the broken bar.
  • EBCDIC broken bar (X'6A') is incorrectly translated to ASCII X'7C', the vertical bar.
  • ASCII broken bar (X'A6') is incorrectly translated to EBCDIC X'50', the ampersand.

    Note: This is but one example of the fact that in prior versions of the Sirius Mods, almost all translations of ASCII code points greater than X'7F' are incorrect.

The concern is that you may have applications that depend on these incorrect translations. In the following discussion, the term “solid bar” is used for the vertical bar character, to help contrast it with the broken bar character.

Search your applications for instances of broken bars:

  • If the broken bar is being used, for example, as a delimiter of items of a value in an XmlDoc received in ASCII, UTF-8, or UTF-16 (say, with the XmlDoc WebReceive method or the HttpResponse ParseXml method), then the document was probably sent with an ASCII solid bar, which was incorrectly translated to EBCDIC broken bar by Janus SOAP.
  • If the broken bar is being used, for example, to populate an XmlDoc that will be sent in UTF-8 (say, with the XmlDoc WebSend method, or the HttpRequest AddXml method), then with prior versions of Janus SOAP the document would have been sent with an ASCII solid bar.

The proper long-term fix to your application is probably to use solid bar rather than broken bar in the above two cases.

The next two subsections discuss the technique for searching your applications for broken bars, and a workaround to use if you are not able to fix your applications at the time that you install version 7.3 of the Sirius Mods.

Searching for broken bar
  1. Run the following ad hoc request:

    Begin Print $C2X('6A') End
  2. “Copy” the result character to your clipboard, for example, by highlighting it and pressing ctl-C.
  3. Go to a procedure search facility, such as SirPro, and “paste” the character as the search string.

    Note: Probably due to odd behavior in some tn3270 packages, you should place the cursor after the broken bar in the search string and delete the blank.

  4. After you have a list of procedures containing the broken bar, edit them and paste the broken bar after a slash (/) in the editor command line to locate the specific lines where they occur.
Perpetuate bad vertical/broken bar translations

If you have applications with broken bars that need to be fixed when using version 7.3 of Janus SOAP, but you are unable to make those changes at that time, you can use the UNICODE command as follows to modify the Unicode tables to mimic some of the translations used by earlier versions. Place the following lines in your Model 204 initialization stream:

* EBCDIC broken bar goes to Unicode vertical bar, and * vice-versa (used until setting consistent vertical/ * broken bars) - note that EBCDIC vertical bar * translates to Unicode vertical bar in the base table: UNICODE Table Standard Map E=6A Is U=007C Note: The above Map subcommand causes uninvertible translations in the Unicode tables: neither the translation from EBCDIC X'4F' to Unicode U+007C, nor the translation from Unicode U+00A6 to EBCDIC X'6A' is invertible. These translations should be viewed as temporary workarounds until the characters can be fixed up in the User Language programs.

Code points, character set mappings

A code point is simply one of the numeric values in the range of a character set encoding scheme.

In EBCDIC, an 8-bit character set, code points vary from X'00' through and including X'FF'. As an example, the character “A” is mapped to the EBCDIC code point X'C1'.

In ASCII, also an 8-bit character set, code points also vary from X'00' through and including X'FF'. As an example, the character “A” is mapped to the ASCII code point X'41'. The first 128 code points (X'00' through X'7F') have well-defined mappings; for code points X'80' through X'FF', the mappings depend on the “flavor” of ASCII being employed (ISO-8859-1 through ISO-8859-9).

In Unicode, the customary way to represent a code point is U+hhhhhh, where hhhhhh is the hexadecimal representation of the value of the code point. As an example, the “trademark” character is mapped to the code point U+2122. Note that the first 256 code points in Unicode have the same mappings as the code points in ISO-8859-1; for this reason, we may use the U+hh notation to refer to ASCII code points.

Some characters are simple to deal with; here are some common EBCDIC and corresponding ASCII mappings (note that these ASCII code points are all less than X'80'):

EBCDIC X'40' <-> ASCII X'20' (space) EBCDIC X'F0' <-> ASCII X'30' (zero) EBCDIC X'C1' <-> ASCII X'41' (uppercase A) EBCDIC X'81' <-> ASCII X'61' (lowercase A)

Unicode U+0080 - U+00FF: 8 bit ASCII

In previous versions of the Sirius Mods, all translation between EBCDIC and ASCII (other than the customization available with the JANUS LOADXT command) was based on tables that ignored all but one ASCII code point greater than X'7F' (the code point for the “cent sign”). Please refer to the section titled “Corrected translations between ASCII/Unicode and EBCDIC” in the Notes for Sirius Mods Version 7.3 for information about various translations that have been corrected.

As of 7.3 of the Sirius Mods, parsing an XML document and non-EBCDIC serialization of an XmlDoc is performed using the corrected translation tables. The actual translations used can be controlled with the UNICODE command during Model 204 initialization, chiefly by selecting the codepage to use.

The common codepages are:

0037
For the USA, Australia, Canada, ...
0285
For the UK
1047
Latin/1 Open Systems for USA, Australia, Canada, ...
If it is not changed by the UNICODE command, codepage 1047 is used. You can see the EBCDIC code point mappings using the “IBM yellow card”: http://publibfp.boulder.ibm.com/epubs/pdf/dz9zs000.pdf

EBCDIC column 5 of that yellow card corresponds to codepage 1047.

Here are some examples of Unicode characters in the range U+80 through U+FF:

  • U+A2: cents sign
  • U+A3: pound (sterling) sign
  • U+A5: Chinese Yuan or Japanese Yen
    (See ISO 4217 for actual currency designations such as USD for “US Dollars,” JPY for “Japanese Yen,” CNY for “Chinese Yuan,” and so on.)
  • U+A9: copyright symbol
  • U+BC: small fraction 1/4
  • U+C1: acute capital A

Unicode: a new User Language type

Version 7.3 of the Sirius Mods introduces a new intrinsic data type, Unicode. A string of type Unicode can contain any of the characters in Unicode's Basic Multilingual Plane (any of the code points U+0000 through and including U+FFFD) which covers most languages and characters.

Each character in a Unicode string occupies 2 bytes.

Values X'D800' through X'DFFF' are used in Unicode for surrogate pairs (not supported in version 7.3 of the Sirius Mods). Values X'FFFE' and X'FFFF' are not characters. So the valid code points of a character in a Unicode string are as follows:

  • U+0000 through U+D7FF
  • U+E000 through U+FFFD
UTF-8 and UTF-16

Any Unicode character can be represented using UTF-8 or UTF-16. As their names imply, these representations use items of 8 or 16 bits in length, respectively.

When using one of the User Language intrinsic functions (Unicode intrinsic functions) to convert between a Unicode string and a UTF-8 or UTF-16 stream, UTF-8 or UTF-16 is stored as a byte stream, in a User Language String or Longstring value.

For conversion from a Unicode string to UTF-8, each character of the UTF-8 representation uses from 1 to 3 bytes per character. This is the most common encoding of Unicode sent over the Internet and usually results in the most compact byte stream.

For conversion from a Unicode string to UTF-16, each character of the UTF-16 representation uses 2 bytes per character. For most commonly used characters, this representation is longer than a UTF-8 representation.

ASCII conversion

User Language programs and Janus Web Server operations have employed translation between ASCII and EBCDIC for many years. Unfortunately, these translations have historically been incorrect for many seldom-used code points.

Version 7.3 of the Sirius Mods corrects the translations for XmlDocs, and it also provides two String intrinsic functions to perform correct translation: EbcdicToAscii AsciiToEbcdic.

Since they are both 8-bit code sets, in principle there need not be untranslatable characters between ASCII and EBCDIC. In fact, however, there are about 30 code points in each which represent characters that do not have representations in the other character set. For example, the EBCDIC code point X'FF' is the EO (“Eight Ones”) control character; there is no ASCII EO control character (ASCII X'FF' is the small letter “y with diaeresis” which corresponds to EBCDIC X'DF').

Besides providing correct translations when they exist, the EbcdicToAscii and AsciiToEbcdic functions throw an exception (CharacterTranslationException exception class) when a character cannot be translated.

AsciiToEbcdic alternatively allows encoding of untranslatable characters using the XML “character reference” mechanism. UnicodeToEbcdic also allows this. The character references can be converted back to ASCII or Unicode by, respectively, EbcdicToAscii or EbcdicToUnicode.

Unicode and Unicode-related intrinsic methods

Janus SOAP support for the Unicode data type includes intrinsic functions that operate on Unicode strings, return Unicode results, or are based on the Unicode tables. These functions are described in the sections below.
Unicode intrinsic functions

These methods treat their method object as a string of type Unicode.

UnicodeReplace

This function gets the Unicode string resulting from applying the Unicode replacement table to the input Unicode string.

%unicode = unicode:UnicodeReplace

Where:

  • The intrinsic method object input is a Unicode string.
  • The result is the input Unicode string, with those characters specified in the Unicode replacement table replaced by their corresponding Unicode strings.

By default (that is, when there is no Unicode replacement table), this function merely copies its input.

Example:

UNICODE Table Standard Rep U=2122 '(TM)' Begin %u Unicode Initial('Cool&#x2122;':U) Print %u:UnicodeReplace End The result is:

Cool(TM)

Note that an updating UNICODE command is shown here “in-line” with a User Language request, to make the example concrete. In actual usage, updating UNICODE commands should only be issued from your Model 204 initialization stream.

UnicodeToEbcdic

This function converts a Unicode string to EBCDIC.

%ebcdic = unicode:UnicodeToEbcdic([CharacterEncode=bool])

Where:

  • The intrinsic method object input is a Unicode string.
  • The optional (name required) CharacterEncode argument is a Boolean:
    • If False, the default, an exception is thrown if the input contains any Unicode character not translatable to EBCDIC.
    • If True, any Unicode character not translatable to EBCDIC is replaced with the hexadecimal character reference of the character, and the ampersand character is replaced with &amp;. For example, the eight characters &#x201C; “left double-quotation mark.”
  • The result is the input string translated to EBCDIC — with untranslatable characters represented with character references, if CharacterEncode=True.

This function throws a CharacterTranslationException exception (CharacterTranslationException exception class) if an input character cannot be translated or encoded.

Note: Unless the CharacterEncode argument is used, or you want to Catch a CharacterTranslationException, this function is generally not needed, because a Unicode string is implicitly converted to EBCDIC when used in an EBCDIC context.

Example:

%u Unicode Initial('&#x31;':U) * Note: "Print %u" gives the same result as the following: Print %u:UnicodeToEbcdic %u = '1&#x80;2':U Print %u:UnicodeToEbcdic(CharacterEncode=True) * Note: "Print %u" cancels the request as well: Print %u:UnicodeToEbcdic The result of the above fragment is:

1 1&#x0080;2 CANCELLING REQUEST: MSIR.0751: Class STRING, function UNICODETOEBCDIC: CHARACTER TRANSLATIONEXCEPTION exception: Unicode character U+0080 without valid translation to EBCDIC at byte position 5 ...
UnicodeToUtf16

This function converts a Unicode string to a UTF-16 Longstring byte stream.

%utf16Stream = unicode:UnicodeToUtf16([InsertBOM=bool])

Where:

  • The intrinsic method object input is a Unicode string.
  • The optional (name required) InsertBOM argument is a Boolean. If its value is True, the “Byte Order Mark” (U+FEFF) is inserted at the start of the output stream. If False, the default, no Byte Order Mark is inserted.
  • The result is the input Unicode string transformed to a UTF-16 Big-Endian byte stream (that is, any Unicode point U+wxyz results in the pair of bytes X'wx' and X'yz', in that order).

Example:

%u Unicode Initial('&#x31;':U) Print %u:UnicodeToUtf16:StringToHex The result of the above fragment is:

0031
UnicodeToUtf8

This function converts a Unicode string to a UTF-8 Longstring byte stream.

%utf8Stream = unicode:UnicodeToUtf8([InsertBOM=bool])])

Where:

  • The intrinsic method object input is a Unicode string.
  • The optional (name required) InsertBOM argument is a Boolean. If its value is True, the “Byte Order Mark” (U+FEFF, encoded as X'EFBBBF') is inserted at the start of the output stream. If False, the default, no Byte Order Mark is inserted.
  • The result is the input Unicode string transformed to a UTF-8 byte stream.

This method may throw a CharacterTranslationException exception (CharacterTranslationException exception class).

Example:

%u Unicode Initial('&#xB2;':U) Print %u:UnicodeToUtf8:StringToHex

The result of the above fragment is:

C2B2
UnicodeUntranslatablePosition

This function finds the character position of the first character in the input Unicode string that is not translatable to EBCDIC.

%position = unicode:UnicodeUntranslatablePosition

Where:

  • The intrinsic method object input is a Unicode string.
  • The result is either of the following:
    • 0, indicating that all of the input Unicode characters are translatable to EBCDIC.
    • The character position of the first character that is not translatable to EBCDIC. Position 1 is the first character in the string.

Example:

%u Unicode Initial('A&#x80;B':U) Print %u:UnicodeUntranslatablePosition

The result of the above fragment is:

2
String intrinsic functions with Unicode result

These methods return a string of type Unicode.

EbcdicToUnicode

This function converts an EBCDIC string to Unicode.

%unicode = string:EbcdicToUnicode([CharacterDecode=bool])

Where:

  • The intrinsic method object input is a Longstring, presumed to contain an EBCDIC character string.
  • The optional (name required) CharacterDecode argument is a Boolean. If its value is True, an ampersand (&) is allowed in the input EBCDIC string only in two ways:
    • As the substring &amp;. This substring is converted to '&'.
    • At the start of a hexadecimal character reference (for example, the eight characters '&#x201C;' for the Unicode “Left double quotation mark”). The character reference is converted to the referenced character.

    The default is False.

  • The result is the input string translated to Unicode — with character references and &amp; references converted to the represented Unicode character, if CharacterDecode=True.

This function may throw a CharacterTranslationException exception (CharacterTranslationException exception class).

Example:

%e String Len 20 %u Unicode %e = '12' %u = %e:EbcdicToUnicode Print %u:UnicodeToUtf16:StringToHex %e = '1&#x2122;2' %u = %e:EbcdicToUnicode(CharacterDecode=True) Print %u:UnicodeToUtf16:StringToHex %e = 'F1FFF2':X %u = %e:EbcdicToUnicode

The result of the above fragment is:

00310032 003121220032 CANCELLING REQUEST: MSIR.0751: Class STRING, function EBCDICTOUNICODE: CHARACTER TRANSLATIONEXCEPTION exception: EBCDIC character X'FF' without valid translation to Unicode at byte position 2 ...
U constant function

Similar to the hexadecimal constant function X, U is a constant function that allows you to specify a Unicode constant.

%unicode = stringWithRefs:U

Where:

  • The constant character string method object of the U function can contain character references. An ampersand (&) is allowed in the following cases:
    • As the substring &amp;. This substring is converted to '&'.
    • At the start of a hexadecimal character reference (for example, the eight characters '&#x201C;' for the Unicode “Left double quotation mark”). The character reference is converted to the referenced character.

Example:

* Constant for trademark symbol: %tm Unicode Initial('&#x2122;':U) Print %tm:UnicodeToUtf16:StringToHex

The result of the above fragment is:

2122
Utf16ToUnicode

This function converts a UTF-16 Longstring byte stream to Unicode.

%unicode = utf16Stream:Utf16ToUnicode

Where:

  • The intrinsic method object input is a Longstring, presumed to contain a UTF-16 byte stream.
  • The result is the input UTF-16 byte stream converted to Unicode.

This function may throw a CharacterTranslationException exception.

Note: The input UTF-16 stream may contain a Byte Order Mark (U+FEFF). If one is present, that controls the conversion from UTF-16 to Unicode. If a Byte Order Mark is not present, the input stream is considered to be a Big Endian stream, that is, it is the same as if the stream were preceded by the two bytes X'FE' and X'FF', in that order.

For example:

%u Unicode %u = '0032':X:Utf16ToUnicode Print %u The result of the above fragment is:

2
Utf8ToUnicode

This function converts a UTF-8 Longstring byte stream to Unicode.

%unicode = utf8Stream:Utf8ToUnicode

Where:

  • The intrinsic method object input is a Longstring, presumed to contain a UTF-8 byte stream.
  • The result is the input UTF-8 byte stream converted to Unicode.

This method may throw a CharacterTranslationException.

Example:

%u Unicode %u = '32':X:Utf8ToUnicode Print %u

The result of the above fragment is:

2
Other Unicode-related intrinsic functions

These intrinsic String methods rely on the Unicode translation tables as optionally modified by the UNICODE command.

AsciiToEbcdic

This function converts an ASCII (ISO-8859-1) string to EBCDIC.

%ebcdic = asciiString:AsciiToEbcdic([CharacterEncode=bool])

Where:

  • The intrinsic method object input is a Longstring, presumed to contain an ASCII string.
  • The optional (name required) CharacterEncode argument is a Boolean:
    • If its value is False, the default, an exception is thrown if the input contains any ASCII character not translatable to EBCDIC.
    • If its value is True, any ASCII character not translatable to EBCDIC is replaced with the hexadecimal character reference of the character, and the ampersand character is replaced with &amp;. For example, the six characters '&#x84;' replace the ASCII “INDEX” control character.
  • The result is the input string translated to EBCDIC — with untranslatable characters represented with character references, if CharacterEncode=True.

This function may throw a CharacterTranslationException exception (further described CharacterTranslationException exception class).

Example:

%a String Len 20 %a = '31':X Print %a:AsciiToEbcdic %a = '318032':X Print %a:AsciiToEbcdic(CharacterEncode=True) Print %a:AsciiToEbcdic The result of the above fragment is:

1 1&#x80;2 CANCELLING REQUEST: MSIR.0751: Class STRING, function ASCIITOEBCDIC: CHARACTER TRANSLATIONEXCEPTION exception: ASCII character X'80' without valid translation to EBCDIC at byte position 1 ...
EbcdicToAscii

This function converts an EBCDIC string to ASCII (ISO 8859-1).

%ascii = string:EbcdicToAscii([CharacterDecode=bool])

Where:

  • The intrinsic method object input is a Longstring, presumed to contain an EBCDIC character string.
  • The optional (name required) CharacterDecode argument is a Boolean: If its value is True, an ampersand (&) is allowed in the input EBCDIC string only in two ways:
    • As the substring &amp;. This substring is converted to '&'.
    • At the start of a hexadecimal character reference (for example, the six characters '&#x84;' for the ASCII “INDEX” control character). The character reference is converted to the referenced character.

    The default is False.

  • The result is the input string translated to ASCII — with character references and &amp; references converted to the represented ASCII character, if CharacterDecode=True.

This function may throw a CharacterTranslationException exception.

Example:

%e String Len 20 %a String Len 20 %e = '12' %a = %e:EbcdicToAscii Print %a:StringToHex %e = '1&#x0A;2' %a = %e:EbcdicToAscii(CharacterDecode=True) Print %a:StringToHex %e = 'F1FFF2':X %a = %e:EbcdicToAscii

The result of the above fragment is:

3132 310A32 CANCELLING REQUEST: MSIR.0751: Class STRING, function EBCDICTOASCII: CHARACTER TRANSLATIONEXCEPTION exception: EBCDIC character X'FF' without valid translation to ASCII at byte position 2 ...
EbcdicRemoveNonUnicode

This function removes the bytes from the EBCDIC input string that do not translate to Unicode.

%string = string:EbcdicRemoveNonUnicode

Where:

  • The intrinsic method object input is a Longstring, presumed to contain an EBCDIC character string.
  • The result is the input string with the bytes removed that are not translatable to Unicode.

This function is useful because there is no way to convert to Unicode an EBCDIC string that contains untranslatable characters.

Example:

%e String Len 20 %e = 'C1FFC2':X Print %e:EbcdicRemoveNonUnicode

The result of the above fragment is:

AB
EbcdicTranslateNonUnicode

This function replaces any bytes from the EBCDIC input string that do not translate to Unicode. Non-translatable bytes are replaced with the character specified as the function argument.

%string = string:EbcdicTranslateNonUnicode(char)

Where:

  • The argument is a one-character EBCDIC string, which is used to replace untranslatable input characters.
  • The result is a copy of the input string, but with each input byte that is not translatable to Unicode replaced by an occurrence of the specified argument character.

This function throws a CharacterTranslationException if the argument character is not translatable to Unicode.

EbcdicTranslateNonUnicode is useful because there is no way to convert to Unicode an EBCDIC string that contains untranslatable characters.

Example:

%e String Len 20 %e = 'C1FFC2':X Print %e:EbcdicTranslateNonUnicode('?') The result of the above fragment is:

A?B

CharacterTranslationException exception class

Various methods throw a CharacterTranslationException exception when they encounter character translation problems. To avert request cancellation, you can catch such an exception, optionally catching to an object of this class.

This class has the following read-only properties:

Reason
A TranslationExceptionReason enumeration instance.
BytePosition
A number that indicates the postion (starting with 1) of the byte at which the exception was thrown.
CharacterPosition
A number that indicates the position (starting with 1) of the character at which the exception was thrown. The number of bytes that constitute a character depends on the type of string that causes the exception:
  • If EBCDIC, one byte corresponds to one character.
  • If Unicode, two bytes correspond to one character.
  • If UTF-16, two bytes correspond to one character.
  • If UTF-8, the relationship between bytes and characters is variable, depending on the code points.
HexValue
A string that contains the hexadecimal representation of the bytes that caused the exception to be thrown.
Description
A string that contains a brief description of the exception.

This class has the following constructor:

New
This constructor's syntax follows. The arguments set the values of the properties of the class that have the corresponding names.

%charTransExceptObj = [(CharacterTranslationException)]: - New ( [Reason = reasonEnum,] - [BytePosition = number,] - [CharacterPosition = number,] - [Description = string] - )

TranslationExceptionReason enumeration

The values of this class are returned by the Reason function of the CharacterTranslationException exception class. The enumeration values in this class are as follows:

InvalidEncoding
An example of invalid encoding is UTF-16 string input to Utf16ToUnicode that contains bytes whose hexadecimal value is D800 (that is, in the surrogates range).
InvalidCharacterReference
For example, EbcdicToUnicode is called specifying CharacterDecode=True, and the input contains an ampersand (&) followed by a space.
UntranslatableCharacter
As examples (with the translation tables as delivered by Sirius):
  • The EBCDIC input to the EbcdicToUnicode method contains a byte whose hexadecimal value is X'FF.
  • The Unicode input to UnicodeToEbcdic contains one of the many Unicode characters that is not translated to an EBCDIC character (for example, U+20AC, the Euro currency symbol).

As do all enumeration classes, this class also contains the ToString method, which converts an enumeration value to a character string whose value is the name of the enumeration value.

UNICODE command

The UNICODE command is used to manage the Unicode tables, effecting the following:

  • Translation between Unicode and EBCDIC and between ASCII and EBCDIC.
  • Replacement of Unicode characters by designated character strings.

In the descriptions of the UNICODE command that follow:

  • h2 is two hexadecimal digits.
  • hex4 is four hexadecimal digits, excluding FFFE, FFFF, and the surrogate areas (D800 through and including DFFF).
  • As a Model 204 command, the term “UNICODE” that starts the UNICODE command must be entered entirely in uppercase letters. The other keywords of the UNICODE command may be entered in any mixture of uppercase or lowercase letters.

    The command descriptions below use an initial capital letter to indicate a keyword, and they use all-lowercase letters to indicate a term that is substituted for a particular value in the command.

The various forms of the UNICODE command are:

UNICODE List Codepages
This form of the command obtains a list of all codepages.
UNICODE Difference Codepages name1 And name2 [Range E=h2 To E=h2]
This form of the command obtains a list of the differences between two codepages for the EBCDIC range specified (which defaults to the 00 to FF range).
UNICODE Difference Xtab name1 And Codepage name2 [Range E=h2 To E=h2]
This form of the command obtains a list of the differences between a JANUS XTAB table and a codepage for the EBCDIC range specified (which defaults to the 00 to FF range).
UNICODE Display Codepage name
This form of the command obtains, in commented form, the Maps of the specified codepage.
UNICODE Display Table Standard
This form of the command obtains, in command form, a display of current replacements and current Maps and/or translations (see Trans subcommands, below) that differ from the base.
UNICODE Table Standard subcommand
The updating forms of the UNICODE command begin with the keyword Table; they are described below.

For the updating subcommands:

  • The user must be a System Administrator (or user 0).
  • These commands should only be invoked during Model 204 initialization, because other users running at the same time as the change may obtain inconsistent results, including the results of UNICODE Display.

    You may test UNICODE command changes as part of a “private” test Online (that is, one which only you access), so no other users are running while you issue updating forms of the UNICODE command.

  • Changing the base codepage and changing translation or mapping points should be done before entering any replacement strings, because a replacement string is translated from EBCDIC to Unicode when the Rep subcommand is processed.

The various subcommand values of the updating forms of the UNICODE command are:

Base Codepage name
Replace the current translation tables with those derived from the named codepage.
Trans E=h2 To U=hex4
Specify one-way translation from EBCDIC point h2 to Unicode point hex4.
Trans E=h2 Invalid
Specify that the given EBCDIC point is not translatable to Unicode.
Trans E=h2 Base
Remove any customized translation or mapping specified for the given EBCDIC point.
Trans U=hex4 To E=h2
Specify one-way translation from Unicode point hex4 to EBCDIC point h2.
Trans U=hex4 Invalid
Specify that the given Unicode point is not translatable to EBCDIC.
Trans U=hex4 Base
Remove any customized translation or mapping specified for the given Unicode point.
Trans All Base
Remove any customized translation or mapping specified from all Unicode and EBCDIC points.
Map E=h2 Is U=hex4
Specify mapping from EBCDIC point h2 to Unicode point hex4, and from Unicode point hex4 to EBCDIC point h2.
Map U=hex4 Is E=h2
Same as Map E=h2 Is U=hex4.
Rep U=hex4 'str'
Specify replacement for Unicode point hex4 by the Unicode string str. str may be a series of the following:
  • Non-ampersand EBCDIC characters (which must be translatable to Unicode).
  • &amp; (for an ampersand).
  • A character reference of the form &#xhhhh;

The length of the resulting Unicode replacement string is limited to 127 characters. No character in the replacement string may be the U=hex4 value in any Rep subcommand.

Norep U=hex4
Specify that there is no replacement string for Unicode point hex4.
Norep All
Specify that there is no replacement string for any Unicode point.

For examples showing the use of the UNICODE command, please refer to the Notes for Sirius Mods Version 7.3.

Compatibility/Bug fixes

Please refer to the Notes for Sirius Mods Version 7.3 for a discussion of any compatibility issues with prior versions of the Sirius Mods and any bugs which have been fixed in this version, but had not, as of the date of this release, been fixed in the immediately prior version.

Return to top of page

Sirius Mods Version 7.2

Version 7.2 of the Sirius Mods was released in February, 2008. Please refer to the Notes for Sirius Mods Version 7.2 for more detailed information.

Supported Model 204 Versions

Version 7.2 of the Sirius Mods supports only Model 204 version V6R1.

All or Multiple Products

Html/Text statement enhancements

The User Language Html and Text statements, alternatives to a series of PRINT statements, are enhanced as described in the following subsections.
To Audit, To Print, and To Trace options

These three new Html/Text statement To options let you direct the contents of an Html/Text block or line to the destinations associated with the User Language statements Audit, Print, or Trace. Respectively these destinations are the journal/audit trail, the current print output device, or the trace destination (which may be the audit trail, print device, or CCATEMP trace table, or a combination of them).

Audit, Print, and Trace keywords

These new keywords act like the Data keyword: they denote that the HTML block consists of only the text that follows the keyword on the logical line. Further, they identify the output destination of the line's text, implying To Audit, To Print, and To Trace, respectively.

AuditText, PrintText, and TraceText options

These options are simply shortened forms of Text Audit, Text Print, and Text Trace, respectively, that place the action first. These are likely to be the common way of auditing, printing, or tracing text when no additional Text statement options need to be specified.

LiteralsToTemp keyword

When this keyword is specified in a Text statement, the literal data in the statement is stored in CCATEMP rather than STBL, avoiding excessive demands on STBL space. Designed for a Text statement with an unusually large amount of literal data, this is an alternative to setting the X'01' bit of the SIRCOMP user parameter (which performs the same function).

{~} directive

In a Text/Html statement block, content enclosed in expression start and end characters is evaluated as if it were the right-hand side of a User Language assignment, and the resulting value takes the place of the expression (and expression start and end characters) in the HTML block. For example, printText {$date} produces 08-02-29.

The special expression {~}, however, directs the compiler to replace this expression with the literal chartacter content of the next expression appearing on the same line. So printText {~} {$date} produces $date 08-02-29. The evaluation of the expression following {~} is carried out as usual.

Longstrings in images

The Longstring datatype is not supported inside images. However, Sirius Mods version 7.2 introduces support for image items with length greater than 255.

The following is an example of a declaration of a 300-byte image item:

image foo bar is string len 300 end image While such image items can't have arbitrary lengths up to 2**31-1 like other longstring variables, they exhibit the same behavior as other longstring variables in:
  • Request cancellation in the case of truncation
  • Upgrading With operations to longstring With operations

Report writer parameters

Report writers can use a lot of virtual storage which can adversely effect other users in an Online. The new CURREP31, CURREP64, HGHREP31, and HGHREP64 system parameters indicate the current and greatest amounts of 31-bit and 64-bit virtual storage used in the Model 204 run by report writers. The MAXREP31 and MAXREP64 parameters indicate the maximum amount allowed.

The only existing report writer is invoked by the SirTuneReport method of the Dataset class. That method is called by the SirTune product, and it can also be called directly.

Only the parameters that specify the maximum amount of storage (MAXREP31 and MAXREP64) are resettable.

Janus stream logging

The JANUS TCPLOG subcommand lets you capture all input and output streams for a particular Janus port. The captured streams are written to a sequential file.

One suggested use for a file of captured streams is to provide “playback” for customer-written applications that simulate real workloads during testing of new system or application code. Details of the format of the log file are available in the Janus TCP/IP Base Reference Manual.

SirScan accepts large datasets

SirScan now supports the use of z/OS large datasets for CCAJRNL.

Janus Debugger and Sirius Debugger

The Janus Debugger is a tool designed for software developers who create and maintain Janus Web Server applications. The Sirius Debugger is designed to debug classical screen-based 3270 applications as well as BATCH2 applications. Though the two debuggers use different thread types on the host, they can run concurrently, and they both use the same Windows-based GUI client. For more information about the debuggers, see the Janus/Sirius Debugger User's Guide.

Features available only with Sirius Mods 7.2

Jump to arbitrary statement

The Jump feature lets you alter the normal flow of program execution in the Debugger by invoking an immediate transfer of control to a specified statement and then executing that statement. The target statement may be earlier or later in the request than the current statement.

You invoke a jump by right-clicking a line in the Client's Source Code window or by using commands in a macro or mapped button or hot key. The commands offer additional functionality: jumps to a line number, jumps that are a number of lines relative to the current line, and jumps to lines that contain specified strings.

Audit Trail display for procedures excluded by White List processing

When white listing is on, the Debugger filters procedures automatically, stopping to interactively debug only the requests that are on the white list. A non-listed procedure executes normally, but it is not interactively debugged, and the Debugger Client's Audit Trail displays are immediately refreshed (as of Sirius Mods 7.2) to specify that such a procedure has been “skipped.”

Interrupting White List or Run Until processing

Once the Debugger's White List processing is invoked, it continues in effect unless you explicitly turn it off or until you exit the Debugger Client. It is manually interruptable, however, as of version 7.2 of the Sirius Mods: the mappable Client command breakOnNextProc lets you override the White List to interactively debug the next procedure.

New features for Sirius Mods 6.9 through 7.2

These features were added by update builds of the Client subsequent to the release of Sirius Mods 7.1.

Enhanced support for macros
User-created macros were made available for the Debugger in Sirius Mods version 7.1. The following subsections describe enhancements to macro support added in Sirius Mods 7.2.
New macro-only commands

These macro-only commands are added:

set
Lets you create and initialize macro variables.
assert
Performs an equality comparison between a) the value of program data or a macro variable and b) a constant or the value of a macro variable or macro function. For example:

assert %i=666

assert failure messages are displayed in the macro console, if it is open. Otherwise, they are displayed in a Windows message box.

vardump
Displays the values of all current macro variables. The message is normally displayed in a standard Windows informational box (entitled varDump for Macro). If the macro console is open, however, the message is sent to the console instead.
echo
The macro-only command echo lets you display a user-specified message. The message is normally displayed in a standard Windows informational box (entitled Macro message). If the macro console is open, however, the message is sent to the console instead.
Passing a command argument to a macro

This feature lets you pass an argument to a macro command at the time the macro runs. You can use either a standard macro variable or a standard macro function:

  • The &argstring is, in effect, a placeholder for a macro command argument. You specify &argstring the command argument. Then, depending how you invoke the macro, the Debugger substitutes an explicit value for &argstring when the macro runs.

    The client obtains the substitute value from the Variable or Field text area, from the Macro Command Line tool, or from a mapped macro command line.

  • The &&prompt is used to prompt for a macro command argument. The function format is:

    &&prompt("promptString") where promptString is a double-quoted character string.

    When a macro command that contains a &&prompt place of the command argument is executed, the Client displays a dialog box which uses promptString to solicit the value to substitute for the command argument.

A console for macro information

The Macro Console is an independent window that logs informational messages about the Debugger macros you run. It is invoked from its option in the Client's Macros menu. When a macro is called, the Macro Console displays information about the macro, including its starting and stopping, as well as any error messages.

Macro command line

The Macro Command Line menu option opens the Macro Command Line dialog box, which provides a command line interface for running macros. This dialog box stays available unless explicitly closed, so it is a step-saver for macro testing.

Macro-running indicator

A ... macro running indicator is now displayed on the Client's title bar while a macro is running or waiting.

Watching mixed-case global variables

Prior to this feature, you add a global variable to the Client's Watch Window by specifying the variable name (in any case) preceded by “G.” or “g”. Then the Debugger searched for (only) the variable with the all-uppercase form of the variable's name.

As of Sirius Mods 7.2, if you enclose the variable name in single quotation marks, however, the Debugger will search for exactly the case of the characters that you specify.

Keyboard-invoked consecutive searches

These two changes to the Search feature enable keyboard-invoked consecutive searches:

  • The default response to pressing the Enter key while the Search text box has focus is changed from "search from the top" to "search from current line." This lets you press Enter repeatedly to find subsequent occurrences of a search string. Formerly, pressing Enter again found the same occurrence as the first time, because it repeated the search from the top.

    Note:This introduces a small upward incompatibility.

  • The new focusToSearchBox command gives the input focus to the Search string text area. The Ctrl+F key combination is changed to perform the same function by default.
New mappable commands

These mappable commands are added:

addWatchOnCurrentLine
Adds to the Client Watch Window any variables found in the current Source Code line. It is the same as right-clicking a line and selecting Add Watch from the context menu.

The new Data Display menu item Add Watch on Current Line has the same effect as this command.

toggleBreakpointOnCurrentLine
Sets (or removes) a breakpoint for the current Source Code line if the line is or starts an executable statement. It is the same as double-clicking a line or right-clicking a line and selecting Toggle Breakpoint from the context menu.

The new Breakpoints menu item Toggle Breakpoint on Current Line has the same effect as this command.

reloadWhiteList
Updates the existing White List with the current contents of the whitelist.txt file, so you can dynamically update your White List. Same as clicking the Reload White List button on the Proc Selection page.

The new Execution menu item Reload White List has the same effect as this command.

turnOnWhiteList, turnOffWhiteList
Activates or deactivates White List filtering (like clicking the Turn On White List button or the Turn Off White List button on the Proc Selection page).

The new Execution menu items Turn On White List and Turn Off White List have the same effect as these commands.

runUntil
Runs program code without interruption until it reaches a specific procedure, then displays that procedure for debugging. Its required argument is the name of, or a character pattern for, the target procedure.

Having the same effect as the Run Until Procedure button., this command was formerly a macro-only command.

The new Execution menu item Run Until Proc has the same effect as this command.

ON UNIT code debugging

An exception to ordinary request-cancellation handling is added for the purpose of ON UNIT code debugging. Instead of stopping you from stepping through a request when the request has a canceling error, the Client lets you continue in the exceptional case of the following error only (which occurs within a User Language ON UNIT):

M204.1982: ILLEGAL JUMP ATTEMPTED OUT OF COMPLEX SUBROUTINE ON UNIT
Reporting for DEBUGGERSERVER and DEBUGGERCLIENT Janus ports

The DEBUGGERSERVER and DEBUGGERCLIENT Janus ports defined for the Debuggers are now reported as DEBUGSRV and DEBUGCLI ports, respectively, in the output from JANUS STATUS and JANUS DISPLAY commands. Formerly, they were reported as SRVSOCK and CLSOCK types.

Janus SOAP ULI

The following sections describe changes in the Janus SOAP ULI in this release.

The Dataset class

The Dataset classes provide an object-oriented interface to sequential datasets. This interface is more flexible than the traditional image-oriented interface used in User Language. In addition, they provide User Language access to Model 204 streams — datastreams composed of one or more sequential datasets via the Model 204 DEFINE STREAM command (see the Model 204 Command Reference Manual.

The Dataset class operates on datasets or streams defined by any of the following:

  • An MVS DD card.
  • A VSE DLBL card.
  • A CMS FILEDEF command.
  • A Model 204 ALLOCATE command.
  • A Model 204 DEFINE STREAM command.

The Dataset class uses two class-specific enumerations: the RecordFormat enumeration, and the DatasetState enumeration.

RecordFormat Enumeration

The RecordFormat enumeration indicates the format of the blocks in the sequential dataset. While, strictly speaking, the RecordFormat enumeration actually describes block formats or maybe file formats, it corresponds to the RECFM value used in DD cards, ALLOCATE statements, etc., so the term RecordFormat was used.

The DatasetState Enumeration

The DatasetState enumeration describes the current state of a Dataset object. A newly created Dataset object starts in the Closed state and then changes state as certain methods are performed on it. Certain methods are restricted to Dataset objects in a particular subset of states.

Dataset methods
The following dataset methods are available:
Blocksize property
Indicates the blocksize for the underlying dataset.
Close subroutine
Closes an open dataset.
Discard subroutine
Discards a dataset object.
New constructor
Creates a new dataset object, associating it with a sequential dataset or stream.
NumberOfBuffers property
Indicates the number of virtual storage buffers to be used, or being used, to read or write blocks of data.
Output property
Indicates whether or not the dataset is to be used for, or is being used for, output (written to).
ReadBlock function
Reads a block of data from the dataset.
ReadRecord function
Reads a record from the dataset.
RecordFormat property
Indicates the record and block format for the underlying dataset.
RecordLength property
Indicates the record length for the underlying dataset.
SirtuneReport function
Reads a SirTune sample dataset and produces a report (in XML format) summarizing the data in that sample dataset. This function is only available to sites authorized for SirTune.
WriteBlock subroutine
Writes a block of data to the dataset.
WriteRecord subroutine
Writes a record to the dataset.

Intrinsic classes

User Language is a legacy programming language for which object-oriented capabilities are a relatively recent addition. So, one might expect that strings and numbers are not maintained internally as objects, since their existence pre-dates objects. This is in fact the case, though as has been shown, this is largely irrelevant from a User Language programmer's perspective, And even if object-oriented capabilities were present in User Language from its inception, strings and numbers might have been special-cased for efficiency anyway.

However, beyond the internal representation of strings and numbers, a distinction between User Language and pure object-oriented languages was that the object:method syntax was not used to manipulate strings and numbers; instead, strings and numbers were manipulated via $functions. In Sirius Mods 7.2, this has been changed to allow the object:method syntax against string and numeric variables and constants.

The following code fragment illustrates how the same operation can be accomplished via traditional $functions and via object-oriented syntax:

%name is string len 32 print $len(%name) print %name:length

While this might not seem very significant, it provides considerable value:

  • It allows User Language to be used as a “pure” object-oriented language. This might be especially appealing to programmers who were trained in a pure object-oriented language.
  • It provides the benefit that expressions can generally be read in the natural left-to-right manner rather than the inside-to-outside manner required to understand an expression coded with $functions.
  • It provides capabilities to methods that operate on strings or numbers that are not available with $functions. These include support for named parameters and the ability to take objects as input parameters and to produce objects as results.

    While it would have been possible to extend $functions to have this same functionality (much as Sirius Mods provided callable $function support), it makes more sense to provide it using true object-oriented syntax. Given that this has now been done, it is unlikely that these capabilities will ever be added to $functions.

Intrinsic method objects

The term “method object” (or “intrinsic method object”) is used for the value or variable to which an intrinsic method is applied, even though the value or variable isn't really an object. This is justified because, strings and numbers can be considered immutable objects, regardless of their history or internal representation.

For example, in the following case, %str is the intrinsic method object for the Length method:

%str is string len 32 print %str:Length

Intrinsic methods can be applied to constants, in addition to variables. For example, the following assigns the length of the string literal “Whatever” to %x:

%x = 'Whatever':length Intrinsic methods can, of course, take the output from another method, intrinsic or not, as its input: For example, the following uses the Right method (which gets the rightmost characters of a string) against the output of a Stringlist Item method:

%list is object stringlist %value = %list:item(%i):right(8) Of course, since it is unnecessary to specify the Item method for a Stringlist, the above can also be written as:

%list is object stringlist %value = %list(%i):right(8) Intrinsic methods can also be applied to image and screen items:

image michigan romulus is string len 32 end image %value = %michigan:romulus:right(8) Intrinsic methods can also be applied to the output from a $function:

%seconds = $time:right(2) Intrinsic methods can even be applied to the results of expressions:

%value = (%tweedledum with %tweedledee):right(8)

As with other methods, the colon that separates the method object from the method name can be optionally preceded or followed by spaces. This could be done to enhance readability, or even to split a long line. The following four statements are all equivalent:

%value = %list:item(%i):right(8) %value = %list: item(%i): right(8) %value = %list :item(%i) :right(8) %value = %list : item(%i) : - right(8)

As with most other uses of intrinsic variables or values, if the method object is of a different type than the data type on which the method operates, the input value is automatically converted into the target datatype. For example, the expression 7/3 clearly produces a numeric value, but the Left method operates on strings. So, in the statement:

%i = (7/3):left(4) the result of the division is converted into a string and then passed to Left, which produces 2.33 as its result.

Because of this automatic conversion, the specific class (String or Float) of an intrinsic method cannot be determined from the datatype of its method object. This means that the class must be determined only from the name of the method, which means that method names must be unique among all intrinsic classes (that is, among String, Float, and Fixed). For example, there may not be a Length method in both the String and Float intrinsic classes. In the case of Length, the method is an intrinsic String method.

Intrinsic Float methods
The individual intrinsic Float methods are described in the following sections.

Float intrinsic methods treat their method object as a Float value. Any value that is not a Float value is automatically converted before it is acted on by the method.

SquareRoot function

This function returns a number that is the square root of the method object. An attempt to get the square root of a negative number results in request cancellation.

%value = number:squareRoot
Intrinsic String methods
The individual intrinsic String methods are described in the following sections.

Intrinsic String methods treat their method object as a Longstring value. Any value that is not a String value is automatically converted before it is acted on by the method.

Base64toString function

Base-64 encoding is useful for encoding strings that might contain binary or other characters that could cause problems in certain contexts. This function returns the unencoded value of a base-64 encoded string.

%out = string:base64toString
HexToString function

This function returns the unencoded value of a hex encoded string. Hex (short for hexadecimal) encoding is usually used for debugging when there is a concern that non-displayable characters (including trailing blanks) might be present in a string. By hex encoding such a string, all non-displayable bytes are converted to displayable hexadecimal equivalents.

%out = string:hexToString
Left function

This function returns the left-most characters of the method object string, possibly padding it on the right.

%out = string:left(length, [Pad=char])
Length function

This function returns the length in bytes of the method object string.

%len = string:length
PositionIn and PositionOf functions

These functions return the numeric position of the first occurrence of one string inside another. The difference between the two methods is that for PositionIn, the method object string is located in the first argument string, whereas for PositionOf, the first argument string is located in the method object string. Which is more convenient to use will be application dependent.

%pos = needle:positionIn(haystack, [start=spos]) %pos = haystack:positionOf(needle, [start=spos])
RegexMatch function

This function determines whether a given pattern (regular expression, or “regex”) matches within a given string according to the “rules” of regular expression matching.

%pos = string:regexMatch(regex [,Options=opts])
RegexReplace function
This function searches a given string for matches of a regular expression, and it replaces matches with, or according to, a specified replacement string. The function stops after the first match and replace, or it can continue searching and replacing until no more matches are found. Matches are obtained according to the “rules” of regular expression matching.

outStr = string:regexReplace(regex, replacement - [,Options=opts])
RegexSplit function

This method repeatedly applies a regular expression, or “regex,” to the method object string until it has tested the entire string. This splits the string into the substrings that are matched by the regex (the "separators") and the substrings that are not matched. By default, the method saves each unmatched substring as a separate item in the StringList result object. The leftmost unmatched substring is the first item in the StringList, the next leftmost is the second item, and so on.

A simple application of the method is to extract only the data items from a string of comma-separated data items. If the specified regex is a comma, each of the resulting StringList items will contain one of the data items. RegexSplit uses the rules of regular expression matching.

outList = string:regexSplit(regex - [,Options=opts] - [,Add=output])
Right function

This function returns the right-most characters of the method object string, possibly padding it on the right.

%out = string:right(length, [pad=char])
StringToBase64 function

This function returns the base-64 encoded value of the method object string.

%out = string:StringToBase64
StringToHex function

This function returns the hex encoded value of the method object string.

%out = string:StringToHex
Substring function

This function returns a specific number of bytes starting at a specific position in the method object string, possibly padding it on the right.

%out = string:substring(start, length, [Pad=char])

Exception handling

To diagnose or correct or reduce the damage from run-time errors that occur in places in a program where the use of a request cancellation, return-value processing, or output-parameter processing are insufficient, the Janus SOAP ULI introduces exception handling.

Exception handling consists of three parts:

  1. The ability to define classes of exceptions and the information available for these classes. Unsurprisingly, classes of exceptions are defined in almost the same way as other classes.
  2. The ability to indicate an unusual or exception situation. This is referred to as throwing an exception.
  3. The ability to detect a thrown exception and to perform special processing for the exception. This is known as catching an exception.

Although the Janus SOAP ULI exception handling support is very similar to many other object-oriented programming languages, such as Java or VB.Net, each language's implementation of exception handling has subtle or not so subtle differences from the others.

As a significant example, while many object-oriented languages make all (or almost all) errors exceptions, Janus SOAP ULI does not. This is partially because many object-oriented languages are not, strictly speaking, application languages — in addition to writing applications in some other object-oriented languages, one might write programming environments or even operating systems. As such, a programming environment or operating system must be able to intercept all errors and try to deal with them, so the object-oriented languages facilitate this by making all errors catchable.

User Language is an application development language. While it is theoretically possible to build a program environment in User Language, or even an operating system, this is not really the focus of User Language and it is not likely anyone would ever do this. The User Language programming environment (Model 204, which is not, itself, written in User Language) is responsible both for the ultimate catching of errors and the providing of information about the nature of the errors so that they can be corrected.

The kinds of errors that Janus SOAP ULI does not turn into exceptions, and thus are not trappable, fall into two broad categories:

  1. Pernicious environmental errors from which it would generally be almost impossible to recover gracefully on an application level.

    For example, if CCATEMP fills up, it is exceedingly unlikely that a request could recover gracefully. Since CCATEMP is used for so many different things (including record sets for finds, stringlists, collections, internal storage of objects swapped out of a server, transaction backout logs, and so on), it would be very difficult for an application to anticipate all the places that CCATEMP could fill. And even if it could anticipate the places, it would be very difficult to avoid doing anything that might also require CCATEMP.

  2. Errors that are indicative of logic errors in a program.

    For example, a class member reference via a null object variable is usually indicative of a programming error. Similarly, a reference to an invalid collection item number is also generally indicative of a programming error.

    While there might be error-causing cases of “sloppy” references to object variables or collection items that you would want to simply catch when they happen:

    • Most of these are handled well by existing facilities such as Auto New and also UseDefault processing for collections.
    • In the odd cases where such sloppy references are useful, it is trivial and efficient to check for the sloppy references (null object variable, invalid collection item number), so an exception-handling paradigm adds little value.
Exception class definitions

The collection of data describing an error situation might be used immediately after the error is detected, or it might be examined elsewhere. As such, this error data should be able to persist indefinitely. Given this requirement, it is clear that the logical place to hold error information is inside an object. And the description of the data associated with a particular error would be a class.

Classes that describe trappable error situations are called exception classes. To a large degree, exception classes are no different from any other class:

  • They can have Public, Private, and Shared blocks; they can have variables, methods, and the same Allow and Disallow rules as any other class.
  • There can be system exception classes, which are maintained by the Janus SOAP ULI environment, and there can be User Language exception classes, which are defined and maintained by User Language code.
  • Exception classes can be used wherever non-exception classes are used, although the reverse is not true. That is, there are certain statements that require an exception class or an object of an exception class. This is largely to prevent accidental misuse of a non-exception class in an exception class context.

User Language exception classes are denoted by using the Exception keyword in the class header:

class tackyColor exception

One can think of the Exception keyword on the Class declaration as indicating that the class extends some hidden base class.

You can put the Exception keyword on almost all class declarations; specifying it removes no capabilities from the class. Doing so, however, is misleading, since most classes are likely never to be used to indicate error situations. In this regard, you can view the Exception keyword on a class declaration as documentation that a class can be used as an exception class. While the compiler cannot ensure that a class with an Exception declaration will be used as an exception, it does ensure that a class not declared as Exception is not used in exception contexts.

The one case where the Exception keyword is not allowed on class declarations is in declarations that extend non-exception classes — exception classes can only extend other exception classes.

Throwing exceptions

When an error situation occurs, the code that detects the situation can do one of two things:

  • It can cancel the request. In User Language this is done with an Assert statement. In system code, this is done by some equivalent of the Assert statement. This is the correct response to an error if the error is clearly indicative of a programming error or a severe environmental constraint that is likely to make request continuation unproductive.
  • It can throw an exception. In User Language this is done with a Throw statement. In system code, this is done by some equivalent of the Throw statement. This is the correct response to an error if the error might occur in the normal course of processing and the code that called the method might be able to recover from the error.

    Note: In the Janus SOAP ULI implementation of exceptions, exceptions can only be thrown by methods.

In both system and User Language methods, a thrown exception can only be handled (caught) by the code that called the method, as opposed to inside the same method that threw the exception.

The exceptions that might be thrown by a method must be documented in the method header.

Specifying a Throws clause

The exceptions thrown by a method are indicated by the Throws clause in the method declaration and definition header. For example, if the method Paint might throw a TackyColor and InvalidHexData exception, it should be declared and defined as:

subroutine paint(%hexColor is string len 6) - throws tackyColor and invalidHexData

The keyword and is used to separate the exceptions that might be thrown by a method. The method can only ever throw one exception at a time, and in most cases, it will not throw an exception at all.

The list of exceptions after a Throws keyword is the list of exception class names. These class names could be User Language exception class names, or they could be system exception class names. If the class is a system class name, it could be fully qualified with the System: namespace indicator. For instance, the previous example could be written as

subroutine paint(%hexColor is string len 6) - throws tackyColor and - system:invalidHexData

As with most method descriptions, the Throws clause on a method declaration and definition must match exactly.

Methods that implement an overridable method cannot throw any exceptions not thrown by the implemented method; however, they do not necessarily have to throw all the exceptions thrown by the implemented method.

Using the Throw statement

Once a method declaration indicates the exceptions it might throw, that method could then throw the exception with the Throw statement. The Throw statement must be followed by an instance of the exception class being thrown. For example, if the method header contains

subroutine paint(%color is string len 6) - throws tackyColor and there is a variable declaration in the method

%tacky is object tackyColor the method could do

throw %tacky

An attempt to throw an exception object whose class does not match one of the classes listed in the method declaration's Throws clause results in a compilation error.

Exception classes extending other exception classes

Exception classes can extend other exception classes. As such, the class of an object specified in a Throw statement does not have to match any class in the method's Throws list exactly — it can be of an extension class of one of the Throws list classes. Because an extension class can, itself, be extended, and because of multiple inheritance, this means that a Thrown exception object might match multiple classes in a method's Throws list.

The thrown (and so catchable) class is the first class in the Throws list that matches the object in the Throw. That is, the first class in the Throws list that exactly matches the thrown object's class or that is a base class of the thrown object is used as the thrown class for the method caller.

Try and Catch

Without any action on a method caller's part, a thrown exception is, for all intents and purposes, a request cancelling error. To prevent the request cancellation, an exception must be “caught.” This is achieved by the use of a Try/Catch block.

A Try/Catch block consists of two parts. The first, the Try section contains one or more User Language statements that might result in an exception. The Try section is then followed by one or more Catch sections, each one of them handling (catching) a particular class of exception.

The following fragment illustrates the use of a Try/Catch block to trap an exception caused by invalid hexadecimal data:

try %binary = %input:hexToString catch invalidHexData %binary = '???' catch invalidBase64Data %binary = '???' end try

This example illustrates a few points:

  • The end of the statements whose exceptions are being caught is indicated by the first Catch block.
  • The class of exceptions being caught follows the Catch statement.
  • A catch block is terminated by another Catch statement or an End Try.
  • One can catch multiple exception types, each within its own Catch block.
  • There is no validation that the type of exception being caught might actually be thrown inside the Try block.

What gets thrown with an exception is an exception object that contains information about the nature of the exception. To reference the thrown exception object, you must specify a To clause, followed by an object variable of the exception class being caught.

For example, if %daemon is a Daemon object and %daemonLost is an object of the DaemonLost exception class, the following block catches the exception thrown if the daemon thread was logged off for some reason, and it displays the output of the last command up to the point where it logged off:

try %daemon:run('INCLUDE NASTY') catch daemonLost to %daemonLost printText Daemon died! Its last words were: %daemonLost:daemonOutput:print end try
Some differences with other languages

The following are some differences between the Janus SOAP ULI implementation of Try/Catch and implementations in other languages. Outside of these differences, Try/Catch support in Janus SOAP ULI is very similar to that in other languages.

  • Unlike Java, it is not necessary to provide a Catch for all exceptions that a method might throw.
  • Unlike many other languages, uncaught exceptions are not automatically propagated to higher level callers. Partially, this is because the User Language environment is not written in User Language, so there is no need to propagate exceptions to some outer User Language environment which, presumably, would clean up the failing request and possibly provide diagnostics about the error. Instead, clean-up and diagnostics are provided by the assembler environment.
  • The absence of automatic exception propagation eliminates the utility of a Finally clause (to “ensure” that the method doesn't leave things in a half-done state), so no Finally clause is available in Try/Catch blocks in User Language.
  • Catches cannot catch locally thrown exceptions. That is, a Throw statement always results in immediate exit from the current method, regardless of whether or not the Throw is inside of a Try block and whether or not there are Catches that correspond to the thrown exception.
Nesting Try/Catch blocks

Like in other languages, Try/Catch blocks can be nested. That is, a Try/Catch block can be inside the try or catch clause of another Try/Catch block.

OnThrow and OnUncaught

An exception class might want to perform special processing at the time an exception is thrown:

  • It might want to make sure the exception object has valid data.
  • It might want to record diagnostic information, perhaps to the audit trail or perhaps to some Model 204 file.
  • It might want to derive some variable values that might not necessarily have been derivable in the constructor.

To provide this capability, Janus SOAP ULI special-cases two method names in a User Language exception class: OnThrow and OnUncaught. Both of these methods must be subroutines (as opposed to Functions or Properties) and cannot have parameters.

The OnUncaught subroutine is automatically called whenever an exception of the containing class is thrown, and the exception will not be caught. The OnThrow subroutine is automatically called whenever an exception of the containing class is thrown, and either the exception will not be caught and there is no OnUncaught method in the class, or the exception will be caught.

These two method names have no meaning in non-exception classes.

These methods can be called explicitly, and they can be either Private or Public (though whether they are Public or Private is irrelevant for implicit calls when an exception is thrown).

The following illustrates an OnThrow subroutine that makes sure the exception data is valid at the time an exception is thrown:

class pratfall exception public variable sound is string len 32 subroutine onThrow end public subroutine onThrow assert %this:sound eq 'splat' or - %this:sound eq 'boing' end subroutine end class

The following illustrates an OnUncaught subroutine that logs information from the exception to the audit trail before allowing the request to be cancelled:

class pratfall exception public variable sound is string len 32 subroutine onUncaught end public subroutine OnUncaught auditText Taking a pratfall -- {%this:sound} end subroutine end class

If SirFact is available and capturing dumps for requesting cancelling errors, all the information one would need is likely to be in the dump, so there is probably little need to collect extra data in an OnUncaught subroutine.

There is no way for an OnUncaught or OnThrow subroutine to undo the effect of the exception, that is, to prevent a request cancellation if the exception is uncaught. Both routines, however, can force a request cancellation, perhaps by using an Assert statement, even if the exception would have been caught. If a request cancellation occurs inside on OnThrow subroutine for an exception that's about to be caught, the catching statements are not executed, because the request is cancelled before the OnThrow subroutine returns.

The Throws clause is invalid on an exception class's OnThrow and OnUncaught subroutines, so these subroutines cannot, themselves, throw an exception.

System Exception classes

As already described, classes that describe trappable error situations are called exception classes. System exception classes are maintained by the Janus SOAP ULI environment, while User Language exception classes are defined and maintained by User Language code.

The system exception classes added in Sirius Mods 7.2 are described in the following sections.

DaemonLost class

The DaemonLost exception class indicates that a daemon thread associated with a daemon object was lost, most probably because of a user restart.

InvalidBase64Data class

The InvalidBase64Data exception class describes an exception associated with finding non-base64-encoded data where base64-encoded data was expected, usually when decoding base64-encoded data.

InvalidHexData class

The InvalidHexData exception class describes an exception associated with finding non-hexadecimal data where hexadecimal data was expected, usually when translating the hexadecimal data to something else.

InvalidRegex class

The InvalidRegex exception class describes an exception associated with an invalid regular expression being passed to a method that takes a regular expression argument.

NoFreeDaemons class

The NoFreeDaemons exception class indicates that the Daemon class constructor was invoked, but there were no daemon threads available to service the object.

Enhancement methods

When using a class, it is not uncommon to want to perform operations on objects of the class that are not one of the standard methods provided by the class. Before Sirius Mods version 7.2, there were three ways of addressing this:

  1. Add a new method to the class.
  2. Create an extension of the class that contains the new method.
  3. Create a shared method in another class that takes objects of the first class as input parameters.
Sirius Mods version 7.2 introduced a new type of shared method called an enhancement method to provide a better way of invoking a method on an object of another class. Because enhancement methods do not operate on objects of the containing class, they are considered shared methods of that class, so they are declared inside the Public Shared or Private Shared blocks of the class.

An enhancement method declaration has the following syntax:

<method> (<class>):<name> [<otherMethodDesc>] Where:
<method>
The method type — Subroutine, Function, or Property. An enhancement method cannot be a constructor.
<class>
The class of the objects to which the method applies. It cannot be the containing class nor an extension class of the containing class.
<name>
The name of the enhancement method. The name can be the same name as that of other methods in the class, shared or non-shared, as long as it is not the same name as an enhancement method on the same class.
<otherMethodDesc>
Method parameters, method type (for Functions and Properties), and other method qualifiers (like AllowNullObject). Any descriptors available to other methods are available to enhancement methods.
An enhancement method invocation has the following syntax:

<object>:(<+containerClass>)<name> [(<arguments>)] Where:
<object>
An object variable of the class against which the enhancement method operates.
<+containerClass>
The name of the class that contains the enhancement method definition. Note that the class name must be preceded by a plus sign (+) to indicate an enhancement method invocation. The plus sign distinguishes an enhancement method container class name from other uses of class names inside parentheses that might appear in the same context.
<name>
The name of the enhancement method.
<parameters>
Any arguments the enhancement method might take as input. Optional, default, and named parameters work exactly the same way with enhancement methods as with any other methods.

For example, to declare and define an enhancement method version of an “EveryOther” method, one would do something like the following:

class utility public shared function (stringlist):everyOther - is object stringlist end public shared function (stringlist):everyOther - is object stringlist %i is float %outList is object stringlist %outlist = new for %i from 1 to %this:count by 2 %outlist:add(%this(%i)) end for return %outlist end function end class As can be seen in this example, an enhancement method has an implicitly declared object variable called %this. As with unshared methods, the %this variable is a reference to the method object. Unlike unshared methods, the %this variable is not an object of the containing class, but is, instead, an instance of the class to which the enhancement method applies.

This enhancement method could then be invoked as follows:

%mylist:(+utility)everyOther:print As this example illustrates, the syntax for invoking an enhancement method is more natural from an object-oriented perspective than invoking a shared method that does the same thing.

Using an enhancement method in a chain of methods makes this point even clearer:

%mylist:sortNew('1,20,A'):(+utility)everyOther:print This chain of methods can be read from left to right rather than from the inside out.
Enhancement methods and inheritance

Enhancement methods are never automatically inherited by extension classes of the methods to which they apply, regardless of whether the Inherit keyword is specified on the class declaration for the extension class. For example, the EveryOther method in the preceding section cannot be directly applied to %mylist if %mylist is actually an object of class Funnylist, where FunnyList is an extension of class Stringlist. However, the method can be applied by explicitly specifying the name of the class to which the method applies:

%mylist:(stringlist)(+utility)everyOther:print

In some languages this is referred to as casting, that is, casting a variable as one of its base classes.

You can also explicitly indicate that an extension class is to inherit a base class's enhancement method with a special form of the Inherit statement in the Public or Private Shared blocks:

public shared function (stringlist):everyOther - is object stringlist inherit (funnylist):everyOther from stringlist end public shared If this were specified, the EveryOther enhancement method could be applied to objects of class Funnylist without any extra qualification.

Note: Because an enhancement method is not defined in the class to which the method applies, it cannot reference private variables in that class. However, it can reference private members of instances of objects of the containing class.

In fact, one typical application for enhancement methods is to provide a method for creating a new instance of the containing class from an instance of the method object class. These are a special kind of factory method. Such a method might not need to access private members of the method object class, but it might need to access private members of the containing class, so an enhancement factory method is perfectly suitable.

Intrinsic Enhancement methods

In addition to Enhancement methods, Sirius Mods 7.2 introduces Intrinsic methods and classes (Intrinsic classes). And, just as you can create enhancement methods for other system classes, you can create enhancement methods for intrinsic classes, specifically for the Float and String classes.

For example, the following definition creates an enhancement method that calculates the length of the hypotenuse of a triangle given the length of one side as the method object and the other side as a parameter:

class calc public shared function (float):hypotenuse(%otherSide is float) - is float end public shared function (float):hypotenuse(%otherSide is float) - is float return ((%this * %this) + - (%otherSide * %otherSide)):squareRoot end function end class You can invoke the above method as follows:

%hyp = 3:(+calc)hypotenuse(4) The preceding statement sets %hyp to 5. As can be seen in this example, for a Float enhancement method, the implicitly defined %this variable has a Float datatype.

The following is an example of a String enhancement method that returns the number of vowels in a string:

class myString public shared function (string):vowels is float end public shared function (string):vowels is float %i is float %vowels is float for %i from 1 to %this:length if %this:substring(%i, 1): - positionIn('aeiouAEIOU') then %vowels = %vowels + 1 end if end for return %vowels end function end class

You can invoke the above method as follows:

%nvowels = 'Canberra':(+myString)vowels

The preceding statement sets %nvowels to 3. For a String enhancement method, the implicitly defined %this variable has a Longstring datatype.

Enhancement methods for Collections

Enhancement methods can be added to any class, including Collection classes (Arraylists, NamedArraylists, and so on). Given this capability, it is quite common for a class to have a need to create an enhancement method on a collection of that class.

For example, you might have an Order class that describes an order for widgets. You might want to provide an enhancement method on Arraylist of Order objects that creates a new Arraylist of objects that contains items that need to be back-ordered (there are insufficient widgets in stock to satisfy the order). The method might look something like:

class order public shared function (arraylist of object order):backorderlist - is collection arraylist of object order end public shared function (arraylist of object order):backorderlist - is collection arraylist of object order %i is float %warehouse is object warehouse global %newlist is collection arraylist of object order %newlist = new for %i from 1 to %this:count if %this(%i):number gt - %warehouse:instock(%this(%i):widgetId) %newlist:add(%this) end if end for return %newlist end function end class To invoke this enhancement method, one might do something like:

%backOrders = %orders:(+order)backOrderlist

However, because a class has a special relationship to collections of objects of that class, it is not necessary to indicate the class of the enhancement method. That is, you can also write the above method invocation as:

%backOrders = %orders:backOrderlist

It is possible to create enhancement methods with the same name as standard collection methods. For example, it is possible to create an Add method. If you create such a method, the collection class method is completely hidden. That is, there is no way to invoke the collection class method of the same name, even from inside the enhancement method. For this reason, it is generally not a good idea to create an enhancement method for a collection class with the same name as a collection class method.

The ability to hide collection class methods is available mainly to preserve backward compatibility when a new collection class method is introduced. If there were already enhancement methods of the same name, those methods would continue to be invoked.

ReadOnly and Protected variables

In Sirius Mods 7.2 and later, it is possible to to declare a class variable as ReadOnly or Protected. A ReadOnly variable can be examined by code outside the class, but it can only be updated inside the class. A Protected variable can be examined by code outside the class, but it can only be updated inside the class or by code inside an extension class. Since a ReadOnly or Protected variable must be accessible outside the class, it would make no sense for such a variable to be in a Private section, so this is not allowed.

ReadOnly and Protected variables are useful for providing an efficient means of accessing relatively static information about objects in a class. Unlike a property, retrieving ReadOnly or Protected variables requires no code to be run in the class.

The term Protected is something of a misnomer. In a very real sense, Protected variables aren't protected, at all. After all, they can be updated by extension classes. Their real purpose is to act as a sort of overridable variable, that is, a value that can be overridden by an extension class.

For example, suppose a class has a ReadOnly variable called PartNumber. Perhaps PartNumber is set by the class's constructor, and then it is never set again (for a particular object instance). Now, suppose this class wants to allow extension classes to set a different PartNumber, probably in their constructors. One approach would be to make PartNumber an Overridable ReadOnly property. But this is a somewhat heavyweight approach, as it requires a bit of code (the property Get method) for each extension class, and this code has to be run every time PartNumber is retrieved. Instead, PartNumber could be made a Protected variable, and an extension class's constructor could simply set it after calling the base class constructor. This allows the extension classes to override the base class's PartNumber using little extra code and using a very efficient access path for the value.

Protected variables differ from Overridable ReadOnly properties, however, in that an Overridable ReadOnly property always guarantees that the extension class's code is run, so it overrides the base class's properties. With a Protected variable, it would be possible for an extension class to set it, and for the base class to then set it to something else, undoing the extension class action.

Because they can be updated by both base and extension classes, Protected variables are probably most useful for very static values, like values that are only set by the constructors. Use of Protected variables that can be set throughout the life of objects of a class is likely to be error-prone, as it requires careful coordination of updates between the base and extension classes.

New System class methods

These new methods are added to the System class: Arguments, CallStack, CallStackDepth, and CallStackCaller.

The Arguments method
The Arguments method allows evaluation-time examination of INCLUDE arguments. This shared function returns the arguments passed in the INCLUDE command for the procedure that contained the Begin for the current request.

%args = %(system):Arguments

For example, if procedure FOO contained the following:

b printText {~} = '{%(system):arguments}' end The following requests (preceded by >) would produce the following outputs:

> I FOO This is a test %(system):arguments = ' This is a test' Note that everything after the INCLUDEd procedure name is returned by the Arguments method, including any blanks or commas after the procedure name.
The CallStack method
This shared function returns a Stringlist containing information about the current call stack: information about the caller of the current method or subroutine, the caller of that caller, and so on.

%callList = %(system):CallStack

The CallStack method returns the name of the procedure and the line within the procedure that made the calls of the current method or subroutine. Generally, each returned StringList item has the name of the file containing the calling procedure at positions one through eight, followed by a blank, followed by the name of the calling procedure, followed by a blank, followed by the line number within the calling procedure.

The CallStackCaller method
This shared function returns a string containing information about the caller of the current method or subroutine. The information can extend back to a specific number of call levels.

%callString = %(system):CallStackCaller(%depth)

The CallStackCaller method returns the name of the procedure and the line within the procedure that made the calls of the current method or subroutine. Generally, the returned string has the name of the file containing the calling procedure at positions one through eight, followed by a blank, followed by the name of the calling procedure, followed by a blank, followed by the line number within the calling procedure.

The CallStackDepth method
This shared function returns a number indicating the depth of the call stack.

%depth = %(system):CallStackDepth

At level-0 (immediately inside a Begin/End), CallStackDepth always returns 0. For a method or subroutine called directly from level-0 code, CallStackDepth would return 1. For a method called from a method called from level-0, CallStackDepth would return 2; and so on.

Janus SOAP Xml API

The following sections describe changes in the Janus SOAP Xml API in this release.

Multiple XPath predicates

XPath expressions may now contain multiple predicates in a single step. Previous versions of Janus SOAP supported some, but not all, cases of multiple predicates.

The primary purpose of the new multiple predicate support is to let you use the position() function to filter based on the position of nodes from the preceding predicate, rather than from the step's nodetest.

For example, the following expression selects the second chapter child of the book, if its author is Alex:

/book/chapter[author="Alex" and 2] While the following expression selects the second chapter child that is authored by Alex:

/book/chapter[author="Alex"] [2]

not() function in XPath predicates

The not() function is now supported in XPath predicates. The argument is a Boolean expression, and the result is true if the value of the argument is false, and false otherwise.

Note: The result of the not() function applied to a comparison expression is different than the same expression with the complementary comparison. For example, this statement selects children that have the value of the status attribute equal to "pending":

%lis = %nod:SelectNodes('*[@status="pending"]')

The following statement selects children that have the value of the status attribute equal to something other than "pending":

%lis = %nod:SelectNodes('*[@status!="pending"]')

And the following statement selects children that have the value of the status attribute equal to something other than "pending", or that have no status attribute:

%lis = %nod:SelectNodes('[not(@status="pending")]')

Nested XPath predicates

An XPath expression is now allowed to have a predicate that contains a location path which itself contains a predicate; that is, predicates may be nested.

For example, this selects Chapters whose first Section has a Racy attribute:

%lis = %bk:SelectNodes('Chapter[Section[1 and @Racy]]')

Boolean parentheses in XPath predicates

In an XPath expression that has a predicate that contains a Boolean expression, parentheses are now allowed for grouping in the Boolean operands. For example, the following predicate is supported by Janus SOAP in Sirius Mods 7.2 and later:

chapter[@type="methods" and (@class="Stringlist" or @class="Daemon")]"

URI now allows hexadecimal escape (%hh)

The various places in Janus SOAP that process a URI (for example, the third argument of the AddElement method, or the string input to the LoadXml method) now allow a URI to contain a “hexadecimal escape,” that is, a percent sign (%) followed by two hexadecimal digits (which may be either uppercase or lowercase when the letters A-F are used).

Note that there is no replacement of the hexadecimal values when URI processing is performed. For example, even though the ASCII code for the number “4” is hexadecimal 34, the following two URIs are different and distinct:

http://my.URI.number4 http://my.URI.number%34 Thus, for instance, the following fragment:

%n = %d:AddElement('x', , 'http://my.URI.number4') %n:AddElement('x', , 'http://my.URI.number%34') %d:Print %d:SelectionPrefix('f') = 'http://my.URI.number4' Print %d:SelectCount('//f:x') And 'matching node(s)' Will have the following result:

<x xmlns="http://my.URI.number4"> <x xmlns="http://my.URI.number%34"/> </x> 1 matching node(s)

Janus Sockets

The following features are new or changed in Janus Sockets:

HTTPRequest class Send method

Prior to the addition of the Send method, the HTTPRequest class had methods only for HTTP GETs and POSTs. The new Send method is a way to carry out HTTP methods in addition to GET or POST.

The Send function sends an HTTP request to an HTTP server using a parameter value to identify which of any of the HTTP method types (GET, POST, PUT, and so on) you want the function to perform. Any HTTP method type is valid as long as its name is 16 characters or less.

The HTTP method type is specified with the Method (name required) parameter. If you set the Method value to GET or POST, the Send method invocation becomes equivalent to the existing Get method or Post method, respectively, of the HTTPRequest class.

%httpresp = %httpreq:Send([[Port=] name,] - [[Cancel=] num,] - Method=methodname )

Janus Web Server

The following features are new or changed in Janus Web Server:

Support for additional HTTP method types

Janus Web Server now accepts any HTTP method in a request as long as the method name is 16 bytes or shorter. This feature is provided by:

  • Adding support for specifying additional HTTP method types in Janus Web rules.

    The new OTHER option in the method parameter in the JANUS WEB command refers to all methods other than PUT, GET, POST, and HEAD. A method whose name exceeds 16 characters is not allowed.

    Examples of rules that use OTHER follow:

    JANUS WEB WEBPORT ALLOW OTHER * USER * JANUS WEB WEBPORT ON OTHER /WEBDAV/* OPEN FILE WEBDAV CMD 'I *'
  • The ANY option of the method parameter now means any HTTP method whose name is 16 bytes or shorter. Prior to Sirius Mods version 7.2, ANY referred only to PUT, GET, POST, or HEAD.

    Note: This is a slight backward incompatibility: if a web rule specifies ANY, URLs indicating methods other than GET, POST, PUT, or HEAD may now trigger unexpected Web Server actions.

    You can detect the method type in an application by a $web_hdr_parm('METHOD') query.

Sirius Functions

The following are new or changed features in the Sirius Functions:

NOURGMSG option of $Wakeup

Prior to Sirius Mods 7.2, the waiting time that remains for a user paused by a $Wakeup call is cancelled if a BROADCAST URGENT message is sent to the user. As of Sirius Mods 7.2, the $Wakeup function accepts an optional argument so that BROADCAST URGENT does not cause the $Wakeup function time to complete.

The string NOURGMSG (or any upper/lower case variant) is the optional argument for $Wakeup that prevents a paused user from being immediately wakened by BROADCAST URGENT.

$Lstr_Word return word longer than 255 bytes

The $Lstr_Word function now may return a Longstring, whose length exceeds 255 bytes. Previously, attempting to return such a result either caused request cancellation, or caused truncation to 255 bytes of the returned string.

Compatibility/Bug fixes

Please refer to the Notes for Sirius Mods Version 7.2 for a discussion of any compatibility issues with prior versions of the Sirius Mods and any bugs which have been fixed in this version, but had not, as of the date of this release, been fixed in the immediately prior version.

Return to top of page

Fast/Unload Version 4.4

Fast/Unload Version 4.4 was released in September, 2007. The major enhancements are summarized below. Please refer to the Fast/Unload Release Notes Version 4.4 for more detailed information.

New Features

The principal purpose of the release of version 4.4 of Fast/Unload is to support the FILEORG X'80' feature introduced in Model 204 V7R1.

In addition, the OPEN command in a “batch” Fast/Unload job (that is, not using the Fast/Unload User Language Interface) now allows specification of multiple filenames, allowing the unload of an ad-hoc group of files.

OPEN statement for ad-hoc groups

Your FUEL program now may specify a group in the OPEN statement. There are two alternatives to the OPEN statement:

OPEN FILE filename
This form indicates that a single file is to be opened, with the given name.
OPEN filename1 [, filename2] ...
This form, if there is more than one filename in the comma-separated list, indicates that a group of files is to be opened, with DD names filename1, filename2, etc.
With this new capability, you are no longer required to use the Fast/Unload User Language Interface to unload a group.

#FILENAME special variable

The #FILENAME special variable is now available. It obtains the name of the file currently being unloaded.

Return to top of page

 

Printer friendly

Sirius Home

 

Sirius Software, Inc.
875 Massachusetts Ave. Suite 21
Cambridge, MA 02139
Phone: 617-876-6677
Fax: 617-234-1200
Email: support

 

 

  © 2010 Sirius Software, Inc.