我正在实现基于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
,则会将其返回为CborBooleanType
或CborNullType
。
代码有什么问题
如何使用TinyCbor对uint8_t
进行编码和解码。
答案 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)
。此函数将编码具有最小表示形式的无符号整数值。