laurencelundblade / QCBOR

Comprehensive, powerful, commercial-quality CBOR encoder/ decoder that is still suited for small devices.
Other
182 stars 47 forks source link

There doesn't appear to be a way to determine how much space is needed for encoding #121

Closed arai-fortanix closed 2 years ago

arai-fortanix commented 3 years ago

qcbor_encode.h has a comment that says:

A common encoding usage mode is to invoke the encoding twice. First with no output buffer to compute the length of the needed output buffer. Then the correct sized output buffer is allocated. Last the encoder is invoked again, this time with the output buffer.

The double invocation is not required if the maximum output buffer size can be predicted. This is usually possible for simple CBOR structures. If the double invocation is implemented, it can be in a loop or function as in the example code so that the code doesn't have to actually be written twice, saving code size.

I don't see a way to encode with no output buffer to compute the needed length. I can create the encoding context with a NULL UsefulBuf. But if I do this, QCBOREncode_Finish() and QCBOREncode_FinishGetSize() just return QCBOR_ERR_BUFFER_TOO_SMALL, and I don't see a way to get the required length. The comment says to look in the examples, but I don't see any of the example code doing the suggested double-invocation. Am I missing something?

laurencelundblade commented 3 years ago

The size of the UsefulBuf should be UINT32_MAX or such to avoid QCBOR_ERR_BUFFER_TOO_SMALL . See the documentation for QCBOREncode_Init()

Let's leave this issue open to remind me to improve the documentation that you reference above.

Thanks for pointing this out.

arai-fortanix commented 2 years ago

Thank you. I have verified that this works as documented by QCBOREncode_Init(). I think one thing that was confusing me was that the NullUsefulBuf constructor creates a UsefulBuf with a pointer of NULL and length of 0. It may make sense to have a UsefulBuf constructor that sets the pointer to NULL and the size to UINT32_MAX, so there's a more obvious way to use this functionality. It would also help to have an example in example.c that shows how to do this.

laurencelundblade commented 2 years ago

123

laurencelundblade commented 2 years ago

Fixed with #123