Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature request] Convenience decode functions for tagged data #120

Open
Anrock opened this issue Aug 31, 2021 · 5 comments
Open

[feature request] Convenience decode functions for tagged data #120

Anrock opened this issue Aug 31, 2021 · 5 comments

Comments

@Anrock
Copy link

Anrock commented Aug 31, 2021

I'm not sure why QCBOR API was designed to treat tags as if they're attached to an enclosed items instead of the other way around but this makes decoders for protocols where major type of an item depend on a tag that wraps it quite inconvinient.

For example, imagine a protocol where one of the fields may contain some complex structure of useful payload or an error code integer. To distinguish, protocol wraps payload in 0x30 tag and error code in 0x31.

In order to decode that, one would have to QCBORDecode_VPeekNext (since it's unknown what major type of the next item) next item into some one-shot QCBORItem variable (since QCBOR attaches tags to an item) and then use QCBORDecode_GetNthTag (since VPeekNext was used) to get the tag, then switch-case on the tag, handle unknown tag values and proceed with spiffy decode functions deeper into the structure. It gets worse if there are multiple nested tags.

I believe that a couple of new functions would ease the situation. One basic decode function, say QCBORDecode_GetTag(uint64_t* tag), that consumes next tag and fills out argument. And one function for spiffy decode, say QCBORDecode_EnsureTag(uint64_t tag) that consumes next tag and checks that it's equal to an argument.

If those functions are present one could write more linear code, something like:

QCBORDecode_EnsureTag(&ctx, TAG_SUCCESS);
QCBORDecode_EnterArray(&ctx);
// decode payload
if (QCBORDecode_GetError(&ctx) != QCBOR_SUCCESS) {
  QCBORDecode_Rewind(&ctx);
  // decode error
}

Instead of multiple nested switch-cases or ifs and a bunch of temp variables.

@laurencelundblade
Copy link
Owner

I agree that improvements can be made and I intend to do this work.

It will take me a little while to get to it and may be a lot of work to do a good job of it.

Thank you for the comment.

@laurencelundblade
Copy link
Owner

Still working on it... Want to do a thorough job. If you have examples of protocols you want to decode, I'm interested. The most complex case I'm looking at is CWT + COSE which has variants and rules for how the tags nest.

Want to be able to cleanly handle branches in decoder flow when a tag is encountered or not encountered.

@Anrock
Copy link
Author

Anrock commented Nov 22, 2021

It's a custom proprietary protocol, so I'm not sure if I can share it here, sorry. But scheme is basically a tree where each node is an array with statically known "envelope"-fields and last field is some tagged array/map structure and it's scheme determined by a tag.

@laurencelundblade
Copy link
Owner

It's just one level of tag, right? No nesting of one tag in another (like CWT/COSE), right?

@Anrock
Copy link
Author

Anrock commented Nov 23, 2021

@laurencelundblade up to 2 tags nesting. As I've mentioned in opening post there is at least (Success)(PayloadType)[fields] and (Failure)(ErrorType)[fields] now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants