[英]Encoding and decoding uint8_t using TinyCbor C Library
我正在實現基於 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
。 或者,如果 value 設置為21
則它返回我的類型為CborBooleanType
或CborNullType
。
代碼有什么問題
如何使用 TinyCbor 對uint8_t
進行編碼和解碼。
你有一些事情在這里發生。
cbor_encoder_create_array(&encode, &array, CborIndefinedLength);
除非您計划流式傳輸編碼,否則不要使用不確定長度。 如果在編碼時您面前有所有數據,請使用定義的長度。 在這里查看原因:也將固定大小的映射序列化為 CBOR ,我不確定您使用的是哪個版本,但不確定長度的對象至少在最近是 TinyCBOR 的待辦事項列表項。
cbor_value_get_simple_type(&array, &val);
在這里你不需要簡單。 簡單類型是大多數未定義的原始類型。 CBOR 的默認類型是 int64_t,signed long long。 簡單確實允許在 8 位自然停止,但簡單中的 20 是布爾假。 21 真,22 空。 你已經發現了這一點。 它不能存儲負數或浮點數,雖然您可以用它來表示像“100”這樣的 8 位,但您真的不應該這樣做。 關於 CBOR 類型的好消息是,雖然默認值是 64 位,但它根據需要使用盡可能少的內存進行編碼。 所以在 CBOR 中存儲 100 是一個字節,而不是 8,不計算一秒鍾的開銷。
我的意思是,當你編碼一個 cbor 整數時,前三位表示 UNSIGNED INTEGER(二進制 000),一位被保留,其他 4 位是值,所以如果你有一個適合這四位的小值(值 0-23) 您可以在一個字節中獲得所有內容。 這個保留位很奇怪,請參閱此處的圖表以了解它: https ://en.m.wikipedia.org/wiki/CBOR 所以 24-255 需要 2 個字節編碼,等等。與它總是使用 8bytes 相去甚遠因為可以。
這里的簡短版本是 CBOR 不會使用比需要更多的空間 - 但是 - 它不是強類型序列化程序! 如果您的意思是將 8 位中的 100 存儲在該數組中,而有人將 10000 存儲為 16 位,那么在您解析並在 8 位位置存儲大量數字之前,它看起來/工作正常。 您需要轉換或驗證您的數據。 我建議解析然后驗證。
cbor_value_get_simple_type(&array, &fval);
cout << "浮點值:" << fval << endl;
我必須查看 TinyCBOR 的代碼,但我認為這是一個快樂的意外,並且在技術上不支持工作。 因為簡單類型使用相同的三個主要位,所以您可以使用 get_simple 獲得值的 64 位精度。 您應該檢查類型並正確調用獲取全精度或半精度浮點數。
TinyCBOR 相當不錯,但肯定隱藏了一些陷阱。 即使您信任序列化程序為您完成工作,它也確實有助於理解 CBOR 編碼。
使用CborError cbor_encode_uint(CborEncoder *encoder, uint64_t value)
代替。 此函數將以最小的表示對無符號整數值進行編碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.