groupId RsslBuffer type to std::string

Below is Description of groupId:

The groupId with which this information is associated. This is typically represented as a series of 2-byte unsigned integers (i.e. two-byte unsigned integers written directly next to each other in the buffer). The example provided in the RANGE / EXAMPLE column of this table shows such a series, with inserted dots to help indicate two-byte value. When encoded into a buffer, do not include dots.

What is the proper way to copy/convert groupId into std::string so that groupId be stored and logged with human readable format?

I have tried the following:

const std::string groupId{msg->refreshMsg.groupId.data, msg->refreshMsg.groupId.length};

const std::string_view groupId{msg->refreshMsg.groupId.data, msg->refreshMsg.groupId.length};

Best Answer

  • Hi @tinmyo.win,

    The buffer can contain a series of 2-byte blocks, in network byte order, representing the groupID. As such, try iterating through the buffer and assigning the 2 bytes into an unsigned short. That is

    image

    Note: ETA also has an example of how they dump the groupID using the 'xmlDumpMsgBegin' function.

    Here is an example of the output from above:

    image

Answers

  • Thanks for the code snippet. I am able to extract groupId correctly now.

    Can you please also point me to how to create RsslBuffer with different length of groupId? The reason is transport API document states that a consumer needs to handle group Id with variable length such as "1.26.102". We requested different security type and different symbols but we have seen only group Id response with single 2-byte integers. We would like to create test cases with groupId, that has series of 2-byte integers.

  • Hi @tinmyo.win,

    EDIT: The answer below was based on testing against an EMA IProvider Training example that set the group ID. However, through further testing, it appears the example does not properly assign the group ID based on network byte order. I will need to confirm with the development team. Please refer to the first answer above for the actual algorithm to process the group ID.

    First thing, I updated my answer above to correct the algorithm to properly extract the 2-bytes and store within an unsigned short. Instead of:

    unsigned short id = (groupId->data[i] << 8) | groupId->[i + 1];

    It now reads:

    unsigned short id = (groupId->data[i] | groupId->[i + 1] >> 8);

    To create a test case that has a series of 2-byte integers, one way is to utilize one of the EMA IProvider Training examples, specifically 250__GroupStatus__Fanout. In there, you can modify the code to add additional groupIds. For example, I defined a new ID called: 'secondaryGroupId = 19', i.e.

    image

    You can add as many as you want to test. Then I simply added the following line within the AppClient::processMarketPriceRequest() method:

    image

    You can then take your ETA consumer application and test it against this Provider and you should see 2 ID values (10 and 19) displayed.

  • Hi @nick.zincone.1, we have been strictly using Eta API and sink_driven_source + ADS as our provider. Is there anyway we can create groupId RsslBuffer with Eta API?

  • Hi @tinmyo.win,

    I understand you are strictly using the ETA API, but to setup a simple provider to test is the easiest way given the EMA examples are packaged alongside the ESDK package. You don't have to download / install any separate software to make this work.

    That being said, if you have to setup a test that must be written in ETA, I would ask this as a separate question. It helps guide the community to find answers. We don't want to see multiple questions within one post.

  • is anything wrong with ?:

    unsigned short id = (groupId.data[i] << 8 | groupId.data[i+1]);

    I am unable to parse group ID with updated answer you have provided below:

    unsigned short id = (groupId.data[i] | groupId.data[i + 1] >> 8)

  • Hi @tinmyo.win,

    Yes, the first formula I gave didn't manipulate the bytes correctly. The 2nd formula is correct. What do you mean "unable to parse"? I just tried it again without issue.

  • @nick.zincone.1 with new algorithms below you suggested:

    unsigned short id = (groupId->data[i] | groupId->[i + 1] >> 8);

    I noticed that all the groupIds are parsed as "0". I ended up using the first algorithm you shared. The first algorithms seem to be working fine as far as I know since I have been testing with large amount of symbols in real endpoints. That's the reason I would like to know is there any situation where the first algorithms won't handle the bit shift correctly.

    If my understanding is correct, the second algorithms uses the bits in the first byte of groupId while the first algorithms uses the bits in the second byte of the groupId. Thanks for your feedback!

  • Hi @tinmyo.win,

    Yes, the value I see when testing against my ADS does come back as zero (0) for the 2nd algorthm - the 1st algorithm, the value I received was 1. The reason I believe the 2nd algorithm is correct is because when I tested the against the Provider, the values came back correct. The 1st algorithm resulted in incorrect values.

    Why do you believe the value zero (0) is incorrect?

  • @nick.zincone.1 I submitted a question in another thread regarding "0" groupId whether it's a valid groupId value: https://community.developers.refinitiv.com/questions/47874/handling-zero-mergetogroup-value.html

    My consumer app is receiving GroupId CLOSE_RECOVER updates followed by mergedToGroupId "0" for the GroupId. For example, I am receiving GroupId "1" CLOSE_RECOVER followed by GroupId "1" to MergeToGroup "0". My assumption is provider was sending the default "0" value for the staled GroupId. Hopefully someone confirms that in the another thread.

  • @nick.zincone.1 you can also crossed check the groupId parsed by rmdstestclient tool with the two algorithms you have shared.

  • Hi @nick.zincone.1, can you please confirm that the following first algorithm is the one we should be using?:

    unsigned short id = (groupId->data[i] << 8) | groupId->[i + 1];

    Please also let us know if it has any issue you are aware of any.

  • Hi @tinmyo.win,

    The 2nd algorithm is the one that you should be using. I know you are seeing zero (0) for your environment but are you able to confirm that your TREP environment has defined group ID's other than zero? Have you tried testing against the EMA example I suggested above? It was that example that allowed me to define my own group ID's to verify that the 2nd algorithm was the one that produced consistent results.

    I've reached out to the TREP infrastructure team to provide a setup where a group ID is defined to further verify. I will come back here once I finalize my testing.

  • thanks @nick.zincone.1 I haven't set up the EMA example you have suggested. However, I compared the two algorithms you have suggested by subscribing to an actual endpoints and found that the groupId parsed by the first algorithms is consistent with the values parsed by rmdstestclient tool at least for the set of symbols I have tested.

  • Thanks @tinmyo.win for testing against the rmdstestclient tool. As it turns out, I found some convenient message dumping functions 'xmlDumpMsg.c' and 'xmlDump.c' that will output the groupID. After testing with these, I found the 1st algorithm I originally posted was correct. It appears that the EMA Provider example may have an issue with how it packs the bytes.

    I've updated the answers above to reflect my findings.

    Note: You may discover that when using the rmdstestclient tool, it displays the groupID in Octal. I can't confirm because I don't have the source code handy, but the ETA dump function prints out in decimal.