Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

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

未关闭
#252 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
35/100
Issue 类型
缺陷
描述清晰度
需要澄清
活跃度
停滞
技术栈
c
领域
backend

调研方向

使用报告中的单数组示例,从 cbor_parser_init、cbor_value_enter_container、cbor_value_leave_container 和 cbor_value_advance 的行为入手。跟踪嵌套遍历期间 CborValue 游标和剩余计数如何变化,然后验证文档化的 API 是否支持重新启动同一个容器;当受支持的重置或重新进入行为得到明确确认时,即视为完成。

由索引模型根据 Issue 内容生成。

描述

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!

主要语言
C
星标
634
派生
222
平均合并
1 天 25 分钟
30 天内合并 PR
2

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

intel/tinycbor 的其他 Issue

查看 intel/tinycbor 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。