Skip to content

Can not leave or re-enter the container when parsing the SENML-CBOR array #252

Open
@Antdigapony

Description

Hello, I am dealing with a such SENML-CBOR array:

[{0: "/3/0/10", 2: 55}]
It has one item and 2 maps as you can see.

Also this aray may be bigger, for example:
[{0: "/3/0/10", 2: 55}, {0: "/3/0/12", 3: "ResetErrors"}, {0: "/3/0/13", 6: 2889055551}, {0: "/3/0/4", 3: "Reboot"}, {0: "/3/0/9", 2: 100}].

I am trying to run through this array once, check the every first map of every item of the array and then I need to get back to the begining of this array and parse it to the end.
But I have an issue with getting back to the array's begining/start.

Here is my code with yours library've been implemented:

    err = cbor_parser_init(buffer, bufferLen, 0, &parser, &array);    
    if (err != CborNoError)
    {
        LOG_ARG("cbor_parser_init FAILED with error %d", err);
        return -1;
    }

    CborType type = cbor_value_get_type(&array);
    LOG_ARG("type = %x(%d)", type, type);
    if (type == CborArrayType) 
    {
        err = cbor_value_get_array_length(&array, &arrLen);
        if (err != CborNoError)
        {
            LOG_ARG("cbor_value_get_array_length FAILED with error %d", err);
            return -1;
        }
        LOG_ARG("array length = %d", arrLen);
        if (arrLen <= 0) {
            LOG("wrong array length FAILED");
            return -1;
        }
        if (arrLen > 0) 
        {
            sCount = prv_count_s_in_array(&array);
            LOG_ARG("s quantity = %d", sCount);
            LOG_ARG("array remaining = %d", array.remaining);
            /// Here I need to get back to the array.start and parse it "once again"
        }                                    
        
  /*  prv_count_s_in_array brief*/      
 size_t prv_count_s_in_array(CborValue* array) {
    CborValue map;
    CborError err;
    CborValue arrayStart;
    int sCount = 0;

    // Enter the CBOR array
    err = cbor_value_enter_container(array, array);
    if (err != CborNoError)
    {
        LOG_ARG("cbor_value_enter_container array FAILED with error %d", err);
        return -1;
    }

    // Save the starting position of the array
    cbor_value_get_next_byte(&arrayStart);
    arrayStart.parser = array->parser;

    // Iterate through each map in the array
    while (!cbor_value_at_end(array)) 
    {
        LOG("CHECKPOINT 1 -------------------------------------------");
        err = cbor_value_enter_container(array, &map); // Enter each map
        if (err != CborNoError)
        {
            LOG_ARG("cbor_value_enter_container map FAILED with error %d", err);
            return -1;
        }

        while (!cbor_value_at_end(&map)) 
        {
            LOG("CHECKPOINT 2 -------------------------------------------");
                
            // Skip the key
            err = cbor_value_advance(&map);
            if (err != CborNoError) {
                printf("Error advancing to value\n");
                return -1;
            }  
            // Get the value
            CborType typeMap = cbor_value_get_type(&map);
            if (typeMap == CborTextStringType) 
            {
            // If the value is a text string, count the backslashes
            // if (cbor_value_is_text_string(&map)) {
                size_t len;
                char *text;
                
                cbor_value_dup_text_string(&map, &text, &len, NULL);
                // Count *** in the string
                int sCount = countS(text);
                // Check if the count is equal to 3 (indicating a resource)
                if (sCount == 2) {
                    sCount++;
                }
            }/// MAP_NAME
            // Move to the next key-value pair
            err = cbor_value_advance(&map);
            if (err != CborNoError) {
                LOG_ARG("cbor_value_advance map FAILED with error %d", err);
                return -1;
            }
        }///!while not end map
        LOG("CHECKPOINT 4 -------------------------------------------");
        err = cbor_value_leave_container(array, &map); /// leave the map
        if (err != CborNoError)
        {
            LOG_ARG("cbor_value_leave_container array FAILED with error %d", err);
            return -1;
        }
        LOG("CHECKPOINT 5 -------------------------------------------");
        LOG_ARG("array->remaining %d", array->remaining);
        /// Move to the next map
        if (array->remaining > 1){
            err = cbor_value_advance(array);
            if (err != CborNoError) {
                LOG_ARG("cbor_value_advance array FAILED with error %d", err);
                return -1;
            }
        }
    }///!while not end of array
    /// Here I have tried to leave the array-array-container or/and enter the array-array-container once more but FAILED
    /// err = cbor_value_leave_container(array, array); /// leave the array
    ///    if (err != CborNoError)
    ///    {
    ///        LOG_ARG("cbor_value_leave_container array FAILED with error %d", err);
    ///        return -1;
    ///    }
    LOG("CHECKPOINT 6 -------------------------------------------");
    /// err = cbor_value_enter_container(array, array); /// re-enter the array
    ///    if (err != CborNoError)
    ///    {
    ///        LOG_ARG("cbor_value_leave_container array FAILED with error %d", err);
    ///        return -1;
    ///    }

    // Reset the array pointer to the starting position
    *array = arrayStart;

    return resourceCount;
} 
        

So, is the entering of the same container possible? Or, maybe, there is some other method to switch back the CborValue to the start of the cbor-buffer?
I guess that leave-container() may not work, cause there may be NO next array - we have only one array and leave_container seems to need the next value to switch to.
But, why the enter-container does not work? I have checked the array.remaining and it was 0 in the end of my function.
Now I am using a workaround - I am saving the starting point and re-setting it when I finish my checking function.
Also I want to admit that leave_container(array,map) works fine. So, question is about re-entering the array mainly.
Maybe there is something I have missed. Will be glad and grateful for any advice.

In any way, thanks for your library! Have a nice day, cheers!

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions