intel / tinycbor

Concise Binary Object Representation (CBOR) Library
MIT License
502 stars 187 forks source link

Buffer full when inserting latter value of pair to the map #190

Open WirepasHannu opened 4 years ago

WirepasHannu commented 4 years ago

Hi!

I have a question which I have not found answer for. Since map contains pairs of items and I understood basically as dictionary (albeit basically same key could occur there multiple times but in my use case not), first value being a key and second one being a value.

So something like:

uint8_t payload[BUFFER_SIZE];
CborEncoder encoder, mapEncoder;
cbor_encoder_init(&encoder, payload, BUFFER_SIZE, 0);
cbor_encoder_create_map(&encoder, &mapEncoder, CborIndefiniteLength); // Don't know in advance how many
...
// Key value pairs are inserted
// until buffer is almost full
...
// Here, inserting key that still fits. Using uint key values for length optimization
// This one succeeds
cbor_encode_uint(&mapEncoder, 0xDEAD);
// Not matter what is the value but something that does not fit. For example string
CborError err = cbor_encode_byte_string(&mapEncoder, "whatever", 8);

What would be the correct procedure to take when writing a key fits to buffer but when writing the value, the buffer is exceeded? We have statically allocated buffer of specific size so it is not possible to reallocate more room.

Currently I'm now evaluating the size of the key+value beforehand and then evaluating whether whole key+value combination is inserted at all. Albeit it works, it feels bit ugly. Instead, if writing of the value fails, the key could be reverted as well (because otherwise when map is closed, last item contains only key and not value). I cannot find any means to do that though.

Any suggestions?

PS Otherwise, this works like a charm and fits to my use case perfectly.

thiagomacieira commented 4 years ago

The correct procedure is to increase the buffer size until it fits. You can get the full size after you've finished encoding all your data (past the encoding error, just keep going!) and reallocate the buffer, using cbor_encoder_get_extra_bytes_needed.

WirepasHannu commented 4 years ago

Hi!

Thanks for comment. However, increasing a size is not an option for me because we have statically allocated buffers and no option to increase the size. I'll let anyone know if I find some better approach to overcome the problem.

thiagomacieira commented 4 years ago

Then you will know at which point you ran out of buffer space and you can re-do it without adding that element pair. If the key fit, then the terminator 0xff definitely does too.

WirepasHannu commented 4 years ago

Yes. So approach is to store the state of the encoder before inserting key/value pair. If either of those fail, then revert the state to previous one. Sounds feasible.