laurencelundblade / QCBOR

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

Add the ability to Tell position from an encoder #247

Open BrianSipos opened 1 month ago

BrianSipos commented 1 month ago

I have a need to encode a structure which is an array of arrays, where each inner array ends with a CRC value computed over the inner array. To support this I could manually encode the outer array and then use separate QCBOREncodeContext for each inner array and process them all independently.

To avoid needing to have multiple encoder states and associated bookkeeping, I would like to be able to use a new QCBOREncode_Tell() (or similar) to identify the encoder cursor position at the end of each inner array. Because of how QCBOR encodes array/map heads when the container is closed, the cursor before the CloseArray() will be different than the cursor after the CloseArray(). This is fine and would just need to be part of the Tell documentation so that there is no confusion about the meaning of the returned position.

BrianSipos commented 1 month ago

This kind of thing would also be useful to improve the efficiency of a C509 natively signed certificate encoder using the C509Certificate structure.

laurencelundblade commented 3 weeks ago

This is about any sequence of items that have been encoded, right. Not the contents of array or map, right?

Probably QCBOREncode_Tell() is the best design, but another might be to return an opaque handle and then have a method that takes the handle and returns the pointer and length of the encoded CBOR. It would be more pointer safe for the caller. Would that do everything you want to do?

BrianSipos commented 3 weeks ago

Yes, this would apply to any contiguous sequence of encoded items.

The BPv7 use case covers the array head and uses a zero-octet placeholder CRC value, which can then be replaced (in the encoded buffer) after running the CRC calculation, so a Tell would be used before OpenArray() and after CloseArray().

The C509 use case does not cover an associated array head and computes a signature over the unframed sequence and then appends the signature bstr item to the sequence, so a Tell would be used after any containing OpenArray() and before the signature item is needed.

I think an alternate interface would still work but in both cases these applications deal with encoded CBOR items so they necessarily have visibility/access into the encoded buffer and will need to deal with all the memory safety that entails, so QCBOR doesn't need to "protect" users of these functions too much. Of course, having an explicit statement in the Doxygen comment for the function doesn't hurt.

laurencelundblade commented 2 weeks ago

Let me know if #251 works for you. Thx!