How to check if field exists or is null in a solace map?

vkhavulya
vkhavulya Member Posts: 2
edited December 2023 in General Discussions #1

I am using Solace c client api (CCSMP), to subscribe to a Solace topic where messages contain a map. A value for the same key in a map can be a string or null. Is there a way to check if a value for a key is null? If I try to retrieve a value for a key and it's null, Solace API logs "Field Type Null could not be converted to string".

Sample code:

solClient_rxMsgCallback_returnCode_t
messageReceivedCallback(solClient_opaqueSession_pt opaqueSession_p, solClient_opaqueMsg_pt msg_p, void *user_p)
{
    solClient_returnCode_t rc = SOLCLIENT_OK;

    solClient_opaqueContainer_pt map_p;
    if ((rc = solClient_msg_getBinaryAttachmentMap(msg_p, &map_p))!= SOLCLIENT_OK)
    {
        //log error
        return  SOLCLIENT_CALLBACK_OK;
    }

    char buffer[128];

    //if(map_p has field "some_field" and it its value is not null) <-- how to do this?
    //{
        solClient_container_getString(map_p, buffer, 128, "some_field");
    //}
}

Thanks,
Vlad

Best Answers

  • Ragnar
    Ragnar Member, Employee Posts: 65 Solace Employee
    edited January 3 #2 Answer ✓

    Hello Vlad,

    You can use solClient_container_getFieldto retrieve the field and type, then your code would look like this:

    solClient_rxMsgCallback_returnCode_t
    messageReceivedCallback(solClient_opaqueSession_pt opaqueSession_p, solClient_opaqueMsg_pt msg_p, void *user_p)
    {
        solClient_returnCode_t rc = SOLCLIENT_OK;
    
        solClient_opaqueContainer_pt map_p;
        if ((rc = solClient_msg_getBinaryAttachmentMap(msg_p, &map_p))!= SOLCLIENT_OK)
        {
            //log error
            return  SOLCLIENT_CALLBACK_OK;
        }
    
        char buffer[128];
    solClient_field_t mapEntry; //if(map_p has field "some_field" and it its value is not null) <-- how to do this? //{ solClient_container_getField(map_p, &mapEntry, sizeof(mapEntry), "some_field");
    switch (mapEntry.type) { case SOLCLIENT_NULL: // handle null field break; case SOLCLIENT_STRING: strncpy (mapEntry.value.string, buffer, sizeof(buffer)); break; default: // handle unexpected field break; } //} return SOLCLIENT_CALLBACK_OK; }

    I've left out the error checking necessary on 'getField' and strncpy but you get the idea.

    Note also that where solClient_container_getString does a copy-out into your buffer, solClient_container_getField returns a pointer to the string (when it's a string) and you must perform the copy-out operation yourself (i.e strncpy). That pointer returned may not be valid outside the scope of the callback and should not be saved or used later.

    Ragnar

  • vkhavulya
    vkhavulya Member Posts: 2
    #3 Answer ✓

    Thanks, that works well!

Answers

  • Ragnar
    Ragnar Member, Employee Posts: 65 Solace Employee
    edited January 3 #4 Answer ✓

    Hello Vlad,

    You can use solClient_container_getFieldto retrieve the field and type, then your code would look like this:

    solClient_rxMsgCallback_returnCode_t
    messageReceivedCallback(solClient_opaqueSession_pt opaqueSession_p, solClient_opaqueMsg_pt msg_p, void *user_p)
    {
        solClient_returnCode_t rc = SOLCLIENT_OK;
    
        solClient_opaqueContainer_pt map_p;
        if ((rc = solClient_msg_getBinaryAttachmentMap(msg_p, &map_p))!= SOLCLIENT_OK)
        {
            //log error
            return  SOLCLIENT_CALLBACK_OK;
        }
    
        char buffer[128];
    solClient_field_t mapEntry; //if(map_p has field "some_field" and it its value is not null) <-- how to do this? //{ solClient_container_getField(map_p, &mapEntry, sizeof(mapEntry), "some_field");
    switch (mapEntry.type) { case SOLCLIENT_NULL: // handle null field break; case SOLCLIENT_STRING: strncpy (mapEntry.value.string, buffer, sizeof(buffer)); break; default: // handle unexpected field break; } //} return SOLCLIENT_CALLBACK_OK; }

    I've left out the error checking necessary on 'getField' and strncpy but you get the idea.

    Note also that where solClient_container_getString does a copy-out into your buffer, solClient_container_getField returns a pointer to the string (when it's a string) and you must perform the copy-out operation yourself (i.e strncpy). That pointer returned may not be valid outside the scope of the callback and should not be saved or used later.

    Ragnar

  • vkhavulya
    vkhavulya Member Posts: 2
    #5 Answer ✓

    Thanks, that works well!