Iterate over %List/$lb in C
I'm using callin to get global values.
Here's a simple function to get string value from global and return it:
int GetGlobalStr(char *global, CACHE_EXSTRP result)
{
int push = CACHEPUSHGLOBAL(strlen(global), global);
// narg Number of subscript expressions pushed onto the argument stack.
int narg = 0;
// flag - Indicates behavior when global reference is undefined:
// 0 — returns CACHE_ERUNDEF
// 1 — returns CACHE_SUCCESS but the return value is an empty string.
int flag = 1;
int get = CACHEGLOBALGET(narg, flag);
int pop = CACHEPOPEXSTR(result);
return ZF_SUCCESS;
}
I get global value in result successfully. However I need to iterate over $lb. How can I do that?
the structure of $LB() is rather simply a binary string
-----------element--------------
TotalLength = 1, 3, 7 bytes depending on size *corrected*
Type = 1 byte (check in JSON converter for codes, or just check with ZZDUMP)
Content : size = TotalLength-1-size of length field
-----------element--------------
TotalLength = 1, 3, 7 bytes depending on size *corrected*
Type = 1 byte (check in JSON converter for codes, or just check with ZZDUMP)
Content : size= TotalLength-1-size of length field
-----------element--------------
...
Therefore concatenation of $lb) is so easy
special case:
0000: 01 .
1
0000: 02 01 ..
2
0
the total size is somewhat strange its format changes from 255 to 256 in size and interpretation
and again at 65535 / 65536 up to <MAXSTRING>
Callin is stack-based. You push function arguments to a stack, call function, read result from stack.
These two functions are used to push and pop $lb to stack, not to get individual $lb elements.
Thank you, @Steven Hobbs ! I'll try to fix my code on LE platforms at the very least.
Is there any place I can familiarize myself with these rules?
Thank you Robert!
To be honest I'm hoping someone has C code to share.
So, you can convert $List to some kind of List in C?
$LIST is a very simple format, but you can't get any particular item just by position. You should go through the list from the first item.
In a simple explanation, it is just concatenation of individual $LIST. So, you can't say how many items you have until you go through this list and count them.
I have not played with C, yet. But I found CachePopList and CachePushList. have you tried to play with it? Looks like it may help you to order over $List.
See %CACHE_HOME%\dev\Cache\callout\demo\czf.pdf (Section "Lists")
Here's a sample C code to iterate over $lb structure.
There are some issues with above C code for manipulating a string of $LIST elements.
I do not believe the above code will work on a big-endian platform, such as PowerPC running the AIX operating system. Conversions from $LIST representation to numeric representation will order the bytes backwards on big-endian hardware.
Decimal floating-point values in IRIS and Caché have almost 19 decimal digits of precision while the above code translates these numbers to IEEE binary double-precision floating-point values which have less than 16 decimal digits of precision. This means that $LISTBUILD(0.3) will be converted by the above code into the value 0.29999999999999998889... . The above code also introduces a double-round error so that decoding $listbuild(x) and $listbuild($double(x)) will not always be equal because the $double(x) function in IRIS/Caché will do the conversion from decimal to binary without a double round.
The above code is inconsistent in resulting type of integer values. Consider,
USER>set L5A=$LISTBUILD(5),L5B=$LISTBUILD(50/10)
USER>WRITE $LISTSAME(L5A,L5B)
1
The $LIST elements in L5A and L5B contain the same value, 5. However, the above code will convert L5A to the C int64_t type while it will convert L5B to the C double type. If the value of the integer is greater than 2**53 then the above C code can convert the identical integer values into different integer values.
Also, the above code does not correctly handle all the special cases when (type==FLOAT) is true.
The IRIS/Caché $LIST representation is not as simple as most people think. There are some unusual rules that must be followed if you want to get the same results as the $LISTxxx functions get in IRIS/Caché.
Social networks
InterSystems resources
Log in or sign up
Log in or create a new account to continue
Log in or sign up
Log in or create a new account to continue
Log in or sign up
Log in or create a new account to continue