- Log in to post comments
Look at the $system.Process.ListFormat(newformat) method.
It allows you to turn off/on IEEE $DOUBLE compression in $LISTBUILD using $LIST code 0x09. For many years this was defaulted off but it is now turned on by default. You may have to turn it off if you are sending $LIST data strings to old client software that does not support $DOUBLE compression.
$system.Process.Listformat(newformat) also allows you to turn on compressed Unicode strings formats in $LISTBUILD using $LIST codes 0x0D, 0x0E and 0x0F. This is turned off by default because some customers are using old client software that does not support Unicode compression. On a Unicode instance this can reduce the number of bytes in a Unicode string that uses mostly one of the ASCII, Latin-1, Greek or Cyrillic character sets with a small number of other Unicode characters mixed in. These codes are used as a replacement for the 0x02 code when the resulting $LIST string will be shortened.
Every IRIS and every Caché server version since 2016.2 will accept $LIST strings containing these $LIST compression codes even when $LISTBUILD has been told not to generate these codes.
$LIST codes 0x0A, 0x0B and 0x0C are reserved for the future and have not been implemented. $LIST code 0x10 is used the the ObjectScript $VECTOR types. $LIST byte codes larger than 0x18 are reserved communicating special cases during internal transfers using $LIST data strings. These special communication bytes codes are never generated by $LISTBUILD.
- Log in to post comments
The behavior of $LISTBUILD on big-endian instances and little-endian instances is identical. $LISTBUILD always builds a string of 8-bit bytes with the payload always in little-endian order. This means $LIST data can be shared between big- and little-endian instances. A $LIST string only uses characters between $C(0) and $C(255) since byte strings can be easily transferred over 8-bit byte network connections and can be efficiently stored in an InterSystems Globals database. On an IRIS Unicode instance a $LIST string in memory wastes half the bytes since in-memory strings are always encoded using UTF-16 representation. However, InterSystems IRIS will convert such data to 8-bit bytes when storing it in the database.
There are additional type codes than those described in the above article.
- Log in to post comments
Detecting what is a valid $LIST string can be difficult and you cannot trust $LISTVALID to always reject illegal $LIST strings, although it will not reject a legal $LIST string. I.e., $LISTVALID gives false positives but does not give false negatives.
I admit that $LISTVALID accepts $C(2,2) and that is probably a bug. However, $LISTVALID will not accept $c(3,2,32), a Unicode $LIST string containing one blank characters while $LISTVALID will accept $C(3,1,32) , an 8-bit $LIST string containing one blank character.
$LISTVALID is the only $LISTxxx function that spends extra execution cycles to find harmless, invalid $LIST strings. The other $LISTxxx functions do check string lengths and byte code ranges to give a <LIST> or <FUNCTION> error signal instead of touching out-of-bounds memory but these other $LISTxxx functions spend no further execution time doing extra testing.
$LISTVALID(result) will accept your 'result' string from above. However, if we change your 'result' variable to make the third $LIST entry encode three 8-bit characters using type type code 0x02 then both $LISTVALID and the ZWRITE command will reject your 'result' string because it contains a Unicode $LIST element that only contains 8-bit characters.
USER>set result = $c(3,4,125,2,2,5, 2,97,98,99)
USER>zw result
result=$c(3,4)_"}"_$c(2,2,5,2)_"abc"
USER>zw $LISTVALID(result)
0
Also, $LIST(result,3) will generate a <FUNCTION> signal as there seems to be some worry about widening a Unicode string that does not need widening. But $LIST(result,4) will signal <NULL VALUE> because $LIST will skip over the properly sized 3rd $LIST element.
Setting x="" is a perfectly valid $LIST string with zero elements and you can repetitively execute
SET x = x _ $LB(.....)
to grow the size of $LIST string 'x'.
If you execute SET y=$LB(), then 'y' is a $LIST string with one element that will signal <NULL VALUE> if you evaluate $LIST(y,1) (or equivalently $LIST(y)).
One final example:
USER>set y=$lb(,,"Z")
USER>zzdump y
0000: 01 01 03 01 5A ....Z
USER>zwrite y
y=$lb(,,"Z")
Summary: It requires care to call a $LISTxxx function with a string argument not generated by $LISTBUILD (or by the concatenation of either empty strings or strings generated by $LISTBUILD or by SET $LIST(variable,i)=value) Carelessly constructed $LIST strings can work in some places but give strange results in other places.