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:
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.
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:
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:
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):
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.
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:
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.
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
“&”.
For example, the following fragment using the new UnicodeWith method:
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:
ASCII
Unicode
Description
X'80'
U+20AC
Euro
X'82'
U+201A
Single comma quotation mark
X'83'
U+0192
Small letter script f
X'84'
U+201E
Double comma quotation mark
X'85'
U+2026
Horizontal ellipsis
X'86'
U+2020
Dagger
X'87'
U+2021
Double dagger
X'88'
U+02C6
Modifier letter circumflex
X'89'
U+2030
Per mille sign
X'8A'
U+0160
Capital letter S with caron
X'8B'
U+2039
Single left-pointing angle quote
X'8C'
U+0152
Capital ligature OE
X'8E'
U+017D
Capital letter Z with caron
X'91'
U+2018
Left single quotation mark
X'92'
U+2019
Right single quotation mark
X'93'
U+201C
Left double quotation mark
X'94'
U+201D
Right double quotation mark
X'95'
U+2022
Bullet
X'96'
U+2013
En dash
X'97'
U+2014
Em dash
X'98'
U+02DC
Small tilde
X'99'
U+2122
Trademark sign
X'9A'
U+0161
Small letter s with caron
X'9B'
U+203A
Single right-pointing angle quote
X'9C'
U+0153
Small ligature oe
X'9E'
U+017E
Small letter z with caron
X'9F'
U+0178
Capital 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 π':u
printText {~} = "{%u}", {~} = "{%u:unicodeReverse}"
end
This request produces the following result:
%u = "Bye-bye, Miss American π"
%u:unicodeReverse = "π 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.
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('@':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).
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.
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.
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.
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).
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.
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 (, , , -
, , ,
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:
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 TextTo 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( [,loopLockStrength=])
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(), 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:
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.
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:
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:
Is Object SelectionCriterion For
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 (): Is
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:
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 then %sel = OR(%sel, EQ(foo, 'A'))
end if
if then %sel = OR(%sel, EQ(foo, 'B'))
end if
if 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:
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 �.
AppendValue method in XmlNode class
A new XmlNode subroutine, AppendValue, appends to
the value of a node in an XmlDoc.
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 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.
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', '™':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', '™':U)
%doc:Print
The result of this fragment is:
™
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('™':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:
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:
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.
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 & 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:
However, starting with version 7.6, it produces the following result:
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.
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.
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.
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.
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.
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('')
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 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:
Cambridge
Attribute format is:
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.
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.
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
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:
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:
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.
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
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.
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 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, ) — 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, ).
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('')
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
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:
Empty Element as top of subtree:
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
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
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
Run the following ad hoc request:
Begin
Print $C2X('6A')
End
“Copy” the result character to your clipboard, for example, by highlighting
it and pressing ctl-C.
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.
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'):
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, ...
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:
EbcdicToAsciiAsciiToEbcdic.
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™':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.
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 &.
For example, the eight characters “
“left double-quotation mark.”
The result is the input string translated to EBCDIC — with
untranslatable characters represented with character references,
if CharacterEncode=True.
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('1':U)
* Note: "Print %u" gives the same result as the following:
Print %u:UnicodeToEbcdic
%u = '12':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
12
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.
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('1':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.
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.
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 &.
This substring is converted to '&'.
At the start of a hexadecimal character reference (for example, the eight characters
'“' 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 & references converted to the represented Unicode
character, if CharacterDecode=True.
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 &.
This substring is converted to '&'.
At the start of a hexadecimal character reference (for example, the eight characters
'“' for the Unicode “Left double quotation mark”).
The character reference is converted to the referenced character.
Example:
* Constant for trademark symbol:
%tm Unicode Initial('™':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.
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 &.
For example, the six characters '„' 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.
%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
12
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).
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 &.
This substring is converted to '&'.
At the start of a hexadecimal character reference (for example, the six characters
'„' 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 & references converted to the represented ASCII
character, if CharacterDecode=True.
This function may throw a CharacterTranslationException exception.
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.
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).
& (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.
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.
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:
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.
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.
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.
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:
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.
The ability to indicate an unusual or exception situation.
This is referred to as throwing an exception.
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:
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.
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:
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:
Add a new method to the class.
Create an extension of the class that contains the new method.
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:
(): []
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:
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:
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:
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.
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.
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.