使用TinyCbor C库对uint8_t进行编码和解码

时间:2018-06-08 14:33:24

标签: c++ c uint8t cbor

我正在实现基于C ++ 11的应用程序,我正在使用TinyCbor C库来编码和解码特定于应用程序的数据,如下所示:

#include "cbor.h"
#include <iostream>

using namespace std;

int main() {

    struct MyTest {
        uint8_t varA;
        float vabB;
    };

    MyTest obj;
    obj.varA = 100; // If I set it t0 below 20 then it works 
    obj.varB = 10.10;

    uint8_t buff[100];

    //Encode
    CborEncode encoder;
    CborEncode array;
    cbor_encoder_init(&encoder, buff, sizeof(buff), 0);

    cbor_encoder_create_array(&encode, &array, CborIndefiniteLength);
    cbor_encode_simple_value(&array, obj.varA);
    cbor_encode_float(&array, obj.varB);
    cbor_encoder_close_container(&encoder, &array);

    // Decode 
    CborParser parse;
    CborValue value;
    cbor_parser_init(buff, sizeof(buff), 0, &parser, &value);

    CborValue array;
    cbor_value_enter_container(&value, &array);

    uint8_t val;
    cbor_value_get_simple_type(&array, &val);
    // This prints blank
    cout << "uint8_t value: " << static_cast<int>(val) << endl;

    float fval;
    cbor_value_get_simple_type(&array, &fval);
    cout << "float value: " << fval << endl;

    return 0;
}

当我将uint8_t varA的值设置为低于20时,上面的代码有效,我看到20在控制台上打印但是如果我设置超过20,那么有时它会给出错误CborErrorIllegalSimpleType。或者,如果将值设置为21,则会将其返回为CborBooleanTypeCborNullType

  1. 代码有什么问题

  2. 如何使用TinyCbor对uint8_t进行编码和解码。

2 个答案:

答案 0 :(得分:1)

您正在做一些事情。

  

cbor_encoder_create_array(&encode,&array,CborIndefiniteLength);

除非您打算流式传输编码,否则请不要使用不确定的长度。如果在加密时将所有数据摆在面前,请使用定义的长度。在这里查看原因:Serialize fixed size Map to CBOR,而且我不确定您使用的是哪个版本,但不确定长度的对象至少在最近是TinyCBOR的“待办事项”列表项。

  

cbor_value_get_simple_type(&array,&val);

这里不需要简单。简单类型是基本未定义的原语。 CBOR的默认类型为int64_t,签名为long long long。 Simple确实允许自然停止在8位,但是simple中的20是布尔值false。 21是,22空。您已经发现了这一点。它不能存储负数或浮点数,虽然可以用它来表示8位(例如“ 100”),但实际上不应该。关于CBOR类型的好消息是,尽管默认值为64位,但它只使用很少的内存即可根据需要进行编码。因此,将100存入CBOR是一个字节,而不是8个字节,这还不算一秒钟的开销。

按开销,我的意思是,当您编码cbor整数时,前三位表示UNSIGNED INTEGER(二进制000),一位保留,其余4位为值,因此,如果您有一个适合这些值的小值四位(值0-23)可以在一个字节中获得全部信息。该保留位很奇怪,请参见此处的图表以了解它:https://en.m.wikipedia.org/wiki/CBOR因此24-255需要2字节编码,以此类推。与之相差甚远的是,总是因为它可以使用8字节。

此处的简短版本是CBOR使用的空间不会超过所需的空间-但是-它不是强类型的序列化器!如果您打算将100个内部8位存储在该数组中,而有人将10000个内部8位存储在16位中,那么在您解析并在8位位置存储大量数字之前,它看起来/可以正常工作。您需要强制转换或验证数据。我建议先解析然后验证。

  

cbor_value_get_simple_type(&array,&fval);

     

cout <<“浮点值:” << fval << endl;

我必须查看TinyCBOR的代码,但是我认为这是一次不幸的事故,没有技术上的支持。由于简单类型使用相同的三个主要位,因此您可以使用get_simple获得该值的64位精度。相反,您应该检查类型并进行正确的调用以获取全精度或半精度浮点数。

TinyCBOR非常不错,但是肯定隐藏了一些陷阱。即使您相信序列化程序可以为您完成工作,了解CBOR编码也确实有帮助。

答案 1 :(得分:0)

改为使用CborError cbor_encode_uint(CborEncoder *encoder, uint64_t value)。此函数将编码具有最小表示形式的无符号整数值。